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

运行例程 [待校准@7036]

该例程使用来自 rclcpp_components, ros2component, and composition 包的可执行文件,并且可以使用以下命令运行。 [待校准@7037]

发现可用组件 [待校准@7038]

要查看工作区中注册和可用的组件,请在shell中执行以下操作: [待校准@7039]

$ ros2 component types
composition
  composition::Talker
  composition::Listener
  composition::Server
  composition::Client

运行时组合使用ROS服务 (1.) 与发布者和订阅者 [待校准@7040]

在第一个shell中,启动组件容器: [待校准@7041]

ros2 run rclcpp_components component_container

验证容器是否通过 ros2 命令行工具运行: [待校准@7042]

$ ros2 component list
/ComponentManager

在第二个外壳中 (参见 talker 源文件代码)。该命令将返回已加载组件的唯一账号以及节点名称。 [待校准@7043]

$ ros2 component load /ComponentManager composition composition::Talker
Loaded component 1 into '/ComponentManager' container node as '/talker'

现在,第一个shell应该显示已加载组件的消息以及用于发布消息的重复消息。 [待校准@7044]

第二个shell中的另一个命令 (请参阅 listener 源文件代码): [待校准@7045]

$ ros2 component load /ComponentManager composition composition::Listener
Loaded component 2 into '/ComponentManager' container node as '/listener'

现在可以使用 ros2 命令行实用程序检查容器的状态: [待校准@7046]

$ ros2 component list
/ComponentManager
   1  /talker
   2  /listener

现在,第一个shell应该为每个接收到的消息显示重复的输出。 [待校准@7047]

使用ROS服务 (1.) 与服务器和客户端的运行时组合 [待校准@7048]

服务器和客户端的示例非常相似。 [待校准@7049]

在第一个shell中: [待校准@7050]

ros2 run rclcpp_components component_container

在第二个外壳中 (见 serverclient 源文件代码): [待校准@7051]

ros2 component load /ComponentManager composition composition::Server
ros2 component load /ComponentManager composition composition::Client

在这种情况下,客户端向服务器发送请求,服务器处理请求并回复响应,客户端打印收到的响应。 [待校准@7052]

使用ROS服务的编译时组合 (2.) [待校准@7053]

此例程显示可以重用相同的共享库来编译运行多个组件的单个可执行文件。可执行文件包含上述所有四个组件: talker和listen以及server和client。 [待校准@7054]

在shell调用中 (参见 source code ): [待校准@7055]

ros2 run composition manual_composition

这应该显示来自两个对的重复消息,谈话者和侦听器以及服务器和客户端。 [待校准@7056]

注解

手动组成的组件不会反映在 ros2 component list 命令行工具输出中。 [待校准@7057]

使用dlopen的运行时合成 [待校准@7058]

此例程提供了1的替代方法。通过创建通用容器进程并显式传递库以加载而不使用ROS接口。该过程将打开每个库,并在库 source code 中创建每个 "rclcpp::Node" 类的一个实例)。 [待校准@7059]

ros2 run composition dlopen_composition `ros2 pkg prefix composition`/lib/libtalker_component.so `ros2 pkg prefix composition`/lib/liblistener_component.so

现在,shell应该为每个发送和接收的消息显示重复的输出。 [待校准@7061]

注解

dlopen组成的组件不会反映在 ros2 component list 命令行工具输出中。 [待校准@7062]

使用launch动作的组件 [待校准@7063]

虽然命令行工具可用于调试和诊断组件配置,但同时启动一组组件通常更方便。为了使这个动作自动化,我们可以使用 ros2 launch 的功能。 [待校准@7064]

ros2 launch composition composition_demo.launch.py

高级话题 [待校准@7065]

既然我们已经看到了组件的基本操作,我们可以讨论一些更高级的话题。 [待校准@7066]

卸载组件 [待校准@7067]

在第一个shell中,启动组件容器: [待校准@7041]

ros2 run rclcpp_components component_container

验证容器是否通过 ros2 命令行工具运行: [待校准@7042]

$ ros2 component list
/ComponentManager

在第二个外壳中 (参见 talker 源文件代码)。该命令将返回已加载组件的唯一账号以及节点名称。 [待校准@7043]

$ ros2 component load /ComponentManager composition composition::Talker
Loaded component 1 into '/ComponentManager' container node as '/talker'
$ ros2 component load /ComponentManager composition composition::Listener
Loaded component 2 into '/ComponentManager' container node as '/listener'

使用唯一账号从组件容器中卸载节点。 [待校准@7068]

$ ros2 component unload /ComponentManager 1 2
Unloaded component 1 from '/ComponentManager' container
Unloaded component 2 from '/ComponentManager' container

在第一个shell中,验证来自talker和listen的重复消息是否已停止。 [待校准@7069]

重新映射容器名称和命名空间 [待校准@7070]

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

ros2 run rclcpp_components component_container --ros-args -r __node:=MyContainer -r __ns:=/ns

在第二个shell中,可以使用更新的容器名称来加载组件: [待校准@7072]

ros2 component load /ns/MyContainer composition composition::Listener

注解

容器的命名空间重映射不影响加载的组件。 [待校准@7073]

重新映射组件名称和命名空间 [待校准@7074]

组件名称和命名空间可以通过load命令的参数进行调整。 [待校准@7075]

在第一个shell中,启动组件容器: [待校准@7041]

ros2 run rclcpp_components component_container

如何重新映射名称和命名空间的一些示例: [待校准@7076]

# Remap node name
ros2 component load /ComponentManager composition composition::Talker --node-name talker2
# Remap namespace
ros2 component load /ComponentManager composition composition::Talker --node-namespace /ns
# Remap both
ros2 component load /ComponentManager composition composition::Talker --node-name talker3 --node-namespace /ns2

相应的条目出现在 ros2 component list : [待校准@7077]

$ ros2 component list
/ComponentManager
   1  /talker2
   2  /ns/talker
   3  /ns2/talker3

注解

容器的命名空间重映射不影响加载的组件。 [待校准@7073]

将参数值传递到组件中 [待校准@7078]

[需手动修复的语法] ros2 component load 命令行支持在节点构造时将任意参数传递给节点。此功能可按如下方式使用: [待校准@7079]

$ ros2 component load /ComponentManager image_tools image_tools::Cam2Image -p burger_mode:=true

将其他参数传递到组件中 [待校准@7080]

[需手动修复的语法] ros2 component load 命令行支持将特定选项传递给组件管理器,以便在构造节点时使用。到目前为止,唯一支持的命令行选项是使用进程内通讯实例化节点。此功能可按如下方式使用: [待校准@7081]

$ ros2 component load /ComponentManager composition composition::Talker -e use_intra_process_comms:=true

作为共享库的可组合节点 [待校准@7082]

如果要将可组合节点从包中导出为共享库,并在执行链接时组合的另一个包中使用该节点,将代码添加到CMake文件中,该文件导入下游包中的实际目标。 [待校准@7083]

然后安装生成的文件并导出生成的文件。 [待校准@7084]

这里可以看到一个实际的例子: ROS Discourse - Ament best practice for sharing libraries [待校准@7085]