ROS知识(18)----Pluginlib原理
目录
Overview
pluginlib 是一个C++ 类库,用于从一个ROS包中加载和卸载插件 plugins. 插件plugins是一种能从运行库(例如:共享对象,动态链接库)中动态导入的类. 使用 pluginlib, 我们就不必在程序中显式地声明或定义类库,而是可以在代码中的任何位置动态的导入外部的类,甚至我们不需要知道类库或头文件或类定义。Plugins在扩展和修改应用程序(这汇总程序不需要修改应用程序的源码)的时候是非常有用的。例如代价地图层中需要添加一层新的代价地图,用于表示车辆或行人,就需要用到pluginlib导入这一层心的代价地图(一个已经被导出的类,这个类称为插件)。
Example
为了更好的理解plugin是如何工作的,我们来看一个小例子。首先,假设已经有了一个多边形接口包“polygon_interface_package”的ROS包,它包含有一个多边形生成的ploygen基类。在假定我们的系统支持两种多边形,一种是矩形,包含在“rectangle_plugin”中;另一种是三角形,,包含在“triangle_plugin”中。rectangle_plugin 和 triangle_plugin必须在package.xml中声明注册,以便于rosbuild系统能够从polygon_interface_package包里索引到这些多边形插件。这样就可以通过rospack命令来查看ros系统中所有的插件了,例如这个例子中的矩形和三角形。

Providing a Plugin
Registering/Exporting a Plugin
为了能够让一个类能够被动态的导入,它必须被标记为一个导出类。这可以通过特定的宏PLUGINLIB_EXPORT_CLASS来实现。该宏可以放到任何源文件(.cpp)中,这样该源文件定义的类就能变成一个插件库了,注意这个宏一般放在源文件的最后来导出类。对于该例子,我们可以在“example_pkg"中创建class_list.cpp文件,这样就可以把矩形rectangle类编译到librectangle库中。
#include <pluginlib/class_list_macros.h>
#include <polygon_interface_package/polygon.h>
#include <rectangle_package/rectangle.h> //Declare the Rectangle as a Polygon class
PLUGINLIB_EXPORT_CLASS(rectangle_namespace::Rectangle, polygon_namespace::Polygon)
The Plugin Description File
plugin 描述文件是一个XML文件,用于存储了plugin所有重要信息,这种信息格式是可读的。主要包含了插件的名字,插件的类型等等。以rectangle_plugin包为例,该包的插件描述文件(rectangle_plugin.xml)看起来像下面的样子:
<library path="lib/librectangle">
<class type="rectangle_namespace::Rectangle" base_class_type="polygon_namespace::Polygon">
<description>
This is a rectangle plugin
</description>
</class>
</library>
插件描述文件及其关联的tags/attributes的详细介绍请参考documentation.
Why Do We Need This File
除了代码宏,我们需要这个文件以便于让ROS系统自动发现,加载和推理插件。插件描述文件也包含重要信息,如插件的描述,这是宏所不能做到的
Registering Plugin with ROS Package System
为了让pluginlib在ROS包中查询到所有有效的插件,每个包都必须显式地声明导出了哪些插件,这就是通过package.xml来实现了,以rectangle_plugin为例子,只需要在文件中添加一下的代码即可:
<export>
<polygon_interface_package plugin="${prefix}/rectangle_plugin.xml" />
</export>
关于插件导出的详细讨论,请参考documentation。
重要提示:为了能够正确导出类,必须要提供该包的接口依赖,例如rectangle_plugin插件必须在package.xml添加以下的依赖:
<build_depend>polygon_interface_package</build_depend>
<run_depend>polygon_interface_package</run_depend>
Querying ROS Package System For Available Plugins
我们可以使用rospack查询ROS系统包(包括自行开发的插件包)中的所有有效的插件,例如:
rospack plugins --attrib=plugin nav_core
这将会返回 nav_core导出的所有插件。结果如下:
global_planner /opt/ros/indigo/share/global_planner/bgp_plugin.xml
dwa_local_planner /opt/ros/indigo/share/dwa_local_planner/blp_plugin.xml
rotate_recovery /opt/ros/indigo/share/rotate_recovery/rotate_plugin.xml
move_slow_and_clear /opt/ros/indigo/share/move_slow_and_clear/recovery_plugin.xml
clear_costmap_recovery /opt/ros/indigo/share/clear_costmap_recovery/ccr_plugin.xml
carrot_planner /opt/ros/indigo/share/carrot_planner/bgp_plugin.xml
base_local_planner /opt/ros/indigo/share/base_local_planner/blp_plugin.xml
navfn /opt/ros/indigo/share/navfn/bgp_plugin.xml
Using a Plugin
pluginlib在class_loader.h中提供了一个ClassLoader类,用于导入外部的插件。更详细的API文档,请参见。下面我们展示一个简单的例子,实现ClassLoader创建一个rectangle的实例:
#include <pluginlib/class_loader.h>
#include <polygon_interface_package/polygon.h> //... some code ... pluginlib::ClassLoader<polygon_namespace::Polygon> poly_loader("polygon_interface_package", "polygon_namespace::Polygon"); try
{
boost::shared_ptr<polygon_namespace::Polygon> poly = poly_loader.createInstance("rectangle_namespace::Rectangle"); //... use the polygon, boost::shared_ptr will automatically delete memory when it goes out of scope
}
catch(pluginlib::PluginlibException& ex)
{
//handle the class failing to load
ROS_ERROR("The plugin failed to load for some reason. Error: %s", ex.what());
}
Important Note: The ClassLoader must not go out scope while you are using the plugin. So, if you are loading a plugin object inside a class, make sure that the class loader is a member variable of that class.
注意 在使用的插件的时候,ClassLoader必须在域范围内。因此,如果在类中加载插件对象,请确保ClassLoader是该类的成员变量。
Changes from Pre-Groovy pluginlib(过时不做翻译)
Simplified Export Macro
Prior to pluginlib 1.9 (Groovy), the macros PLUGINLIB_REGISTER_CLASS and PLUGINLIB_DECLARE_CLASS were used to register exported classes. These have been deprecated in favor of the new PLUGINLIB_EXPORT_CLASS. The new macro is simpler as it only takes two arguments.
A script has been provided with pluginlib which can be run in the root of your source folder to automatically update the legacy macros to utilize the new one:
plugin_macro_update
Legacy "Lookup Name"
Pre-Groovy versions of pluginlib required specifying a "lookup name" for exported classes in both the plugin description file and export macro. This lookup name acted as an alias for the true class name -- the true class name was not used in the user facing interface. The reason why this lookup alias was used instead of the real name was due to a technical limitation in older versions.
One can now use the real name of a class instead of the lookup name. However, if users want to still use the lookup name, they can add it in their plugin description file. For example:
<library path="lib/librectangle">
<class name="rviz/Rectangle" type="rectangle_namespace::Rectangle" base_class_type="polygon_namespace::Polygon">
<description>
This is a rectangle plugin
</description>
</class>
</library>
pluginlib will now utilize "rviz/Rectangle" instead of "rectangle_namespace::Rectangle" to refer to the class. The real class name cannot be used to refer to the class if a lookup name alias is used. If no lookup name is provided, the lookup name and true class name are equivalent.
Report a Bug
ROS知识(18)----Pluginlib原理的更多相关文章
- ROS知识(5)----消息与服务的示例
ROS中已经定义了较多的标准类型的消息,你可以用在这些标准类型的消息上再自定义自己的消息类型.这个在复杂数据传输很有用,例如节点和服务器进行交互时,就可能用到传输多个参数到服务器,并返回相应的结果.为 ...
- ROS知识(23)——行为树Behavio Tree原理
机器人的复杂行为的控制结构CA(Contrl Architecture)通常使用有限状态机来实现,例如ROS提供的smach.行为树是另外一种实现机器人控制的方法,ROS下代表的开源库有pi_tree ...
- ROS知识(19)----写一个简单的pluginlib例子
参考资料: 官方教程:Writing and Using a Simple Plugin
- mysql数据库补充知识7 索引原理与慢查询优化
一 介绍 为何要有索引? 一般的应用系统,读写比例在10:1左右,而且插入操作和一般的更新操作很少出现性能问题,在生产环境中,我们遇到最多的,也是最容易出问题的,还是一些复杂的查询操作,因此对查询语句 ...
- #知识#室内设计原理ing
室内设计原理 第一章 室内设计的含义和基本观点 人的一生,绝大部分时间是在室内度过的,因此,人们设计创造的室内环境,必然会直接关系到室内生活.生产活动的质量,关系到人们的安全.健康.效率.舒适等等.室 ...
- JSP的学习(1)——基本知识与底层原理
通过之前的学习,我们已经对Servlet有所了解,现在我们先来学习JSP,当能使用JSP进行友好的页面显示之后,再回去学习Servlet的其他高级特性会将整个学习很好的融入进来. JSP,即Java ...
- Synchronized的基本知识、实现原理以及其与ReentrantLock的区别
一.synchronized知识 在谈论synchronized之前,我们需要了解线程安全问题的主要诱因.线程安全问题的主要诱因如下: 存在共享数据(也称为临界资源) 存在多条线程共同操作这些共享数据 ...
- ROS知识(15)----Actionlib的使用(一)
Actionlib是ROS非常重要的库,像执行各种运动的动作,例如控制手臂去抓取一个杯子,这个过程可能复杂而漫长,执行过程中还可能强制中断或反馈信息,这时Actionlib就能大展伸手了. 1.原理 ...
- ROS知识(2)----理解ROS系统结构
学习新事物,方法高于技术本身,如果没有把握"BIG PICTURE"的话很难理解进去.通过以下几点进行理解ROS: ROS实际上不是操作系统,他只是一个通信的框架,一个代码管理的架 ...
随机推荐
- Jenkins无法安装插件或首次安装插件界面提示Offline
一.首先点击系统管理 二.点击插件管理 三.选择高级管理 四.将升级站点中的https改成http即可
- linux用户权限 -> 系统特殊权限
set_uid 运行一个命令的时候,相当于这个命令的所有者,而不是执行者的身份. suid的授权方法 suid 权限字符s(S),用户位置上的x位上设置. 授权方法: passwd chmod u+s ...
- MYSQL-重做系统恢复MYSQL过程
记笔记是好习惯,记笔记是好习惯,记笔记是好习惯! 重要的事情说三遍. 说多了都是泪.第一次装MYSQL时候就遇到了很多问题,当时解决了忘记记录了.家里硬盘满了,于是买了个4T的硬盘重装系统.重装系统后 ...
- L1和L2特征的适用场景
How to decide which regularization (L1 or L2) to use? Is there collinearity among some features? L2 ...
- css文字环绕图片--遇到的问题及解决方法
一.前言 需要实现一个文字环绕图片的效果,心想so easy嘛. 1)代码部分 <style> .img-left { border: 3px solid #005588; width:3 ...
- MySQL基础 - 视图
创建视图: 假设要将posts表的前十条数据作为视图 mysql> CREATE VIEW view_test AS SELECT * FROM POSTS LIMIT 10; 使用: 可以把视 ...
- 2017-2018-2 20165301 实验四《Java面向对象程序设计》实验报告
2017-2018-2 20165301 实验四<Java面向对象程序设计>实验报告 一.Android Stuidio的安装测试 实验要求: 参考<Java和Android开发学习 ...
- MySQL学习笔记:floor、round —— 取整
在MySQL中做数值处理,需要取整或者四舍五入. floor:函数只返回整数部分,小数部分舍弃: round:函数四舍五入: END 2018-05-29 11:31:22
- 选择性卸载eclipse安装过的工具
我们有时候需要卸载eclipse中之前安装的一些工具,而不想全部删除,那就可以采取下面的方式: 打开eclipse,Help->About Eclipse->Installation De ...
- hdu 4664 划线(SG)
N个平面,每个平面有ni个点 两个人玩游戏,划线,他们可以划任意一个平面的两个点,有以下要求:两个人划得线不能交叉,不要划已经划过的线,如果一个平面被划了一个空心的三角形,那么这个平面就不能继续划线了 ...