2. ROS2基础架构
ROS2 并不是“ROS1 的升级版补丁”,而是一次通信内核的重构。理解 ROS2,关键不是记住 API,而是看清它如何把应用逻辑与通信机制解耦:上层用节点、话题、服务、动作、参数描述“系统要做什么”,下层用 DDS 完成“数据怎么可靠、实时、可发现地流动”。本节从分层架构入手,逐层拆解核心概念及其协作关系。
一、ROS2 分层架构:从应用到 DDS
ROS2 采用清晰的分层设计,自上而下可划分为四层:
- 应用层:开发者编写的节点、算法、感知/规划/控制模块,使用 rclcpp、rclpy 等客户端库。
- 客户端库层:rclcpp(C++)、rclpy(Python)等,提供节点、发布者、订阅者、服务、动作、参数等编程接口。
- 中间件抽象层(rmw):ROS Middleware Interface,定义统一通信 API,屏蔽不同 DDS 实现的差异。
- DDS 层:具体 DDS 实现(如 Fast DDS、Cyclone DDS),负责发现、序列化、QoS、传输。
这种分层的价值在于:更换 DDS 实现时,上层应用代码几乎不需要改动,只需替换 rmw 实现并重新编译。对于自动驾驶系统,这意味着可以在开发阶段用通用 DDS,在量产阶段切换到满足功能安全与实时性要求的 DDS 实现。
二、核心概念:节点、话题、服务、动作、参数
ROS2 用五种基本通信模式覆盖自动驾驶中的绝大多数交互场景:
| 概念 | 通信模式 | 典型场景 | 关键特征 |
|---|---|---|---|
| 节点 Node | 进程/线程单元 | 感知、规划、控制各一个节点 | 最小功能单元,可独立启停 |
| 话题 Topic | 发布/订阅,异步 | 激光雷达点云、摄像头图像、车辆状态 | 多对多,持续数据流,QoS 可配 |
| 服务 Service | 请求/响应,同步 | 查询地图、切换模式、标定触发 | 一对一,短时交互,有返回值 |
| 动作 Action | 目标/反馈/结果,异步 | 导航到目标点、泊车、跟车 | 长时任务,可取消,带进度反馈 |
| 参数 Parameter | 键值配置,动态可调 | 控制增益、阈值、传感器标定值 | 节点级配置,支持运行时修改 |
选择通信模式的核心判断依据是:数据是持续流还是单次请求?交互是短时还是长时?是否需要反馈和取消? 例如,激光雷达数据必须用话题,因为它是高频持续流;而“请求地图切片”适合服务;导航任务则必须用动作,因为需要持续反馈进度并允许中途取消。
三、执行器与客户端库:让节点真正跑起来
节点定义好后,需要执行器(Executor)来驱动回调。ROS2 提供多种执行器:
- 单线程执行器:所有回调在一个线程中顺序执行,简单但可能阻塞。
- 多线程执行器:回调可并行执行,适合高吞吐场景,但需注意线程安全。
- 事件执行器:基于事件循环,适合实时性要求高的场景。
客户端库方面,rclcpp 和 rclpy 是最常用的两个。rclcpp 适合性能敏感的感知、控制模块;rclpy 适合快速原型、脚本工具和调试。两者共享相同的 rmw 接口,因此可以混合使用。
# 查看当前节点列表
ros2 node list
# 查看话题列表及类型
ros2 topic list -t
# 查看某个话题的实时数据
ros2 topic echo /vehicle/status
# 调用服务
ros2 service call /map/query nav_msgs/srv/GetMap "{}"
# 发送动作目标
ros2 action send_goal /navigate_to_pose nav2_msgs/action/NavigateToPose "{pose: ...}"
# 查看和修改参数
ros2 param list /controller
ros2 param set /controller max_speed 5.0
四、DDS 通信模型:发现、QoS 与数据流
DDS 是 ROS2 的通信底座,其核心机制包括:
- 自动发现:节点加入网络后自动发现彼此,无需中心 broker,避免单点故障。
- QoS 策略:可靠性(RELIABLE/BEST_EFFORT)、持久性(TRANSIENT_LOCAL/VOLATILE)、历史深度、截止时间等,直接决定通信行为。
- 数据序列化:CDR 格式,跨语言、跨平台一致。
- 传输层:支持 UDP、TCP、共享内存,共享内存可大幅降低大点云传输延迟。
自动驾驶场景中的 QoS 选择示例:
- 激光雷达点云:BEST_EFFORT + 深度 5,允许丢帧但不能阻塞。
- 车辆控制指令:RELIABLE + 深度 1,必须可靠且只保留最新。
- 地图/标定数据:TRANSIENT_LOCAL + RELIABLE,晚加入的节点也能拿到。
五、案例与误区复盘
案例:某自动驾驶项目在实车上出现“控制指令偶尔延迟 200ms”的问题。排查发现,控制话题使用了默认 QoS(RELIABLE + 深度 10),当网络抖动时,DDS 重传旧指令,导致控制节点处理了过期数据。改为 RELIABLE + 深度 1 后,问题消失。
常见误区:
- 把所有话题都设为 RELIABLE,导致高带宽场景下重传风暴。
- 用服务做长时任务,导致客户端阻塞、无法取消。
- 忽略执行器线程模型,在回调中做重计算,造成回调堆积。
- 认为 ROS2 自带实时性,实际上实时性依赖 DDS 配置、执行器选择和操作系统调优。
理解 ROS2 基础架构,最终要落到“选对通信模式、配好 QoS、用对执行器”这三件事上。它们共同决定了自动驾驶中间件是否可靠、实时、可扩展。