2、ROS核心概念与通信机制:节点、话题、服务、动作、参数服务器

好,咱们直接进入正题。ROS这套系统,说白了就是让一堆程序能互相说话、协同干活。你想想看,一个机器人身上可能有激光雷达、摄像头、电机驱动、路径规划……这些模块如果各干各的,那机器人就是个傻子。ROS的核心价值,就是把这些零散的东西串起来。

我个人习惯把ROS的通信机制比作一个「公司」:节点就是员工,话题就是广播喇叭,服务就是打电话问事,动作就是派一个长期任务,参数服务器就是公司公告栏。咱们一个一个聊。

2.1 节点(Node)—— 最小执行单元

节点,就是ROS里跑起来的一个个进程。每个节点负责一件事。比如一个节点专门读激光雷达数据,另一个节点专门做路径规划。

关键点:

  • 每个节点有唯一的名字(比如 /camera_node
  • 节点之间互相独立,一个挂了不影响其他(除非你设计成依赖关系)
  • rosrun 启动,用 rosnode list 查看

重要:节点名不能重复。我在项目中遇到过两次节点名冲突,结果两个节点互相抢资源,机器人直接原地打转。后来我养成了习惯,每次启动前先 rosnode list 看一眼。

# 启动一个节点
rosrun turtlesim turtlesim_node

# 查看所有节点
rosnode list

2.2 话题(Topic)—— 异步广播通信

话题是ROS里最常用的通信方式。一个节点发布消息,其他节点订阅。发布者和订阅者互不知道对方存在,这就是解耦。

为什么用话题? 因为传感器数据是持续产生的。激光雷达每秒转10圈,你总不能每转一圈就打个电话吧?用话题,发布者只管发,订阅者只管收,中间有ROS Master帮你牵线。

我记得刚学ROS时,总搞不清话题和服务有什么区别。后来我师傅跟我说了一句:「话题是广播,服务是点对点」。广播就是你在广场上喊一嗓子,谁爱听谁听;服务就是你专门找一个人问路。

小技巧:rostopic echo /topic_name 可以实时看话题里的数据流,调试时特别好用。我曾经靠这个命令抓到一个传感器数据丢包的bug。

# 发布话题
rostopic pub /cmd_vel geometry_msgs/Twist "linear:
  x: 0.5
  y: 0.0
  z: 0.0
angular:
  z: 0.5"

# 订阅话题
rostopic echo /turtle1/pose

2.3 服务(Service)—— 同步请求/响应

服务适合「一问一答」的场景。比如你让机器人拍张照片,它拍完告诉你「拍好了」。这种有来有回的通信,用服务最合适。

服务的特点:

  • 客户端发送请求,服务端返回响应
  • 同步阻塞——客户端发完请求后,必须等响应回来才能继续
  • 适合偶尔调用、需要确认结果的操作

注意:千万别用服务做高频通信。我曾经有个同事,把传感器数据用服务传,结果每秒钟请求几百次,ROS Master直接崩溃。传感器数据就该用话题,别折腾服务。

# 查看可用服务
rosservice list

# 调用服务
rosservice call /spawn "x: 2.0
y: 2.0
theta: 0.0
name: 'turtle2'"

2.4 动作(Action)—— 长时间任务

动作是服务的升级版。当任务需要很长时间(比如导航到某个点、机械臂抓取),你总不能一直等着吧?动作允许你:

  • 发送目标后,可以继续干别的事
  • 随时查询任务进度
  • 可以中途取消任务

说白了,动作就是「异步服务 + 进度反馈」。我个人在开发AGV小车时,导航任务全用动作实现。因为导航可能要花几十秒,你总不能让主控干等着。

核心三要素:目标(Goal)、反馈(Feedback)、结果(Result)。动作客户端发送目标,服务端不断反馈进度,最后返回结果。

# 动作的典型结构
# 目标:移动到 (x=1.0, y=2.0)
# 反馈:当前坐标 (0.5, 1.0) 进度 50%
# 结果:到达目标,耗时 12.3秒

2.5 参数服务器(Parameter Server)—— 全局共享字典

参数服务器就是个全局的键值对存储。所有节点都能读写。适合放一些配置参数,比如:

  • 机器人的最大速度
  • 摄像头的帧率
  • PID控制器的系数

注意:参数服务器不是数据库,别往里面塞大数据。我见过有人把地图数据存进去,结果启动时卡了半分钟。参数服务器只适合放小数据,几百个字节那种。

我的习惯:所有可调参数都放到参数服务器里,然后用launch文件加载。这样改参数不用重新编译代码,改个yaml文件就行。调试效率翻倍。

# 设置参数
rosparam set /max_speed 0.5

# 获取参数
rosparam get /max_speed

# 从文件加载参数
rosparam load params.yaml

2.6 四种通信机制对比

特性 话题 服务 动作 参数服务器
通信模式 异步发布/订阅 同步请求/响应 异步目标/反馈/结果 全局键值存储
适用场景 传感器数据、高频流 偶尔调用、需确认 长时间任务、需反馈 配置参数、全局变量
是否阻塞 否(可查询进度)
典型例子 激光雷达数据 拍照、重置位置 导航、机械臂抓取 最大速度、PID系数

嗯,到这里ROS的核心通信机制就讲完了。你可能会问:这么多通信方式,我到底该用哪个?我的建议很简单——持续数据流用话题,一问一答用服务,长时间任务用动作,全局配置用参数服务器。记住这个口诀,基本不会选错。

下一章咱们会深入代码层面,手把手写一个发布者和订阅者。到时候你会发现,理解了这些概念,写代码就是水到渠成的事。