2. ROS2核心概念速通:节点、话题、服务、动作、参数,以及它们与Apollo的对应关系
好,咱们直接进入正题。这一章我打算带你快速过一遍ROS2的五大核心概念——节点、话题、服务、动作、参数。你可能会问,为什么学Apollo要先搞ROS2?
其实很简单。Apollo的底层通信框架,说白了就是基于ROS1魔改的。而ROS2作为新一代标准,设计更现代、更可靠。我当年从ROS1迁移到ROS2时,最大的感受就是——「嗯,这才对嘛」。搞懂了ROS2,再看Apollo的Cyber RT,你会发现很多设计思路是相通的。
2.1 节点(Node)—— 系统的「细胞」
节点是ROS2里最小的可执行单元。每个节点负责一个具体的功能,比如感知、规划、控制。
我的理解:节点就像公司里的员工。每个员工只干自己那摊事,但大家通过消息沟通,协同完成大项目。
在ROS2里启动一个节点很简单:
# Python示例
import rclpy
from rclpy.node import Node
class MyNode(Node):
def __init__(self):
super().__init__('my_node')
self.get_logger().info('节点已启动!')
def main(args=None):
rclpy.init(args=args)
node = MyNode()
rclpy.spin(node)
rclpy.shutdown()
Apollo对应关系:Apollo里的每个模块(如Planning、Control)本质上就是一个大节点。只不过Apollo用的是Cyber RT框架,节点叫CyberNode。但设计思想完全一致——模块化、独立运行、消息驱动。
2.2 话题(Topic)—— 异步通信的「广播」
话题是ROS2里最常用的通信方式。发布者往话题里发消息,订阅者从话题里收消息。一对多、异步、非阻塞。
你想想看,这就像电台广播。主播(发布者)只管播,听众(订阅者)只管听。主播不知道谁在听,听众也不知道主播长啥样。但大家通过同一个频道(话题名)连接起来。
# 发布者
self.publisher_ = self.create_publisher(String, 'topic_name', 10)
# 订阅者
self.subscription = self.create_subscription(
String, 'topic_name', self.callback, 10)
Apollo对应关系:Apollo的Cyber RT里,话题叫Channel。比如/apollo/planning/trajectory就是一个Channel,Planning模块往里面发轨迹,Control模块订阅它。本质上和ROS2的话题一模一样。
2.3 服务(Service)—— 同步通信的「问答」
服务是同步的请求-响应模式。客户端发请求,服务端处理完返回结果。适合那些需要立即得到结果的场景,比如「查询当前车速」、「设置某个参数」。
我个人习惯把服务比作「打电话」。你拨号(发请求),对方接听(处理),然后你们对话(返回结果)。通话期间,你只能等着,不能干别的。
# 服务端
self.srv = self.create_service(AddTwoInts, 'add_two_ints', self.add_callback)
# 客户端
self.cli = self.create_client(AddTwoInts, 'add_two_ints')
req = AddTwoInts.Request()
req.a = 3
req.b = 5
future = self.cli.call_async(req)
Apollo对应关系:Apollo里也有类似的服务机制,叫Service。但Apollo用得不多,因为自动驾驶场景里,大多数通信都是异步的、流式的。服务更多用于调试和配置。
2.4 动作(Action)—— 带反馈的「长任务」
动作是ROS2里最复杂的通信方式。它本质上是「服务+话题」的组合。客户端发起一个目标,服务端执行过程中不断发反馈,最终返回结果。
举个例子:你让自动驾驶车辆「从A点开到B点」。这是一个长任务,你希望知道执行进度(比如「已行驶50%」),而不是傻等。动作就是干这个的。
# 动作服务端
self._action_server = ActionServer(
self, Fibonacci, 'fibonacci', self.execute_callback)
# 动作客户端
self._action_client = ActionClient(self, Fibonacci, 'fibonacci')
goal_msg = Fibonacci.Goal()
goal_msg.order = 10
self._action_client.send_goal_async(goal_msg)
Apollo对应关系:Apollo里没有直接对应的「动作」概念。但它的Task机制(比如RoutingTask)本质上就是动作——发起一个导航任务,持续接收状态反馈,最终完成。
2.5 参数(Parameter)—— 运行时配置的「旋钮」
参数是ROS2里用来动态配置节点行为的机制。你可以把参数想象成设备的「旋钮」——运行时拧一下,行为就变了,不用重启。
比如,你可以通过参数调整PID控制器的Kp值,或者切换感知算法的模型版本。
# 声明参数
self.declare_parameter('my_param', 'default_value')
# 获取参数
param = self.get_parameter('my_param').value
# 动态设置参数(通过命令行)
ros2 param set /my_node my_param new_value
Apollo对应关系:Apollo的Cyber RT里,参数叫Parameter,用法几乎一样。Apollo的模块启动时,会加载一个配置文件(比如planning_config.pb.txt),里面就是一堆参数。运行时也可以通过cyber_launch动态修改。
2.6 核心概念对比一览
| ROS2概念 | 通信模式 | Apollo对应 | 典型场景 |
|---|---|---|---|
| 节点(Node) | — | CyberNode | 感知、规划、控制等模块 |
| 话题(Topic) | 异步发布/订阅 | Channel | 传感器数据、轨迹消息 |
| 服务(Service) | 同步请求/响应 | Service | 查询状态、触发操作 |
| 动作(Action) | 异步+反馈 | Task机制 | 路径规划、泊车任务 |
| 参数(Parameter) | 键值对配置 | Parameter | 算法参数、模块配置 |
2.7 知识体系总览
下面这张图,是我自己梳理的ROS2核心概念与Apollo的对应关系。你可以把它当作一张「地图」,后续学习时随时回来对照。
嗯,这一章的内容就到这里。ROS2的这五个概念,你只要搞懂了,再看Apollo的Cyber RT源码,会发现很多似曾相识的东西。下一章我们会动手搭建联调环境,到时候这些概念都会用上。
可可精品资料库