创建和使用插件(C++)

目标 学习使用 插件库.

辅导水平: 初学者

时间 20 分钟

背景介绍

本教程源自 http://wiki.ros.org/pluginlib编写和使用简单插件教程.

插件库 是一个 C++ 库,用于在 ROS 软件包中加载和卸载插件。插件是从运行时库(即共享对象、动态链接库)中动态加载的类。有了 pluginlib,你就不必显式地将你的应用程序与包含类的库进行链接,而只需要 插件库 插件可以在任何时候打开包含导出类的库,而应用程序事先并不知道该库或包含类定义的头文件。插件可用于扩展/修改应用程序行为,而无需使用应用程序源代码。

先决条件

本教程假定您具备基本的 C++ 知识,并且已经成功地 安装了 ROS 2.

任务

在本教程中,您将创建两个新包,一个定义基类,另一个提供插件。基类将定义一个通用的多边形类,然后我们的插件将定义特定的形状。

1 创建基类软件包

中创建一个新的空软件包 ros2_ws/src 文件夹:

ros2 pkg create --build-type ament_cmake --license Apache-2.0 --dependencies pluginlib --node-name area_node polygon_base

打开您最喜欢的编辑器,编辑 ros2_ws/src/polygon_base/include/polygon_base/regular_polygon.hpp并在其中粘贴以下内容:

#ifndef POLYGON_BASE_REGULAR_POLYGON_HPP
#define POLYGON_BASE_REGULAR_POLYGON_HPP

命名空间 多边形基数
{
   正多边形
  {
    :
      虚拟 空白 初始化(双人 边长) = 0;
      虚拟 双人 地区() = 0;
      虚拟 ~正多边形(){}

    受保护的:
      正多边形(){}
  };
}  // 命名空间 polygon_base

#endif  // 基本多边形_不规则多边形_hpp

上面的代码创建了一个名为 正多边形.需要注意的是初始化方法的存在。使用 插件库因此,如果需要类的任何参数,我们可以使用 initialize 方法将参数传递给对象。

我们需要让其他类也能使用这个头信息,因此打开 ros2_ws/src/polygon_base/CMakeLists.txt 进行编辑。在 ament_target_dependencies 指挥:

安装(
  目录 包括
  目的地 包括
)

并在 ament_package 指挥:

ament_export_include_directories(
  包括
)

我们稍后将回到这个软件包来编写测试节点。

2 创建插件包

现在,我们要为抽象类编写两个非虚拟实现。在您的 ros2_ws/src 文件夹:

ros2 pkg create --build-type ament_cmake --license Apache-2.0 --dependencies polygon_base pluginlib --library-name polygon_plugins polygon_plugins

2.1 插件的源代码

开放 ros2_ws/src/polygon_plugins/src/polygon_plugins.cpp 进行编辑,并在其中粘贴以下内容:

#include <polygon_base/regular_polygon.hpp>;
#include <cmath>;

命名空间 多边形插件
{
   方形 :  多边形基数::正多边形
  {
    :
      空白 初始化(双人 边长) 否决
      {
        边长 = 边长;
      }

      双人 地区() 否决
      {
        返回 边长 * 边长;
      }

    受保护的:
      双人 边长;
  };

   三角形 :  多边形基数::正多边形
  {
    :
      空白 初始化(双人 边长) 否决
      {
        边长 = 边长;
      }

      双人 地区() 否决
      {
        返回 0.5 * 边长 * 获取高度();
      }

      双人 获取高度()
      {
        返回 平方((边长 * 边长) - ((边长 / 2) * (边长 / 2)));
      }

    受保护的:
      双人 边长;
  };
}

#include <pluginlib/class_list_macros.hpp>;

pluginlib_export_class(多边形插件::方形, 多边形基数::正多边形)
pluginlib_export_class(多边形插件::三角形, 多边形基数::正多边形)

正方形和三角形类的实现相当简单:保存边长,并用它来计算面积。唯一与插件库相关的部分是最后三行,它调用了一些神奇的宏,将这些类注册为实际的插件。下面我们来看看 pluginlib_export_class 宏观:

  1. 插件类的全称类型,在本例中是插件类的全称类型、 多边形插件::正方形.

  2. 这里是基类的全称类型、 polygon_base::RegularPolygon.

2.2 插件声明 XML

通过上述步骤,我们可以在加载包含插件的库时创建插件实例,但插件加载器仍然需要找到该库,并知道在该库中要引用哪些内容。为此,我们还将创建一个 XML 文件,配合软件包清单中的特殊导出行,向 ROS 工具链提供有关插件的所有必要信息。

创建 ros2_ws/src/polygon_plugins/plugins.xml 代码如下

图书馆 path="多边形插件";>;
  类别 type="多边形插件::方形"; base_class_type="polygon_base::RegularPolygon";>;
    <描述>;  a 方形 插件。</description>;
  </class>;
  类别 type="polygon_plugins::Triangle"; base_class_type="polygon_base::RegularPolygon";>;
    <描述>;  a 三角形 插件。</description>;
  </class>;
</library>;

有几件事需要注意:

  1. "(《世界人权宣言》) 图书馆 标签给出了包含我们要导出的插件的库的相对路径。在 ROS 2 中,这只是库的名称。在 ROS 1 中,它包含前缀 lib 或者有时 lib/lib (即 lib/libpolygon_plugins),但这里更简单。

  2. "(《世界人权宣言》) 标记声明了我们要从程序库中导出的插件。让我们来看看它的参数:

  • 类型:插件的完全限定类型。对我们来说是 多边形插件::正方形.

  • 基类:插件的完全限定基类类型。对于我们来说,就是 polygon_base::RegularPolygon.

  • 描述:说明插件及其功能。

2.3 CMake 插件声明

最后一步是通过 CMakeLists.txt.这与 ROS 1 有所不同,在 ROS 1 中,导出是通过 package.xml.在您的 ros2_ws/src/polygon_plugins/CMakeLists.txt 行之后 find_package(pluginlib 必填):

pluginlib_export_plugin_description_file(多边形基数 plugins.xml)

的参数 pluginlib_export_plugin_description_file 命令是

  1. 基类的软件包,即 多边形基数.

  2. 插件声明 xml 的相对路径,即 plugins.xml.

3 使用插件

现在是使用插件的时候了。这可以在任何软件包中进行,但我们要在基础软件包中进行。编辑 ros2_ws/src/polygon_base/src/area_node.cpp 包含以下内容

#include <pluginlib/class_loader.hpp>;
#include <polygon_base/regular_polygon.hpp>;

int 主要(int 参数, 烧焦** 参数)
{
  // 避免出现未使用参数警告
  (空白) 参数;
  (空白) 参数;

  插件库::类加载器<;多边形基数::正多边形>; 多负载("多边形基座";, "polygon_base::RegularPolygon";);

  尝试
  {
    标准::共享_ptr<;多边形基数::正多边形>; 三角形 = 多负载.创建共享实例("polygon_plugins::Triangle";);
    三角形->;初始化(10.0);

    标准::共享_ptr<;多边形基数::正多边形>; 方形 = 多负载.创建共享实例("多边形插件::方形";);
    方形->;初始化(10.0);

    printf(三角形面积:%.2f\n";, 三角形->;地区());
    printf("平方面积:%.2f\n";, 方形->;地区());
  }
  捕捉(插件库::PluginlibException及样品; )
  {
    printf(由于某种原因,插件加载失败。错误:%s\n";, .什么());
  }

  返回 0;
}

"(《世界人权宣言》) 类加载器 是需要了解的关键类,它定义在 class_loader.hpp 头文件:

  • 它以基类为模板,即 polygon_base::RegularPolygon.

  • 第一个参数是基类包名的字符串,即 多边形基数.

  • 第二个参数是一个字符串,包含插件的完整限定基类类型,即 polygon_base::RegularPolygon.

实例化类实例的方法有很多。在本例中,我们使用共享指针。我们只需调用 创建共享实例 在本例中,使用插件类的完全限定类型、 多边形插件::正方形.

重要说明 多边形基数 定义此节点的软件包不依赖于 多边形插件 类。插件将被动态加载,无需声明任何依赖关系。此外,我们使用硬编码的插件名称对类进行实例化,但您也可以使用参数等进行动态实例化。

4 构建和运行

返回工作区的根目录、 ros2_ws然后创建新软件包:

colcon build --packages-select polygon_base polygon_plugins

来自 ros2_ws请确保设置文件的来源:

source install/setup.bash

现在运行节点:

ros2 运行多边形基点区域节点

应该打印出来:

三角形面积43.30
广场面积100.00

摘要

恭喜您您刚刚编写并使用了第一个插件。