本节摘要:ROS2 不是 ROS1 的功能升级,而是通信基座的推倒重铸。本节是全册的起点,从 ROS1 的实验室基因讲起,把 Master 单点、无实时、无安全三类结构性缺陷对应到真实故障现象,再解释社区为什么选择 DDS 作为新基座。理解这些因果,后面所有章节遇到的设计选择才不显得凭空。
别以为 ROS2 只是 ROS1 换了个数字。如果只是加功能、修漏洞,社区犯不着把通信层整个换掉。要理解 ROS2 每一个"看起来奇怪"的设计——为什么没有 Master、为什么话题会自动发现、为什么节点有生命周期——都得先回到 ROS1 的身体里,看看它到底哪里疼。
ROS1 诞生于 2007 年前后的斯坦福与 Willow Garage,目标很具体:让实验室里的几台 PR2 机器人能快速组合别人的代码。这个出身决定了它的取舍——灵活性至上,工程化靠边。跑在实验室里它确实好用,可一旦机器人要出厂、要上产线、要 7×24 小时运行,三处先天缺陷就藏不住了。
缺陷一:中央 Master 是全系统的单点。 ROS1 里所有节点启动时都要向 roscore 登记地址,任何两个节点通信前都要先问 Master 要对方的联系方式。这意味着两件事:roscore 一崩,全系统瘫痪——不是降级运行,是彻底失联;更隐蔽的是,节点 A 重启后拿到的新地址,节点 B 的缓存里可能还是旧的,出现"看起来都在跑、就是连不上"的僵尸状态。现场维护过 ROS1 机器人的人,几乎都经历过"先重启 roscore 再重启所有节点"的玄学仪式。
缺陷二:通信层对时间没有承诺。 ROS1 的 TCPROS 只保证"尽力送达",控制环要求微秒级抖动、传感器流要求有界延迟,它都给不了。更麻烦的是它的传输选择:大消息用 TCP 会因丢包重传造成延迟尖峰,UDP 又完全不保证送达。深挖下去还有实现层的包袱——消息序列化与传输逻辑耦合在一起,想换一套更可靠的传输协议,等于重写整个通信层。
缺陷三:安全模型接近裸奔。 任何接入网络的节点都能发现并调用所有话题与服务,没有认证、没有加密、没有权限边界。实验室里这是便利,医院里就是事故。2017 年前后安全团队演示过:只要接入同一网段,就能向手术辅助机器人的话题发布伪造指令。
把三类缺陷放进一张对照表,ROS2 的重铸逻辑就一目了然:
| ROS1 缺陷 | 现场故障表现 | ROS2 的对应解法 |
|---|---|---|
| 中央 Master 单点 | roscore 崩溃全系统失联;重启后地址缓存失效 | 去中心化发现,节点间直接互相广播 |
| 无实时保障 | 控制环抖动、传感器流延迟尖峰 | DDS 时间协议 + 实时调度钩子 |
| 无安全机制 | 任意节点可伪造指令 | DDS Security 认证与加密 |
| 传输不可替换 | 换协议等于重写 | RMW 抽象层,实现可插拔 |
| 无生命周期 | 节点启动顺序全靠 sleep 碰运气 | 生命周期节点显式状态机 |
重铸通信层时,社区没有自己发明协议,而是选中了 DDS——数据分发服务,一个在国防与工业控制领域已经运行了十几年的 OMG 标准。这个选择在当年有争议:DDS 规范厚、概念多,比"自己写个 pub/sub"重得多。但放到今天看,它是 ROS2 少数几个无需返工的关键决策。
DDS 给的三样东西恰好对症。自动发现:节点加入网络时通过组播互相广播自己的能力,无需任何中央登记处,缺陷一的病灶被直接移除。QoS 合约:可靠性、历史深度、存活检测这些通信承诺变成发布端与订阅端之间的可配置契约,通信行为第一次变得可声明、可推理。传输可插拔:ROS2 在应用与 DDS 之间垫了一层 RMW 抽象,Fast DDS、Cyclone DDS、RTI Connext 都能即插即用,换实现只是改一个环境变量的事。
// 同一个发布者,ROS1 与 ROS2 的初始化差别 // ROS1:先有 roscore,节点向它登记 ros::init(argc, argv, "talker"); ros::NodeHandle nh; ros::Publisher pub = nh.advertise<std_msgs::String>("chatter", 10); // ROS2:节点自注册进网络,无需任何中央进程 rclcpp::init(argc, argv); auto node = rclcpp::Node::make_shared("talker"); auto pub = node->create_publisher<std_msgs::String>("chatter", 10);
代码的差别只是表象,实质差别在幕后:ROS1 的 advertise 要先问 Master;ROS2 的 create_publisher 只是在本地声明"我提供这个话题",剩下的交给 DDS 发现协议在后台完成。这个细节在第 2.3 节解剖发现失败时会再次出现。
ROS2 的演进分三个阶段,理解阶段有助于理解为什么某些特性"晚到"。第一阶段(Ardent 到 Foxy,2017 至 2020)解决"能不能用":去中心化发现、RMW 抽象、基本 QoS 落地。第二阶段(Galactic 到 Humble,2020 至 2023)解决"好不好管":生命周期节点、ros2_control、TF2 的时间语义补齐。第三阶段(Iron 至今)解决"能不能规模化":安全框架、rosbag2 增强、micro-ROS 把协议压进 MCU。本册以 Humble 之后的长期支持版为基准,所有特性都已稳定。
一个常被问起的问题:老项目怎么办?社区给的答案是迁移而非兼容——ROS1 已经于 2025 年停止维护,rclcpp 与 rospy 的 API 面貌不同但概念一一对应,官方迁移指南列了逐条映射。实际项目里最费力的从来不是改 API,而是本书第 2 章要讲的 QoS 行为差异:同样的代码,ROS1 里"反正能收到",ROS2 里会因为可靠性策略不匹配而静默丢消息。
下一节把"重铸后的系统"真正装到你的机器上,并用五项验证确认它值得信任。