警告
您正在阅读的 ROS 2 文档版本已达到 EOL(生命周期结束),不再受官方支持。如果您想了解最新信息,请访问 Jazzy.
创建和使用插件(C++)
目标 学习使用 pluginlib 创建和加载一个简单的插件。
辅导水平: 初学者
时间 20 分钟
背景介绍
本教程源自 http://wiki.ros.org/pluginlib 和 编写和使用简单插件教程.
pluginlib 是一个 C++ 库,用于在 ROS 软件包中加载和卸载插件。插件是从运行时库(即共享对象、动态链接库)中动态加载的类。有了 pluginlib,应用程序就不必显式链接到包含类的库,相反,pluginlib 可以在任何时候打开包含导出类的库,而应用程序事先并不知道该库或包含类定义的头文件。插件可用于扩展/修改应用程序行为,而无需使用应用程序源代码。
先决条件
本教程假定您具备基本的 C++ 知识,并且已经 插件库
已安装。
sudo apt-get install ros-foxy-pluginlib
任务
在本教程中,您将创建两个新包,一个定义基类,另一个提供插件。基类将定义一个通用的多边形类,然后我们的插件将定义特定的形状。
1 创建基类软件包
中创建一个新的空软件包 ros2_ws/src
文件夹:
ros2 pkg create --build-type ament_cmake polygon_base --dependencies pluginlib --node-name area_node
打开您最喜欢的编辑器,编辑 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
指挥:
安装
目录 include/
目的地包括
)
并在 ament_package
指挥:
ament_export_include_directories(
包括
)
我们稍后将回到这个软件包来编写测试节点。
2 创建插件包
现在,我们要为抽象类编写两个非虚拟实现。在您的 ros2_ws/src
文件夹:
ros2 pkg create --build-type ament_cmake polygon_plugins --dependencies polygon_base pluginlib --library-name 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
宏观:
插件类的全称类型,在本例中是插件类的全称类型、
多边形插件::正方形
.这里是基类的全称类型、
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>;
有几件事需要注意:
"(《世界人权宣言》)
图书馆
标签给出了包含我们要导出的插件的库的相对路径。在 ROS 2 中,这只是库的名称。在 ROS 1 中,它包含前缀lib
或者有时lib/lib
(即lib/libpolygon_plugins
),但这里更简单。"(《世界人权宣言》)
类
标记声明了我们要从程序库中导出的插件。让我们来看看它的参数:
类型
:插件的完全限定类型。对我们来说是多边形插件::正方形
.
基类
:插件的完全限定基类类型。对于我们来说,就是polygon_base::RegularPolygon
.
描述
:说明插件及其功能。
名字
:以前有一个 name 属性,但现在不再需要。
2.3 CMake 插件声明
最后一步是通过 CMakeLists.txt
.这与 ROS 1 有所不同,在 ROS 1 中,导出是通过 package.xml
.将以下代码块添加到 ros2_ws/src/polygon_plugins/CMakeLists.txt
行之后 find_package(pluginlib 必填)
:
add_library(polygon_plugins src/polygon_plugins.cpp)
target_include_directories(polygon_plugins PUBLIC)
$<BUILD_INTERFACE:${cmake_current_source_dir}/include>;
$<INSTALL_INTERFACE:include>;)
ament_target_dependencies(
多边形插件
多边形基数
插件库
)
pluginlib_export_plugin_description_file(polygon_base plugins.xml)
安装
参数 polygon_plugins
EXPORT export_${PROJECT_NAME} 出口
存档目的地 lib
图书目录 lib
运行时目的地 bin
)
的参数 pluginlib_export_plugin_description_file
命令是
基类的软件包,即
多边形基数
.插件声明 xml 的相对路径,即
plugins.xml
.
最后,在 ament_package
命令,添加
ament_export_libraries(
多边形插件
)
ament_export_targets(
export_${PROJECT_NAME} 出口
)
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
install/setup.bash
调用 install/setup.bat
现在运行节点:
ros2 运行多边形基点区域节点
应该打印出来:
三角形面积43.30
广场面积100.00
摘要
恭喜您您刚刚编写并使用了第一个插件。