当 ROS 2 被介绍为“机器人操作系统”时,它最容易被误解。这个名字保留了有用的历史线索,却会让架构听起来像机器人下方的一套单一运行时。更合适的理解是一张分布式图:许多节点,常常来自不同的软件包和语言,通过 topic、service、action 和 parameter 交换带类型的消息,中间件层负责发现与传输。[1][3]
这套图模型解释了 ROS 2 作为开源基础设施的意义。真实机器人不是一个程序。它是摄像头驱动、激光雷达流水线、定位栈、规划器、控制器、仿真桥、诊断节点、日志路径、安全监视器和操作员界面,共同处理时间、丢包、进程边界和硬件变动。ROS 2 的架构押注在于,这些部件应当通过明确的图契约相遇,而不是挤进一个巨大的应用进程。
当前维护信号仍然活跃。截至 2026-06-27T03:33:20Z UTC,ros2/ros2 GitHub API 报告了 5,684 个 star、919 个 fork、150 个开放 issue,默认分支为 rolling,最近一次 push 时间戳为 2026-06-23T20:21:04Z。[9] 发布 feed 列出了近期二进制发布,包括 ROS Lyrical Luth 于 2026-06-23 发布,以及 ROS 2 Jazzy Jalisco 于 2026-06-18 发布。[8] 发布计划说明了更大的节奏:ROS 2 每年发布一次,偶数年 LTS 版本如 Lyrical 目标支持期约五年,奇数年非 LTS 版本目标支持期约 1.5 年。[7] 对建造机器人的团队而言,这种节奏不是背景知识。它决定平台支持、发行版迁移和依赖测试何时变成真实工程工作。
图片语境:这里有意使用 ROSCon 的真人会议照片,而不是标志、图示或生成的机器人场景。ROS 2 的架构具有技术性,但它的耐久性来自许多组织同意共同维护一个机器人共享表面;没有这层共享表面,许多机器人会由私有胶水代码拼接出来。[7][10]
节点让机器人变得可见
ROS 2 中最小的有用单元是节点。文档把节点定义为 ROS 2 图中的参与者,通常负责一件逻辑任务,并说明节点可以在同一进程内、跨进程或跨机器通信。[3] 一个节点可以发布和订阅 topic,暴露或调用 service,提供或消费长时间运行的 action,并携带用于运行时配置的 parameter。[3]
这些词听起来像普通分布式系统词汇,直到它们被放进机器人语境里。一个以每秒 30 帧发布图像的摄像头节点、一个消费这些图像的感知节点,以及一个需要新鲜位姿估计的控制器,并非可以互换的微服务。它们的时序需求和故障需求不同。有些数据适合 best effort,因为过期帧比丢帧更糟。有些命令应当可靠传递,因为丢失它们会改变物理行为。有些 callback 可以并行运行,另一些则必须串行。
图的价值在于让这些关系可以被检查。如果每个子系统都藏在一个应用里,故障分析就会变成进程考古。在 ROS 2 中,团队可以提出更精确的问题:哪个节点拥有这条传感器流,哪个 topic 承载它,哪个 service 改变模式,哪个 action 拥有一次长运动,哪个 parameter 改变运行时行为,以及哪个发现域应当和隔壁房间的测试机器人隔离。架构不会移除复杂性。它给复杂性命名。
DDS 移除了 Master,也加入了一份契约
ROS 1 有一个中心 master。ROS 2 围绕 DDS 和 RTPS 作为中间件基础设计,用分布式发现替代那个中心协调点。[1] 早期 ROS-on-DDS 设计说明坦率描述了这项取舍。DDS 带来既有标准、发布-订阅传输、消息序列化、分布式发现和丰富的 Quality of Service 控制;它也带来复杂性,以及一种不同于旧 ROS 社区的文化。[1]
这是一次影响深远的选择。设计目标不是把 DDS 直接暴露给每一位机器人开发者。设计说明指出,目标是在类似 ROS 的 API 下方把 DDS 作为实现细节,保留熟悉的 node、publisher、subscriber 和 message 概念,同时让高级用户在需要时进入更深层。[1] 中间件接口设计进一步收紧了这条分界:ROS 客户端库应当操作 ROS 数据结构,而中间件层在下方转换为具体实现自己的表示形式。[2]
对采用者来说,这条分界比缩写本身更重要。如果一台机器人只有在每个开发者都理解 DDS 厂商配置模型时才能工作,抽象就已经泄漏得过多。如果团队完全忽略中间件行为,它又会在发现行为、QoS 不兼容、多播限制或跨厂商差异上遭遇意外。合适的位置在中间:编写正常的 ROS 2 节点,同时把中间件视为明确的部署决策。
这正是 rmw 层具有战略意义的原因。文档列出的受支持实现包括作为默认值和打包 RMW 的 Fast DDS、Cyclone DDS、Connext DDS、GurumDDS 和 Zenoh,其中 Zenoh 从 Kilted Kaiju 开始打包。[5] 文档也警告说,跨厂商 DDS 通信并非在所有情况下都有保证,并建议在可靠性重要时,让分布式系统保持相同 ROS 版本和相同 RMW 实现。[5] 有用的工程规则很直接:当机器人跨越进程、主机或网络边界时,中间件选择不能留到最后处理。
QoS 是机器人语义变成传输语义的地方
Quality of Service 是 ROS 2 中最清楚地区分机器人图和通用消息传递的部分。QoS 文档列出了 history、depth、reliability、durability、deadline、lifespan、liveliness 和 lease duration 等策略。[4] 它也说明了关键兼容规则:publisher 提供一个 QoS profile,subscription 请求一个 QoS profile,只有请求的 profile 与 publisher 提供的 profile 兼容时,连接才会建立。[4]
这不只是配置表面。它把团队关于物理时间的假设转换为传输语义。一帧激光雷达扫描只有在新鲜时才有用。一条地图更新可以容忍延迟,却不能容忍丢失。service request 通常应避免 transient-local durability,因为服务器重启后重放旧请求会带来副作用。[4] 内置 sensor-data profile 偏向及时样本,完整投递放在次要位置;默认 publisher/subscription QoS 使用可靠投递、volatile durability,以及深度为 10 的队列。[4]
风险在于,QoS 故障看起来会像应用 bug。publisher 和 subscriber 都存在。名称匹配。类型也匹配。节点仍然无法通信,因为 QoS 的 request-offer 组合不兼容。[4] 只有团队知道该去检查它时,这才是一种良好的故障模式。ROS 2 给机器人图提供了比 ROS 1 更强的词汇,但它也要求团队编码意图,而不是默认各处都是类似 TCP 的投递。
在实践中,成熟的 ROS 2 部署应当像 Web 团队审查 API 契约那样审查 QoS。传感器 topic、命令 topic、生命周期事件、诊断、类似 latched 的状态,以及安全相关消息,都不应意外继承默认值。默认值适合教程。一台在仓库、野外、医院或存在有损 Wi-Fi 的实验室中运行的机器人,需要图中每条重要边都说明自己能容忍怎样的丢失、延迟、陈旧度和活跃性。
执行器决定工作何时真正运行
在发现和传输之后,下一个分界是进程内部的调度。ROS 2 执行器会调用 subscription、timer、service server、action server 和其他事件的 callback。[6] 文档描述了 rclcpp::spin(node) 在最简单的 C++ 情况下会展开为单线程执行器,同时也记录了多线程执行器和较新的事件导向执行器工作。[6]
执行器页面包含 ROS 2 与 ROS 1 之间一个最重要的底层差异:为了避免抵消中间件 QoS,传入消息不会存入客户端库队列,而是保留在中间件中,直到某个 callback 取走它进行处理。[6] 这个细节改变了对过载的理解。一个缓慢的感知 callback 不只是“慢代码”。它会影响消息何时被取走、timer 是否按时触发,以及 callback group 是否允许有用的并行。
callback group 让这条分界变得明确。ROS 2 支持 mutually exclusive callback group,其中的 callback 不能并行运行;也支持 reentrant callback group,其中的 callback 可以并行运行。[6] 多线程执行器只有在 callback 分组允许时,才能制造有用的并行。[6] 这说明调度设计属于应用架构,而不只属于性能调优。一个导航栈如果把阻塞式 service call、高频传感器 callback 和控制 timer 混在一条偶然形成的调度通道里,即使中间件没有失败,也会自行破坏运行表现。
rolling 文档中描述的较新 EventsCBGExecutor 指向同一方向。它使用事件队列而不是轮询 wait set,并被记录为从 Lyrical Luth 起可用,同时警告过载进程会在队列中积累无界数量的 ready event。[6] 这是诚实的架构信号:更好的执行器机理可以降低开销,但不能取消过载物理。机器人仍然需要有边界的 callback 工作、经过测量的延迟,以及处理器落后时的故障行为。
ROS 2 适合放在哪里
当机器人系统需要跨硬件、团队、仿真和部署环境的模块化时,ROS 2 最有力量。它为开发者提供了一套共享语言,用来描述节点、topic、service、action、parameter、QoS、中间件选择和 callback 调度。当替代方案是只有一个实验室理解的私有集成层时,它尤其有价值。
当团队把它当作神奇胶水时,它会变弱。如果 topic 归属、QoS 策略、RMW 选择、执行器配置和发布目标都保持隐含,一张 ROS 2 图会变成分布式纠缠。框架给出了足够多的绳索,因为真实机器人需要这些绳索:best-effort 传感器、可靠命令、进程内组合、跨机器发现、生命周期控制和多种中间件实现,在不同系统中都是正当需求。[3][4][5][6]
因此,合适的采用模式是架构性的,不是装饰性的。先从图开始:命名节点,识别高频流,选择 service 和 action 的位置,决定哪些消息可以丢失,为整支机队固定 RMW 实现,并写下延迟敏感进程的执行器假设。然后用发布节奏规划平台升级,而不是等到现场部署时才发现它们。[5][7][8]
ROS 2 的价值来自它让机器人在压力下更容易被理解。重点不在于每个节点都会说话。重点在于,当机器人停止正常表现时,团队可以检查图、QoS 边、中间件通道和执行器路径,而不用猜测哪个隐藏 callback 或私有 socket 吞掉了现实。
Sources
- William Woodall,《ROS on DDS》,ROS 2 设计文档 - DDS 选型理由、分布式发现、QoS 灵活性、ROS API 分界和中间件取舍。
- Dirk Thomas,《ROS 2 middleware interface》,
ros2/design- RMW 抽象、ROS 数据结构、DDS 适配器和与中间件无关的客户端库分界。 - ROS 2 documentation source,《Nodes》- 节点定义、图参与、通信范围、topic、service、action、parameter 和分布式发现。
- ROS 2 documentation source,《Quality of Service settings》- QoS 策略、预定义 profile、request/offered 兼容性,以及 sensor-data/default 行为。
- ROS 2 documentation source,《Different ROS 2 middleware vendors》- DDS/RTPS 基础、
rmw实现、默认 Fast DDS、Cyclone DDS、Connext、GurumDDS、Zenoh 和跨厂商注意事项。 - ROS 2 documentation source,《Executors》- callback 执行、单线程和多线程执行器、wait set、callback group、EventsCBGExecutor 和过载提示。
- ROS 2 documentation source,《Release Schedule》- 年度发布节奏、LTS/非 LTS 模式、平台支持理由和支持时长。
- GitHub REST API,
repos/ros2/ros2/releases?per_page=5- 文章创建时采样的近期 ROS 2 发布 feed。 - GitHub REST API,
repos/ros2/ros2- 文章创建时采样的仓库活动快照,用于 star、fork、开放 issue、默认分支和最近 push 时间戳。 - Open Robotics,《ROSCon 2023 Recap》- 文章图片所用真实 ROSCon 2023 集体照片的来源页面。