“机器人操作系统”这个名字记录着 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] 发布源列出的近期二进制版本包括 ROS Lyrical Luth(2026-06-23)和 ROS 2 Jazzy Jalisco(2026-06-18)。[8] 从更长的发布周期看,ROS 2 每年发布一个版本;Lyrical 这类偶数年 LTS 版本计划支持约五年,奇数年的非 LTS 版本计划支持约 1.5 年。[7] 对机器人研发团队,这些日期会直接决定平台支持、发行版迁移和依赖测试何时进入工程日程。
图片说明:本文有意选用 ROSCon 的与会者合影,让维护者出现在画面中央,标志、图示和生成的机器人场面退到一旁。ROS 2 的架构充满技术细节,它的持续生命力则来自许多组织共同维护一套机器人软件基础。若失去这套共同约定,各家的机器人往往只能依靠私有胶水代码拼装。[7][10]
节点让机器人系统可观察
ROS 2 中的最小实用单元是节点。文档将节点定义为 ROS 2 图中的参与者,通常承担一项逻辑功能;节点既能在同一进程内通信,也能跨进程或跨机器通信。[3] 节点可以发布和订阅话题,开放服务供其他节点调用,也能调用外部服务;它还能作为动作服务端处理耗时任务,或作为客户端发起动作,并通过参数接受运行时配置。[3]
这些词原本属于普通的分布式系统,放进机器人之后便有了物理后果。摄像头节点每秒发布 30 帧图像,感知节点读取这些图像,控制器则依赖最新的位姿估计;三者职责有别,对时序和故障处理的要求也各不相同。对某些数据,过期帧造成的影响大于偶发丢帧,因此适合尽力而为(best effort)传输;另一些命令必须可靠送达,丢失命令会改变机器人的物理行为。有些回调函数(callback)可以并行执行,有些必须互斥。
图把这些依赖关系清楚列出,便于逐项检查。所有子系统都藏在同一个应用里时,故障排查只能在进程内部层层翻找。有了 ROS 2,团队可以沿图追问:传感器数据流归哪个节点,在什么话题上传输?哪项服务切换模式,哪项动作负责一段耗时较长的运动?哪个参数会改变运行时行为?又该用哪个发现域把隔壁房间的测试机器人隔开?复杂性仍在,每一处关系都有了可追查的名字。
DDS 去掉了中央 Master,也带来一套新契约
ROS 1 依靠中央 master 协调通信。ROS 2 以 DDS 和 RTPS 为中间件基础,由分布式发现接替中央协调。[1] 最初的 ROS-on-DDS 设计说明清楚记录了这项取舍:DDS 带来现成的标准、发布—订阅传输、消息序列化、分布式发现和丰富的服务质量(Quality of Service,QoS)控制,也引入了更高的复杂度,以及一套有别于早期 ROS 社区的技术文化。[1]
设计者把 DDS 放在近似 ROS 的 API 之下,将它收进底层。开发者仍然面对熟悉的节点、发布者、订阅者和消息概念,高级用户也能在需要时深入探查。[1] 中间件适配层又把职责分工说得更具体:ROS 客户端库操作 ROS 数据结构,中间件层再把数据转换成各款中间件采用的表示形式。[2]
对采用 ROS 2 的团队,职责分工比缩写更要紧。若一台机器人要求每位开发者都掌握 DDS 厂商的配置模型,说明抽象层已经漏出太多细节。反过来,把中间件完全当作透明层,也会在节点发现、QoS 不兼容、多播限制或跨厂商差异上遭遇意外。合理做法介于两端:日常仍按 ROS 2 API 编写节点,部署时则明确选定中间件。
因此,rmw(ROS 中间件适配层)是部署设计中的关键一环。文档列出的受支持选项包括 Fast DDS、Cyclone DDS、Connext DDS、GurumDDS 和 Zenoh;Fast DDS 是默认方案,也随 ROS 2 打包,Zenoh 则从 Kilted Kaiju 起进入发行包。[5] 文档同时警告,跨厂商 DDS 通信无法保证在所有组合下都能成功;重视可靠性的分布式系统应统一 ROS 版本,并选用同一种 RMW。[5] 工程上的原则很直接:机器人一旦跨越进程、主机或网络,中间件就要提前选定。
QoS 把机器人的运行要求写进传输规则
机器人图与普通消息传递的差异,在 QoS 上表现得最清楚。QoS 文档列出了 history、depth、reliability、durability、deadline、lifespan、liveliness 和 lease duration 等策略。[4] 其中最重要的兼容规则是:发布端给出它所能满足的 QoS profile,订阅端提出需求;两者相容时才会建立连接。[4]
这些配置直接把团队对物理时间的要求写进传输规则。激光雷达扫描过时后便失去价值;有的地图更新能容忍延迟,却承受不起丢失。服务请求通常要避开 transient-local durability,因为服务器重启后重放旧请求会引发副作用。[4] 内置的 sensor-data profile 把样本时效性放在完整投递之前;默认的 publisher/subscription QoS 采用可靠投递、volatile durability,以及深度为 10 的队列。[4]
QoS 故障常会伪装成应用程序 bug。发布者和订阅者都在,名称与类型也完全匹配,节点依然无法通信,原因是 QoS 的 request-offer 组合互不相容。[4] 团队知道检查 QoS,这类故障才容易诊断。ROS 2 对机器人通信的描述比 ROS 1 更精确,也要求团队逐条写明传输意图,舍弃“所有链路都像 TCP 一样投递”的默认想象。
成熟的 ROS 2 部署应当像 Web 团队审查 API 契约那样审查 QoS。传感器话题、命令话题、生命周期事件、诊断信息、锁存式状态和安全相关消息,都应逐项选择 QoS,默认值也要经过明确确认。教程往往可以沿用默认值。仓库、野外、医院,以及 Wi-Fi 容易丢包的实验室,对机器人提出了更严格的要求:图中每条重要连接都要写明能承受怎样的丢包、延迟与数据陈旧,以及如何判断发布端仍在工作。
执行器决定任务何时运行
节点完成发现并建立传输之后,下一个关口是进程内调度。ROS 2 执行器会调用订阅、定时器、服务端、动作服务端及其他事件对应的回调函数。[6] 在最简单的 C++ 用法中,rclcpp::spin(node) 底层使用单线程执行器;文档也介绍了多线程执行器和较新的事件驱动执行器方案。[6]
执行器文档指出了 ROS 2 与 ROS 1 之间一项重要的底层差异:为保持中间件的 QoS 行为,收到的消息先留在中间件,等回调函数取用时才离开;客户端库由此省去一层消息队列。[6] 这项差异改变了过载问题的分析方式。感知回调执行太慢,会拖延消息取用,影响定时器能否准时触发,也会限制回调组是否有机会并行处理任务。
回调组(callback group)把这项调度约束明确写了出来。ROS 2 支持互斥回调组,其中的回调函数不能并行;也支持可重入回调组,其中的回调函数可以并行。[6] 多线程执行器能否真正并行处理任务,取决于回调分组是否允许。[6] 调度设计要提前纳入应用架构,再进入性能调优。导航栈若把阻塞式服务调用、高频传感器回调和控制定时器无意中塞进同一条调度路径,即使中间件正常,也会因调度失当而失稳。
rolling 文档介绍的 EventsCBGExecutor 也指向同一个问题。它用事件队列替代轮询等待集(wait set),从 Lyrical Luth 起可用;文档同时警告,进程过载时,就绪事件存在无限积累的风险。[6] 这项警告揭示了一个基本事实:事件驱动执行器可以减少开销,系统过载的物理限制依然存在。机器人应用仍要给每次回调设定明确的工作量或执行时长上限,测量实际延迟,并规定处理器跟不上时的故障处理方式。
ROS 2 适合哪些系统
当机器人系统需要跨硬件、团队、仿真和部署环境拆分模块时,ROS 2 最能发挥作用。它让开发者用同一套术语描述节点、话题、服务、动作、参数、QoS、中间件选型和回调调度。若替代方案是一套只有单个实验室熟悉的私有集成层,这种共同语言尤其有价值。
把 ROS 2 当成万能胶,价值就会迅速削弱。话题归属、QoS 策略、RMW 选择、执行器配置和目标发行版若一直含糊不清,整张图会缠成难以排查的分布式线团。ROS 2 留出很大的配置自由度,因为真实机器人确实有多种合理需求:尽力而为的传感器、可靠传递的命令、进程内组合、跨机器发现、生命周期控制和多种中间件方案,都会出现在不同系统里。[3][4][5][6]
采用 ROS 2 要从架构设计起步。先画出通信图:给节点命名,标出高频数据流,明确哪些交互使用服务、哪些使用动作,决定哪些消息允许丢失,选定整支机器人队伍统一使用的 RMW,并记下延迟敏感进程对执行器的要求。随后按照发布周期安排平台升级,避免到现场部署时才发现版本迁移问题。[5][7][8]
ROS 2 的价值,在于机器人承受压力时,系统行为依然容易分析。节点彼此通信只是起点;当机器人行为失常,团队可以依次检查通信图、QoS 配置、中间件传输和执行器调度,查清隐藏回调或私有套接字究竟在哪一步打乱了数据与时序。
资料来源
- William Woodall,《ROS on DDS》,ROS 2 设计文档——DDS 选型理由、分布式发现、QoS 灵活性、ROS API 职责划分和中间件取舍。
- Dirk Thomas,《ROS 2 middleware interface》,
ros2/design——RMW 抽象、ROS 数据结构、DDS 适配器,以及客户端库与中间件的职责划分。 - ROS 2 文档源码,《Nodes》——节点定义、节点在图中的角色、通信范围、话题、服务、动作、参数和分布式发现。
- ROS 2 文档源码,《Quality of Service settings》——QoS 策略、预设 profile、request/offered 兼容规则,以及 sensor-data/default 行为。
- ROS 2 文档源码,《Different ROS 2 middleware vendors》——DDS/RTPS 基础、
rmw实现、默认的 Fast DDS、Cyclone DDS、Connext、GurumDDS、Zenoh 和跨厂商通信注意事项。 - ROS 2 文档源码,《Executors》——回调执行、单线程与多线程执行器、等待集、回调组、EventsCBGExecutor 和过载警告。
- ROS 2 文档源码,《Release Schedule》——年度发布周期、LTS/非 LTS 模式、平台支持理由和支持时长。
- GitHub REST API,
repos/ros2/ros2/releases?per_page=5——文章创建时采样的近期 ROS 2 发布记录。 - GitHub REST API,
repos/ros2/ros2——文章创建时采样的仓库活动快照,记录 star、fork、未关闭 issue、默认分支和最近一次 push 的时间戳。 - Open Robotics,《ROSCon 2023 Recap》——文章所用 ROSCon 2023 与会者合影的来源页面。