ROS学习笔记46(写和使用一个简单的插件)

1 准备

首先,安装插件的教程功能包,我的是kinetic版本的,安装应如下:

$ apt-get install ros-kinetic-common-tutorials

然后呢,需要建立一个功能包进行测试。这个功能包推荐放在catkin_ws/src目录下。

2 创建一个基础类

我们需要建立一个我们的插件将要继承的基础类。在这个例子中,我们将要创建两个RegularPolygon对象,并将之后使用它们,所以我们需要创造一个RegularPolygon类。打开你常用的编辑器,并在catkin_ws/src/pluginlib_tutorials_/include/pluginlib_tutorials_/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

 

这里创建一个抽象类。需要注意的一个地方是initialize成员函数。

3 创建插件

打开include/pluginlib_tutorials_/polygon_plugins.h,并粘贴上如下内容

#ifndef PLUGINLIB_TUTORIALS__POLYGON_PLUGINS_H_
#define PLUGINLIB_TUTORIALS__POLYGON_PLUGINS_H_
#include 
#include 

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()
      {include/pluginlib_tutorials_/polygon_plugins.h
        return side_length_ * side_length_;
      }

    private:
      double side_length_;

  };
};
#endif

程序很简单,我们创建了两个继承RegularPolygon的类。

4 注册插件

打开src/polygon_plugins.cpp,并粘贴如下内容:

#include 
#include 
#include 

PLUGINLIB_EXPORT_CLASS(polygon_plugins::Triangle, polygon_base::RegularPolygon)
PLUGINLIB_EXPORT_CLASS(polygon_plugins::Square, polygon_base::RegularPolygon)

注意:允许我们把C++类注册为一个插件。

注意:PLUGINLIB_EXPORT_CLASS(polygon_plugins::Square, polygon_base::RegularPolygon)
     1.第一个参数是:插件类的全名
     2.第二个参数是:插件基类的全名

5 动态链接库

想要建立一个插件库,需要在CMakeLists.txt文件中添加如下内容:

include_directories(include)
add_library(polygon_plugins src/polygon_plugins.cpp)

然后通过catkin_make编译。

6 插件能够被ROS Toolchain识别和管理

6.1 插件的Plugin XML描述文件
创建一个创建名为polygon_plugin.xml的文件


  
    This is a triangle plugin.
  
  
    This is a square plugin.
  

很简单,不再解释。
6.2 注册插件到ROS系统
为确保pluginlib可以查到ROS系统所有插件,定义插件的package必须显式的指定哪个包导出了什么插件。
这通常在package.xml文件中定义。


  

这里标签pluginlib_tutorials_ plugin是定义插件基类的package名称,属性plugin是前面定义的插件描述符文件。
注意:如果插件类与基类不在同一package,为了使插件的export生效,还必须添加对插件基类所在package的依赖。

     my_plugin_test
     my_plugin_test

7 调用插件

#include 
#include 

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

  try
  {
    boost::shared_ptr triangle = poly_loader.createInstance("polygon_plugins::Triangle");
    triangle->initialize(10.0);

    boost::shared_ptr square = poly_loader.createInstance("polygon_plugins::Square");
    square->initialize(10.0);

    ROS_INFO("Triangle area: %.2f", triangle->area());
    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;
}

 

8 运行程序

需要给CMakeLists.txt文件添加如下内容:

add_executable(polygon_loader src/polygon_loader.cpp)
target_link_libraries(polygon_loader ${catkin_LIBRARIES})

最后使用catkin_make进行编译,并大概可以看到如下内容:
[ INFO] [WallTime: 1279658450.869089666]: Triangle area: 43.30
[ INFO] [WallTime: 1279658450.869138007]: Square area: 100.00

 

 

你可能感兴趣的:(ROS)