当前位置:网站首页>ROS学习(24)plugin插件
ROS学习(24)plugin插件
2022-07-06 18:12:00 【敲代码的雪糕】
前言
ROS中的插件就是可以动态加载的扩展功能类。
ROS中的pluginlib功能包提供了加载喝卸载plugin的C++库,开发者在使用插件时,不需要考虑plugin类的链接位置,只需要将插件注册到pluginlib中,即可直接动态加载。
一、工作原理
如图所示:
实现一个插件需要如下几个步骤:
- 创建基类,定义统一接口(如果基于现有基类实现插件,跳过该步)
- 创建plugin类,继承基类,实现统一的接口
- 注册插件(使用pluginlib的宏完成注册)
- 编译生成插件的动态链接库(修改CMakefile.txt文件)
- 将插件加入到ROS中(创建喝修改相应xml文件)
二、具体实现
按照上述步骤,下面利用pluginlib实现一个插件。创建名为pluginlib_tutorials的功能包,命令如下:
catkin_create_pkg pluginlib_tutorials roscpp pluginlib
注意,创建时添加pluginlib依赖。
1、创建基类
在include/pluginlib_tutorials/polygon_bash.h文件中,创建polygon基类,定义一些接口,注意initialize()接口的使用。文件内容如下:
#ifndef PLUGINLIB_TUTORIALS_POLYGON_BASE_H_
#define PLUGINLIB_TUTORIALS_POLYGON_BASE_H_
namespace polygon_base
{
class RegularPolygon
{
public:
//pluginlib要求构造函数不能带有参数,所以定义initialize来完成需要初始化的工作
virtual void initialize(double side_length) = 0;
//计算面积的接口函数
virtual double area() = 0;
virtual ~RegularPolygon(){
}
protected:
RegularPolygon(){
}
};
};
#endif
2、创建plugin类
在include/pluginlib_tutorials/polygon_plugins.h文件中,定义rectangle_plugin和triangle_plugin类,实现基类的接口,也可以添加plugin自身需要的接口。文件内容如下:
#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();
}
// Triangle类自己的接口
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
3、注册插件
在src/pluginlib_tutorials/polygon_plugins.cpp文件中,注册创建好的插件。文件内容如下:
//包含pluginlib的头文件,使用pluginlib的宏来注册插件
#include <pluginlib/class_list_macros.h>
#include <pluginlib_tutorials/polygon_base.h>
#include <pluginlib_tutorials/polygon_plugins.h>
//注册插件,宏参数:plugin的实现类,plugin的基类
PLUGINLIB_EXPORT_CLASS(polygon_plugins::Triangle, polygon_base::RegularPolygon);
PLUGINLIB_EXPORT_CLASS(polygon_plugins::Square, polygon_base::RegularPolygon);
4、编译插件的动态链接库
修改CMakefile.txt文件,如下:
add_library(pluginlib_tutorials src/polygon_plugins.cpp)
target_link_libraries(pluginlib_tutorials ${
catkin_LIBRARIES})
5、将插件加入ROS
- 创建src/pluginlib_tutorials/polygon_plugins.xml文件,内容如下:
<library path="lib/libpluginlib_tutorials">
<class name="pluginlib_tutorials/regular_triangle" type="polygon_plugins::Triangle" base_class_type="polygon_base::RegularPolygon">
<description>This is a triangle plugin.</description>
</class>
<class name="pluginlib_tutorials/regular_square" type="polygon_plugins::Square" base_class_type="polygon_base::RegularPolygon">
<description>This is a square plugin.</description>
</class>
</library>
这个XML主要描述了plugin的动态库路径、实现类、基类、功能描述等信息。
- 修改src/pluginlib_tutorials/package.xml文件,内容如下:
<?xml version="1.0"?>
<package>
<name>pluginlib_tutorials</name>
<version>0.1.10</version>
<description>The pluginlib_tutorials package</description>
<maintainer email="[email protected]">Daniel Stonier</maintainer>
<license>BSD</license>
<url type="website">http://www.ros.org/wiki/pluginlib/Tutorials</url>
<url type="bugtracker">https://github.com/ros/common_tutorials/issues</url>
<url type="repository">https://github.com/ros/common_tutorials/</url>
<author>Eitan Marder-Eppstein</author>
<buildtool_depend>catkin</buildtool_depend>
<build_depend>pluginlib</build_depend>
<build_depend>roscpp</build_depend>
<run_depend>pluginlib</run_depend>
<run_depend>roscpp</run_depend>
<export>
<pluginlib_tutorials plugin="${prefix}/polygon_plugins.xml" />
</export>
</package>
可以使用如下命令,查看功能包的插件路径:
rospack plugins --attrib=plugin pluginlib_tutorials
如果配置正确,效果如下:
6、调用插件
上面已经实现了该插件的所有代码,现在开始调用该插件,创建src/pluginlib_tutorials/polygon_loader.cpp文件,内容如下:
#include <boost/shared_ptr.hpp>
#include <pluginlib/class_loader.h>
#include <pluginlib_tutorials/polygon_base.h>
int main(int argc, char** argv)
{
// 创建一个ClassLoader,用来加载plugin
pluginlib::ClassLoader<polygon_base::RegularPolygon> poly_loader("pluginlib_tutorials", "polygon_base::RegularPolygon");
try
{
// 加载Triangle插件类,路径在polygon_plugins.xml中定义
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;
}
修改CMakefile.txt文件,如下:
add_executable(polygon_loader src/polygon_loader.cpp)
target_link_libraries(polygon_loader ${
catkin_LIBRARIES})
7、运行效果
编译成功后,运行该插件,命令如下:
rosrun pluginlib_tutorials polygon_loader
效果如下:
边栏推荐
- POJ 3177 Redundant Paths POJ 3352 Road Construction(双连接)
- How to prevent overfitting in cross validation
- 1123. The nearest common ancestor of the deepest leaf node
- 字符串的相关编程题
- AcWing 1142. Busy urban problem solving (minimum spanning tree)
- Box stretch and pull (left-right mode)
- 域分析工具BloodHound的使用说明
- Set up [redis in centos7.x]
- When grep looks for a process, it ignores the grep process itself
- 黑马笔记---创建不可变集合与Stream流
猜你喜欢
随机推荐
Gin 入门实战
What does front-end processor mean? What is the main function? What is the difference with fortress machine?
盒子拉伸拉扯(左右模式)
shell脚本快速统计项目代码行数
AcWing 344. Solution to the problem of sightseeing tour (Floyd finding the minimum ring of undirected graph)
Start from the bottom structure to learn the customization and testing of fpga---- FIFO IP
AcWing 346. 走廊泼水节 题解(推公式、最小生成树)
Machine learning: the difference between random gradient descent (SGD) and gradient descent (GD) and code implementation.
【信号与系统】
Set up [redis in centos7.x]
C语言实例_3
JS Es5 can also create constants?
Compile command line terminal swift
我如何编码8个小时而不会感到疲倦。
Sword finger offer II 035 Minimum time difference - quick sort plus data conversion
C language instance_ five
Comparison of picture beds of free white whoring
Ds-5/rvds4.0 variable initialization error
安利一波C2工具
一文带你走进【内存泄漏】