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

举报
zhangrelay 发表于 2021/07/15 06:39:06 2021/07/15
【摘要】 ROS专题----pluginlib简明笔记 http://wiki.ros.org/pluginlib/Tutorials ---- 使用简单的插件本教程介绍如何使用pluginlib创建并加载一个简单的插件。 pluginlib的主要参考可以在它的主页pluginlib上找到。 ---- 简单解析:这个plugin计算边长为10的等边三角形和正方形的面积。...

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

----

公式:


  
  1. #ifndef PLUGINLIB_TUTORIALS_POLYGON_PLUGINS_H_
  2. #define PLUGINLIB_TUTORIALS_POLYGON_PLUGINS_H_
  3. #include <pluginlib_tutorials/polygon_base.h>
  4. #include <cmath>
  5. namespace polygon_plugins
  6. {
  7. class Triangle : public polygon_base::RegularPolygon
  8. {
  9. public:
  10. Triangle() : side_length_() {}
  11. void initialize(double side_length)
  12. {
  13. side_length_ = side_length;
  14. }
  15. double area()
  16. {
  17. return 0.5 * side_length_ * getHeight();
  18. }
  19. double getHeight()
  20. {
  21. return sqrt((side_length_ * side_length_) - ((side_length_ / 2) * (side_length_ / 2)));
  22. }
  23. private:
  24. double side_length_;
  25. };
  26. class Square : public polygon_base::RegularPolygon
  27. {
  28. public:
  29. Square() : side_length_() {}
  30. void initialize(double side_length)
  31. {
  32. side_length_ = side_length;
  33. }
  34. double area()
  35. {
  36. return side_length_ * side_length_;
  37. }
  38. private:
  39. double side_length_;
  40. };
  41. };
  42. #endif


----


  
  1. #include <boost/shared_ptr.hpp>
  2. #include <pluginlib/class_loader.h>
  3. #include <pluginlib_tutorials/polygon_base.h>
  4. int main(int argc, char** argv)
  5. {
  6. pluginlib::ClassLoader<polygon_base::RegularPolygon> poly_loader("pluginlib_tutorials", "polygon_base::RegularPolygon");
  7. try
  8. {
  9. boost::shared_ptr<polygon_base::RegularPolygon> triangle = poly_loader.createInstance("pluginlib_tutorials/regular_triangle");
  10. triangle->initialize(10.0);
  11. ROS_INFO("Triangle area: %.2f", triangle->area());
  12. }
  13. catch(pluginlib::PluginlibException& ex)
  14. {
  15. ROS_ERROR("The plugin failed to load for some reason. Error: %s", ex.what());
  16. }
  17. try
  18. {
  19. boost::shared_ptr<polygon_base::RegularPolygon> square = poly_loader.createInstance("pluginlib_tutorials/regular_square");
  20. square->initialize(10.0);
  21. ROS_INFO("Square area: %.2f", square->area());
  22. }
  23. catch(pluginlib::PluginlibException& ex)
  24. {
  25. ROS_ERROR("The plugin failed to load for some reason. Error: %s", ex.what());
  26. }
  27. return 0;
  28. }


----

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

概述

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

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

pluginlib / plugin_model.png

提供插件

注册/导出插件

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

切换行号
   1 包括<pluginlib / class_list_macros.h>
   2 包括<polygon_interface_package / polygon.h>
   3 包括<rectangle_package / rectangle.h>
   4 
   5 //将Rectangle声明为多边形类
   6 PLUGINLIB_EXPORT_CLASSrectangle_namespace :: Rectanglepolygon_namespace :: Polygon

插件说明文件

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

<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包,相关行将如下所示:

<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>

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

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

rospack plugins --attrib = plugin nav_core

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

使用插件

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

切换行号
   1 包括<pluginlib / class_loader.h>
   2 包括<polygon_interface_package / polygon.h>
   3 
   4 // ... some code ... 
   5 
   6 pluginlib :: ClassLoader < polygon_namespace :: Polygon > poly_loaderpolygon_interface_package polygon_namespace :: Polygon ); 
   7 
   8 尝试
   9 { 
  10   boost :: shared_ptr < polygon_namespace :: Polygon > poly = poly_loadercreateInstancerectangle_namespace :: Rectangle ); 
  11 
  12   // ...使用多边形,boost :: shared_ptr会在超出范围
  13时自动删除内存 } 
  14 catchpluginlib :: PluginlibExceptionex
  15 { 
  16   //处理类无法加载
  17   ROS_ERROR该插件未能加载由于某种原因,错误:%s。 ” 什么()); 
  18 }}

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

来自Pre-Groovy pluginlib的更改

简化导出宏

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

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

 plugin_macro_update

旧版“查找名称”

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

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

<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”来引用类。如果使用查找名称别名,则不能使用实际类名来引用类。如果未提供查找名称,则查找名称和真类名称是等效的。


----


文章来源: zhangrelay.blog.csdn.net,作者:zhangrelay,版权归原作者所有,如需转载,请联系作者。

原文链接:zhangrelay.blog.csdn.net/article/details/62045629

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。