主要参考来源:http://wiki.ros.org/pluginlib/Tutorials/Writing%20and%20Using%20a%20Simple%20Plugin
1.创建一个cmake空间,在该空间下创建一个包Plugin1,依赖包pluginlib roscpp .
#mkdir -p Pluginsample/src
#cd Pluginsample
#catkin_make
#source devel/setup.bash
#catkin_create_pkg Plugin1 roscpp pluginlib
2.创建插件基类和继承类
#cd ~/Pluginsample/src/plugin1/include/plugin1
(1)创建基类RegularPolygon
#vim polygon_base.h
在新建的文件中粘贴:
#ifndef PLUGINLIB_TUTORIALS__POLYGON_BASE_H_
#define PLUGINLIB_TUTORIALS__POLYGON_BASE_H_
namespace polygon_base // (基类空间)
{
class RegularPolygon // (基类)
{
public:
virtual void initialize(double side_length) = 0;
virtual double area() = 0;
virtual ~RegularPolygon(){}
protected:
RegularPolygon(){}
};
};
#endif
这里创建了求多边形面积的插件基类,需要被重载。
(2)创建继承类:polygon_plugins.h
#vim polygon_plugins.h
在新建的文件中粘贴:
#ifndef PLUGINLIB_TUTORIALS__POLYGON_PLUGINS_H_
#define PLUGINLIB_TUTORIALS__POLYGON_PLUGINS_H_
#include <plugin1/polygon_base.h>
#include <cmath>
namespace polygon_plugins // (实现空间)
{
class Triangle : public polygon_base::RegularPolygon // (具体实现类)
{
public:
Triangle(){}
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(){}
void initialize(double side_length)
{
side_length_ = side_length;
}
double area()
{
return side_length_ * side_length_;
}
private:
double side_length_;
};
};
#endif
这里重载实现了求多边形面积的插件:三角形、正方形面积
3.注册、编译插件
(1)声明上述插件类为插件。
# cd ~/Pluginsample/src/plugin1/src
#vim polygon_plugins.cpp
在新创建的文件中粘贴:
#include <pluginlib/class_list_macros.h> //插件库宏定义
#include <plugin1/polygon_base.h>
#include <plugin1/polygon_plugins.h>
PLUGINLIB_EXPORT_CLASS(polygon_plugins::Triangle, polygon_base::RegularPolygon) //声明插件类
PLUGINLIB_EXPORT_CLASS(polygon_plugins::Square, polygon_base::RegularPolygon)
(2)编译插件。
#vim ~/Pluginsample/src/plugin1/CMakeLists.txt
在文本中添加:
include_directories(
include
${catkin_INCLUDE_DIRS}
)
add_library(polygon_plugins src/polygon_plugins.cpp) //编译库
编译包:
#cd ~/Pluginsample
#catkin_make
4.将插件添加到ROS Toolchain
创建polygon_plugins.xml,添加:
<library path="lib/libpolygon_plugins">
<class type="polygon_plugins::Triangle" base_class_type="polygon_base::RegularPolygon">
<description>This is a triangle plugin.</description>
</class>
<class type="polygon_plugins::Square" base_class_type="polygon_base::RegularPolygon">
<description>This is a square plugin.</description>
</class>
</library>
5.对外声明plugin:
在package.xml中添加:
<export>
<plugin1 plugin="${prefix}/polygon_plugins.xml" />
</export>
验证声明成功:
rospack plugins --attrib=plugin plugin1
显示:polygon_plugins.xml的绝对路径。
6.使用插件:新建src/polygon_loader.cpp,粘贴:
1 #include <pluginlib/class_loader.h>
2 #include <plugin1/polygon_base.h>
3
4 int main(int argc, char** argv)
5 {
6 pluginlib::ClassLoader<polygon_base::RegularPolygon> poly_loader("plugin1", "polygon_base::RegularPolygon");
7
8 try
9 {
10 boost::shared_ptr<polygon_base::RegularPolygon> triangle = poly_loader.createInstance("polygon_plugins::Triangle");
11 triangle->initialize(10.0);
12
13 boost::shared_ptr<polygon_base::RegularPolygon> square = poly_loader.createInstance("polygon_plugins::Square");
14 square->initialize(10.0);
15
16 ROS_INFO("Triangle area: %.2f", triangle->area());
17 ROS_INFO("Square area: %.2f", square->area());
18 }
19 catch(pluginlib::PluginlibException& ex)
20 {
21 ROS_ERROR("The plugin failed to load for some reason. Error: %s", ex.what());
22 }
23
24 return 0;
25 }
7.在CMakelists.txt中添加:
add_executable(polygon_loader src/polygon_loader.cpp)
target_link_libraries(polygon_loader polygon_plugins ${catkin_LIBRARIES})
8.执行:
./~Pluginsample/devel/lib/pluginlib_tutorials_/polygon_loader
输出:
[ INFO] [WallTime: 1279658450.869089666]: Triangle area: 43.30
[ INFO] [WallTime: 1279658450.869138007]: Square area: 100.00