< >
Home » ROS与C++入门教程 » ROS与C++入门教程-pluginlib-插件介绍

ROS与C++入门教程-pluginlib-插件介绍

ROS与C++入门教程-pluginlib-插件介绍

说明:

  • 介绍pluginlib软件包
  • pluginlib包提供了使用ROS构建的基础结构来编写和动态加载插件的工具。
  • 这些工具需要插件提供者在其包的package.xml中注册他们的插件。

概述

  • pluginlib是一个用于从ROS包中加载和卸载插件的C++库。
  • 插件是从运行时库(即共享对象,动态链接库)加载的动态可加载类。
  • 使用pluginlib,不必显式地将其应用程序与包含类的库链接
  • 而是pluginlib可以在任何时候打开包含导出类的库,而应用程序不必预先知道库或包含类定义的头文件。
  • 插件可用于扩展/修改应用程序行为,而不需要应用程序源代码。

原理

  • 要了解pluginlib的工作原理,让我们考虑一个小例子
  • 首先,假设存在包含多边形基类(“polygon_interface_package”)的ROS 包。
  • 也可以说有两种不同类型的多边形的:rectangle_plugin包(矩形)和triangle_plugin包(三角形)
  • rectangle_plugin和triangle_plugin使用都是在package.xml文件中包含指定的export项
  • 这告诉rosbuild构建系统,想在polygon_interface_package包里提供polygon类的插件。
  • 增加的export项,事实上是在build/packaging系统里注册这些类
  • 就是说可以通过rospack查询到所有可用的polygon类,它能返回所有可用的类列表,这里主要是rectangle和triangle。
  • 图示类结构:

请输入图片描述

提供插件

(1)注册/导出插件

  • 为了允许类被动态加载,它必须被标记为导出类。
  • 这是通过特殊宏PLUGINLIB_EXPORT_CLASS来完成的。
  • 这个宏可以放在构成插件库的任何源(.cpp)文件中,但通常放在导出类的.cpp文件的末尾。
  • 对于上面的示例,我们可能在包'example_pkg'中创建一个class_list.cpp文件
  • 如下所示,并将其编译到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)

(2)插件描述文件

  • 该插件描述文件是用于存储所有关于插件的重要信息的XML文件
  • 它包含有关插件所在的库的信息,插件的名称,插件的类型等
  • 如果我们考虑上面讨论的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>
  • 有关插件描述文件及其相关标签/属性的详细描述,请参阅以下文档
  • 为什么我们需要这个文件?
  • 我们需要这个文件除了代码宏,允许ROS系统自动发现,加载和解释插件。
  • 插件描述文件还包含重要信息,如插件的描述,这些信息不适合放在宏里。

(3)注册插件

  • 为了让pluginlib查询跨所有ROS包的系统上的所有可用插件,每个包必须显式指定它导出的插件,以及哪些包库包含这些插件。
  • 一个插件提供者必须在其package.xml中的export块指向它的插件描述文件。
  • 注意,如果您有其他导出,他们都必须在同一导出字段。
  • rectangle_plugin为例:
<export>
  <polygon_interface_package plugin="${prefix}/rectangle_plugin.xml" />
</export>
  • 有关导出插件的详细说明,请参阅以下文档
  • 重要说明:为了使上述export命令正常工作,提供包必须直接依赖于包含插件接口的包。
  • 例如,rectangle_plugin必须在其catkin/package.xml中具有以下行:
<build_depend>polygon_interface_package</build_depend>
<run_depend>polygon_interface_package</run_depend>

(4)查询插件

  • 可以通过rospack查询ROS包系统,以查看任何给定包可用的插件。
  • 例如:
rospack plugins --attrib=plugin nav_core
  • 这将返回从nav_core包导出的所有插件

(5)使用插件

  • pluginlib在class_loader.h头文件中提供了一个ClassLoader类,使得它能够快速和容易地使用提供的类。
  • 有关此工具的代码级API的详细文档,请参阅pluginlib::ClassLoader文档。
  • 下面,我们将展示一个使用ClassLoader在一些使用多边形的代码中创建矩形实例的简单示例:
#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());
}
  • 重要说明:在使用插件时,ClassLoader不能超出范围。
  • 所以,如果你在类中加载一个插件对象,请确保类加载器是该类的成员变量。

纠错,疑问,交流: 请进入讨论区点击加入Q群

获取最新文章: 扫一扫右上角的二维码加入“创客智造”公众号


标签: ROS与C++入门教程