第一次把 ROS 2 装完,不少人会愣一下:桌面没有多出什么图标,打开终端敲完 ros2 却只有一个 usage 帮助页,好像“什么都没发生”。这跟平时装一个软件、打开一个界面、点几个按钮的体验完全不一样。如果你也是从 ROS 1 或者刚接触具身智能、机器人开发的新手,对“ROS 2 到底是个什么东西”感到困惑,我建议你先放下“软件产品”这个词,把 ROS 2 当成一套组装积木的规则和底座来看。这个视角一旦建立起来,后面学装包、写节点、调导航、接机械臂,都会顺畅很多。
这篇文章我想从“超级乐高底座 + 通用连接标准”这个比喻出发,把 ROS 2 的模块化设计、功能复用、不重复造轮子的逻辑拆开讲清楚,并结合自己实际搭建机器人系统时踩过的坑,整理一套可以直接参考的实操路径。内容会比较长,适合正在学 ROS 2、准备入门具身智能开发、或者已经被安装和编译折磨到头大的朋友。
1. 先理解核心:ROS 2 为什么能被叫成“超级乐高底座 + 通用连接标准”
1.1 从一次“装机翻车”说起:ROS 2 不是拿来即用的软件
我最早接触 ROS 2 是在 Ubuntu 20.04 上装 Foxy,装完按照教程跑小海龟,确实画面出来了,也能用键盘控制。但当我试图理解“ROS 2 这个软件”的界面在哪里、设置在哪里、菜单在哪里时,我发现自己什么也找不到。后来看了官方设计文档才意识到,ROS 2 并不是一个像 MATLAB 或 Gazebo 那样可以被“打开”的软件,它是一整套进程间通信框架 + 中间件标准 + 开发工具链 + 功能包生态的组合体。
你可以把它理解成一套 LEGO:底座是通信机制(DDS、ROS 2 核心库),颗粒是无数独立的节点程序(比如一个激光雷达驱动、一个路径规划器、一个电机控制节点),连接件是话题、服务、动作这三种通信方式。你拿到手的 ROS 2 发行版,本质上只是告诉你“积木之间怎么咬合”的标准,以及帮你把一些常用颗粒打包好了。你真正要做的事情,是去挑选、搭建、配置这些颗粒,拼出自己的机器人系统。
这也是为什么 ROS 2 经常在讨论具身智能时被反复提及——具身智能系统需要感知、决策、执行一体,而 ROS 2 的模块化设计天然适合把视觉、导航、机械臂控制、语音交互这些能力拆成独立模块,再通过统一接口组合起来。它解决的从来不是“怎么做一个功能”,而是“不同功能之间怎么高效协作”。
提示:如果你现在卡在“装完不知道下一步干嘛”的阶段,不用慌。ROS 2 的设计目标本来就是“骨架级”的,不是“应用级”的。你需要的下一步,是往这个骨架上挂第一个节点。
1.2 “超级乐高底座”怎么理解:底座、颗粒、拼接件
我用一张对应关系表把乐高比喻和 ROS 2 的概念映射起来,这样你在看任何教程时都能把抽象概念落到“积木”上:
| 乐高概念 | ROS 2 对应物 | 实际例子 |
|---|---|---|
| 底板 | DDS 中间件 + rclcpp/rclpy 客户端库 | Fast DDS、Cyclone DDS,以及 ROS 2 自带的节点基础库 |
| 常规颗粒 | 节点(Node) | 摄像头驱动节点、激光雷达驱动节点、导航节点、机械臂规划节点 |
| 特殊颗粒 | 功能包(Package) | navigation2、moveit2、gazebo_ros2_pkgs、slam_toolbox |
| 凸点拼接结构 | 话题(Topic) | 激光数据 /scan、里程计 /odom、速度指令 /cmd_vel |
| 拼插结构 | 服务(Service) | 地图保存服务、机器人复位服务 |
| 复杂传动机构 | 动作(Action) | 导航到目标点、机械臂执行轨迹 |
| 说明书 | URDF/XACRO 模型描述 | 描述机器人有多少关节、每个关节在哪、传感器怎么装 |
这意味着什么?意味着你在 ROS 2 里写一个节点,不需要知道另一个节点是谁写的、跑在哪台机器上、用什么语言写的。你只需要知道它的接口,就像你只需要知道乐高颗粒上有凸起和凹陷,就能跟任意积木咬合。这个思路是 ROS 2 区别于传统“单体软件”的最大不同。
对具身智能开发来说,这种模块化解耦特别关键。比如你做一个轮式机器人,底盘驱动是团队 A 写的,导航是团队 B 用 navigation2 配置的,视觉识别是团队 C 用深度学习模型封装成节点的。只要大家都遵循 《ROS 2 接口标准》,这三个模块就能像乐高一样拼到同一个系统里。换一个底盘,不需要重写导航;换一个相机,不需要重写路径规划。
1.3 “通用连接标准”为什么是设计灵魂:不重复造轮子的底层逻辑
ROS 2 把通信抽象成了统一的接口定义语言(IDL),你通过 .msg、.srv、.action 文件定义数据结构,然后系统自动生成对应语言的代码。这就是“通用连接标准”的载体。
举个例子,导航模块要发布速度指令,它会向话题 /cmd_vel 发一个 geometry_msgs/msg/Twist 类型的消息。Twist 定义是固定的:线速度 x、y、z,角速度 x、y、z。无论你用的是差速底盘、四轮麦轮底盘还是全向底盘,只要你的底盘驱动节点最终以 Twist 格式输出,导航模块就能无缝控制它。这就像 USB 接口一样:你不需要知道 U 盘内部的芯片怎么工作,只要它有 USB 接口,插上就能用。
这种设计的核心价值在于功能复用。导航功能不必为每一种底盘单独开发一套,它只需要面向 Twist、Odometry、LaserScan 这些标准消息工作。反过来,底盘厂商只需要把驱动写好,支持 ROS 2 接口,就能直接用社区里成熟的导航、建图、机械臂规划方案,不用造轮子。
我见过太多人一开始学 ROS 2 时,喜欢自己写一个“发送消息的函数”,或者自己定义一套通信格式,结果后面要对接 Gazebo、Nav2、MoveIt 时,发现完全不兼容,只能推倒重来。这就是没有吃透“标准”两个字的教训。ROS 2 给的这份标准,是多年机器人社区沉淀下来的“接口公约”,建议不要轻易绕开它。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 功能复用:常见的大型功能包是怎么被“拼”进系统的
2.1 导航三件套:Nav2、SLAM 工具与 RViz2 怎么配合
如果你做过移动机器人,一定知道导航是“熟悉的陌生人”:听起来就是从一个点走到另一个点,但背后牵扯到定位、建图、全局规划、局部规划、速度平滑、避障等一大堆模块。ROS 2 社区里已经有一套成熟方案,叫 Nav2,它本身就是“功能复用”的典范。
Nav2 不是一个单一大节点,而是由 planner_server、controller_server、bt_navigator、amcl、behavior_server 等一堆节点组成。这些节点之间通过话题和服务沟通。你唯一需要做的,是为自己的机器人提供以下几样东西:
- 机器人的 URDF 模型;
- 激光雷达或深度相机的数据话题(如
/scan); - 里程计话题(如
/odom); - 底盘速度控制话题(如
/cmd_vel); - 一张地图(用 SLAM 工具建,或者在已知地图里直接加载)。
把这些给齐,Nav2 的节点就会自动帮你完成“定位 → 导航规划 → 避障 → 输出速度指令”的全流程。你不需要自己写“怎么从 A 点规划到 B 点”的算法——社区已经写好了,而且经过大量真机验证。
SLAM 工具同样可以直接复用。slam_toolbox 是 ROS 2 里很常用的 2D 激光 SLAM 包,它订阅 /scan 和 /odom,实时输出占据栅格地图,并发布到 /map 话题上。RViz2 的作用则是把这些数据可视化出来,让你能直观看到机器人建的地图长什么样、规划的路径是否合理。三者关系可以用一句话概括:slam_toolbox 负责“我身边长啥样”,Nav2 负责“我该怎么走”,RViz2 负责“你肉眼能看见它们在干啥”。
注意:很多新手会忽略
robot_state_publisher和tf2。没有正确的坐标变换树,Nav2 和 RViz2 全都跑不起来。曾经有个朋友拿着完全正常的 Nav2 配置一直报错,查了半天发现是 URDF 里 base_link 和 laser_frame 的父子关系写反了。
2.2 机械臂运动规划:MoveIt 2 的复用思路
如果你的项目涉及机械臂,MoveIt 2 几乎绕不开。它是 ROS 2 里做运动规划的事实标准。很多人听到“运动规划”觉得很难,但在 MoveIt 2 里,你通常只需要做三件事:
- 提供机械臂的 URDF,里面写好各关节的
<joint>定义; - 用 MoveIt Setup Assistant 生成 SRDF(描述哪些关节构成规划组、哪些是末端执行器);
- 配置一个规划器插件,默认用 OMPL,里面有多种采样规划算法。
完成后,MoveIt 2 会自动封装出一个 move_group 节点,对外提供一系列服务:规划到目标位姿、执行轨迹、计算逆运动学、进行碰撞检测。你在自己的代码里只需要调用这些服务,不需要关心 OMPL 的底层采样流程、FCL 碰撞检测怎么算三角形包围盒,更不需要自己研究 IK 求解。这些全都是“轮子”,MoveIt 2 把它们打包好了,而且每个轮子都可以单独换。
我在实际工程里最深的感受是:复用的前提,是把接口做对。MoveIt 2 要正常工作,你的 URDF 里必须正确声明每个关节的类型(旋转关节还是滑动关节)、运动学参数、碰撞几何体。很多人 URDF 写得特别浮夸,用了很精细的 STL 模型,碰撞检测时反而卡到帧率掉到个位数;换成一个粗糙的圆柱体包络,速度立刻快几十倍。这就是“复用”过程中你自己需要承担的适配工作。
2.3 仿真环境:Gazebo、RViz2 与 ros2_control 的分工
在把代码跑上真机之前,仿真无疑是最安全的试验场。具身智能开发里经常提到 sim-to-real,ROS 2 生态给了你一套可悲可叹的复用工具体系:
- Gazebo 负责物理仿真。它模拟重力、碰撞、摩擦力、传感器噪声,把真实世界的物理规律跑起来;
- RViz2 负责可视化。它本身不仿真,只负责显示数据;
- ros2_control 负责“真实控制器”和“仿真控制器”之间做抽象。它定义了一套标准控制器接口,让你可以在 Gazebo 里和真机上用几乎一样的代码控制电机。
这里要重点说下 ros2_control 的设计思路。它把硬件抽象成了 hardware_interface,把控制逻辑抽象成了 controller_manager 管理的各种 controller。Gazebo 里有一个对应的仿真硬件插件,真机上则有一个基于串口或者 CAN 的硬件插件。你写的上层机器人控制逻辑不变,只需要切换底层的 hardware_interface 实现,就能从仿真跑到真机,这本身就是“不重复造轮子”的极佳体现。
不过说实话,仿真和真机的差距永远存在。Gazebo 里的轮子不打滑、电机无延迟、激光雷达没有真实噪声,这些“过于完美”的条件会导致控制参数在真机上需要重新调。我的建议是:仿真用于验证逻辑,真机用于标定参数,两者互补,不要偏废。
3. 实操:像“拼乐高”一样从零组装一个能跑的 ROS 2 系统
3.1 环境准备:Ubuntu 版本与 ROS 2 发行版怎么对应
ROS 2 的发行版和 Ubuntu 版本是绑定的,对应关系不能乱。我自己就有过在 Ubuntu 24.04 上强行装 Humble 的惨痛经历——第三方源里的二进制包全部编译不过,最后老老实实换成了 Jazzy。常见对应关系如下:
| Ubuntu 版本 | ROS 2 发行版 | 建议 |
|---|---|---|
| Ubuntu 22.04 LTS | Humble Hawksbill | 最成熟、文档最多、包最全,新手首选 |
| Ubuntu 24.04 LTS | Jazzy Jalisco | 较新,适合新项目,部分旧包需要自行编译 |
| Ubuntu 20.04 LTS | Foxy Fitzroy | 已接近 EOL,不推荐新项目 |
| Debian 11 | Humble | 可在树莓派、RK3588 板子上用 |
| Windows 11 | 可通过 WSL2 + Docker 安装 | 适合没有 Linux 机器但想快速体验的情况 |
安装方式上,最省心的是用官方 apt 源。步骤大致是:启用 universe 源 → 添加 ROS 2 GPG key → 把 apt 源写入 /etc/apt/sources.list.d/ros2.list → sudo apt update → sudo apt install ros-humble-desktop。安装完执行一行 source /opt/ros/humble/setup.bash。
国内用户经常卡在下载速度上,可以选择阿里云、清华等镜像源,速度提升明显。另外社区里也有人做了那种“一键安装”脚本,对于只是想快速搭个环境体验一下的人来说确实方便,但我建议动手能力允许的话,最好自己手动装一遍,至少要知道装了什么、装到了哪里。出了问题才不至于连环境变量都不知道去哪看。
一个实用的验证命令:
bash复制ros2 --help
ros2 topic list
ros2 run turtlesim turtlesim_node
如果前两条命令能正常输出,且第三条能弹出小海龟窗口,说明你的 ROS 2 基础环境已经通了。
3.2 第一个“颗粒”:从小海龟开始理解节点和话题
小海龟(turtlesim)其实是学习 ROS 2 最好的入门积木。它虽然简单,但包含了 ROS 2 最核心的通信模型。
打开两个终端,分别执行:
bash复制ros2 run turtlesim turtlesim_node
ros2 run turtlesim turtle_teleop_key
第一个终端是海龟仿真器节点,第二个终端是键盘控制节点。此时你在第二个终端按方向键,小海龟就会动。我们试着用命令观察底层发生了什么:
bash复制ros2 node list # 查看当前运行的所有节点
ros2 topic list # 查看所有话题
ros2 topic echo /turtle1/cmd_vel # 实时查看键盘节点发布的速度指令
你会看到 turtle_teleop_key 节点在发布 geometry_msgs/msg/Twist 类型消息到 /turtle1/cmd_vel,而 turtlesim 节点订阅了这个话题,然后控制海龟移动。这个简单的例子,就是 ROS 2 分布式通信模型的最小闭环。
这时候你再看“乐高”比喻:键盘控制是一个颗粒,海龟仿真器是另一个颗粒,它们通过“话题”这个拼接件连接。你在实际机器人项目里做的事情,本质上跟这个一样,只不过控制的不再是屏幕上的海龟,而是一个真实底盘,或者一条仿真机械臂。
3.3 拼装第二步:自己写一个发布订阅节点
光跑现成的小海龟还不够,我们试着做一个自己的“积木颗粒”。下面是一个完整的 Python 发布节点例子(参考 Humble 官方教程写法):
python复制#!/usr/bin/env python3
import rclpy
from rclpy.node import Node
from std_msgs.msg import String
class MinimalPublisher(Node):
def __init__(self):
super().__init__('minimal_publisher')
self.publisher_ = self.create_publisher(String, 'topic', 10)
timer_period = 0.5 # 秒
self.timer = self.create_timer(timer_period, self.timer_callback)
self.i = 0
def timer_callback(self):
msg = String()
msg.data = 'Hello ROS 2: %d' % self.i
self.publisher_.publish(msg)
self.get_logger().info('Publishing: "%s"' % msg.data)
self.i += 1
def main(args=None):
rclpy.init(args=args)
minimal_publisher = MinimalPublisher()
rclpy.spin(minimal_publisher)
minimal_publisher.destroy_node()
rclpy.shutdown()
if __name__ == '__main__':
main()
这个节点每隔 0.5 秒向 topic 话题发一条字符串消息。你还需要建一个 package.xml 和 setup.py(或者用 ros2 pkg create 自动生成),然后:
bash复制cd ~/ros2_ws
colcon build --packages-select my_package
source install/setup.bash
ros2 run my_package minimal_publisher
另一个终端用 ros2 topic echo /topic 就能看到消息。
这个过程看似简单,但它帮你打通了“写一个独立节点 → 在 ROS 2 系统中注册 → 与其他节点通信”的完整链路。之后你写激光雷达驱动、相机驱动、底盘控制,本质上都是这个模式的扩展——换成不同的消息类型、不同的回调函数。
3.4 拼装第三步:把底盘、传感器、导航“拼”成一个最小机器人系统
如果前面的步骤都走通了,我建议你试着拼一个“最小可移动机器人系统”。不需要真机,用 Gazebo 仿真就行。这里给你一个组装清单:
| 组件 | 作用 | 关键接口 |
|---|---|---|
urdf 或 xacro 文件 |
描述机器人车体、轮子、传感器安装位置 | 为 robot_state_publisher 提供模型 |
robot_state_publisher |
发布 TF 坐标变换 | 订阅 /robot_description,发布 /tf |
gazebo_ros2_pkgs |
在 Gazebo 中加载 URDF,生成物理仿真 | 读取 URDF,发布 /scan、/odom |
slam_toolbox |
建图 | 订阅 /scan、/odom,发布 /map |
| Nav2 | 导航 | 订阅 /map、/scan、/odom,发布 /cmd_vel |
| RViz2 | 可视化展示 | 订阅所有可视化话题 |
在 Gazebo 里加载你的机器人模型后,手动遥控它到处走一圈,同时运行 slam_toolbox,就能在 RViz2 里看到实时构建的地图。建完图保存为 pgm 和 yaml 文件,再启动 Nav2 加载地图,设置一个目标点,机器人就会自动规划路径并走过去。
这里的核心技巧是:把每个组件单独启动,观察它是否产生了预期话题。先用 ros2 topic list 确认 /scan 和 /odom 有数据,再启动 SLAM;地图正常发布了,再启动 Nav2。如果一气呵成全部启动,出了问题你根本不知道是哪个环节断链。
3.5 特殊情况:Windows、ARM 板卡、一键脚本到底用不用
不是所有开发环境都是 Ubuntu 桌面。有相当一部分朋友在 Windows 11 上做 ROS 2 开发,常用方案是 WSL2 + Docker。思路是:WSL2 提供一个轻量 Linux 内核,ROS 2 跑在 Docker 容器里,显示通过 WSLg 转发。这个方案的优点是环境隔离干净,缺点是摄像头、串口这类硬件设备需要额外做设备透传,且实时性较差,不适合做运动控制级开发,但用来学基础、调试算法问题不大。
ARM 平台(比如 RK3588、树莓派)在具身智能项目里很常见。这类板卡通常预装 Debian 或 Ubuntu 桌面,可以直接安装对应发行版。需要注意的是,部分 ROS 2 包的预编译二进制在 ARM 上可能缺失,需要源码编译。交叉编译可以加速,但坑不少——网上常见的问题比如“在 x86 电脑上给 ARM 设备交叉编译 ROS 2 功能包”,需要先准备好 sysroot 和交叉工具链,再逐包编译,工作量较大。我的建议是,能直接在板卡上编就在板卡上编,真交叉了再用交叉编译方案。
对于一键安装脚本,我的态度是:可以用,但要清楚它帮你做了什么。一键安装本质上是自动执行了官网安装步骤,省去手工敲命令。如果你是一个刚接触 ROS 2 的新手,为了效率用一下无妨;但至少要在装完之后,知道 setup.bash 在哪里、CYCLONE_DDS_URI 是什么、rosdep 是用来干什么的。否则后续遇到环境问题,排查会非常困难。
4. 常见问题与排查技巧实录:装完用起来最容易卡住的几个坑
4.1 版本不匹配:Ubuntu 24.04 安装 ROS 2 时 apt 源选错
Ubuntu 24.04 只能在官方源里找到 Jazzy,没有 Humble。如果你尝试把 Humble 源硬加到 24.04 上,apt update 会报一堆 Release 文件不匹配的错,或者装到一半出现依赖崩溃。
排查方法很简单:执行 lsb_release -a 看系统版本,然后对照官方对应表选择发行版。如果项目必须用 Humble,那就老老实实装 Ubuntu 22.04,或者用 Docker 拉一个 ros:humble 镜像。不要试图强行移植,否则你会陷入“编译 ros-core 三小时,然后死在依赖上”的痛苦循环。
4.2 colcon build 编译报错:Python 版本、依赖缺失、交叉编译各种劈叉
colcon build 报错是 ROS 2 新手遇到最多的场景。典型几类错误:
| 报错特征 | 常见原因 | 解决思路 |
|---|---|---|
ModuleNotFoundError: No module named 'xxx' |
缺 Python 依赖 | pip install xxx 或 sudo apt install python3-xxx |
Could not find a package configuration file provided by "rclcpp" |
没有 source ROS 2 基础环境 | 确认 source /opt/ros/humble/setup.bash 是否执行 |
undefined reference to ... |
缺少系统库 | 检查 CMakeLists.txt 中的 find_package 和链接库 |
| 在你的工程用 Humble 写的代码,换到 Jazzy 上编译报错 | API 接口变更 | 先查迁移文档,再改代码,而不是硬编 |
还有人会碰到“同一个工程在一个版本上能编译,换另一个发行版就报错”的问题。这通常是因为 ROS 2 的 API 在不同版本间有调整,比如 rclcpp 的参数声明、create_client 的接口形式都有变化。我的建议是:项目级的代码尽量绑定固定发行版,升级发行版时除了迁移文档之外,最好跑一遍官方 demo 来确认基础接口没有变化。虽然工作量大,但这是长期维护绕不开的。
4.3 Gazebo、RViz2 启动黑屏、崩溃、渲染异常
Gazebo 或 RViz2 启动后黑屏,八成是显卡驱动或 OpenGL 环境问题。在虚拟机里尤其常见,因为虚拟显卡默认不支持某些 OpenGL 特性。解决办法:给虚拟机显存加大,开启 3D 加速;或者在启动前设置环境变量强制用软渲染(速度会慢,但能用)。在 NVIDIA 显卡机器上,先检查驱动是否装好,执行 nvidia-smi 看是否正常输出。
RViz2 打开后窗口空白、不发数据,另一个原因是 Fixed Frame 设置不对。比如机器人的 TF 只有 map、odom、base_link,但 RViz2 的全局固定坐标系被默认设成了 map,如果你还没启动 Nav2,map 这个坐标系根本不存在,画面自然一片空白。把 Fixed Frame 改成 base_link 或 odom,数据通常就刷出来了。
4.4 多机通信不通:DDS 默认配置的“看不见对方”
ROS 2 底层用的是 DDS,默认配置下同一局域网内的多台机器之间通信,会发现节点完全发现不了对方。这通常不是 ROS 2 的问题,而是 DDS 的发现协议走了组播,而路由器禁用了组播,或者不同机器用了不同的 DDS 实现。
解决方法有两种:一种是在所有机器上设置相同的 ROS_DOMAIN_ID,并确保它们的网卡能互相 ping 通;另一种是手动指定 DDS 的发现服务器地址。对于大多数开发场景,如果只是局域网调试,先把防火墙关掉或放行相关端口,再设置 ROS_DOMAIN_ID 一致,基本能解决。如果还不行,可以考虑统一安装 Fast DDS 并显式配置 FASTDDS_URI。
4.5 问题速查:一分钟定位“到底是谁的锅”
我整理了一份按“现象 → 原因 → 解决”组织的速查表,方便你排查时对照:
| 现象 | 可能原因 | 快速排查命令 / 操作方法 |
|---|---|---|
ros2 命令找不到 |
未 source 环境 | source /opt/ros/humble/setup.bash,或写入 ~/.bashrc |
ros2 topic list 只有 /rosout |
节点未启动或者通信域不一致 | 检查 ROS_DOMAIN_ID,确认节点运行中 |
colcon build 找不到依赖包 |
未安装依赖或未 source 依赖环境 | 使用 rosdep install --from-paths src -y |
| 话题有数据但界面不显示 | 坐标系或固定帧设置错误 | 检查 /tf 是否发布,调整 RViz2 Fixed Frame |
| Gazebo 加载模型崩溃 | URDF 引用过期或网格路径错误 | 用 check_urdf 验证 URDF 合法性 |
| Nav2 启动后机器人不动 | 底盘 cmd_vel 话题不匹配 |
ros2 topic info /cmd_vel 查看发布订阅关系是否成对 |
排查的本质,是把一个“不工作的系统”拆成一个个“独立的连接点”去检查。ROS 2 提供了大量调试工具,比如 ros2 node info、ros2 topic hz、ros2 topic bw、rqt_graph,找一个不工作的链路段,先看节点有没有在发,再看有没有人在收,再检查数据类型对不对,90% 的问题都能定位出来。
最后再说两句实在话
关于 ROS 2 是“超级乐高底座 + 通用连接标准”这件事,我自己的理解是:它并不替你解决具体业务问题,但它帮你把所有业务模块之间最麻烦的“连接”问题标准化了。你在一个项目里写好的驱动节点,换一个项目只要接口不变,拷贝过来就能用;社区里十几年前沉淀下来的经典算法包,直到今天依然能通过标准消息接入你的新系统。这种“一次封装,到处复用”的价值,真的会随着你参与的项目越多,体会越深。
尤其是做具身智能相关方向的朋友,我建议大家不要一上来就追着某个新框架跑。把 ROS 2 这套底座用熟,把话题、服务、动作、TF、URDF、colcon 这些基础颗粒吃透,你会发现后来接视觉、接机械臂、接导航、接语音,都只是在已有的“标准接口”上做组合。乐高积木的乐趣在于拼装的无限可能,而 ROS 2 把这套可能性留给了你。
