1. ROS2核心概念:节点、话题、服务、动作的定义与关系

大家好,我是你们的机器人调试工程师。今天咱们来聊聊ROS2里最基础、也最绕不开的四个概念——节点、话题、服务、动作。说实话,我带过不少新人,很多人一开始就被这些术语搞晕了。其实没那么复杂,你想想看,它们就像是一个团队里不同角色的沟通方式。

1.1 节点:机器人里的“独立个体”

节点,说白了就是一个独立的可执行程序。每个节点只干一件事,比如控制电机、处理激光雷达数据、做路径规划。我习惯把节点比作公司里的员工——每个人都有自己的岗位职责。

核心要点:ROS2系统就是由多个节点组成的分布式网络。节点之间通过话题、服务、动作来通信。

我在项目中遇到过一个问题:有人把所有功能都写在一个节点里,结果调试时改一处就崩全局。后来我强制自己遵循“单一职责原则”——一个节点只做一件事。这样出了问题,定位起来特别快。

# 启动一个节点
ros2 run turtlesim turtlesim_node

# 查看所有运行中的节点
ros2 node list

1.2 话题:异步的“广播式”通信

话题是ROS2里最常用的通信方式。它是一种发布/订阅模型——发布者不断往外发数据,订阅者接收数据。双方不需要知道对方的存在。

嗯,这里要注意:话题通信是单向的、异步的。发布者只管发,订阅者只管收,谁也不等谁。我刚开始学的时候,总以为话题像函数调用一样有返回值,其实不是的。

我的经验:传感器数据(激光雷达、摄像头、IMU)最适合用话题。因为数据是持续产生的,而且订阅者可能不止一个。

# 查看话题列表
ros2 topic list

# 查看话题数据
ros2 topic echo /turtle1/pose

# 发布话题数据
ros2 topic pub /turtle1/cmd_vel geometry_msgs/msg/Twist "{linear: {x: 2.0}, angular: {z: 0.0}}"

1.3 服务:同步的“请求-应答”式通信

服务跟话题不一样。它是同步的、双向的。客户端发一个请求,服务端处理完再返回一个响应。客户端必须等响应到了才能继续往下走。

我曾经犯过一个错误:用服务来传输高频的传感器数据。结果客户端一直阻塞等待,整个系统卡死了。后来我才明白,服务适合那种“偶尔调用、需要立即知道结果”的场景。

避坑指南:千万不要用服务传高频数据!服务是阻塞的,频率一高,系统就崩了。我曾经在项目里吃过这个亏,后来全部改成话题才解决。

# 查看服务列表
ros2 service list

# 调用服务
ros2 service call /spawn turtlesim/srv/Spawn "{x: 2, y: 2, theta: 0.2}"

1.4 动作:带反馈的“长任务”通信

动作是ROS2里最复杂的通信方式。它结合了话题和服务的特点——既有服务那样的目标请求和结果返回,又有话题那样的实时反馈。

你想想看,如果让机器人从A点走到B点,用服务行不行?不行。因为走路需要时间,服务会一直阻塞。用话题行不行?也不行。因为话题没有“目标”和“结果”的概念。这时候就需要动作了。

动作的三要素:目标(Goal)、反馈(Feedback)、结果(Result)。

我记得第一次用Nav2的时候,看到一堆动作接口(NavigateToPose、FollowPath)有点懵。后来理解了动作的机制,才发现它就是为了这种“长时间执行、需要中途反馈”的任务量身定做的。

# 查看动作列表
ros2 action list

# 发送动作目标
ros2 action send_goal /navigate_to_pose nav2_msgs/action/NavigateToPose "{pose: {header: {frame_id: 'map'}, pose: {position: {x: 1.0, y: 1.0}}}}"

1.5 四者的关系与选择

说了这么多,你可能想问:到底什么时候用话题,什么时候用服务,什么时候用动作?我整理了一个表格,你一看就明白了。

通信方式 通信模式 是否阻塞 典型场景
话题 发布/订阅(异步) 否 传感器数据、状态信息
服务 请求/应答(同步) 是 查询参数、触发一次性操作
动作 目标/反馈/结果 否(有反馈) 导航、机械臂运动、长时间任务

我个人习惯这样选:

  • 数据是持续产生的,用话题
  • 需要立即知道结果的,用服务
  • 任务执行时间长、需要中途反馈的,用动作

1.6 知识体系图

下面这张图是我自己画的,把四个概念的关系梳理了一遍。你看完应该能有个整体印象。

ROS2 核心通信概念关系图 节点 A 发布者 / 客户端 节点 B 订阅者 / 服务端 话题(异步) /turtle1/pose 服务(同步) 请求 → 响应 动作(带反馈的长任务) 发送目标 反馈(持续) 结果(最终) 话题:单向数据流 | 服务:请求-响应 | 动作:目标 → 反馈 → 结果

你看这张图,节点A和节点B之间,话题是单向的虚线箭头,服务是双向的实线箭头,动作则是一个完整的三段式流程。搞清楚了这些,你写代码的时候就知道该用哪个了。

小技巧:如果你不确定用哪种通信方式,先问自己三个问题:

  1. 数据是持续产生的吗?→ 是 → 用话题
  2. 我需要立即知道结果吗?→ 是 → 用服务
  3. 任务执行时间长,需要中途反馈吗?→ 是 → 用动作

好了,这一章的内容就到这里。记住这四个概念,后面的Nav2调试就轻松多了。

可可精品资料库