3. ROS2 核心概念详解
这一章我们聊聊 ROS2 里最基础的四个概念:节点、话题、服务、动作。说白了,你写任何机器人程序都绕不开它们。我刚开始接触 ROS2 的时候,觉得这些概念有点绕,但后来发现——理解它们就像学会用扳手和螺丝刀,后面就顺手了。
3.1 节点(Node)—— 程序的“细胞”
节点就是 ROS2 里最小的执行单元。每个节点负责一件事,比如读取激光雷达、控制电机、处理定位。我个人习惯把节点想象成一个独立的小工人,各干各的,互相通过“通信管道”说话。
创建节点(Python 示例)
import rclpy
from rclpy.node import Node
class MyRobotNode(Node):
def __init__(self):
super().__init__('my_robot_node')
self.get_logger().info('节点已启动!')
def main(args=None):
rclpy.init(args=args)
node = MyRobotNode()
rclpy.spin(node)
node.destroy_node()
rclpy.shutdown()
你想想看,一个机器人可能有几十个节点同时运行。我曾经在一个项目中同时跑了 30 多个节点,那时候才体会到节点拆分的好处——哪个崩了不影响其他,重启单个就行。
3.2 话题(Topic)—— 发布与订阅
话题是 ROS2 里最常用的通信方式。一个节点发布消息,其他节点订阅。就像电台广播,发布者不管谁在听,订阅者只管收。
避坑指南: 我曾经因为话题名打错一个字母,调试了半小时。后来我习惯把所有话题名写在常量文件里,用的时候导入,再也没犯过。
# 发布者
self.publisher_ = self.create_publisher(String, 'chatter', 10)
# 订阅者
self.subscription = self.create_subscription(String, 'chatter', self.callback, 10)
话题的 QoS(质量服务设置)也很关键。我记得有一次机器人走偏,就是因为订阅的传感器数据丢包了,调了 QoS 的可靠性才解决。
3.3 服务(Service)—— 一问一答
服务适合“请求-响应”模式,比如你让机械臂移动到某个位置,它告诉你“到位了”或者“出错”。服务分客户端和服务器,客户端发请求,服务器回响应。
| 角色 | 行为 | 典型场景 |
|---|---|---|
| 服务端 (Server) | 接收请求,返回响应 | 控制机械臂、查询状态 |
| 客户端 (Client) | 发送请求,等待响应 | 调用服务、获取结果 |
# 服务端示例
self.srv = self.create_service(SetBool, 'set_led', self.callback)
# 客户端示例
self.cli = self.create_client(SetBool, 'set_led')
while not self.cli.wait_for_service(timeout_sec=1.0):
self.get_logger().info('等待服务...')
req = SetBool.Request()
req.data = True
future = self.cli.call_async(req)
嗯,这里要注意:服务调用是同步或异步的。我建议用异步,不然容易阻塞整个节点。
3.4 动作(Action)—— 长任务的好帮手
动作和服务有点像,但动作适合耗时长的任务,比如导航到某个点、执行一段轨迹。动作有反馈(feedback),你可以实时知道进度。
我曾经踩过的坑: 动作服务器忘记设置超时,结果客户端一直等,最后整个系统卡住。记得给动作加上超时和取消逻辑。
# 动作服务器(简化)
from action_tutorials_interfaces.action import Fibonacci
class FibonacciActionServer(Node):
def __init__(self):
super().__init__('fibonacci_server')
self.action_server = ActionServer(
self, Fibonacci, 'fibonacci', self.execute_callback)
async def execute_callback(self, goal_handle):
# 执行长任务,发送反馈
feedback_msg = Fibonacci.Feedback()
# ... 业务逻辑
goal_handle.succeed()
return Fibonacci.Result()
动作客户端可以取消任务、接收反馈。我个人觉得动作是 ROS2 里最优雅的设计,特别适合机器人这种需要“边做边汇报”的场景。
3.5 四个概念怎么选?
一句话总结:
- 话题:持续的数据流,比如传感器数据、里程计。
- 服务:短请求-响应,比如开关灯、设置参数。
- 动作:长任务+反馈,比如导航、机械臂轨迹。
- 节点:以上所有通信的载体。
你想想看,一个机器人系统就是把这些概念组合起来。我刚开始做项目时,总想把所有逻辑塞到一个节点里,后来拆成多个节点,用话题和服务通信,代码清晰多了。
核心要点回顾
- 节点是基本单元,一个进程可以包含多个节点。
- 话题用于广播式通信,一对多。
- 服务用于同步请求-响应。
- 动作支持异步、反馈、取消,适合长时间任务。