前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ROS专题----pluginlib简明笔记

ROS专题----pluginlib简明笔记

作者头像
zhangrelay
发布2019-01-23 11:47:00
9400
发布2019-01-23 11:47:00
举报
文章被收录于专栏:机器人课程与技术

ROS专题----pluginlib简明笔记

http://wiki.ros.org/pluginlib/Tutorials

----

  1. 使用简单的插件本教程介绍如何使用pluginlib创建并加载一个简单的插件。

pluginlib的主要参考可以在它的主页pluginlib上找到。

----

简单解析:这个plugin计算边长为10的等边三角形和正方形的面积。

分别为43.3和100.0,如下:

$ rosrun pluginlib_tutorials polygon_loader [ INFO] [1489481879.738071797]: Triangle area: 43.30 [ INFO] [1489481879.738268345]: Square area: 100.00

----

公式:

代码语言:javascript
复制
#ifndef PLUGINLIB_TUTORIALS_POLYGON_PLUGINS_H_
#define PLUGINLIB_TUTORIALS_POLYGON_PLUGINS_H_
#include <pluginlib_tutorials/polygon_base.h>
#include <cmath>

namespace polygon_plugins 
{
  class Triangle : public polygon_base::RegularPolygon
  {
    public:
      Triangle() : side_length_() {}

      void initialize(double side_length)
      {
        side_length_ = side_length;
      }

      double area()
      {
        return 0.5 * side_length_ * getHeight();
      }

      double getHeight()
      {
        return sqrt((side_length_ * side_length_) - ((side_length_ / 2) * (side_length_ / 2)));
      }

    private:
      double side_length_;
  };

  class Square : public polygon_base::RegularPolygon
  {
    public:
      Square() : side_length_() {}

      void initialize(double side_length)
      {
        side_length_ = side_length;
      }

      double area()
      {
        return side_length_ * side_length_;
      }

    private:
      double side_length_;

  };
};
#endif

----

代码语言:javascript
复制
#include <boost/shared_ptr.hpp>

#include <pluginlib/class_loader.h>
#include <pluginlib_tutorials/polygon_base.h>

int main(int argc, char** argv)
{
  pluginlib::ClassLoader<polygon_base::RegularPolygon> poly_loader("pluginlib_tutorials", "polygon_base::RegularPolygon");

  try
  {
    boost::shared_ptr<polygon_base::RegularPolygon> triangle = poly_loader.createInstance("pluginlib_tutorials/regular_triangle");
    triangle->initialize(10.0);

    ROS_INFO("Triangle area: %.2f", triangle->area());
  }
  catch(pluginlib::PluginlibException& ex)
  {
    ROS_ERROR("The plugin failed to load for some reason. Error: %s", ex.what());
  }

  try
  {
    boost::shared_ptr<polygon_base::RegularPolygon> square = poly_loader.createInstance("pluginlib_tutorials/regular_square");
    square->initialize(10.0);

    ROS_INFO("Square area: %.2f", square->area());
  }
  catch(pluginlib::PluginlibException& ex)
  {
    ROS_ERROR("The plugin failed to load for some reason. Error: %s", ex.what());
  }

  return 0;
}

----

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

内容

  1. 概述
  2. 提供插件
    1. 注册/导出插件
    2. 插件说明文件
    3. 使用ROS包系统注册插件
    4. 为可用的插件查询ROS包系统
  3. 使用插件
  4. 来自Pre-Groovy pluginlib的更改
    1. 简化导出宏
    2. 旧版“查找名称”
  5. 报告错误

概述

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

要了解pluginlib的工作原理,让我们考虑一个小例子。首先,假设存在包含多边形基类(“ polygon_interface_package ”)的ROS 。让我们也说,有两种不同类型的多边形的在系统中支持的:其中生活在“一个矩形rectangle_plugin ”包和生活在“三角形triangle_plugin ”包。两者的实施者rectangle_plugin和triangle_plugin包将包括在它们的特殊出口线包。xml 文件告诉rosbuild系统他们打算为polygon_interface_package包中的多边形类提供插件。这些导出线实际上是用ROS构建/打包系统注册类。这意味着希望查看系统中所有可用的多边形类的人可以运行一个简单的rospack查询,它将返回可用类的列表,在这种情况下,矩形和三角形。

pluginlib / plugin_model.png
pluginlib / plugin_model.png

提供插件

注册/导出插件

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

切换行号

代码语言:javascript
复制
   1 #包括<pluginlib / class_list_macros.h>
   2 #包括<polygon_interface_package / polygon.h>
   3 #包括<rectangle_package / rectangle.h>
   4 
   5 //将Rectangle声明为多边形类
   6 PLUGINLIB_EXPORT_CLASS(rectangle_namespace :: Rectangle,polygon_namespace :: Polygon)

插件说明文件

插件描述文件是用于存储所有关于在机器可读格式的插件的重要信息的XML文件。它包含有关插件所在的库的信息,插件的名称,插件的类型等。如果我们考虑上面讨论的rectangle_plugin包,插件描述文件(例如rectangle_plugin.xml)将看起来像这样:

代码语言:javascript
复制
<library path =“lib / librectangle”>
  <class type =“rectangle_namespace :: Rectangle”base_class_type =“polygon_namespace :: Polygon”>
  <description>
  这是一个矩形插件
  </ description>
  </ class>
</ library>

有关插件描述文件及其相关标签/属性的详细描述,请参阅以下文档

为什么我们需要这个文件

我们需要这个文件除了代码宏,允许ROS系统自动发现,加载和推理插件。插件描述文件还包含重要信息,如插件的描述,不适合在宏中。

使用ROS包系统注册插件

为了让pluginlib查询跨所有ROS包的系统上的所有可用插件,每个包必须显式指定它导出的插件,以及哪些包库包含这些插件。一个插件提供者必须指向它的插件描述文件,在其package.xml中的内外销标签块。注意,如果您有其他导出,他们都必须在同一导出字段。

再次考虑rectangle_plugin包,相关行将如下所示:

代码语言:javascript
复制
<export>
  <polygon_interface_package plugin =“$ {prefix} /rectangle_plugin.xml”/>
</ export>

有关导出插件的详细说明,请参阅以下文档

重要说明:为了使上述export命令正常工作,提供包必须直接依赖于包含插件接口的包。例如,rectangle_plugin必须在其catkin / package.xml中具有以下行:

代码语言:javascript
复制
  <build_depend> polygon_interface_package </ build_depend>
  <run_depend> polygon_interface_package </ run_depend>

为可用的插件查询ROS包系统

可以通过rospack查询ROS包系统,以查看任何给定包可用的插件。例如:

代码语言:javascript
复制
rospack plugins --attrib = plugin nav_core

这将返回从nav_core包导出的所有插件。

使用插件

pluginlib在class_loader.h头文件中提供了一个ClassLoader类,使得它能够快速和容易地使用提供的类。有关此工具的代码级API的详细文档,请参阅pluginlib :: ClassLoader文档。下面,我们将演示一个使用ClassLoader在一些使用多边形的代码中创建矩形实例的简单示例:

切换行号

代码语言:javascript
复制
   1 #包括<pluginlib / class_loader.h>
   2 #包括<polygon_interface_package / polygon.h>
   3 
   4 // ... some code ... 
   5 
   6 pluginlib :: ClassLoader < polygon_namespace :: Polygon > poly_loader(“ polygon_interface_package ”,“ polygon_namespace :: Polygon ”); 
   7 
   8 尝试
   9 { 
  10   boost :: shared_ptr < polygon_namespace :: Polygon > poly = poly_loader。createInstance(“ rectangle_namespace :: Rectangle ”); 
  11 
  12   // ...使用多边形,boost :: shared_ptr会在超出范围
  13时自动删除内存 } 
  14 catch(pluginlib :: PluginlibException&ex)
  15 { 
  16   //处理类无法加载
  17   ROS_ERROR(“ 该插件未能加载由于某种原因,错误:%s。 ”, 恩。什么()); 
  18 }}

重要说明:在使用插件时,ClassLoader不能超出范围。所以,如果你在类中加载一个插件对象,请确保类加载器是该类的成员变量。

来自Pre-Groovy pluginlib的更改

简化导出宏

在pluginlib 1.9(Groovy)之前,宏PLUGINLIB_REGISTER_CLASS和PLUGINLIB_DECLARE_CLASS用于注册导出的类。这些已被弃用,支持新的PLUGINLIB_EXPORT_CLASS。新的宏是更简单,因为它只需要两个参数。

已提供了一个脚本,可以在源文件夹的根目录中运行pluginlib,以自动更新旧宏以利用新的:

代码语言:javascript
复制
 plugin_macro_update

旧版“查找名称”

pre-Groovy版本的pluginlib需要为插件描述文件和导出宏中的导出类指定一个“查找名称”。此查找名称充当真实类名称的别名 - 在面向用户界面中未使用真正的类名称。使用此查找别名而不是真实名称的原因是由于旧版本中的技术限制。

现在可以使用类的真实名称,而不是查找名称。但是,如果用户仍然使用查找名称,他们可以将其添加到其插件描述文件中。例如:

代码语言:javascript
复制
<library path =“lib / librectangle”>
  <class name =“rviz / Rectangle”type =“rectangle_namespace :: Rectangle”base_class_type =“polygon_namespace :: Polygon”>
  <description>
  这是一个矩形插件
  </ description>
  </ class>
</ library>

pluginlib现在将使用“rviz / Rectangle”而不是“rectangle_namespace :: Rectangle”来引用类。如果使用查找名称别名,则不能使用实际类名来引用类。如果未提供查找名称,则查找名称和真类名称是等效的。

----

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017年03月14日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 概述
  • 提供插件
    • 注册/导出插件
      • 插件说明文件
        • 为什么我们需要这个文件
      • 使用ROS包系统注册插件
        • 为可用的插件查询ROS包系统
        • 使用插件
        • 来自Pre-Groovy pluginlib的更改
          • 简化导出宏
            • 旧版“查找名称”
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档