ROS-----pluginlib使用总结

2023-05-16

1 简介

pluginlib是一个C++库,可以实现为一个ROS包动态的加载和卸载插件。这里的插件通常是一些功能类,且以运行时可动态加载的库(如共享对象,动态链接库)的形式存在。借助pluginlib的帮助,用户不必关心自己的应用程序该如何链接包含自己想使用的的class的库(如定义class的头文件在哪里,如何定义的),因为pluginlib会在你调用时自动打开你需要的插件库(Note:需要提前将插件库注册到pluginlib)。使用插件来扩展或者修改应用程序的功能非常方便,不用改动源码重新编译应用程序,通过插件的动态加载即可完成功能的扩展和修改。


2 插件编写

    pluginlib利用了C++多态的特性,不同的插件只要使用统一的接口,便可以替换使用。这样用户通过调用在插件中实现的统一的接口函数,不需要更改程序,也不需要重新编译,更换插件即可实现功能修正。

    利用pluginlib编写插件的方法大致包括如下四步:

  1. 创建插件基类,定义统一接口(如果为现有接口编写插件,则跳过该步)
  2. 编写插件类,继承插件基类,实现统一接口
  3. 导出插件,并编译为动态库
  4. 将插件加入ROS系统,使其可识别和管理
2.1 创建插件基类

首先,创建工作空间,创建后如下所示



其次,开始编写插件基类,基类所在头文件polygon_base.h放在include/my_plugin_test下即可,

#ifndef POLYGON_BASE_H_
#define POLYGON_BASE_H_
namespace polygon_base
{
class Polygon{ 
public:
	Polygon() {};
	virtual ~Polygon() {};
	virtual void init(float side_len) = 0;
	virtual float area() = 0;
};

};
#endif

2.2 创建插件类

所插件类的头文件polygon_plugin.h在放在include/my_plugin_test目录下。

#ifndef POLYGON_PLUGIN_H_
#define POLYGON_PLUGIN_H_
#include <cmath>
#include <my_plugin_test/polygon_base.h>

namespace polygon_plugin{

	class Square: public polygon_base::Polygon{
		public:
			Square() {};
			virtual ~Square() {};
			virtual void init(float side_len)
			{
				this->side_len = side_len;
			}
			virtual float area()
			{
				return (side_len * side_len);
			}
		private:
			float side_len;
	};

	class Triangle: public polygon_base::Polygon{
		public:
			Triangle() {};
			virtual ~Triangle() {};
			virtual void init(float side_len)
			{
				this->side_len = side_len;
			}
			virtual float area()
			{
				return 0.5 * (side_len * ( sqrt( (side_len * side_len) - (0.5 * side_len)*(0.5 * side_len) ) ) );
			}

		private:
			float side_len;
	};
};
#endif


3 导出插件,并编译为动态链接库

3.1导出插件

   利用 pluginlib 库提供的宏操作注册插件,并且编译为动态链接库。

  在src目录下添加polygon_plugin.cpp,

#include <pluginlib/class_list_macros.h>
#include <my_plugin_test/polygon_base.h>
#include <my_plugin_test/polygon_plugin.h>

 //mark Square and Triangle as the exported class  
PLUGINLIB_EXPORT_CLASS(polygon_plugin::Triangle, polygon_base::Polygon)
PLUGINLIB_EXPORT_CLASS(polygon_plugin::Square, polygon_base::Polygon)

如果要实现class可动态加载,必须要将其标记为可导出的class。通过特定的宏PLUGINLIB_EXPORT_CLASS可以完成导出,该宏通常放置于cpp文件的底部。这个宏第一个参数是插件类全名(含namespace),第二个参数是插件基类全名(含namespace)。

3.2 编译为动态链接库

    要将插件编译为动态链接库,需要相应修改CMakeLists.txt文件,添加如下几行:

 include_directories(
       include
       ${catkin_INCLUDE_DIRS}
 )
     
 ## Declare a C++ library
 add_library(polygon_plugin
       src/${PROJECT_NAME}/polygon_plugin.cpp
 )

4 将插件加入ROS系统,使其可识别和管理

4.1 创建插件描述文件

   插件描述文件是一个XML格式的文件,用于存储插件的重要信息(如,插件库路径,插件名称,插件类类型,插件基类类型)。

  我们在my_plugin_test目录下,创建名为polygon_plugin.xml的文件,

<library path="lib/libpolygon_plugin">
         <class type="polygon_plugin::Triangle" base_class_type="polygon_base::Polygon">
             <description>This is a triangle plugin.</description>
         </class>
         <class type="polygon_plugin::Square" base_class_type="polygon_base::Polygon">
             <description>This is a square plugin.</description>
         </class>
</library>

这里标签library和其属性path一起定义了主package相对于插件库的路径,一个插件库可以包含多个不同的插件类(如这里是2个插件类)。

这里的标签class用以描述插件库中的插件类,属性type指定插件类的类型(必须全名),属性base_class_type指定插件基类的类型(必须全名),属性description描述插件类的功能。

注意:插件描述文件还有一个标签class_libraries这里没有使用,其可以实现在一个插件描述文件包含多个库,该标签无属性。


4.2 注册插件到ROS系统

    为确保pluginlib可以查到ROS系统所有插件,定义插件的package必须显式的指定哪个包导出了什么插件。

这通常在package.xml文件中定义,

<export>
         <my_plugin_test plugin="${prefix}/polygon_plugin.xml">
</export>

这里标签my_plugin_test是定义插件基类的package名称,属性plugin是前面定义的插件描述符文件。

注意:如果插件类与基类不在同一package,为了使插件的export生效,还必须添加对插件基类所在package的依赖。

 <build_depend>my_plugin_test</build_depend>
 <run_depend>my_plugin_test</run_depend>

5 check插件是否在ROS下可以查看

    在catkin_make执行成功之后,source  develop/setup.bash,然后运行如下命令如果能正确看到输出polygon_plugin.xml则ok。

   rospack plugins --attrib=plugin my_plugin_test


6 调用插件

6.1 在src目录下创建my_plugin_loader.cpp

#include <ros/ros.h>
#include <pluginlib/class_loader.h>
#include <my_plugin_test/polygon_base.h>


int main(int argc, char ** argv)
{
	ros::init(argc, argv, "my_plugin_loader");
	ros::NodeHandle nh;

    float side_len = 5.0;
   
	std::string param_name = "polygon_plugin";
	std::string plugin_class;
	

	if(!nh.getParam(param_name.c_str(), plugin_class))
	{
		ROS_ERROR("can't get param");
		return 0;
	}

	/**
	 * Define plugin loader object(polygon_loader) for loading my plugin.
	 * param1: the path of plugin package, param2:the base class of plugin class with full name
	 */
	pluginlib::ClassLoader<polygon_base::Polygon> polygon_loader("my_plugin_test", "polygon_base::Polygon");
    
	try
	{
		/*Based on input param to create the corresponding plugin instance by ClassLoader*/
		boost::shared_ptr<polygon_base::Polygon> polygon_cal = polygon_loader.createInstance(plugin_class);

		polygon_cal->init(side_len);

		ROS_INFO("plugin class is %s, area is %f",plugin_class.c_str(), polygon_cal->area());
	}

    /*catch exception ClassLaoder object(polygon_loader) exception*/
	catch(pluginlib::PluginlibException& ex)
	{
		ROS_ERROR("The plugin failed to load for some reason. Error: %s", ex.what());
	}

	return 0;
}

6.2 修改CMakeLists.txt,添加
## Declare a C++ executable
add_executable(my_plugin_loader src/my_plugin_loader.cpp)

## Add cmake target dependencies of the executable
## same as for the library above
# add_dependencies(my_plugin_test_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})

## Specify libraries to link a library or executable target against
target_link_libraries(my_plugin_loader
  ${catkin_LIBRARIES}
)

6.3 创建启动文件

在my_plugin_test目录下创建launch文件夹添加文件my_plugin_loader.launch

<launch>
	<!--plugin select-->
	<!--<param name="polygon_plugin" value="polygon_plugin::Square"/> -->
	<param name="polygon_plugin" value="polygon_plugin::Triangle"/>
	<node name="my_plugin_loader" pkg="my_plugin_test" type="my_plugin_loader" output="screen"/>
</launch>

最后目录工作空间目录结构如下所示:


6.4 测试

方式一:通过启动文件

roslaunch my_plugin_test my_plugin_loader.launch

输出:
... logging to /home/siriansu/.ros/log/f05ccba8-a4a7-11e6-9012-001fc69be782/roslaunch-siriansu-nuc-24328.log
Checking log directory for disk usage. This may take awhile.
Press Ctrl-C to interrupt
Done checking log file disk usage. Usage is <1GB.

started roslaunch server http://siriansu-nuc:40746/

SUMMARY
========

PARAMETERS
 * /polygon_plugin: polygon_plugin::T...
 * /rosdistro: kinetic
 * /rosversion: 1.12.5

NODES
  /
    my_plugin_loader (my_plugin_test/my_plugin_loader)

ROS_MASTER_URI=http://localhost:11311

core service [/rosout] found
process[my_plugin_loader-1]: started with pid [24346]
[ INFO] [1478842570.904729245]: plugin class is polygon_plugin::Triangle, area is 10.825317
[my_plugin_loader-1] process has finished cleanly
log file: /home/siriansu/.ros/log/f05ccba8-a4a7-11e6-9012-001fc69be782/my_plugin_loader-1*.log
all processes on machine have died, roslaunch will exit
shutting down processing monitor...
... shutting down processing monitor complete
done


方式二:命令行方式

rosparam set polygon_plugin polygon_plugin::Square

rosrun my_plugin_test my_plugin_loader

输出:

[ INFO] [1478842687.012935017]: plugin class ispolygon_plugin::Square, area is25.000000

rosparam set polygon_plugin polygon_plugin::Triangle

rosrun my_plugin_test my_plugin_loader

输出:

[ INFO] [1478844657.917205466]: plugin class ispolygon_plugin::Triangle, area is10.825317


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ROS-----pluginlib使用总结 的相关文章

  • 图像物体分类与检测算法综述

    图像物体分类与检测算法综述 转自 计算机学报 目录 图像物体分类与检测算法综述 目录图像物体分类与检测概述物体分类与检测的难点与挑战物体分类与检测数据库物体分类与检测发展历程 图像物体分类与检测是计算机视觉研究中的两个重要的基本问题 xff

随机推荐

  • 海康威视网络摄像头SDK二次开发(QT版本)

    暂时使用到的主要功能有四个 xff1a 1 连接相机 xff0c 2 实时显示 xff0c 3 取图 xff08 bmp格式 xff09 xff0c 4 关闭相机 在官网下载对应的win64的SDK xff0c 在库文件中运行demo ex
  • Android7.0成长之路---新特性Jack server

    准备 今天正式担任Android7 0 N 项目模块的开发和维护工作 xff0c 借此机会git和make了一套系统代码用来研究 在编译的过程中 xff0c 与以往系统不同的是Android7 0系统编译工具链使用了全新的Jack serv
  • A-Softmax(SphereFace)

    论文 xff1a SphereFace xff1a https arxiv org abs 1704 08063 SphereFace在MegaFace数据集上识别率在2017年排名第一 xff0c 用的A Softmax Loss有着清晰
  • Java 面试题宝典 (每天更新)

    目录 一 Java 基础部分 第一天 1 一个 34 java 34 源文件中是否可以包括多个类 xff08 不是内部类 xff09 xff1f 有什么限制 2 Java 有没有 goto 3 说说 amp 和 amp amp 的区别 4
  • skyfans之每天一个Liunx命令系列之三十三:chomd

    今天我们继续来学习每天一个命令 xff0c 今天我们继续学习此章节内容 xff1a 文件权限管理类命令 xff08 FILE PERMISSIONS xff09 xff0c 今天学习的是什么命令呢 xff0c 那就是chmod xff08
  • 部署node_exporter

    部署node exporter 1 下载node exporter安装包 xff0c 解压安装 span class token punctuation span root 64 bogon ljy span class token pun
  • 阿里 datax工具 impala 数据导入到mongo

    datax下载地址 1 解压datax包 2 具体安装测试datax工具可以在网上进行查询 其对jdk python maven 都有版本的要求 需确认当前系统中的版本 datax安装以及测试方式 3 确认安装无误后 xff0c 在安装目录
  • android开发Installed Build Tools revision 33.0.2 is corrupted. 问题解决方法

    方案一 xff1a 在你的 android sdk安卓目录中找到build tools目录中的d8 bat xff0c 将文件名修改为dx bat 找到build tools目录中的lib d8 jar xff0c 将文件名修改为dx ja
  • [ROS]三、建立工作空间

    系列文章目录 ROS 一 ROS的基本概念 ROS 二 命令与工具的使用 文章目录 系列文章目录前言一 工作空间二 创建步骤1 命令2 创建功能包 总结 前言 在前两个章节中我们已经学习了ros相关基本概念和基本工具的使用 xff0c 今天
  • ubuntu20.04配置vnc文件xorg.conf后重启输入开机密码后一直循环在登入界面的问题

    1 在配置vncserver的时候 xff0c 可能导致该用户不能正常登录桌面 2 问题现象 xff1a 正确输入密码 xff0c 系统无法进入桌面 xff0c 闪回到登录界面 3 在登录界面按ctrl 43 Alt 43 F4 xff08
  • Java序列化与反序列化详解

    面试官 兄弟 说说你对transient的理解和感悟 哪吒 what 还有感悟 先说结论 在序列化 反序列化时 被transient关键字修饰的成员属性变量不会被序列化 面试官 这就完了 哪吒 面试官明显不是很满意 这怎么能够 追根溯源 先
  • 导航软件哪个最好用?这里有3款最流行的导航软件

    导航软件哪个最好用 xff1f 在自助游越来越盛行的今天 xff0c 当你走到一个人生地不熟的环境 xff0c 随身携带一台GPS导航设备无疑能够为你的出行带来极大的便利 于是 xff0c 只要人们出行 xff0c 都离不开一个东西 导航
  • [软件工程] 面向对象设计

    面向对象设计 面向对象设计一 面向对象设计的准则 xff08 一 xff09 模块化 xff08 二 xff09 抽象 xff08 三 xff09 信息隐藏 xff08 四 xff09 弱耦合对象之间的耦合可分为两大类 xff1a 1 交互
  • 【持续更新】Python常用语法糖汇总

    1 if else简写 值1 if 条件 else 值2 的形式 如果 If 里的条件满足 xff0c 那么表达式的值为 值1 xff0c 否则为 值2 x y 61 1 10 z 61 x if x gt y else y print z
  • strtok函数 的原理及一个坑

    我们知道strtok是一个字符串切割函数 xff0c 先来了解一下它 原型 xff1a char strtok char str const char delim 功能 xff1a 分解字符串为一组字符串 参数说明 xff1a str为要分
  • 机载处理器(树莓派、Jetson TX2及个人pc等均适用)配置ROS+mavros开发环境 (Pixhawk飞控测试)

    需要事先准备的 xff1a 树莓派 xff1a xff08 1 xff09 一块装了Ubuntu16 04 mate系统的树莓派 xff08 我的是3代 xff0c 别的平台没有测试过 xff09 xff0c xff08 2 xff09 键
  • 使用Autoware进行(双目)相机与激光雷达的联合标定

    使用Autoware进行 双目 相机与激光雷达的联合标定 VLP 16 与 ZED相机使用Autoware提供的 autoware camera lidar calibrator 工具进行标定 64 author Kehan Xue 64
  • svn status

    svn 是在提交前查看本地文本和版本库里面的文件的区别 返回值有许多种具体含义如下 xff1a url 61 L abc c svn已经在 svn目录锁定了abc c M bar c bar c的内容已经在本地修改过了 M baz c ba
  • rosserial通信协议简介

    1 概述 rosserial是一种ROS串行通信协议 xff0c 通过串行传输介质实现ROS的P2P通信 这种协议通过简单的添加包头和包尾可以实现了多主题或者服务共享串行通信介质 xff08 如串口 xff0c 网络socket xff09
  • ROS-----pluginlib使用总结

    1 简介 pluginlib是一个C 43 43 库 xff0c 可以实现为一个ROS包动态的加载和卸载插件 这里的插件通常是一些功能类 xff0c 且以运行时可动态加载的库 xff08 如共享对象 xff0c 动态链接库 xff09 的形