ROS中如何快速实现plugin插件

wiki百科:plugin插件

目录

步骤:

step1:创建基类

step2: 创建插件类

step3: 注册插件

step4: 编译插件库

step5: 插件设置ROS系统可见

step6: 应用插件


步骤:

step1:创建基类

#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

基类的构造函数可有可无
构造函数放在protected下,说明父类的初始化需要initialize()函数来完成。

step2: 创建插件类

插件类即派生类,用以实例化的类。

#ifndef PLUGINLIB_TUTORIALS__POLYGON_PLUGINS_H_
#define PLUGINLIB_TUTORIALS__POLYGON_PLUGINS_H_
#include "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

step3: 注册插件类

PLUGINLIB_EXPORT_CLASS(子类1, 父类)
...
PLUGINLIB_EXPORT_CLASS(子类n, 父类)
功能:导出派生类,并向ROS系统注册派生类。目的能让ROS系统搜索到该类。
PS:该导出行语句,一般写在对应派生类的**.cpp文件末尾

#include <pluginlib/class_list_macros.h>
#include "pluginlib_test/polygon_base.h"
#include "pluginlib_test/polygon_plugins.h"

/*
 注册插件
*/
PLUGINLIB_EXPORT_CLASS(polygon_plugins::Triangle, polygon_base::RegularPolygon)
PLUGINLIB_EXPORT_CLASS(polygon_plugins::Square, polygon_base::RegularPolygon)

step4: 编译插件库

修改CMakeLists.txt文件中的add_library(${PROJECT_NAME} src/*.cpp),使之能编译出库文件(插件的实质即为库文件)。

step5: 插件设置ROS系统可见

create 一个插件描述文件plugins.xml文件,描述插件的详细内容。例如

<library path="lib/libpluginlib_test">
  <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>

其中 pluginlib_test为step4中生成的库的名字,Triangle和Square为插件类(子类),RegularPolygon为父类。

把该插件的描述文件plugins.xml,添加到功能包的查询文件package.xml中,例如:
 

  <!-- The export tag contains other, unspecified, tags -->
  <export>
    <!-- Other tools can request additional information be placed here -->
    <pluginlib_test plugin="${prefix}/polygon_plugins.xml" />
  </export>

其中 pluginlib_test为功能包的包名

step6: 应用插件

应用案例如下:

#include <pluginlib/class_loader.h>
#include "pluginlib_test/polygon_base.h"

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

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

    boost::shared_ptr<polygon_base::RegularPolygon> 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;
}

包含ClassLoader:插件加载类 。

猜你喜欢

转载自blog.csdn.net/weixin_44937328/article/details/114845642