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实际上不是操作系统,他只是一个通信的框架,一个代码管理的架 ...
随机推荐
- Django-ORM简介
ORM简介 MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库 ORM是“对象-关系-映射”的简称 ...
- JavaScript 简单吗
英文:Aurélien Hervé 译文:众成翻译/msmailcode 这里有一些 Javascript初学者应该知道的技巧和陷阱.如果你已经是专家了,顺便温习一下. Javascript也只不过 ...
- python基础-实现进度条功能,for和yield实现
实现进度条功能 方法一:简单FOR实现打印进度条功能 for i in range(10): print("#",end="",flush=True) time ...
- 简单计算器的C实现-函数指针,main函数传参
/** 程序功能:简单计算器,实现加减乘除平方* 作者版本日期:2015.11.08 zhouhb OK* 源代码:李明 <新概念C语言培训>第33集 C语言Shell命令解释器的实现* ...
- Description Resource Path Location Type The superclass "javax.servlet.http.HttpServlet" was not foun
一段时间没亲自建新项目玩乐,今天建立了一Maven project的时候发现了以下异常,Description Resource Path Location Type The superclass & ...
- (二)SpringMVC控制器
第一节:@RequestMapping请求映射 第二节:@RequestParam请求参数 第三节:ModelAndView返回模型和视图 第四节:SpringMVC对象属性自动封装 第五节:Spri ...
- jQuery使用JSONP时的错误处理
概述 什么是域,简单来说就是协议+域名或地址+端口,3者只要有任何一个不同就表示不在同一个域.跨域,就是在一个域中访问另一个域的数据. 如果只是加载另一个域的内容,而不需要访问其中的数据的话,跨域是很 ...
- CVE-2011-0104 Microsoft Office Excel缓冲区溢出漏洞 分析
漏洞简述 Microsoft Excel是Microsoft Office组件之一,是流行的电子表格处理软件. Microsoft Excel中存在缓冲区溢出漏洞,远程攻击者可利用此 ...
- cve-2010-3333 Microsoft Office Open XML文件格式转换器栈缓冲区溢出漏洞 分析
用的是泉哥的POC来调的这个漏洞 0x0 漏洞调试 Microsoft Office Open XML文件格式转换器栈缓冲区溢出漏洞 Microsoft Office 是微软发布的非常流行的办公 ...
- hdu 4813(2013长春现场赛A题)
把一个字符串分成N个字符串 每个字符串长度为m Sample Input12 5 // n mklmbbileay Sample Outputklmbbileay # include <iost ...