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实际上不是操作系统,他只是一个通信的框架,一个代码管理的架 ...
随机推荐
- python 根据输入的内容输出类型
类型判断 from functools import singledispatch import numbers from collections import abc from collection ...
- 含有ref out 参数 的方法反射 Emit 与 普通
反射中很多朋友应该屡屡被带有ref out参数的方法折腾 当使用正常反射一个方法时候: 代码如下调用一个后期绑定方法MakeByRefType 就行了 MemberInfo test = typeof ...
- 如何提高单片机Flash的擦写次数
所谓提高flash的擦写次数,并不是真正的提高flash擦写次数,而是通过以"空间换时间"概念,在软件上实现“操作的次数大于其寿命”.详见链接: http://bbs.eeworl ...
- Ubuntu下软件安装方式、PATH配置、查找安装位置
Ubuntu 18.04, 安装方式 目前孤知道的Ubuntu下安装软件方式有3种(命令): 1.make 2.apt/apt-get 3.dpkg 方式1基于软件源码安装,需要经历配置(可选).编译 ...
- image配准,发布geoserver服务
1.arcmap配准:注:png只保留需要显示范围,多余部分删除,,配准后再进行栅格裁剪(为了去除偏移后出现的NoData值) 2.导出tif:注:NoData值设置,一般为256(有时候经过裁剪会默 ...
- 阿里妈妈MLR模型(论文)
论文来源:https://arxiv.org/abs/1704.05194v1 阿里技术:https://mp.weixin.qq.com/s/MtnHYmPVoDAid9SNHnlzUw?scene ...
- windows下同时安装python2和python3
之前学习的时候使用2.7比较多. 想练习3.7的时候,两个版本兼容的问题,苦恼了几天. 查了一下资料,发现了一个很好的方法.记录一下,也做一个分享. 本篇内容主要讲一下,在同一台电脑上如何同时安装Py ...
- opencv(5)GUI
OpenCV的图形用户界面(Graphical User Interface, GUI)和绘图等相关功能也是很有用的功能,无论是可视化,图像调试还是我们这节要实现的标注任务,都可以有所帮助. 窗口循环 ...
- ROS数据可视化工具Rviz和三维物理引擎机器人仿真工具V-rep Morse Gazebo Webots USARSimRos等概述
ROS数据可视化工具Rviz和三维物理引擎机器人仿真工具V-rep Morse Gazebo Webots USARSimRos等概述 Rviz Rviz是ROS数据可视化工具,可以将类似字符串文本等 ...
- Linux学习笔记:pwd与dirs的区别
在Linux中可以使用pwd和dirs进行当前目录查看,分别用于显示当前目录和显示完整目录记录.具体如下: 1.pwd 显示当前目录 2.dirs 显示目录堆叠中的记录 END 2018-08-21 ...