最近总有人问我同样一个问题:想进入具身智能这行,到底该学ROS1还是直接上ROS2?问的人里有刚毕业的学生,有做传统嵌入式转过来的工程师,还有一些是想给实验室搭机器人平台的老师。网上关于两个版本谁优谁劣的讨论也吵了好几年,有人说ROS2稳定了赶紧上,有人说ROS1生态庞大、资料齐全不用急着迁,夹在中间的新手往往一头雾水。
我接触ROS大概是从Indigo那会儿开始的,后来在Melodic、Noetic上做过移动底盘,也接过机械臂的MoveIt方案,ROS2的Dashing、Foxy、Humble也都实际跑过项目,包括用ROS2做过机器狗的导航和感知模块。这篇文章我会把这些年两个版本都用下来的真实感受写清楚:它们到底差在哪里、选型的决策逻辑是什么、从ROS1迁到ROS2要跨越哪些坑,以及具身智能硬件接入时两个版本各自的适用场景。
1. 具身智能研发里,ROS版本选择为什么让人头疼
1.1 一套机器人软件框架牵动整条技术栈
先说一个基本事实:ROS不是单纯的“操作系统”,也不是某个算法库,它是介于操作系统和机器人应用之间的一整套分布式通信框架。放到具身智能的场景里看,一台机器人身上同时存在感知、定位、导航、规划、控制、人机交互等多个模块,这些模块分属不同的开发团队、运行在不同计算单元上,它们需要一套约定俗成的消息格式和通信方式把数据“串”起来。ROS解决的就是这个问题,这也是为什么你在任何一家机器人公司、任何一篇具身智能论文里都能看到它的身影。
但“无处不在”和“版本分裂”是两回事。我在2023年看到不少新开的机器人创业公司,技术栈里写的是Ubuntu 20.04 + ROS1 Noetic,招聘要求也写着“熟悉ROS1/ROS2”,这个“/”其实很微妙——他们自己可能都没想清楚新项目到底用哪个,因为团队里老一辈工程师只会ROS1,新招进来的年轻人又只会ROS2。
如果你只是做一个固定场景的轮式机器人,ROS1完全够用,没必要折腾。但如果你要做的是一台要进入千行百业的通用具身智能机器人,需要支持多机协同、需要和云平台对接、需要对底层关节做实时控制、需要和其他机器人共享地图和任务——那ROS1的架构瓶颈就会逐渐冒出来。
1.2 老代码资产与新项目需求之间的拉锯
具身智能这个领域有一个独特的现象:学术论文和开源代码更新极快,但底层机器人平台反而长时间停留在ROS1。比如你在GitHub上搜一个“mobile manipulation”的仓库,很多是基于ROS1的,跑起来还要依赖特定版本的Gazebo和MoveIt;而另一方面,像宇树、波士顿动力这类新一代机器人平台,官方给出的SDK和示例已经全面转向ROS2。
我在带项目时经常遇到这种局面:团队里有现成的ROS1代码库,是一年多时间积累的底盘驱动、状态机、导航配置,直接扔掉太可惜;但客户要求的新功能,比如多台机器人协同避让、动态任务分配,在ROS1里做要多写很多底层逻辑。这个拉锯如果没有清晰的判断标准,项目很容易卡在半路,团队心力也会被反复折腾掉。
这篇文章就是想把选择标准讲透,让你面对具体场景时能快速判断“该用哪个”,而不是靠感觉。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. ROS1与ROS2的本质差异:从架构上理解两个版本的“脾气”
2.1 最大的分水岭:中心化Master与去中心化DDS
先说ROS1最核心的架构。ROS1的每个节点在启动时要向一个叫做roscore的Master节点进行注册,Topic、Service的通信双方也通过Master完成匹配。你可以把它理解成“所有人都要通过一个总机来转接电话”:总机知道每个节点的地址和话题,通信双方交换信息之前先通过总机建立连接。这个过程本身很稳定,但它有一个天然的缺点——总机一旦挂了,整台机器人的所有通信就全部瘫痪。在实验室里多节点崩溃、重启是家常便饭,但你没法接受一台在外跑着的机器人突然“失联”。
ROS2则把Master整个拿掉了,底层换成DDS(Data Distribution Service)这套分布式通信标准。每个节点在启动时会通过“发现机制”主动去探测同网络内的其他节点,话题、服务、动作的匹配变成了节点与节点之间直接协商。最直观的感受是:启动多个节点时,不需要先启动一个roscore,各个节点开起来之后它们自己就能找到彼此。这个“各自发现”的机制看起来只是去掉了Master,实际上改变了整个系统的容错能力和扩展方式,也直接影响了ROS2在多机器人、多机协同场景下的天然优势。
2.2 通信质量、实时性与QoS策略
ROS1的通信质量模型相对简单:话题消息默认用TCP传输,也有UDPROS的选项,但日常开发中很少人真的去用。TCP本身可靠、稳定,但它的重传机制对高频率、大带宽的数据不太友好,而且实时性没有保证。曾经有人在ROS1里用激光雷达和视觉数据做融合,点云消息一大,就直接挤占其他话题的带宽,整个系统的延迟就上来了。
ROS2基于DDS引入了QoS(Quality of Service)策略。QoS可以理解成一套“通信契约”,你可以告诉系统这种消息是“必须送达”还是“丢了就算了”、是“只发给最新的订阅者”还是“保留历史数据”。这对具身智能非常重要:比如传感器高频数据,你希望订阅者拿到尽可能新鲜的帧,丢失一两帧可以接受,那就用“尽力传输”策略;比如任务调度指令,你希望绝对不丢,那就用“可靠传输”策略。不同的模块用不同的QoS策略,整个系统在数据洪流下依然能保持稳定。
为了直观表示两个版本的差异,我整理了一个表格:
| 维度 | ROS1 | ROS2 |
|---|---|---|
| 系统架构 | 中心化Master(roscore) | 去中心化DDS自动发现 |
| 通信机制 | TCPROS/UDPROS | DDS(默认FastDDS/CycloneDDS等) |
| 实时性 | 不支持 | 支持零拷贝、线程绑定等实时方案 |
| Python版本 | Noetic支持Python3,早期多为Python2 | 原生Python3 |
| 构建系统 | catkin | ament + colcon |
| 参数服务 | rosparam服务器 | 参数节点+参数回调 |
| 坐标系统 | tf/tf2 | 只有tf2 |
| 多机通信 | 需要配置ROS_MASTER_URI | DDS自动发现,仍需要网络配置 |
| 嵌入式支持 | 无官方方案 | micro-ROS |
| 社区生态 | 庞大、多年积累 | 增长迅速,核心包已覆盖 |
2.3 构建系统、启动方式与命令行工具的变化
从开发者的实际操作感受来看,ROS2带来的改变非常明显。ROS1里包依赖关系是catkin管理,写CMakeLists.txt的方式对刚入门的人来说不够友好;ROS2换成了ament和colcon,虽然上手时稍微绕一点,但理念更清晰,Python包和C++包在构建时会统一编译到install目录,少了ROS1里那个source devel/setup.bash的别扭感。
启动方式也从roslaunch变成了ros2 launch。ROS1的launch文件是XML语法,写复杂嵌套时比较痛苦;ROS2的launch文件可以用Python脚本描述,逻辑控制、动态参数、条件分支都直接写在代码里,功能强大了不少,但要会写Python才能玩得转。命令行工具方面,ROS2的ros2 node list、ros2 topic echo、ros2 service call等指令更规整,自带的tab补全也更友好,用习惯后很难再回到ROS1那套。
3. 选型决策:哪种情况该留在ROS1,哪种情况该直接上ROS2
3.1 一种情况判断法:看你的机器人是否只待在“实验室”
这里给一个很实用的判断思路:你的机器人是只在一个固定环境里跑,还是要面对动态变化的环境、和其他机器人协作、甚至要和云端和边缘设备联动?
如果是前者,比如课程设计、科研楼道里巡检、实验室里的抓取演示,ROS1完全够用,生态成熟、排错资料多,遇到问题能搜到大把现成答案。特别是你手里已经有大量基于ROS1的算法包、驱动、工具链,快速出结果比追新更重要,那就别折腾,继续用ROS1。
如果是后者,即你正在搭建的是一个面向真实场景的具身智能系统——机器人可能要走出实验室,要能在网络不稳定的条件下运行,要多个机器人之间动态协同,要对接云端的任务编排,要支持远程监控和OTA升级——那么即使初期麻烦一点,也强烈建议直接上新项目用ROS2。因为ROS2在这些场景下的网络配置、安全认证、多机通信能力都原生具备,省去很多ROS1中间加自研组件的脏活累活。
3.2 从具身智能的技术栈层次看选型
另一个实用的角度是看你的工作落在哪一个技术层次:
- 如果你做的是底盘导航、定位、建图,ROS1的move_base和gmapping相当成熟,ROS2的Nav2也早已稳定,这两个版本都有得选;
- 如果你做的是机械臂运动规划,ROS1的MoveIt 1资料丰富,ROS2的MoveIt 2在Humble上开始正常工作,但安装和配置过程比ROS1要复杂一点;
- 如果你做的是多传感器融合、多机协同、云端对接,ROS2的DDS天然解决跨设备通信问题,这个层面基本没有理由回头选ROS1;
- 如果你做的是嵌入式底层控制,即直接在MCU上跑节点、直接控制电机,ROS2有micro-ROS方案,ROS1在这方面几乎是空白。
很多加入具身智能团队的人是从导航或机械臂切入的,他们会发现这两个场景在ROS1里都有非常成熟的开源方案,所以老工程师不愿意迁移很正常。但如果你看整台机器人的全链路——传感器采集、决策大脑、动作执行、多机协作——ROS2的架构上限明显更高。
3.3 一个相对稳妥的学习路线
如果你刚入行,我建议不要一上来就把自己绑定到某个版本上。比较稳妥的路线是:先用ROS1去理解“节点、话题、服务、动作、参数”这些核心概念,因为这个心智模型在两个版本里是通用的,而且ROS1的资料多、社区活跃,入门门槛低;然后把项目切换到ROS2环境,重新写一遍发布订阅、服务调用、参数读取这些基本流程,这时候你会发现两个版本的对应关系非常清晰,迁移成本其实没有想象中那么高。
我的一个切身体会是:ROS1是很好的“入门教练”,ROS2才是真正的“生产工具”。停留在ROS1太久,会错过很多现代机器人系统需要的特性;但完全没有ROS1基础直接上ROS2,又会因为很多概念没有“前因”而理解得不够透彻。
4. 从ROS1迁移到ROS2:核心概念的对应关系与代码差异
4.1 概念对应表:先把字典建好
用ROS1一段时间后转ROS2,最大的障碍不是语法,而是概念对应。比如ROS1里python脚本可以不用类、直接写回调;ROS2里建议用class封装Node子类,这种代码结构的差异不小。下面这些是我认为最核心的对照:
| ROS1概念 | ROS2对应概念 | 说明 |
|---|---|---|
| roscore | 不需要 | ROS2自动发现节点 |
| roslaunch | ros2 launch | 支持Python launch文件 |
| rospy/roscpp | rclpy/rclcpp | 客户端库重写 |
| catkin_make | colcon build | 构建工具不同 |
| rosparam | ros2 param | 参数管理方式变化 |
| tf/tf2 | tf2 | 只保留tf2 |
| rosbag | ros2 bag | 录制功能保留,命令不同 |
| nodelet | composition container | 进程内组合节点机制变化 |
| message_filters | message_filters (ROS2版) | 时间同步工具仍有对应 |
4.2 一个面向初学者的代码对比:发布订阅
以最简单的发布订阅为例。ROS1的talker一般写成这样:
python复制#!/usr/bin/env python
import rospy
from std_msgs.msg import String
rospy.init_node('talker')
pub = rospy.Publisher('chatter', String, queue_size=10)
rate = rospy.Rate(1)
while not rospy.is_shutdown():
pub.publish(String('hello'))
rate.sleep()
ROS2的写法则要明显“面向对象”一点:
python复制import rclpy
from rclpy.node import Node
from std_msgs.msg import String
class Talker(Node):
def __init__(self):
super().__init__('talker')
self.pub = self.create_publisher(String, 'chatter', 10)
self.timer = self.create_timer(1.0, self.timer_callback)
def timer_callback(self):
self.pub.publish(String('hello'))
def main(args=None):
rclpy.init(args=args)
node = Talker()
rclpy.spin(node)
node.destroy_node()
rclpy.shutdown()
if __name__ == '__main__':
main()
对比一下就发现:ROS2里没有全局的rospy.init_node,而是在init之后显式创建Node实例;循环也要用自己的Timer实现,而不是while + sleep。这个变化对写多节点程序影响很大,毕竟你能直接持有节点实例,夸节点调用和模块解耦变得更顺手。
4.3 服务、动作与参数:迁移时容易踩的细节
服务在ROS1中用rospy.Service和rospy.ServiceProxy,在ROS2中则变成create_service和create_client,这个功能上对应比较清楚。动作Action的迁移略麻烦,ROS1的actionlib需要定义.action文件,用actionlib库来通信;ROS2中则统一叫Action,使用rclpy action的API,而且action和service一样,也支持QoS设置。
参数系统是另一个容易忽略的差异点。ROS1里rosparam是一个中心参数服务器,节点用rospy.get_param获取参数;ROS2里参数是节点自身的一部分,用Node.declare_parameter和get_parameter,你可以从外部动态设置,也可以用parameter callback监听参数变化。对需要在线调参的避障PID、导航速度上限这类场景,ROS2的参数系统反而实现得更干净。
4.4 launch文件和包管理的变化
如果你以前用XML写launch,到ROS2里会明显感觉新风格的Python launch文件自由度更高。最简单的一个launch差异:
ROS1的launch文件:
xml复制<launch>
<node name="talker" pkg="demo_talker" type="talker.py" output="screen"/>
<node name="listener" pkg="demo_listener" type="listener.py" output="screen"/>
</launch>
ROS2的launch文件(Python):
python复制from launch import LaunchDescription
from launch_ros.actions import Node
def generate_launch_description():
return LaunchDescription([
Node(package='demo_talker', executable='talker', name='talker', output='screen'),
Node(package='demo_listener', executable='listener', name='listener', output='screen'),
])
当你需要在launch里写条件判断、动态参数、组合节点时,Python launch的优势会非常明显。包管理上,你不再是“源码放在src下然后catkin_make”,而是写package.xml + setup.py(Python包)或CMakeLists.txt(C++包),再用colcon build统一编译,最后source install/setup.bash。
5. 环境搭建与安装:Ubuntu版本、Docker与一键脚本的实际落地经验
5.1 Ubuntu版本和ROS发行版的对应关系
新手最容易在这里翻车:装错Ubuntu版本导致ROS装不上,或者装完ROS后才发现和系统不匹配。ROS对Ubuntu版本的要求非常严格,不是随便哪个版本都兼容。我整理了一张我实际用过的组合表:
| Ubuntu版本 | 推荐ROS发行版 | 类型 | 个人建议 |
|---|---|---|---|
| Ubuntu 18.04 | ROS1 Melodic / ROS2 Dashing | 老旧 | 不推荐新项目 |
| Ubuntu 20.04 | ROS1 Noetic / ROS2 Foxy | Noetic是ROS1最后的绝唱 | 兼容老代码选这里 |
| Ubuntu 22.04 | ROS2 Humble | LTS,较稳定 | 当前最推荐新手/新项目 |
| Ubuntu 24.04 | ROS2 Jazzy | 较新,部分包仍在适配 | 尝鲜可以,生产项目等一等 |
Ubuntu 20.04是个特殊时间点:它同时支持ROS1 Noetic和ROS2 Foxy,很多人以为可以在这里平滑过渡,但实际上两个版本不可以简单混装,多装几轮你就会发现依赖关系冲突严重。我的经验是如果你有大量ROS1代码要继续用,就在20.04上装Noetic;如果你是全新项目,直接用22.04装Humble,体验会顺畅得多。
5.2 手动安装与一键脚本脚本的取舍
经常看到群里有人问:“一键安装脚本靠谱吗?”我的回答是:能用,但要知道它在干什么。
以社区流传较广的ROS一键安装脚本为例,它本质上做的事情是替换软件源、添加ROS官方源、update和install,中间还会顺手配置rosdep、初始化rosdep,省去你手动敲一堆命令的麻烦。对刚入门的同学来说,一键脚本确实能帮你快速把环境跑起来,避免在“安装”这个环节消磨掉学习热情。
但我还是建议你至少手动装过一次ROS,因为安装过程能让你理解环境变量、软件源、依赖关系这些基础,后面排障时会非常有用。手动安装的大致路径是:换源 -> 添加ROS 2 GPG key -> 添加ROS 2 apt源 -> apt install ros-humble-desktop -> 安装rosdep并初始化 -> source /opt/ros/humble/setup.bash并写入.bashrc。不要跳过rosdep init这一步,后面的依赖管理全靠它。
5.3 Windows环境下的Docker方案
有一个现实问题是:很多人的主力电脑是Windows,不想装双系统或虚拟机。我的建议是用Docker Desktop跑一个Linux容器,在容器里安装Ubuntu对应的ROS镜像。Docker的isolated环境对ROS开发很友好,而且方便随时销毁重建,特别适合做课程实验或快速测试。
需要注意几个细节:一是Docker容器默认没有图形界面,跑rviz、gazebo这类带GUI的程序要额外配置X11转发,Windows上用WSL2 + WSLg或者Xming都可以解决,但第一次配置会费点劲;二是Docker里跑ROS2,需要给容器指定host网络模式(--network host),否则DDS自动发现会找不到其他容器里的节点;三是如果你要接USB设备(比如激光雷达、相机),要在docker run时加上--device参数把设备映射进容器。这些经验都是一步步踩出来的,网上很多教程没有讲清楚,照抄容易卡死。
5.4 多机通信配置的差异:主从机在ROS1和ROS2里的不同坑
热词里有个“ROS配主从机”,这确实是两个版本差别最大的地方之一。ROS1的多机通信需要指定一台机器作为Master(运行roscore),其他机器通过配置ROS_MASTER_URI指向这台机器;同时还要手动设置ROS_IP保证各节点能正确通告自己的地址。我在实验室里不止一次因为两台设备不在同一网段、防火墙没放行或者ROS_IP设错而排查很久,尤其是在WiFi环境下,主从机经常出现节点发现不了的问题。
ROS2因为基于DDS自动发现,省掉了配置Master和ROS_IP的步骤——两台机器连到同一个局域网,各跑各的节点,它们会自动发现彼此。但DDS自动发现并不是完全没有网络要求:如果开启了防火墙,需要放行UDP的7400-7500范围端口和TCP的一些动态端口;如果设备有多个网卡,还要设置RMW_IMPLEMENTATION和网卡绑定参数,否则会发现不到节点。ROS2把“配置主体”从环境变量转移到了网络策略,听起来轻松了,但实际调网络时反而要多懂一点DDS。
6. 具身智能硬件接入:激光雷达、相机、机械臂与机器狗的ROS版本适配
6.1 老型号传感器的ROS1困境与新设备的ROS2原生支持
具身智能系统的硬件接入基本是绕不开的一环。我在实际项目里接触过各种传感器和执行器,最大的感知是:老设备和新框架之间,往往存在一个“驱动断层”。
举个例子,Neato XV-11激光雷达是从扫地机器人里拆下来改造的雷达,很多入门项目喜欢拿它来当低成本建图设备。这类雷达的成熟驱动、串口解析代码、点云转换节点,几乎清一色是ROS1的,在ROS2里能用的版本要么不完整、要么已经很久没人维护。如果你手里正好是这样一台设备,在ROS1 Noetic上跑通方案会更省心。
反过来看,新一代硬件厂商已经全面倒向ROS2。宇树Go2机器狗的官方SDK、客户端的消息接口、控制指令封装都是面向ROS2设计的;一些新出的机械臂控制库、3D相机驱动、激光雷达驱动同样首选支持ROS2。所以如果你做的是全新的具身智能硬件集成,直接上ROS2反而能享受更干净的驱动适配。
6.2 相机、机械臂和仿真环境的实战感受
海康相机这类工业相机在ROS1下有成熟的驱动和相机标定流程,但到了ROS2下,官方驱动支持偶尔会慢半拍。我的建议是如果相机厂家的SDK只提供ROS1版本,不要硬着头皮在ROS2里重写驱动,更不要自己造轮子去解SDK的底层数据,可以直接在ROS1环境里跑相机驱动,再用一个网桥/串口节点把图像消息转发给ROS2主系统。两个版本之间做“桥接”虽然多了一层开销,但在驱动不齐的情况下能救急。
机械臂方面,MoveIt 2在ROS2上的工作流已经相当成熟,尤其是结合机器人的URDF模型做运动规划,比ROS1的体验更顺滑。但要注意版本匹配:ROS2 Humble对应MoveIt 2的Humble分支,ROS2 Foxy对应Foxy分支,不同发行版之间不能混用,否则编译会报一堆错。
仿真层面,如果你只是做SLAM、导航算法验证,ROS1的Gazebo + turtlebot/testbot方案资料极多,出图快;如果要做多机协同仿真,ROS2 + Gazebo(或新版的gz sim)能更贴近真实的多机通信环境,但安装和配置的坑也多,尤其要留意gazebo_ros插件在ROS2下的版本兼容问题。我的经验是:仿真环境要“舍得花时间搭”,因为后面所有算法调试都在这个环境里进行,环境搭不好后面全是坑。
6.3 微控制器执行层的差异:micro-ROS的补位
具身智能机器人最终一定涉及底层电机控制、力控、关节驱动,这个层面很多团队用的是STM32或ESP32这类MCU。ROS1时代MCU直接接入系统很麻烦,通常只能在MCU里写自定义协议,再通过串口和上位机上的ROS节点通信。ROS2的出现带来了micro-ROS,它能在资源有限的MCU上直接跑ROS2节点,话题、服务、参数这些概念直接到执行层。这套方案对机器人关节闭环、末端执行器控制这类高实时性需求非常有用。
虽然micro-ROS的生态还比较新,很多工业级应用还没有完备校验,但方向已经非常明确:未来执行层和控制层的通信会越来越多地走ROS2的通道,而不是自定义串口协议。
7. 几个容易忽略的实操细节
7.1 rosdep、软件源与网络超时的日常折磨
ROS日常使用中最容易出现的问题往往不是代码逻辑,而是环境本身。rosdep update抽风会导致工作空间构建时依赖检查过不了;默认源节点网络不稳定会导致某个基础包安装失败。我的做法是装好ROS后第一时间配置好国内软件源,并且让rosdep也走可用的镜像源,会省掉很多次无谓的等待。网上还有很多维护得很及时的ROS一键安装脚本和社区镜像源教程,遇到环境问题时多看看别人踩坑记录,一般都能快速定位。
7.2 虚拟环境、Docker与多版本共存的建议
如果你在工作中需要同时维护ROS1和ROS2项目,我的经验是按“会话”隔离而不是按“机器”隔离:用Docker分别构建ROS1镜像和ROS2镜像,每次开发时进入对应容器。这样两个版本的依赖不会互相污染,环境也方便复制给别人。如果实在要在同一台机器上共存,至少要把环境变量隔离好,source一个版本的setup.bash后不要轻易切换,更不要放在同一个bash里反复source,否则依赖链接会乱到你怀疑人生。
7.3 社区资料、学习路径与实战建议
实际学习路径上,我建议先完整跑一遍ROS2官方的turtlesim和demo talker/listener,对通信机制有个感性认识;然后用一个带激光雷达的机器人(真实或仿真都行)做一次建图和导航,把SLAM、路径规划、避障整条链路打通;最后再拿一个具体业务场景(比如机械臂抓取、多机协同配送)做项目。如果已经学完ROS1再迁ROS2,重点关注4.1节那个对照表,把自己以前写过的package改写一遍,基本就能过渡过去。
网上很多资料会把ROS12、ROS27这种过时版本混在一起讲,阅读时要特别留意教程对应的发行版和Ubuntu版本。遇到“编译失败”之类的问题,不一定是代码问题,先检查ROS发行版和依赖版本是否匹配,往往能少走很多弯路。
8. 写在最后:我对两个版本的真实态度
我见过不少团队在ROS版本选择上浪费了大量时间,也见过一些项目因为选对了版本而少踩很多坑。个人的体会是:不要神化ROS2,也不要死守ROS1,它们本质上都是工具,关键看你的项目和团队处于什么阶段。如果你现在手里有一个迫切要交付的机器人项目,且代码基础都在ROS1,那就用ROS1尽快交付,别因为追求技术新而给自己制造风险;如果你是在建一个新平台、新产品,那就大胆用ROS2,虽然前期配置和找资料的成本高一点,但后面路会越走越宽。
如果你正好卡在“要不要把系统迁到ROS2”的决策点上,最后再分享一个小技巧:不要一上来就全量迁移,而是先搭一个ROS2的空壳工程,把最核心的一个数据链路(比如雷达数据从驱动到建图节点)跑通,再逐步把其他模块搬过来。这样风险和进度都可控,团队信心也更容易建立起来。ROS版本之争短期内不会结束,但只要你对两个版本的底层逻辑和适配边界有清晰判断,版本本身就不会再是你的瓶颈。
