You're reading the documentation for a development version. For the latest released version, please have a look at Galactic.

理解 ROS 2 主题

目标:使用 rqt_graph 和命令行工具来介绍 ROS 2 的主题。

Tutorial level: Beginner

Time: 20 minutes

背景

ROS 2 将复杂的系统分解成许多模块化节点。主题是 ROS graph 的一个重要元素,它充当节点交换消息的总线。

../../_images/Topic-SinglePublisherandSingleSubscriber.gif

节点可以向任意数量的主题发布数据,并同时订阅任意数量的主题。

../../_images/Topic-MultiplePublisherandMultipleSubscriber.gif

主题是数据在节点之间以及系统的不同部分之间移动的主要方式之一。

先决条件

前面的教程 提供了一些关于在此基础上构建的节点的有用背景信息。

像往常一样,不要忘记在 你打开的每一个新终端 中为 ROS 2 激活源代码。

任务

1 设置

现在你应该能自如地启动海龟模型了。

打开一个新的终端并运行:

ros2 run turtlesim turtlesim_node

打开另一个终端并运行:

ros2 run turtlesim turtle_teleop_key

回想一下 之前的教程,默认情况下,这些节点的名称是 /turtlesim/teleop_turtle

2 rqt_graph

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

turtlesim 教程 告诉您如何安装 rqt 及其所有插件,包括 rqt_graph

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

rqt_graph

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

../../_images/rqt_graph.png

您应该看到上面的节点和主题,以及围绕图外围的两个操作(现在让我们忽略它们)。如果你将鼠标悬停在主题的中心,你会看到颜色高亮如上图。

该图描述了 /turtlesim 节点和 /teleop_turtle 节点如何在一个主题上相互通信。/teleop_turtle 节点将数据(您为移动海龟而输入的击键)发布到 /turtle1/cmd_vel 主题,并且 /turtlesim 节点订阅该主题以接收数据。

rqt_graph 的高亮显示特性在检查更复杂的系统时非常有用,这些系统中有许多节点和主题,它们以许多不同的方式连接在一起。

rqt_graph 是一个图形自省工具。现在我们来看一些用于内省主题的命令行工具。

3 ros2 topic list

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

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

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

/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]

这些属性,尤其是类型,是节点如何在跨越主题时知道它们所讨论的是相同的信息。

如果你想知道所有这些主题在 rqt_graph 中的位置,你可以取消选中隐藏下面的所有框:

../../_images/unhide.png

不过,现在还是检查一下这些选项,以避免混淆。

4 ros2 topic echo

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

ros2 topic echo <topic_name>

因为我们知道 /teleop_turtle 通过 /turtle1/cmd_vel 主题将数据发布到 /turtlesim,所以让我们使用 echo 对该主题进行内测:

ros2 topic echo /turtle1/cmd_vel

起初,这个命令不会返回任何数据。这是因为它正在等待 /teleop_turtle 发布一些内容。

返回 turtle_teleop_key 运行的终端,使用箭头移动海龟。观察你的 echo 同时运行的终端,你会看到你做的每一个动作都会发布位置数据:

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

现在返回到 rqt_graph 并取消 Debug 框。

../../_images/debug.png

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

5 ros2 topic info

主题不必只是点对点的交流;它可以是一对多、多对一或多对多。

另一种看待这个问题的方式是运行:

ros2 topic info /turtle1/cmd_vel

这将返回:

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

6 ros2 interface show

节点使用消息通过主题发送数据。发布者和订阅者必须发送和接收相同类型的消息进行通信。

在运行 ros2 topic list -t 之后,我们看到的主题类型让我们知道每个主题使用的消息类型。回想一下 cmd_vel 主题的类型:

geometry_msgs/msg/Twist

这意味着在包 geometry_msgs 中有一个名为 Twistmsg

现在我们可以在这个类型上运行 ros2 interface show <msg type> 来了解它的详细信息,特别是消息所期望的数据结构。

ros2 interface show geometry_msgs/msg/Twist

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

# 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 节点需要一个带有两个向量(linearangular)的消息,每个向量有三个元素。如果你回想一下我们看到的 /teleop_turtle 通过 echo 命令传递给 /turtlesim 的数据,它的结构是相同的:

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

7 ros2 topic pub

现在你有了消息结构,你可以直接从命令行发布数据到主题使用:

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

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

需要注意的是,这个参数需要在 YAML 语法中输入。像这样输入完整的命令:

ros2 topic pub --once /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 是一个可选参数,表示“发布一条消息然后退出”。

您将在终端收到以下信息:

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))

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

../../_images/pub_once.png

turtle(通常是它要模拟的真正的机器人)需要稳定的指令流来持续操作。所以,为了让 turtle 继续移动,你可以:

ros2 topic pub --rate 1 /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 选项并添加了 --rate 1 选项,该选项告诉 ros2 topic pub 以 1Hz 的稳定流发布命令。

../../_images/pub_stream.png

您可以刷新 rqt_graph 以查看图形化的方式发生了什么。你会看到 ros 2 topic pub ... 节点(/_ros2cli_30358)在 /turtle1/cmd_vel 主题上发布,并且被两个 ros2 topic echo ... 节点(/_ros2cli_26646)和 /turtlesim 节点接收。

../../_images/rqt_graph2.png

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

ros2 topic echo /turtle1/pose
../../_images/rqt_graph3.png

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

8 ros2 topic hz

关于这个过程的最后一个自省,你可以查看数据发布的速率,使用:

ros2 topic hz /turtle1/pose

它将返回 /turtlesim 节点将数据发布到 pose 主题的速率。

average rate: 59.354
  min: 0.005s max: 0.027s std dev: 0.00284s window: 58

回想一下,您使用 ros2 topic pub --rate 1turtle1/cmd_vel 的速率设置为以稳定的 1Hz 发布。如果使用 turtle1/cmd_vel 而不是 turtle1/pose 运行上面的命令,您将看到反映该速率的平均值。

9 清理

此时,您将有许多节点在运行。不要忘记在每个终端输入 {kbd}`Ctrl`+{kbd}`C`来阻止它们。

小结

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

下一步

接下来你将通过教程了解 ROS graph 中的另一种通信类型 理解 ROS2 服务