Skip to content

ROS2主要创新的1/3:通信topics

01. 背景

ROS 2 将复杂的系统分解为许多模块化节点。topics(话题)是ROS graph的重要组成部分,充当节点交换消息的总线(Bus),如下图所示:

话题通信的示意图

一个节点可以将数据发布到任意数量的话题,同时订阅任意数量的话题,如下图所示:

话题订阅、接收的拓扑关系示意图

话题是数据在节点之间传送的主要方式之一,因此也是在ROS2系统不同部分之间传送数据的主要方式之一。

02. 学习任务

在这堂课,我们要学习如何在命令行中使用ROS2的话题通信,以在不同节点之间传递数据,并了解如何使用ROS2的一些命令行工具来调查话题的工作状态。

不要忘了先在终端中运行如下命令,以加载必要的工作环境配置变量:

Shell
source /opt/ros/jazzy/setup.zsh

2.1 运行好turtlesim及节点

在终端中输入以下命令:

Shell
ros2 run turtlesim turtlesim_node

打开另一个终端,输入以下命令:

Shell
ros2 run turtlesim turtle_teleop_key

根据上一节课的内容,您可以使用 ros2 node list 命令查看正在运行的节点。

2.2 rqt_graph

在本教程中,我们将使用 rqt_graph 来可视化不断变化的节点和主题,以及它们之间的联系。

要运行 rqt_graph,请打开新终端并输入命令:

shell
rqt_graph

还可以通过打开 rqt 并选择 Plugins > Introspection > Node Graph 来打开 rqt_graph。

rqt_graph运行界面

此时,我们从上图可以看到两个节点,以及最外层的两个actions(关于action的概念我们暂放一边).

该图描述了 /turtlesim 节点和 /teleop_turtle 节点如何通过主题相互通信。/teleop_turtle 节点正在将数据(我们输入的用于移动 turtle 的按键)发布到 /turtle1/cmd_vel 主题(topic),而 /turtlesim 节点订阅该主题以接收数据。

rqt_graph 是一个图形化的调查工具。现在,我们将查看一些用于调查topic的命令行工具。

2.3 ros2 topic list

在新终端中运行 ros2 topic list 命令将返回系统中当前活动的所有topic的列表:

shell
/parameter_events
/rosout
/turtle1/cmd_vel
/turtle1/color_sensor
/turtle1/pose

ros2 topic list -t 将返回相同的主题列表,这次topic的类型 (type) 附加在括号中:

shell
/parameter_events [rcl_interfaces/msg/ParameterEvent]
/rosout [rcl_interfaces/msg/Log]
/turtle1/cmd_vel [geometry_msgs/msg/Twist]
/turtle1/color_sensor [turtlesim/msg/Color]
/turtle1/pose [turtlesim/msg/Pose]

通过这些属性尤其是类型(type),有助于我们获取节点(node) 在主题(topic)之间传递数据的具体格式。

如果您想知道所有这些主题的rqt_graph在哪里,您可以取消选中 Hide (隐藏) 下的所有框:

查看所有的topics

不过,现在,请选中Hide中的这些选项以避免干扰视线。

2.4 ros2 topic echo

要查看有关某个主题发布的数据,请使用:

shell
ros2 topic echo <topic_name>

既然我们知道 /teleop_turtle 通过 /turtle1/cmd_vel 主题向 /turtlesim 发布数据,那么让我们使用 echo 来内省该主题:

shell
ros2 topic echo /turtle1/cmd_vel

返回到 turtle_teleop_key 正在运行的终端,并使用箭头移动 turtle。同时观察运行 echo 的终端,您将看到您所做的每个动作都发布了位置数据:

shell
linear:
  x: 2.0
  y: 0.0
  z: 0.0
angular:
  x: 0.0
  y: 0.0
  z: 0.0
  ---

现在返回 rqt_graph 并取消选中 Debug 框。

在ROS2的graph中查看echo节点

/_ros2cli_26646 是我们刚刚运行的 echo 命令创建的节点(数字可能不同)。现在,您可以看到发布者正在通过 cmd_vel 主题发布数据,并且有两个订阅者订阅了该主题。

2.5 ros2 topic info

topic不必只是一对一的交流;它们可以是一对多、多对一或多对多。 另一种看待这种情况的方法是 running:

shell
ros2 topic info /turtle1/cmd_vel

这将返回:

shell
Type: geometry_msgs/msg/Twist
Publisher count: 1
Subscription count: 2

2.6 ros2 interface show

节点使用消息通过主题发送数据。发布者和订户必须发送和接收相同类型的消息才能进行通信。我们之前在运行 ros2 topic list -t 后看到的主题类型让我们知道每个主题使用了什么消息类型。回想一下,cmd_vel 主题的类型为:

shell
geometry_msgs/msg/Twist

现在我们可以运行 ros2 interface show <msg_type> 此类型以了解其详细信息。具体来说,消息需要什么数据结构。

shell
ros2 interface show geometry_msgs/msg/Twist

对于上面的消息类型,它会产生:

shell
# This expresses velocity in free space broken into its linear and angular parts.

    Vector3  linear
            float64 x
            float64 y
            float64 z
    Vector3  angular
            float64 x
            float64 y
            float64 z

这告诉您 /turtlesim 节点需要一条消息,其中包含两个向量(线性角度),每个向量有三个元素。如果你还记得我们看到 / teleop_turtle 使用 echo 命令传递给 /turtlesim 的数据,它采用相同的结构:

shell
linear:
  x: 2.0
  y: 0.0
  z: 0.0
angular:
  x: 0.0
  y: 0.0
  z: 0.0
  ---

2.7 ros2 topic pub

现在,您拥有了消息结构,可以使用以下方法直接从命令行将数据发布到主题:

shell
ros2 topic pub <topic_name> <msg_type> '<args>'

'<args>' 参数是您将传递给主题的实际数据,采用您刚刚在上一节中发现的结构。

(通常是它要模仿的真实机器人)需要稳定的命令流才能连续运行。因此,要让移动并保持它移动,您可以使用以下命令。请务必注意,此参数需要在 YAML 语法中输入。输入完整的命令,如下所示:

shell
ros2 topic pub /turtle1/cmd_vel geometry_msgs/msg/Twist "{linear: {x: 2.0, y: 0.0, z: 0.0}, angular: {x: 0.0, y: 0.0, z: 1.8}}"

在没有命令行选项的情况下,ros2 topic pub 以 1 Hz 的稳定流发布命令。

在命令行中发布消息

有时,您可能希望仅将数据发布到主题一次(而不是连续)。要仅发布一次命令,请添加 --once 选项。

shell
ros2 topic pub --once -w 2 /turtle1/cmd_vel geometry_msgs/msg/Twist "{linear: {x: 2.0, y: 0.0, z: 0.0}, angular: {x: 0.0, y: 0.0, z: 1.8}}"

--once 是一个可选参数,意思是 “发布一条消息然后退出”。

-w 2 是一个可选参数,表示“等待两个匹配的订阅”。这是必需的,因为我们同时订阅了 turtlesim 和 echo 主题。

您将在终端中看到以下输出:

shell
Waiting for at least 2 matching subscription(s)...
publisher: beginning loop
publishing #1: geometry_msgs.msg.Twist(linear=geometry_msgs.msg.Vector3(x=2.0, y=0.0, z=0.0), angular=geometry_msgs.msg.Vector3(x=0.0, y=0.0, z=1.8))

你会看到你的像这样移动:

发布一次移动命令的turtle

您可以刷新rqt_graph以图形方式查看发生的情况。您将看到 ros2 topic pub ... 节点 (/_ros2cli_30358) 正在通过 /turtle1/cmd_vel 主题发布,该主题现在由 ros2 topic echo ... node (/_ros2cli_26646) 和 /turtlesim 节点接收。

在rqt_graph中查看发布一次移动命令的turtle

最后,您可以在 pose 主题上运行 echo 并重新检查 rqt_graph:

shell
ros2 topic echo /turtle1/pose

查看发布订阅的节点拓扑图

您可以看到 /turtlesim 节点也发布到了新 echo 节点已订阅的 pose 主题。

2.8 ros2 topic hz

(暂时不看,此阶段有些抽象)

2.9 ros2 topic bw

(暂时不看,此阶段有些抽象)

2.10 ros2 topic find

要列出给定类型的可用主题列表,请使用:

shell
ros2 topic find <topic_type>

回想一下,cmd_vel 主题的类型为:

shell
geometry_msgs/msg/Twist

使用 find 命令将在给定消息类型时输出可用的主题:

shell
ros2 topic find geometry_msgs/msg/Twist

这将输出:

shell
/turtle1/cmd_vel

2.11 退出运行节点并清理

此时,您将有很多节点正在运行。不要忘记通过在每个终端中输入 Ctrl+C 来停止它们。

03. 小结

节点通过主题发布信息,这允许任意数量的其他节点订阅和访问该信息。在本教程中,您使用 rqt_graph 和命令行工具检查了主题上多个节点之间的连接。您现在应该对数据如何在 ROS 2 系统中移动有一个很好的了解。

附录:如何重置Linux密码

  • Author: Ningfeng CHEN