ROS1的痛点——为什么行业必须迁移到ROS2
上一篇讲了ROS的历史,这篇深入聊聊ROS1到底有哪些问题,以及为什么这些问题在工业场景下是致命的。
面试的时候这个问题很常见:"ROS1有什么缺点?ROS2是怎么解决的?"如果你只能回答"ROS1有master节点是单点故障",那还不够。面试官想听的是你对这些问题的切身体会,或者至少是深入理解。
单点故障:rosmaster的致命弱点
ROS1的通信架构是中心化的。所有节点启动时都要向rosmaster注册,节点之间要通信也得先问master"这个topic谁在发布"。master就像一个电话总机,所有通话都得经过它转接。
具体来说,节点A想和节点B通信,流程是这样的:A先向master注册说"我要订阅/topic_x",master查一下谁在发布这个topic,找到B,然后把B的地址告诉A,之后A和B直接建立TCP连接。所以master只在连接建立时起作用,一旦连接建立了,master挂了已建立的连接不受影响。但新连接就建不了了,而且如果有节点重启,也注册不上去。
在实验室里这不是问题,因为master很少挂。但在实际产品中,任何单点故障都是不可接受的。你想想,一台在仓库里搬货的AGV,如果通信中枢突然挂了,正在运行的节点可能收不到新的指令,传感器数据也无法被新的处理模块接收,后果不堪设想。
ROS2怎么解决的?去中心化。每个节点都能独立发现其他节点,不需要中间人。底层用的是DDS的发现机制,节点之间通过组播自动发现彼此。没有master,也就没有单点故障。
网络不可靠时的表现
ROS1的通信基于TCP,默认保证消息可靠传输。但TCP有自己的问题:延迟不确定、拥塞控制可能导致消息堆积、在网络不稳定的时候连接容易断开。
更关键的是,ROS1没有QoS(Quality of Service)策略。所有topic一视同仁,不管是关键的控制指令还是不太重要的状态日志,都用同样的方式传输。但在实际场景中,控制指令需要可靠传输,而传感器数据可以容忍偶尔丢失——因为下一帧马上就来。
ROS2的QoS策略是它最大的优势之一。你可以为每个topic单独配置:可靠性(可靠传输vs尽力而为)、持久性(是否有历史数据缓存)、截止时间(消息超时就丢弃)、生命周期(按存活时间过滤)。这些策略让开发者能根据实际需求精细控制通信行为。
举个例子:激光雷达数据用"尽力而为"(best effort),因为每帧数据都很大,丢一帧无所谓,下一帧马上来。而急停指令用"可靠传输"(reliable),确保一定送达。
实时性问题
ROS1不是实时系统。它的调度完全依赖操作系统的调度器,消息的传输延迟不可预测。有时候1毫秒就到了,有时候可能延迟100毫秒甚至更多。
对于导航、路径规划这种模块,延迟几十毫秒可能还能接受。但对于底层控制——比如电机PID控制环,要求严格的1毫秒周期——ROS1完全做不到。
有些团队通过在ROS1上加实时补丁来缓解这个问题,但效果有限,因为ROS1的通信层本身就不是为实时设计的。
ROS2从一开始就考虑了实时性。DDS本身就支持实时通信,配合RT-Preempt Linux或者FreeRTOS这样的实时操作系统,可以实现确定性的通信延迟。这在工业机器人的控制场景中是必须的。
安全问题
ROS1完全没有安全机制。任何能访问网络的设备都可以:向你的topic发布消息、调用你的service、读取你的参数。在实验室里,这没什么,大家都是自己人。
但在产品环境中,这是巨大的安全隐患。想象一下,有人通过网络向你的机器人发送了一个虚假的导航目标点,或者篡改了传感器数据。对于一台正在公共道路上运行的机器人来说,这可能造成严重后果。
ROS2内建了SROS2安全机制,基于DDS Security标准。它支持身份认证(确认节点的身份)、访问控制(限制谁能发布什么topic)、数据加密(通信内容不被窃听)。虽然配置起来比较繁琐,但至少有了这个能力。
多机器人系统
ROS1对多机器人的支持很弱。多个机器人共享同一个rosmaster的话,topic名字会冲突。你总得手动加namespace来区分,比如/robot1/cmd_vel和/robot2/cmd_vel。但很多现成的ROS包并没有考虑namespace的问题,代码里硬编码了/cmd_vel这样的topic名字,你想加namespace就得改源码。
导航栈就是个典型的例子。move_base里面大量硬编码的topic和frame名字,你想让两台机器人各自跑导航,得把整个导航包fork一份改topic名字。维护两套代码的噩梦,谁改谁知道。
ROS2天然支持多机器人。每个机器人可以通过namespace隔离,同一个topic名字在不同namespace下互不干扰。而且因为没有中心化的master,几十台机器人在同一个网络里也不会出现注册冲突。ROS2的很多核心包在设计时就考虑了namespace的问题,不需要你手动去改。
跨平台支持
ROS1基本上只能在Ubuntu上跑。macOS的支持是社区维护的,时好时坏。Windows就更不用想了。
但在实际项目中,你可能需要在Windows上跑上位机软件,在嵌入式板子上跑RTOS,在云端跑数据分析。
ROS2支持Linux、macOS、Windows,而且官方维护的DDS实现有好几个选择:Fast DDS、Cyclone DDS、Connext DDS等。不同的DDS实现在不同平台上的表现不同,你可以根据目标平台选择最合适的。
更值得关注的是micro-ROS项目。它把ROS2的功能裁剪到了微控制器级别,可以在STM32、ESP32这类资源受限的嵌入式设备上运行。这意味着你可以用统一的ROS2接口和底层硬件通信,不用自己写串口协议或者自定义通信格式。这在ROS1时代是不可想象的。
面试中怎么聊
面试官问ROS1的缺点,不要只是罗列问题。最好能结合自己的经验或者具体场景来讲。
比如:"我们之前用ROS1做一台服务机器人,遇到过rosmaster意外退出导致整个系统瘫痪的问题。后来我们加了自动重启master的脚本,但这只是治标。迁移到ROS2之后,去中心化的架构从根本上解决了这个问题。另外ROS2的QoS策略让我们能区分关键数据和非关键数据的传输策略,这在ROS1里是做不到的。"
迁移实战中的经验教训
分享一个真实的迁移经验。我们团队把一个中等规模的ROS1项目迁移到ROS2,花了大约两个月。最大的坑不是通信层的替换,而是参数管理。ROS1的参数服务器是全局的,任何节点都能读写任何参数。ROS2把参数绑定到了每个节点上,原来那种"全局共享参数"的模式需要重新设计。
另一个经验是:不要试图一次性替换所有模块。我们采用了"双系统并行"的策略——ROS2的新模块和ROS1的旧模块通过ros1_bridge共存,每迁移完一个模块就断开一条桥接。这样风险最小,出了问题也容易回滚。
ROS1遗留系统的维护经验
虽然ROS2是未来,但很多企业和实验室仍在使用ROS1系统。维护ROS1项目的常见挑战包括:依赖的库版本过旧、在新版Ubuntu上编译报错、文档缺失等。一个实用的技巧是用Docker固定运行环境,避免系统升级带来的兼容性问题。另外,rosbridge可以把ROS1的话题通过WebSocket暴露出来,方便和Web前端或Python脚本集成。
还有一个实用建议:如果是新项目,强烈建议直接用ROS2。ROS1已经在2025年EOL了,新项目再选ROS1会增加后续维护成本。
给你的建议
理解ROS1的问题不是为了贬低它。ROS1在它的时代做出了巨大贡献,很多机器人开发者是通过ROS1入门的。但技术要进步,ROS2确实解决了ROS1在工业场景下的核心痛点。
如果你现在还在用ROS1,建议开始规划迁移了。ROS1 Noetic已经在2025年停止维护,不会再有安全更新和bug修复。新项目直接用ROS2,老项目制定迁移计划。
迁移的时候不要想着一口气全换完。先把最核心的通信层换掉,其他部分逐步跟进。社区的经验是,一个中等规模的ROS1项目,熟练的团队大概需要两到三个月完成迁移。
上一篇:第106篇 ROS的前世今生——从ROS1到ROS2的进化逻辑
下一篇预告:第108篇 ROS2安装与第一个Hello World程序
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐

所有评论(0)