跳到主要内容

话题的通信流程和常用命令

ROS2 中的信息传递和节点

在 ROS2 操作系统中,一共有四种通信类型,分别是话题、服务、动作和参数。他们的工作模式和特点如表 1所示:

表1 ROS2中的通信类型

通信类型模式特点应用场景
话题(Topic)发布/订阅实时性强、异步传感器数据、控制指令
服务(Service)请求/响应同步、阻塞配置、控制请求
动作(Action)请求/反馈/结果支持取消、持续反馈导航、操作控制
参数(Parameter)读写参数配置型,非流式节点行为调整

节点(Node) 是 ROS2 通信图中的基本参与者。每个节点通过客户端库(如 rclcpp)与其他节点进行通信。节点可以运行在同一进程中,也可以分布在不同进程或不同计算机上。

在实际系统中,一个节点通常会同时包含话题、服务、动作和参数等多种通信接口,用于完成特定的功能任务。节点之间的连接由 ROS2 的分布式发现机制自动完成,无需手动配置网络连接。

ROS2 中的话题工作原理

图 1 展示了话题的工作原理,图中发布者向话题发布数据,订阅者通过订阅话题得到数据,从而完成数据的传输。在使用 ROS2 编程时,我们会觉得“话题”很像一个“特殊变量”,但是话题本身并不保存任何数据,它更像是一个命名的通信通道。我们可以把它想象成一个广播频道,每个话题都必须绑定一个特定的消息类型,这是一种数据结构,定义了这个话题中可以传输哪些数据。例如: /chatter 话题使用的是 std_msgs/msg/String 类型(ROS 系统自定义的数据类型),只包含一个字符串字段;/cmd_vel 话题使用的是 geometry_msgs/msg/Twist 类型,包含线速度和角速度两个向量。

ROS 2 话题的工作流程

图 1: ROS 2 话题的工作流程

图2 展示了 ROS 2 中“功能包(Package)”与“节点(Node)”之间的基本组织结构,以及发布者(Publisher)与订阅者(Subscriber)之间的通信关系。

  • 工作空间中的功能包 图 2 的左上部分表示:在一个 ROS 2 工作空间中,通常会有多个功能包(Package),比如用 C++ 编写的功能包1,或用 Python 编写的 功能包2。功能包是 ROS 2 的基本组织单元,每个功能包可以包含多个节点、消息、服务、自定义接口等资源。

  • 功能包包含多个节点 右上部分说明:一个功能包中可以包含多个节点(例如 节点1节点2)。这些节点可以独立运行,也可以协同工作。节点是 ROS 中的最小运行单元,用于执行某个具体的功能,比如采集传感器数据、控制电机等。

  • 节点内部通信(一个功能包内) 左下角图示中,发布者和订阅者节点在同一个功能包内。这种情况下,它们之间的通信逻辑可以直接构建在同一个程序结构中,例如一个 Python 脚本中同时定义发布者和订阅者。

  • 节点跨功能包通信 右下角发布者和订阅者也可以分属不同的功能包。这是 ROS 2 系统的强大特性之一——只要它们订阅和发布的是同一个“话题”,通信就能正常进行,彼此的代码互不依赖。这种结构更利于模块化设计、功能复用和团队协作开发。

ROS 2 功能包与节点之间的关系

图 2: ROS2 功能包与节点之间的关系

话题的常用命令

在 ROS 2 中,话题(Topic)是节点之间进行发布/订阅通信的主要机制。为了方便调试和开发,ROS 2 提供了一组常用的命令行工具来操作和查看话题。这些命令都以 ros2 topic 开头,下面是常用的相关命令:

命令作用说明
ros2 topic list列出当前系统中所有可用的话题
ros2 topic info <话题名>查看某个话题的详细信息(如消息类型、发布者、订阅者等)
ros2 topic echo <话题名>持续打印某个话题的消息内容(即查看发布的数据)
ros2 topic hz <话题名>查看话题的发布频率(Hz)
ros2 topic type <话题名>显示话题对应的消息类型
ros2 topic pub <话题名> <类型> <数据>手动发布一条消息到某个话题上(用于调试或测试)
ros2 topic bw <话题名>查看某话题的数据带宽使用情况
ros2 topic delay <话题名>检查消息从发布到订阅的延迟(需要时钟同步)

示例讲解

  1. 查看所有话题

    ros2 topic list

  2. 查看 /chatter 话题的消息类型

    ros2 topic type /chatter

  3. 查看话题的实时数据

    ros2 topic echo /chatter

  4. 发布一条字符串消息

    ros2 topic pub /chatter std_msgs/msg/String '{data: "Hello ROS 2!"}'

  5. 查看发布频率

    ros2 topic hz /chatter