How to quickly implement plugin in ROS

Wikipedia: plugin

table of Contents

step:

step1: Create a base class

step2: Create a plug-in class

step3: Register the plug-in

step4: Compile the plug-in library

step5: The plug-in settings are visible to the ROS system

step6: Apply the plug-in


step:

step1: Create a base class

#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

The constructor of the base class is optional. The
constructor is placed under protected, indicating that the initialization of the parent class needs to be completed by the initialize() function.

step2: Create a plug-in class

The plug-in class is the derived class, the class used for instantiation.

#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: Register the plug-in class

PLUGINLIB_EXPORT_CLASS (subclass 1, parent class)
...
PLUGINLIB_EXPORT_CLASS (subclass n, parent class)
function: export derived classes and register them with the ROS system. The purpose is to enable the ROS system to search for this category.
PS: The export line statement is generally written at the end of the **.cpp file corresponding to the derived class

#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: Compile the plug-in library

Modify add_library(${PROJECT_NAME} src/*.cpp) in the CMakeLists.txt file to compile the library file (the essence of the plug-in is the library file).

step5: The plug-in settings are visible to the ROS system

create a plugin class description file plugins.xml file, describing the detailed content of the plugin. E.g

<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>

Among them, pluginlib_test is the name of the library generated in step 4, Triangle and Square are plugin classes (subclasses), and RegularPolygon is the parent class.

Add the description file plugins.xml of the plug-in to the query file package.xml of the function package, for example:
 

  <!-- 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>

Where pluginlib_test is the package name of the function package

step6: Apply the plug-in

The application cases are as follows:

#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;
}

Contains ClassLoader: plug-in loading class.

 

Guess you like

Origin blog.csdn.net/weixin_44937328/article/details/114845642