理解主题

目标: 使用 rqt_graph 和命令行工具来内省 ROS 2 主题。

教程级别: 初学者

时间: 20 分钟

背景

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

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

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

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

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

先决条件

上一个教程 提供了一些有关节点的有用背景信息,在此基础上进行构建。

与往常一样,不要忘记在 每次打开新终端 中获取 ROS 2。

任务

1 设置

现在您应该可以轻松启动 turtlesim。

打开一个新终端并运行:

ros2 run turtlesim turtlesim_node

打开另一个终端并运行:

ros2 run turtlesim turtle_teleop_key

Recall from the previous tutorial that the names of these nodes are /turtlesim and /teleop_turtle by default.

2 rqt_graph

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

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

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

rqt_graph

您还可以通过打开 rqt 并选择 插件> 自省> **节点图**来打开 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 主题列表 -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 主题信息

主题不必只是一对一通信;它们可以是一对多、多对一或多对多。

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

ros2 topic info /turtle1/cmd_vel

它将返回:

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

6 ros2 界面展示

节点使用消息通过主题发送数据。

发布者和订阅者必须发送和接收相同类型的消息才能进行通信。

运行 ``ros2 topic list -t``后,我们之前看到的主题类型让我们知道每个主题使用什么消息类型。 回想一下,“cmd_vel”主题具有以下类型:

geometry_msgs/msg/Twist

这意味着在包 geometry_msgs``中有一个名为 ``Twist``的 ``msg

现在我们可以在这个类型上运行 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 /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 的频率稳定流发布命令。

../../../_images/pub_stream.png

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

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。

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

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

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

../../../_images/pub_once.png

您可以刷新 rqt_graph 以图形方式查看发生的情况。 您将看到 ros2 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 节点已订阅该主题。

发布带有时间戳的消息时,pub 有两种方法可以自动用当前时间填充它们。 对于带有 std_msgs/msg/Header 的消息,可以将 header 字段设置为 auto 以填充 stamp 字段。

ros2 topic pub /pose geometry_msgs/msg/PoseStamped '{header: "auto", pose: {position: {x: 1.0, y: 2.0, z: 3.0}}}'

如果消息没有使用完整的标头,而只是有一个类型为 builtin_interfaces/msg/Time 的字段,则可以将其设置为值 now

ros2 topic pub /reference sensor_msgs/msg/TimeReference '{header: "auto", time_ref: "now", source: "dumy"}'

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 的发布速率设置为以稳定的 1 Hz。 如果您使用 turtle1/cmd_vel 而不是 turtle1/pose 运行上述命令,您将看到反映该速率的平均值。

9 ros2 topic bw

可以使用以下方式查看主题使用的带宽:

ros2 topic bw /turtle1/pose

它返回带宽利用率和发布到 /turtle1/pose 主题的消息数量。

Subscribed to [/turtle1/pose]
1.51 KB/s from 62 messages
    Message size mean: 0.02 KB min: 0.02 KB max: 0.02 KB

10 ros2 topic find

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

ros2 topic find <topic_type>

回想一下, cmd_vel 主题具有以下类型:

geometry_msgs/msg/Twist

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

ros2 topic find geometry_msgs/msg/Twist

输出:

/turtle1/cmd_vel

11 清理

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

摘要

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

下一步

接下来,您将通过教程 了解服务 了解 ROS 图中的其他通信类型。