When developing ROS applications that require runtime extensibility, pluginlib provides a powerful mechanism for loading plugins dynamically without modifying the core application. This tutorial demonstrates how to create a basic plugin system using pluginlib.
First, create a new ROS package to house the plugin implementation:
$ roscd
$ cd ../src
$ catkin_create_pkg shape_plugins roscpp pluginlib
Now define the base class interface. Create include/shape_plugins/shape_base.h with the following code:
#ifndef SHAPE_PLUGINS__SHAPE_BASE_H_
#define SHAPE_PLUGINS__SHAPE_BASE_H_
namespace shape_base
{
class Polygon
{
public:
virtual void setDimension(double side) = 0;
virtual double computeArea() = 0;
virtual ~Polygon(){}
protected:
Polygon(){}
};
}
#endif
Next, create the plugin implementations. Add include/shape_plugins/shape_plugins.h:
#ifndef SHAPE_PLUGINS__SHAPE_PLUGINS_H_
#define SHAPE_PLUGINS__SHAPE_PLUGINS_H_
#include <shape_plugins/shape_base.h>
#include <cmath>
namespace shape_plugins
{
class Triangle : public shape_base::Polygon
{
public:
Triangle(){}
void setDimension(double side) override
{
side_ = side;
}
double computeArea() override
{
return 0.5 * side_ * calculateHeight();
}
private:
double calculateHeight()
{
return std::sqrt((side_ * side_) - ((side_ / 2) * (side_ / 2)));
}
double side_;
};
class Square : public shape_base::Polygon
{
public:
Square(){}
void setDimension(double side) override
{
side_ = side;
}
double computeArea() override
{
return side_ * side_;
}
private:
double side_;
};
}
#endif
The base class declares two pure virtual methods: setDimension() for configuring the polygon and computeArea() for calculating its area. The Triangle plugin implements these methods along with a helper function to compute height from the side length. The Square plugin provides a straightforward implementation where the area equals the side squared.
To use these plugins, the client code instantiates the Polygon base class and loads implementations at runtime using pluginlib's class loader. This architecture allows adding new polygon types without modifying the exitsing client code.