想基于宇树机器人做二次开发,路径该怎么走
- 按「你要做哪一类事」把几十个宇树开源仓库收敛成四条可执行的推进路线
- 分清每条路线上哪个仓库是入口、哪个是中途站、哪个可以先跳过
- 识别几个最常见的错误起点,避开硬件损坏与无效学习
机器人到了,箱子拆了,你打开 GitHub 上那个组织页面,然后愣住了。
五十多个仓库。SDK 有两代,ROS 有四个包,强化学习有三套,遥操作有三四个,还有一堆你连名字都读不顺的——unifolm-world-model-action、point_lio_unilidar、teleimager。每个仓库的 README 都写得挺认真,但没有任何一篇告诉你:你应该先看哪个。
开源仓库多,本来是好事。可当它们平铺在一个列表里、没有先后关系的时候,反而成了负担。你会陷入一种很消耗人的状态:每个都点开看两眼,每个都觉得"好像有用",两天过去,一行自己的代码都没写。
先说清楚这篇的边界:**本文基于公开仓库的文档与代码结构做梳理,没有真机验证。**所有关于"这个仓库做什么"的说法都来自它自己的 README 和目录组织,我不替上游承诺任何运行效果。这篇要解决的也不是技术问题,而是顺序问题——顺序错了,技术再好也是白费力气。
先回答一个问题:你要做的是哪一类事
不要问"我该学什么",问"我要交付什么"。这两个问题的答案完全不同。
把绝大多数需求拍扁,其实只有四类:
- 你要让机器人去做某件事——巡检一圈、跟着人走、到点了播报一句话、把摄像头画面传回来。机器人怎么迈腿你不关心,你关心的是任务逻辑。
- 你要研究机器人怎么迈腿——步态、平衡、力控、强化学习策略。你要动的就是控制器本身。
- 你要让机器人用手完成操作任务——抓取、装配、整理。这是具身智能那条线,核心是数据和策略。
- 你的团队已经在 ROS 上——有现成的建图、规划、感知栈,只想把这台机器接进去。
这四类的推进路径几乎没有重叠。**走错路线的代价不是慢一点,是完全白走。**一个只想做巡检应用的人,花两周去读 MPC 的实现,读完了对交付没有任何帮助;反过来一个要做控制研究的人,只学高层运动接口,压根碰不到他要改的东西。
下面四条路线,各自给出仓库顺序和理由。
路线 A:做应用——巡检、导航、跟随、交互
这是需求量最大的一类,也是最容易被带偏的一类。
核心原则只有一条:从高层接口进,别碰低层。
厂商的运动控制器已经解决了这条路上最难的部分——怎么在不平地面上不摔倒。你要做的是在这个能力之上写业务逻辑,而不是重新发明它。高层与低层控制的边界这篇专门讲了这条线画在哪儿,做应用之前值得先看一遍,因为它决定的其实是责任归属:你调高层接口,摔倒了是控制器的事;你自己发关节指令,摔倒了是你的事。
建议顺序
第一站,把通信跑通。unitree_sdk2 的 example/helloworld/ 里只有 publisher.cpp 和 subscriber.cpp 两个文件,跟机器人毫无关系,就是一个纯粹的 DDS 收发示例。它放在那儿是有意的——先确认你的机器能和机器人通上话,再谈别的。这一步卡住的人比你想象的多,而且卡的往往不是代码,是网口和网段配置。
**第二站,用高层运动接口。**在 SDK 的型号目录下,四足型号的运动模块叫 sport,人形型号的叫 loco,每个能力模块都是 xxx_api.hpp / xxx_client.hpp / xxx_error.hpp 三件套。这个规整程度意味着你学会一个就学会了全部,unitree_sdk2 架构拆解里把这套分层讲透了。如果你更习惯 Python,unitree_sdk2_python 的接口与 C++ 版保持一致,Python 接口那篇说明了它是怎么对齐的。
第三站,接感知与导航。unitree_slam 这个仓库很值得单独看它的示例目录:
unitree_slam_example/
start_mapping.cpp end_mapping.cpp —— 建图的开始与结束
start_relocation.cpp pose_init.cpp —— 重定位与初始位姿
start_nav.cpp pause_nav.cpp —— 导航启停
recover_nav.cpp return_origin.cpp —— 恢复与返回原点
single_nav.cpp multiple_nav_default.cpp
multiple_nav_set.cpp —— 单点与多点导航
add_node.cpp delete_node.cpp query_node.cpp
add_edge.cpp delete_edge.cpp query_edge.cpp —— 拓扑图的点与边
demo_h1.cpp demo_b2.cpp
demo_mid360.cpp demo_xt16.cpp
把这份清单读一遍,一个巡检应用该怎么拆就出来了:建图 → 存图 → 重定位 → 按拓扑点位巡航 → 中途可暂停可恢复 → 结束返回原点。节点与边的增删查接口告诉你,路线不是写死的坐标序列,而是一张可以在运行时编辑的图。这些原语就是你业务逻辑的积木,SLAM 与导航栈那篇展开讲了它的组织方式。
另外注意这个仓库自带了一份 unitree_robotics/include/unitree/common/dds/ ——和 SDK 里那套 DDS 封装是同源的。整个体系的通信底座是统一的,这不是巧合,是设计。
**第四站,才是写你自己的业务逻辑。**到这一步你已经有了"能动、能定位、能巡航"三块能力,剩下的就是普通软件工程了。
一句提醒
做应用的人最常见的冲动是"我自己写个控制器肯定更贴合我的场景"。从工程角度看,这个判断在九成情况下是错的——你增加的是自己的责任面积,减少的是可用时间。真到了高层接口确实满足不了的那天再下沉,而且是只下沉那一个环节。
路线 B:做控制或算法研究
这条路线的规则是反过来的:你必须下到低层,而且必须先在仿真里做。
低层意味着你直接发关节指令、直接读关节状态。控制器的稳定性从此归你负责,一个符号写反,机器人可能就是硬件损伤。这不是吓唬人,这是这条路线的入场费。
建议顺序
第一站,把仿真环境跑起来。unitree_mujoco 是基于 unitree_sdk2 和 MuJoCo 做的模拟器,README 里写它的目的是让用 unitree_sdk2、unitree_ros2、unitree_sdk2_python 写的控制程序能直接接进来。仓库分成几块:
simulate/ —— C++ 版模拟器(README 标注为推荐)
simulate_python/ —— Python 版模拟器
unitree_robots/ —— 各型号的 MJCF 描述文件
terrain_tool/ —— 生成仿真地形的工具
example/ —— 示例程序
这里有个必须留意的说明:README 明确写了当前版本只支持低层开发,主要用于控制器的 sim to real 验证,支持的消息是 LowCmd、LowState、SportModeState、IMUState 这几类。也就是说它不是给你测高层业务逻辑用的,它就是为这条路线准备的。terrain_tool 的存在也印证了这一点——会去关心地形生成的,只有做步态和平衡的人。MuJoCo 仿真环境那篇拆了它的内部结构。
第二站,读一份传统控制的完整实现建立直觉。unitree_guide 是配套一本四足机器人控制算法书籍的开源工程,依赖 unitree_ros 和 unitree_legged_msgs,在 Gazebo 里跑。它的价值不在于你要用它上线,而在于它把状态估计、步态生成、平衡控制这些模块用可读的代码摆在了一起。先有这份直觉,再去看强化学习,你才知道那个神经网络到底替代了哪些模块。unitree_guide 与 MPC 那篇对它做了逐模块的拆解。(该仓库 README 推荐的系统与 ROS 版本偏老,以官方仓库当前文档为准。)
**第三站,进训练框架。**这里有三套并存,选哪套取决于你的仿真后端:
unitree_rl_gym —— 入门路径最短的一套,任务定义清晰
unitree_rl_lab —— 构建在 Isaac Lab 之上,README 写当前支持 Go2、H1
以及 G1 的一种关节配置
unitree_rl_mjlab —— 构建在 mjlab 之上,以 MuJoCo 为物理后端,
README 列出的支持范围更宽
新手从 unitree_rl_gym 开始最省事,强化学习环境那篇讲了它的观测、奖励与任务是怎么组织的。三套的存在本身说明一件事:仿真后端不是唯一的,训练框架也不是唯一的,选型的时候你要考虑的是团队现有的 GPU 环境和熟悉度,而不是哪个"更先进"。
**第四站,sim2sim 再 sim2real。**训练出的策略先在另一个仿真器里验一遍,是很多团队的惯例——同一套策略在两个不同物理引擎下都稳,说明它没有过拟合到某个引擎的数值特性。跨过这一关再考虑真机,从仿真到真机那篇讲了中间这段落差从哪儿来。
一句提醒
这条路线上,仿真跑通不等于真机安全。真机验证要有吊装、有急停、有人手扶,并且第一次一定是小幅度动作。这些流程不写在任何 README 里,但它们是这条路线真正的门槛。
路线 C:做具身智能与操作任务
这条线的逻辑和前两条都不一样:数据是核心资产,遥操作是采集手段,策略是数据的函数。
你不是在写控制律,你是在建一条数据流水线。
建议顺序
第一站,把遥操作系统搭起来。xr_teleoperate 用 XR 设备做人形机器人遥操作,它把职责拆给了两个配套仓库:televuer 负责 XR 端的视觉与手部/手柄追踪接口(README 里提到它适配了多种 XR 设备),teleimager 是图像服务端,从多路相机取流并通过 ZeroMQ 或 WebRTC 发出去。这个拆分很清楚——视觉输入、图像传输、机器人控制是三件事,XR 遥操作那篇讲了它们怎么拼在一起。
仓库里的 assets/ 目录也值得看一眼,里面按不同灵巧手和机器人本体分了子目录,各自带 URDF 与网格文件。这说明遥操作的映射不是通用的,换一只手就得换一套描述。
**第二站,采数据,然后处理数据。**采集环节的产出直接决定后面训练的上限。unitree_lerobot 的 README 里专门讲了数据处理这一步——它做了一个数据编辑器,用来裁掉 episode 里多余的片段、删掉失败的 episode。这个细节很实在:真实采集里失败的轨迹一定存在,不清理就会污染训练。
第三站,格式转换与训练。unitree_lerobot 是在 LeRobot 框架基础上改的,目录分工是:
lerobot/ —— 训练用的上游框架代码
utils/ —— 宇树的数据处理工具(格式转换在这里)
eval_robot/ —— 真机推理验证
三个目录对应三个阶段:转格式、训练、验证。LeRobot 与模仿学习那篇讲了这条链路的接缝在哪里。
第四站,如果你要走更大的模型。unifolm-vla 是 UnifoLM 家族的视觉-语言-动作框架;unifolm-world-model-action 走的是世界模型路线,README 描述它的世界模型有两个用途——作为交互式模拟器生成合成数据,以及连上动作头做策略增强。这两个仓库门槛明显更高,不建议作为起点,等你手上已经有一批自己采的数据、跑通过一次完整训练之后再来。
第五站,部署前先在仿真里验。unitree_sim_isaaclab 是基于 Isaac Lab 的仿真环境,它有一条说明必须记住:启动后它会收发与真机相同的 DDS 话题,所以如果同一个网络里还有真机在跑,你要小心区分。这个坑很隐蔽,出事的时候你会以为是策略有问题。
路线 D:走 ROS 生态
如果你的团队已经有成熟的 ROS 技术栈——现成的建图、规划、行为树、可视化流程——那你根本不需要从 SDK 从头搭,直接从这条线进。
四个包,用途完全不同,别搞混:
unitree_ros —— Gazebo 仿真包,含大量机器人描述文件
unitree_ros2 —— ROS2 支持,直接用 ROS2 msg 通信
unitree_ros_to_real —— ROS1 到真机(面向早期 SDK 与型号)
unitree_ros2_to_real —— ROS2 到真机(面向早期 SDK 与型号)
**unitree_ros2 是这条路线上最值得先看的一个。**它的 README 讲清了一件事:宇树 SDK2 的通信基于 CycloneDDS,而 ROS 2 的通信底层也是 DDS,所以两边可以直接对上,不需要再包一层 SDK 接口。这是整条路线成立的技术前提,ROS 2 桥接那篇展开讲了这个对接关系。
unitree_ros 那边有一句提醒不能漏:README 明确说 Gazebo 仿真做不了高层控制(也就是走路),只能做低层的力矩、位置、角速度控制。很多人在 Gazebo 里试着发高层指令没反应,就是撞在这句话上。
至于 unitree_ros_to_real 和 unitree_ros2_to_real,它们的 README 里绑定的是较早的 SDK 版本与型号。先确认它和你手上的机器是不是一个时代的东西,再决定要不要投入时间。
无论走哪条路,都绕不开的三件事
四条路线的入口不同,但有三块地基是共用的。
**第一,通信机制。**宇树这套体系从 SDK、仿真器、SLAM 接口到 ROS 2 桥接,底座都是 DDS。unitree_slam 仓库里自带的那份 DDS 封装头文件和 SDK 里是同源的,unitree_sim_isaaclab 收发的是和真机一样的话题——这些不是各自为政的项目,是同一张网上的不同节点。理解 DDS 的话题、QoS 和发现机制,是所有路线的前置条件,DDS 通信机制那篇专门讲这块。不理解它,你后面遇到的每一个"收不到数据"都会变成玄学。
**第二,高层与低层的边界。**这条线决定的不是"能不能",而是"出了事算谁的"。调高层接口,你在厂商的安全网内;发低层指令,安全网就是你自己写的。SDK 里 high_level/ 和 low_level/ 分成两个目录,不是随手分的组织方式,是责任的分界线。
**第三,仿真先行。**四条路线里有三条的第一步都应该是仿真。哪怕你做的是应用层、只调高层接口,先在仿真里把状态机跑一遍也比直接上真机安全——仿真里犯的错误只花时间,真机上犯的错误花钱。
给团队的建议
从工程角度看,有三件事值得在第一周就定下来。
把 SDK 调用隔离在一层接口后面。unitree_sdk2 的 example/state_machine/ 示例本身就是这么组织的:robot_interface.hpp 单独一层包住 SDK 调用,user_controller.hpp 放自己的逻辑,state_machine.hpp 管模式切换,参数走 params/params.json 而不是硬编码。这个分层可以直接照抄。它保护你的是未来——换型号、换通信方式、从仿真切真机的时候,你只需要动 robot_interface 那一层,业务代码一行不用改。
**先用高层跑通端到端,再针对瓶颈下沉。**不要一上来就设计"完美架构"。先让机器人从 A 走到 B 并把结果上报,这条链路通了,你才知道真正的瓶颈在哪儿——它常常不在你以为的地方。可能是网络抖动,可能是定位漂移,也可能只是日志没打全。发现了具体瓶颈再下沉到低层,这时候的下沉是有依据的。
**安全流程第一天就建立。**急停位置、断电流程、测试场地的清空标准、谁能上手谁不能、真机测试必须两人在场——这些规矩要在还没出事的时候写下来。出事之后再补的流程,成本是硬件加信心。
几个常见的错误起点
**一上来就读最底层的代码。**很多人打开 SDK 的第一件事是去翻 include/unitree/common/dds/ 底下那十几个头文件,想"彻底搞懂"。这是最低效的路径。正确的顺序是先跑通最简单的示例,让机器动起来或者让一条消息通起来,建立正反馈,再带着具体问题回头读实现。带问题读代码和无目的读代码,效率差一个数量级。
**跳过仿真直接上真机。**理由通常是"仿真配置太麻烦""跟真机差别很大所以没意义"。前半句是真的,后半句是错的。仿真拦下的从来不是那些精细的动力学差异,它拦的是符号写反、单位搞错、数组索引越界这类低级错误——而这些错误在真机上的代价,可能是一次实打实的硬件损伤。
**想着"先把所有仓库都看一遍"。**不可能,也没必要。五十多个仓库里,与你当前目标相关的通常不超过五个,剩下的在你需要之前看了也记不住。收藏夹不是知识,跑通的代码才是。
**在错误的抽象层上花时间。**做应用的人研究步态生成,做控制的人纠结业务状态机——这是最隐蔽的一种浪费,因为过程中你确实在学东西,只是学的不是你现在需要的东西。
一个最小可行的开始
如果你今天刚拿到机器,不想再做任何选择题,那就按这个顺序来。
**第一步,把网络通了。**这是所有路线的零号前提。unitree_slam 的 README 里那行示例命令要传网口名(比如 eth0),这个细节提醒你:网口和网段配置是实打实的一环,不是可以跳过的杂事。
**第二步,跑 helloworld。**纯 DDS 的收发示例,不涉及任何机器人动作。收到消息的那一刻,你才真正确认了链路是通的。
**第三步,装仿真。**按你的路线选 unitree_mujoco 或 unitree_ros。这一步会花掉一整天甚至更久,忍住不要跳过。
**第四步,在仿真里跑通一个官方示例。**不改一行代码,先让它按原样跑起来。这是你的基线,后面所有问题都要和这个基线对比。
**第五步,改一个参数,看变化。**改速度、改目标点、改一个增益,观察结果。从"能跑"到"能改",才算真正上手。
**第六步,才是写你自己的第一段逻辑。**而且第一段逻辑应该短到二十行以内。
走到这里,你会发现之前那五十多个仓库的列表不再让人焦虑了——因为你已经知道自己在哪条路上,也知道下一个要打开的是哪一个。剩下的仓库不是没用,它们只是还没轮到。
这一卷把这些仓库逐个拆开讲过,卷 U 的文章列表按主题分好了组,你可以顺着自己选定的那条路线依次读下去。如果你连机器人的基本构成都还没摸过,建议先绕道机器人与具身智能卷,用一台小车把电机、传感器、控制回路这几件事亲手过一遍——那之后再回来看这四条路线,你会清楚得多。
本文为公开资料整理,非亲测。关键参数与代码请结合实物与下列官方来源验证。