ROS学习之pluginlib

错误不足的地方还请大家指正

随着项目的不断进行,对ROS的学习也不断深入。ROS的一些基础操作已不能满足需求,所以最近开始学习ROS的一些更“好”的机制,首先介绍比较基础的插件机制pluginlib。ROS的很多项目都是用插件的形式来加载的,比如navigation这个包,里面的costmap_2d中的各个地图层,就是以插件的形式动态加载。采用插件的形式有什么好处呢,我个人理解就是可以在不改变原有基类的前提下,融入自己创建的类。这些类可以实现某种算法,也可以是简单的做一些操作。具体的实现方式就是类继承,只不过针对ROS系统做了封装,使我们用起来更方便。但问题也就容易出现在封装的过程中,所以这里对其进行详细的介绍。

关于pluginlib的详细说明,可以移步ROS Wiki pluginlib教程

其他博主对pluginlib也有过介绍,推荐这个

这里介绍具体实现过程,同样使用ROSWiki上的多边形实例,这里通过两个lib来实现加载:

代码可以在这里下载

1.创建plugin基类:

创建ROS包,在include文件夹下创建base.h,里面申明基类

namespace polygon_base 
{
  class RegularPolygon
  {
    public:
      virtual void initialize(double side_length) = 0;
      virtual double area() = 0;
      virtual ~RegularPolygon(){}

    protected:
      RegularPolygon(){}
  };
};

2.创建插件类:

为了使用两种lib分别加载,这里用两个文件申明两个基类:

square.h下  namespace:polygon_plugins    class :Square

triangle.h下  namespace:polygon_plugins    class :Triangle

namespace polygon_plugins 
{
  class Square : public polygon_base::RegularPolygon
  {
    public:
      Square() : side_length_() {}

      void initialize(double side_length)
      {
        side_length_ = side_length;
      }

      double area()
      {
        return side_length_ * side_length_;
      }

    private:
      double side_length_;

  };
};

namespace polygon_plugins 
{
  class Triangle : public polygon_base::RegularPolygon
  {
    public:
      Triangle() : side_length_() {}

      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_;
  };
};
当然完全可以在同一个文件下实现这两个类,这里分开主要是为了在后面plugin描述文件中用新的方式实现。

3.注册插件:

在plugins1.cpp中注册triangle插件:PLUGINLIB_EXPORT_CLASS(polygon_plugins::Triangle,polygon_base::RegularPolygon);

在plugins2.cpp中注册square插件:PLUGINLIB_EXPORT_CLASS(polygon_plugins::Square,polygon_base::RegularPolygon);

其中,第一个参数表示子类的命名空间加类,第二个参数表示基类的命名空间加类

4.修改Cmakelists,生成库,添加头文件

include_directories(
 ${catkin_INCLUDE_DIRS}
 include
)
…
add_library(polygon_plugins1src/plugins1.cpp)
add_library(polygon_plugins2src/plugins2.cpp)
5.写插件描述文件

<class_libraries>
       <librarypath="lib/libpolygon_plugins1">
              <classtype="polygon_plugins::Triangle"base_class_type="polygon_base::RegularPolygon">
              <description>Thisis a triangle plugin.</description>
              </class>
       </library>
      
       <librarypath="lib/libpolygon_plugins2">
              <classtype="polygon_plugins::Square"base_class_type="polygon_base::RegularPolygon">
              <description>Thisis a square plugin.</description>
              </class>
       </library>
</class_libraries>
注意:这里library填写Cmakelists生成的库,当然前面加上lib

class type写第3步里面注册的子类,base_class_type写第3步里面注册的基类

具体的写法可以参考ROS Wiki上的介绍,里面有介绍同一个包加载不同lib以及同一个lib加载不同class的方法。

6.向ROS注册插件

在package.xml里面添加:

<export>
   <mypluginlib plugin="${prefix}/plugins.xml" />
 </export>

测试:

执行:rospack plugins --attrib=plugin mypluginlib 会看到输出的xml信息。注意 mypluginlib是pkg名称

7.使用pluginlib:

polygon_loader.cpp 使用pluginlib的一个代码实例

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

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

    ROS_INFO("Triangle area: %.2f", triangle->area());
  }
  catch(pluginlib::PluginlibException& ex)
  {
    ROS_ERROR("The plugin failed to load for some reason. Error: %s", ex.what());
  }

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

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

pluginlib::ClassLoader<polygon_base::RegularPolygon>poly_loader("mypluginlib", "polygon_base::RegularPolygon");//这一句是插件实例化,第一个是包名,第二个是基类。

boost::shared_ptr<polygon_base::RegularPolygon>square = poly_loader.createInstance("polygon_plugins::Triangle");

boost::shared_ptr<polygon_base::RegularPolygon>square = poly_loader.createInstance("polygon_plugins::Square");

上面两句是加载插件,<>里面是基类,()里面是要具体加载的插件类,也就是我们之前介绍的子类,


  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值