警告

您正在阅读的 ROS 2 文档版本已达到 EOL(生命周期结束),不再受官方支持。如果您想了解最新信息,请访问 Jazzy.

在单个进程中组合多个节点

背景介绍

参见 概念文章.

运行演示

这些演示使用的可执行文件来自 rclcpp_components, ros2component构成 软件包,并可使用以下命令运行。

了解可用组件

要查看工作区中已注册和可用的组件,请在 shell 中执行以下命令:

$ 玫瑰2 组成部分 类型构成
  构成::谈话者
  composition::Listener
  组成::服务器
  composition::Client

使用 ROS 服务 (1.) 与发布者和订阅者进行运行时组合

在第一个外壳中,启动组件容器:

玫瑰2 运行 rclcpp_components 组件容器

通过 玫瑰2 命令行工具:

$ 玫瑰2 组成部分 list /ComponentManager

在第二个外壳中(见 话匣子 源代码)。该命令将返回已加载组件的唯一 ID 和节点名称。

$ 玫瑰2 组成部分 负荷 /ComponentManager 构成 composition::Talker Loaded 组成部分 1  '/ComponentManager'; 集装箱 网站 作为 '/talker';

现在,第一个 shell 应显示组件已加载的信息以及重复发布信息的信息。

第二个 shell 中的另一条命令(见 听众 源代码):

$ 玫瑰2 组成部分 负荷 /ComponentManager 构成 已加载 composition::Listener 组成部分 2  '/ComponentManager'; 集装箱 网站 作为 '/listener';

"(《世界人权宣言》) 玫瑰2 命令行实用程序现在可以用来检查容器的状态:

$ 玫瑰2 组成部分 list /ComponentManager
   1  /对话者
   2  /听众

现在,第一个 shell 应该会重复显示每条接收到的信息的输出。

使用 ROS 服务 (1.) 与服务器和客户端进行运行时组合

服务器和客户端的例子非常相似。

第一个外壳

玫瑰2 运行 rclcpp_components 组件容器

在第二个外壳中(见 服务器客户 源代码):

玫瑰2 组成部分 负荷 /ComponentManager 构成 composition::Server ros2 组成部分 负荷 /ComponentManager 构成 composition::Client

在这种情况下,客户端向服务器发送请求,服务器处理请求并回复一个响应,客户端打印收到的响应。

使用 ROS 服务进行编译时合成 (2.)

该演示表明,可以重复使用相同的共享库来编译运行多个组件的单个可执行文件。该可执行文件包含上述所有四个组件:通话器和监听器以及服务器和客户端。

在 shell 调用中(见 源代码):

玫瑰2 运行 构成 手动合成

这应该会显示来自交谈者和倾听者以及服务器和客户端这两对人的重复信息。

备注

手动组成的组件不会反映在 玫瑰2 组成部分 清单 命令行工具输出。

使用 dlopen 进行运行时合成

本演示介绍了 1.的替代方法,即创建一个通用容器进程,明确传递要加载的库,而不使用 ROS 接口。进程将打开每个库,并为库中的每个 "rclcpp::Node "类创建一个实例 源代码).

玫瑰2 运行 构成 dlopen_composition `玫瑰2  词头 构成`/lib/libtalker_component.so `玫瑰2  词头 构成`/lib/liblistener_component.so

现在 shell 应该会重复显示每条发送和接收信息的输出。

备注

dlopen 组件不会反映在 玫瑰2 组成部分 清单 命令行工具输出。

使用发射行动进行合成

虽然命令行工具对调试和诊断组件配置很有用,但同时启动一组组件往往更方便。为了自动执行这一操作,我们可以使用 玫瑰2 启动.

玫瑰2 启动 构成 composition_demo.launch.py

高级主题

在了解了组件的基本操作之后,我们可以讨论一些更高级的话题。

卸载组件

在第一个外壳中,启动组件容器:

玫瑰2 运行 rclcpp_components 组件容器

通过 玫瑰2 命令行工具:

$ 玫瑰2 组成部分 list /ComponentManager

在第二个外壳中(见 话匣子 源代码)。该命令将返回已加载组件的唯一 ID 和节点名称。

$ 玫瑰2 组成部分 负荷 /ComponentManager 构成 composition::Talker Loaded 组成部分 1  '/ComponentManager'; 集装箱 网站 作为 '/talker';
$ 玫瑰2 组成部分 负荷 /ComponentManager 构成 已加载 composition::Listener 组成部分 2  '/ComponentManager'; 集装箱 网站 作为 '/listener';

使用唯一 ID 从组件容器中卸载节点。

$ 玫瑰2 组成部分 卸载 /ComponentManager 1 2
已卸载 组成部分 1  '/ComponentManager'; 卸载的集装箱 组成部分 2  '/ComponentManager'; 集装箱

在第一个 shell 中,验证通话者和监听者的重复信息是否已经停止。

重新映射容器名称和命名空间

组件管理器名称和命名空间可通过标准命令行参数重新映射:

玫瑰2 运行 rclcpp_components 组件容器 --ros-args -r __节点:=我的容器 -r __ns:=/ns

在第二个外壳中,可以使用更新后的容器名称加载组件:

玫瑰2 组成部分 负荷 /ns/MyContainer 构成 composition::Listener

备注

容器的命名空间重映射不会影响已加载的组件。

重新映射组件名称和命名空间

组件名称和命名空间可通过加载命令的参数进行调整。

在第一个外壳中,启动组件容器:

玫瑰2 运行 rclcpp_components 组件容器

如何重新映射名称和命名空间的一些示例:

# 重新映射节点名称
玫瑰2 组成部分 负荷 /ComponentManager 构成 构成::谈话者 --节点名 Talker2
# 重新映射命名空间
玫瑰2 组成部分 负荷 /ComponentManager 构成 构成::谈话者 --节点名称空间 /ns
# 重新映射两者
玫瑰2 组成部分 负荷 /ComponentManager 构成 构成::谈话者 --节点名 talker3 --节点名称空间 /ns2

相应的条目出现在 玫瑰2 组成部分 清单:

$ 玫瑰2 组成部分 list /ComponentManager
   1  /talker2
   2  /ns/talker
   3  /ns2/talker3

备注

容器的命名空间重映射不会影响已加载的组件。

作为共享库的可组合节点

如果你想从一个软件包中导出一个可组合节点作为共享库,并在另一个可进行链接时组合的软件包中使用该节点,请在 CMake 文件中添加代码,导入下游软件包中的实际目标。

然后安装生成的文件并导出生成的文件。

在这里可以看到一个实际的例子: ROS Discourse - Ament 库共享最佳实践