概要:这篇内容主要介绍将多个node节点组合到单一进程中

环境:ubuntu20.04,ros2-foxy,vscode

最后如果没有陈述实操过程中碰到问题的话,则表示该章节都可被本人正常复现

3.5多个node节点组合到单一进程中(原文:https://docs.ros.org/en/foxy/Tutorials/Composition.html)

>>教程>>多个node节点组合到单一进程中

你正阅读的是ros2较老版本(Foxy),但仍然支持的说明文档.想查看最新版本的信息,请看galactic版本链接( https://docs.ros.org/en/galactic/Tutorials.html)

多个node节点组合到单一进程中

目录

1.背景
2.运行这些demos
2.1发现可使用的部件
2.2运行时使用发布器和订阅器组合的ROS服务(1)
2.3运行时使用服务器和客户端组合的ROS服务(1)
2.4编译时使用ROS服务组合(2)
2.5运行时使用dlopen组合
2.6使用lauunch操作组合
3.高级话题
3.1卸载组件
3.2重映射容器名称和命名空间
3.3重映射组件名称和命名空间
4(将)可组合节点作为共享库

1.背景

参考本文(https://docs.ros.org/en/foxy/Concepts/About-Composition.html)概念.

2.运行这些demos

这些demos使用rclcpp_components, ros2componentcomposition包里面可执行文件,并且可以使用以下指令运行.

2.1发现可使用的部件

查看工作空间有哪些注册的和可使用的组件,终端执行下面指令:

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

2.2运行时使用发布器和订阅器组合的ROS服务(1)

第一个终端,运行组件容器:

ros2 run rclcpp_components component_container

使用ros2命令行确认正在运行中的容器

$ ros2 component list
/ComponentManager

在第二个终端(查看talker源码(https://github.com/ros2/demos/blob/foxy/composition/src/talker_component.cpp)).这个指令会返回已启动的模块id,其跟节点名字一样独一无二.

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

现在,第一个终端应该看到已启动模块消息,也会因为发布讯息重复该消息.

第二个终端的另一条指令(查看listener代码(https://github.com/ros2/demos/blob/foxy/composition/src/listener_component.cpp))

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

ros2命令行实用程序现在是可以用来检查容器的状态:

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

现在,第一个终端应该会重复显示输出每一条接受到的消息.

2.3运行时使用服务器和客户端组合的ROS服务(1)

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

在第一个终端:

ros2 run rclcpp_components component_container

在第二个终端(查看服务器(https://github.com/ros2/demos/blob/foxy/composition/src/server_component.cpp)和客户端(https://github.com/ros2/demos/blob/foxy/composition/src/client_component.cpp)源码):

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

在案例中,客户端发送一个请求到服务器,服务器处理请求,并且返回响应,客户端打印收到的响应.

2.4编译时使用ROS服务组合(2)

这个案例展示的是,可以重用相同的共享库编译一个可执行文件运行多个组件.这个可执行文件包含上面四个组件:talker与 listener和 server与client.

第一个终端运行(查看源码(https://github.com/ros2/demos/blob/foxy/composition/src/manual_composition.cpp)):

ros2 run composition manual_composition

这应该会显示这两组的重复消息,talker listener serverclient

注意

手动组合的组件并不能使用ros2 component list输出命令行显示的.

2.5运行时使用dlopen组合

这里案例通过创建一个泛型容器进程,并且明确通过库加载而不是使用ros接口,给1提出了可替代性(方案).这个过程会打开每一个库并在库源码里面创建每一个rclcpp::Node类实例(https://github.com/ros2/demos/blob/foxy/composition/src/dlopen_composition.cpp).

linux:

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

现在,终端应该显示重复输出每一条发送或接收的消息.

注意

dlopen库函数模块并不能用ros2 component list输出指令行显示.

2.6使用lauunch操作组合

命令行工具用来调试和诊断组件配置,它通常是在同一时间启动一组组件(的方式)更方便。为了使得该操作自动化(完成),我们可以使用ros2 launch功能指令.

ros2 launch composition composition_demo.launch.py

3.高级话题

现在,我们已经了解组件的基本操作,我们可开始讨论一些高级话题.

3.1卸载组件

第一个终端,启动组件容器:

ros2 run rclcpp_components component_container

运用ros2命令行工具确认正在运行的容器

$ ros2 component list
/ComponentManager

在第二个终端(查看talker源码(https://github.com/ros2/demos/blob/foxy/composition/src/talker_component.cpp)).这个指令会返回已启动的模块id,其跟节点名字一样独一无二.

$ 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'

用专属的ID来卸载组件容器的节点。

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

在第一个终端,确认来自talkerlistener复述信息已经停止.

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

组件管理器名称和命名空间可以通过标准的命令行参数重新映射(给个新名字意思):

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

在第二个终端,可使用更新的容器名来加载组件:

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

注意

容器命名空间的重映射并不影响影响已经启动的组件.

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

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

第一个终端,启动组件容器:

ros2 run rclcpp_components component_container

一些重映射名字和命名空间的例子:

# 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有相应的条目出现:

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

注意

容器名称空间的重新映射不影响已经加载的组件.

4(将)可组合节点作为共享库

如果你想从一个包内输出一个组合节点作为一个共享库,并且在链接时组成的另一包使用该节点,(则)添加代码到CMake文件里面,该文件会导入下游包的实际目标(含target参数定义).

然后安装生成文件,输出生成文件.

实际案例可以看这里:ros分析-共享库的ament最好练习(https://discourse.ros.org/t/ament-best-practice-for-sharing-libraries/3602

其他

个人认为重点:

组件相关指令,罗列,重映射(名字或命名空间),类型查看,加载,(多个时)launch启动,卸载

这课程是在等毕业证那十几天搞的,室友问,现在在线翻译这么强大,为啥还在这里瞎折腾呢?我说,我的目地是好好认真看一下,了解一下,自己折腾,目前是我想到最好的办法来获得最佳效果,即使这翻译有点别扭,哈哈哈.

###############
不积硅步,无以至千里
好记性不如烂笔头
感觉有点收获的话,麻烦大大们点赞收藏哈

原文链接:https://blog.csdn.net/qq_45701501/article/details/119281785?spm=1001.2014.3001.5502