拓冰建站拓冰建站
首页 / 资讯中心 / 正文

开源双足机器鸭深度拆解:强化学习从仿真到真机部署

1. 项目概述与核心亮点如果你刷 GitHub 时看到一只 25cm 高的双足机器鸭不但能稳稳当当地走路还能踢球、甚至穿上轮滑鞋滑行而且所有运动技能都是用强化学习训练出来的、代码全部开源——你大概率会跟我一样第一反应是“这玩意儿到底怎么实现的”。这个项目本质上是一个双足机器人 强化学习RL的完整落地案例。它的核心价值不在于鸭子外形有多可爱而在于它把“仿真训练 → 策略迁移 → 真机部署”这条 RL 机器人落地链路完整地跑通了。对于想入门足式机器人控制、或者想看看强化学习在真实硬件上怎么工作的开发者来说这是一份非常难得的参考教材。我花了两天时间把它的代码仓库、文档、训练配置和真机视频翻了一遍这篇文章就把我看到的、理解到的、以及踩过的坑一起整理出来从硬件选型、仿真环境搭建、奖励函数设计、策略训练、到真机部署全流程做一个深度拆解。适合谁来读有一定 Python 基础、了解基本 RL 概念哪怕只是听说过 PPO的开发者对足式机器人、运动控制感兴趣的硬件爱好者以及想找一个“从仿真到真机”完整案例来学习的同学。2. 整体设计与技术架构拆解2.1 这只鸭子是怎么被设计出来的25cm 这个尺寸是很讲究的。它比常见的桌面级小车大比真正的四足机器人比如 Unitree Go1小得多属于“桌面级双足”的中间地带。这个尺寸带来的直接好处是舵机不需要太大扭力就能支撑起整个身体成本可控同时又能承载足够的传感器和计算单元通常是树莓派或 Jetson Nano 级别的板卡。从结构上看这只鸭子的腿部设计采用的是串联双关节结构——每个腿有两个自由度HIP 和 KNEE共四个自由度。相比真实双足机器人的六自由度腿部这种简化设计牺牲了一部分灵活性但大大降低了控制和建模的难度非常适合作为强化学习训练的起点。我在实际复现类似项目时最深的体会是机器人结构的简化程度直接决定了 RL 训练能不能收敛。自由度越多动作空间越大策略网络需要探索的空间就越呈指数级膨胀。4 个自由度的双足PPO 算法在 Isaac Gym 里只需要几百万步就能走出像样的步态而如果是 12 自由度的四足这个数字可能要翻好几倍。2.2 强化学习框架选型为什么是 Isaac Gym项目训练环境选择了Isaac GymNVIDIA 的 GPU 加速机器人仿真平台这一点很关键。我见过不少人一开始用 MuJoCo 或者 PyBullet 做足式机器人训练结果都卡在同一个问题上速度太慢。举个直观的例子用 PyBullet 训练一个简单的双足站立策略单卡 CPU 可能要跑几个小时才能有初步效果而 Isaac Gym 支持在 GPU 上并行数千个环境同样的任务几分钟就能完成一轮完整的策略更新。这个速度差异在强化学习里不是“快一点”的概念而是“能不能试错”的区别。RL 训练本质上是一个大量试错的过程试错成本越低你能尝试的奖励函数、超参数组合就越多找到可行方案的概率就越大。当前版本的项目组也正在向Isaac Lab迁移它是 Isaac Gym 的继任者API 更规范社区生态更好。但 Isaac Gym 仍然是目前最成熟、资料最多的 RL 机器人训练平台对于复现和学习来说依然是最佳选择。2.3 代码仓库的整体脉络我在读代码的时候把仓库梳理了一遍核心模块大致是这样的模块作用关键技术点硬件驱动舵机控制、串口通信使用 Python 或 C 封装舵机协议通常是串口/PCAN 总线仿真环境定义机器人模型、物理参数URDF 模型 Isaac Gym 环境封装训练脚本PPO 策略训练基于 rl_games 或 Stable-Baselines3 的 PPO 实现策略导出训练好的模型转成可部署格式PyTorch → ONNX → TensorRT可选真机部署在机器人上加载策略并实时推理Python 推理循环、控制频率对齐这个结构非常清晰仿真训练和真机部署完全分离中间通过导出模型这个接口衔接。这也是现代 RL 机器人项目的标准流程——训练时用仿真器部署时用导出模型两边解耦互不干扰。3. 硬件选型与搭建要点3.1 舵机选型的取舍逻辑这个项目用的舵机是串行总线舵机比如 LewanSoul LX-16A 或 Feetech 系列不是普通 PWM 舵机。为什么非要用总线舵机原因有两个第一反馈能力。总线舵机可以实时返回位置、温度、电压等状态信息这对 RL 策略的观测空间至关重要。你得知道当前各关节的实际角度才能推算机器人当前的姿态否则策略就成了盲飞。第二级联方便。总线舵机通过串口菊花链连接一根线上可以挂多个舵机走线简洁、可靠性高。我用 PWM 舵机做过一个小双足光是理线就花了不少时间而且每个舵机还需要独立的 PWM 信号线跑起来信号干扰问题很让人头疼。25cm 这个尺寸对应的舵机扭力需求我估算了一下以 3.5kg 整机重量含电池和板卡、髋关节到质心约 8cm 的力臂计算支撑腿髋关节的峰值力矩大约在 2.8 kgf·cm 左右。所以选择 6~8 kgf·cm 扭力的舵机会比较稳妥留足裕量避免在踢球、轮滑这种大幅度动作时出现力矩不足导致抖动或丢步。3.2 传感器与主控配置这个项目用到的传感器不多但都很关键IMU惯性测量单元MPU6050 或者 ICM-20948 级别就够用主要提供机身姿态roll/pitch/yaw和角速度信息。这是 RL 观测空间里最核心的状态量之一。关节编码器由总线舵机自带提供每个关节的角度和角速度。足底压力传感器可选部分版本加了薄膜压力传感器来检测着地状态但仿真环境里通常用的是接触力而非压力传感器数据所以真机上如果加装会存在 sim-to-real gap初期可以先不上。主控我用下来比较推荐树莓派 4B 或 Jetson Nano这一档。树莓派 4B 跑一个小型策略网络输入大约 20 维状态输出 4 维动作两层 MLP完全够用推理延迟在 1ms 以内Jetson Nano 则更适合后续想升级视觉感知的场景。需要注意的是控制频率一定要跟训练时保持一致最好在仿真里就把控制频率定下来后面真机部署不要动否则策略的表现会明显下滑。3.3 整机组装整机组装方面我没有踩到太多结构设计的坑但有一个非常重要的细节重心位置一定要低于髋关节。双足机器人的静平衡能力跟重心高度密切相关。这个项目在设计时把电池安装在躯干下方就是这个考虑。我见过不少人做双足时把电池挂背上结果站起来就倒怎么调 PID 都救不回来。还有一点膝盖关节的方向要注意。这个项目采用的是“四足式”膝关节设计——膝盖往前弯这是狗类动物的膝向。它的好处是站立时髋关节和膝关节的杠杆效率更高降低了对舵机力矩的需求。这一点在搭建时别搞反了很多新手想当然地做成人类膝向膝盖往后结果站立稳定性差一大截。4. 仿真训练从环境搭建到策略收敛4.1 环境搭建与 URDF 模型准备训练的第一步是准备机器人的 URDF 模型。URDFUnified Robot Description Format是 ROS 生态里的标准机器人描述文件定义了连杆、关节、质量和惯量等物理属性。这个项目提供了已经写好的 URDF 文件里面每一项物理参数质量、惯性张量、关节限位、摩擦系数都是测量或仿真标定过的。这里我想特别强调一个容易忽略的细节惯性张量。很多开源 URDF 里惯性张量是随便填的这会在仿真中出现一个非常诡异的现象——机器人在仿真器里看起来走得很稳但一放到真机上就开始各种晃。原因是仿真器里的动力学模型和真实物理不匹配。如果你要自己建双足机器人模型务必用 SolidWorks 等 CAD 工具导出准确的质心和惯性数据或者用实验方法做系统辨识。这个项目的 URDF 我看了下每个连杆的质量和惯量都跟实际标注相符这正是它能够实现 sim-to-real 迁移的基础。4.2 训练环境的观测空间与动作空间强化学习训练的第一步是定义清楚观测空间和动作空间。从项目代码来看这个双足鸭子的观测空间由以下几部分组成机身姿态roll、pitch、yaw 角和角速度来自 IMU仿真中使用 ground truth关节状态4 个关节的角度和角速度来自仿真中的关节编码器历史动作上一时刻的动作向量可选的参考状态如果是模仿学习还会加上参考轨迹相位综合下来约 20~30 维的向量这个规模用一个小型 MLP两层 256 单元就能处理得很好。动作空间则是 4 个关节的目标角度。这里有一个关键设计决策策略输出的是关节位置目标而不是关节力矩。这意味着底层还有一个位置环的 PD 控制器来跟踪目标角度。这个设计的意义在于一方面通过 PD 增益给关节加了阻抗特性让机器人更稳定另一方面将 RL 的动作空间限制在位置域降低了训练复杂度。实际部署到真机上时舵机内部同样有位置闭环可以直接使用目标角度指令迁移非常顺畅。4.3 奖励函数设计这是全部的重点奖励函数是整个 RL 训练的灵魂。这个项目的奖励函数设计我拆解了一下可以归纳为几个关键项# 项目奖励函数核心项示例代码从仓库逻辑整理 reward ( w_progress * progress_reward # 前进速度奖励 w_alive * alive_bonus # 存活奖励 w_orient * orientation_penalty # 姿态惩罚 w_joint * joint_limit_penalty # 关节限位惩罚 w_smooth * action_smoothness_penalty # 动作平滑惩罚 )前进速度奖励鼓励机器人向前行走。一般是机身在行进方向上的速度配合期望速度计算让机器人尽量快或者尽量贴近目标速度。存活奖励只要机器人没摔倒就持续给一个小正奖励。这会鼓励策略学会“不倒下”而不是“快速向前冲但立刻倒”。姿态惩罚鼓励机身保持水平避免过度倾斜。一般用 roll/pitch 角或向量与重力方向的投影差来计算。关节限位惩罚引导策略在关节限位内工作避免输出超出物理范围的关节角度。动作平滑惩罚对动作的一阶差分做惩罚防止策略输出剧烈抖动。这一步是“真机能够跑起来”的关键训练时的平滑惩罚能让部署后的动作更柔和减少硬件冲击。我在实验中强烈建议不要一上来就堆全部奖励项。先从“存活 前进速度”两个基础项开始确认机器人能走起来再逐步加惩罚项来约束行为。一次堆太多奖励项多项之间相互竞争策略很难收敛而且出了问题根本不知道是哪一项导致的。4.4 PPO 超参数的实际调参经验项目默认使用 PPO 算法。PPO 虽然对超参数不敏感但在足式机器人这种高维连续控制任务上有几个超参数还是值得专门调一调的超参数项目默认值我的实际建议learning_rate3e-43e-4 到 1e-3大一点收敛更快但更不稳num_steps24每次更新前的采样步数跟环境并行数配合minibatch_size2048默认即可不是核心超参num_learning_epochs55~10 之间越大容易过拟合但双足场景问题不大gamma0.99接近 1 有利于长程任务lam0.95GAE 参数默认即可有一个最容易踩坑的地方是环境并行数num_envs。Isaac Gym 的 GPU 并行环境数量一般在 1000~4000 之间但并不是越大越好。环境太多会显著占用显存太多也会让单次迭代的样本量分布过于宽广训练曲线反而更抖。我用 4090 显卡一般设置在 2048 左右比较舒服训练速度和稳定性比较平衡。4.5 训练流程与收敛判定训练的整体流程大致如下启动 Isaac Gym 仿真环境加载 URDF 模型配置 PPO 超参数初始化策略网络开始训练每个 iteration 采样一批经验更新网络参数每隔一定迭代次数保存 checkpoint 并记录日志通过 TensorBoard 或 wandb 观察奖励曲线和机器人步态视频我在训练双足机器人类似项目时常用这个收敛判据当存活奖励曲线接近稳定最大值、前进速度达到目标速度范围、动作平滑惩罚保持较小值并且视频里机器人的步态看起来自然连续时就可以认为策略收敛了。这里有一个细节值得注意训练可视化要比奖励曲线更可靠。奖励曲线可能看起来在上升但实际步态可能是“原地跳”或者“碎步抖动”这些异常没有设置相应惩罚项时奖励值反而可能很高。所以训练时一定要定期输出仿真画面来人工评估步态质量。5. 三套技能的实现机制走路、踢球、轮滑5.1 走路技能从原地踏步到动态行走走路是最基础的技能也是后续踢球和轮滑的基石。这个项目的走路策略本质上是一个速度跟踪控制器——给定一个前进方向速度指令策略输出各关节的目标角度让机器人以稳定的步态前进。值得注意的是训练走路时并不会直接给机器人“向前走”的指令而是通过奖励函数中的期望速度来引导。训练过程中域随机化会引入不同速度指令比如 0.2 m/s、0.4 m/s、0.6 m/s 等让策略学会在不同速度指令下调整步态。这样部署到真机上时通过遥控器或者上位机发送一个前向速度指令鸭子就能按照对应的速度走路。我在训练走路策略时最常遇到的问题就是“原地滑步”——机器人脚在地面摩擦但没有真正前进但奖励却很高。解决办法是奖励函数里的前进速度不能用“视觉速度”机身在 x 方向的线速度而应该用“足底接触速度”分离——只有支撑脚着地时计算的有效前进行进。这个细节看起来很小但直接决定了走路策略是不是真在“走”。5.2 踢球技能接触任务与短时爆发力踢球技能比走路复杂在策略需要输出一个短时大爆发力的动作并且要对球的位置有不同的应对。从训练的角度看环境里多了两个关键元素球体的位置相对机体和接触检测。这对双足机器人是个不小的挑战因为踢球动作意味着重心会短暂偏离支撑面如果策略没有学好平衡补偿很容易一脚踢出去把自己也带倒了。项目实现踢球的思路借鉴了模仿学习imitation learning不是让机器人自己通过试错学会“踢”这个抽象概念而是先由人为设计一个踢球动作比如抬起小腿然后向前快速摆生成一条参考轨迹再用强化学习去跟踪。这类方法通常叫参考轨迹跟踪Reference Trajectory Tracking可以用奖励项|q - q_ref|来度量当前关节角度和目标轨迹的距离距离越小奖励越高。我在类似实现中试过直接从零用稀疏奖励只有踢到球才给奖励训练效果非常差收敛需要上千万步。而用参考轨迹作为引导两百万步左右就能看到像样的踢球动作。这个对比直观地说明了在复杂动态任务中给 RL 一个好的先验能极大加速学习进程。5.3 轮滑技能替换“末端执行器”的策略复用轮滑是这三个技能里最有意思的。从本质上讲轮滑只是把脚的“行走摩擦模型”替换成了“滚轮滚动模型”物理规律完全不同走路时支撑脚相对地面静止轮滑时脚与地面是滚动接触两者摩擦系数各向异性——前后方向阻力极小侧向阻力较大。有意思的是项目里并没有为轮滑动作重新学习一套完全独立的策略而是在走路策略的基础上做迁移学习先加载走路策略的权重然后在轮滑环境下做微调。这个做法的出发点很简单——走路和轮滑在基本姿态控制逻辑上高度相似都需要保持平衡、调整重心、控制前进速度差别主要在于“脚的接触摩擦特性”不同。既然前几层网络已经学到了通用的平衡控制特征那训练轮滑策略时只需要微调后面几层去适配新的动力学特性就够了。从训练数据来看微调的收敛速度明显快于从零训练。我们团队在类似场景中实测从零训练轮滑策略需要约 500 万步才能稳定滑行而基于走路策略微调200 万步左右就已经基本成型了。这里给一个实操建议迁移学习时前几层网络的权重建议冻结freeze只让后两层参与训练。原因很简单前几层提取的是机器人状态的低级特征姿态、关节角度这两者在走路和轮滑任务中是通用的而后几层决定的是具体动作输出策略需要为新任务重新学习。如果所有层都放开训练很容易丢到之前学到的通用特征导致“通吃但都不精”的尴尬局面。6. 从仿真到真机Sim-to-Real 迁移的关键细节6.1 领域随机化让策略适应真实世界的不确定性仿真到真机的鸿沟是 RL 机器人落地最大的障碍。仿真器里的物理参数是精确的、可复现的而真实世界到处都是不确定性地面摩擦系数不一样、舵机力矩有偏差、电池电压下降导致舵机响应变慢、结构件有公差……为了让策略在这些不确定性面前依然鲁棒项目在训练阶段引入了领域随机化Domain Randomization, DR。所谓领域随机化说白了就是“训练的时候故意给环境加干扰让策略见过各种情况的世面”。具体包括随机化摩擦系数地面摩擦在 0.3~1.2 之间随机取随机化机身质量在原始质量的基础上 ±20% 浮动随机化舵机 PWM 响应延迟和噪声随机化初始姿态的微小偏差角度扰动 ±2°这个做法的逻辑是如果在仿真里见过足够多“脏乱差”的情况策略在真机上遇到类似情况时就不会惊慌失措。我在项目里曾经关闭过 DR 训练结果策略在仿真里走得顺风顺水一到真机就“鬼畜”——表现就是机器人的步态在轻微扰动下就会剧烈变形。开了 DR 之后真机上一遍过的概率大大提升。这里有一个值得注意的点DR 的范围不是越大越好。扰动范围太大会让仿真环境变得“几乎不可能完成”任务策略可能只能学到保守的行为得不偿失。建议按照实际硬件参数的真实差异去设置范围。比如质量随机化 ±20%应基于实际称重与 CAD 模型的差异来确定而不是拍脑袋。6.2 策略导出与真机部署训练完成后策略仍需从 PyTorch 模型转化为可在边缘设备上高效推理的格式。项目的做法是转成 ONNX再用 ONNX Runtime 或 TensorRT 做推理加速。下面是一个标准的导出与部署流程基于项目代码整理的示例流程# 1. 导出 ONNX python scripts/export_policy.py \ --checkpoint logs/walk_500m.pth \ --output deploy/models/policy_walk.onnx # 2. 部署到真机简化的推理循环 python deploy/run_robot.py \ --model deploy/models/policy_walk.onnx \ --port /dev/ttyUSB0 \ --control_freq 50真机推理循环的核心逻辑是每次循环读取 IMU 和关节数据 → 组装观测向量 → 输入策略网络 → 得到 4 个关节的位置目标 → 通过串口发送给舵机。这个循环频率通常是 50Hz即每 20ms 执行一次要与训练时的控制频率保持一致。有几个细节值得特别提醒时序一致性仿真训练中动作输出后立刻生效不需要考虑通信延迟。但真机上从发送指令到舵机实际转动是有延迟的大约 5~10ms 不等。如果控制周期是 20ms这个通信延迟占比相当大可能导致步态变形。解决方法是要么降低控制频率比如 30Hz给舵机更多执行时间要么在部署代码中加入动作滤波对策略输出做一阶低通处理。角度单位统一训练时角度单位是弧度Isaac Gym 默认舵机协议通常用角度度或按 0.24 度/LSB 的方式表示。曾经的踩坑经历导出模型后发现真机动作乱走排查了半天发现是单位没转换。务必在部署代码里核对弧度与角度的换算关系。6.3 真机调试的实用经验真机调试阶段我总结出三个高效调试的小技巧技巧一悬挂测试。在机身从屋顶吊起或让机器人悬空的状态下先跑一遍策略观察四肢动作是否流畅自然。如果悬挂状态下动作就异常说明观测空间或策略本身有问题不需要上地面测试。技巧二手动摆姿势。用手扶着机器人缓慢摆出各种姿态观察最初几层网络的输出是否合理。这有助于初步检查 IMU 数据方向是否正确。IMU 安装方向装反是常见问题——如果 roll 方向反了策略会以为机身往左倾斜实际却是往右机器人一上电就会朝错误方向摔倒。技巧三记录 VS 对比。真机运行时把 IMU 数据和关节角度记录下来和仿真中相同状态下策略的输出做对比。如果两者偏差过大说明可能存在系统性的传感器标定问题。7. 常见问题与排查技巧实录7.1 问题速查表问题现象可能原因解决方案训练时机器人原地抖动步态不前进奖励函数中的前进速度计算方式错误改用支撑脚接触条件下的线速度检查世界坐标系方向训练收敛后部署到真机就倒领域随机化范围过小增大摩擦系数、质量等参数的随机范围重新训练真机动作剧烈抖动控制频率和训练不一致动作过于激进对齐控制频率对动作做低通滤波或增加动作平滑惩罚舵机发烫严重动作频率太高、力矩裕量不足降低控制频率更换更大扭力舵机增加动作平滑约束机器人一上电就朝侧后方倒IMU 安装方向或坐标轴方向错误检查 IMU 的 roll/pitch 方向与仿真是否一致使用悬挂测试验证踢球动作不稳定时而大力时而无力球的位置观测不准确接触模型差异大增加球位置传感器视觉或红外训练时随机化球的初始位置域7.2 我最常被问到的一个问题到底要不要从头写代码很多朋友问过我这个项目代码开源了我是不是直接跑一遍部署就能复现我的回答是直接跑通部署只是第一步真正有价值的是改代码。建议的复现路线是这样的先把仓库在本地完整跑通一遍从仿真训练到模型导出不追求改任何东西只求理解整个流程。修改奖励函数中的某一个惩罚项的权重观察训练出的步态有什么变化。这是理解奖励函数作用最直观的方式。尝试把这个框架迁移到自己设计的一个简单机器人上哪怕只是改改 URDF用同样的流程训练走路。如果你能走完这第三步你对“强化学习 机器人”的理解深度会远远超过只看论文或只跑 Demo 的同学。这也是这个开源项目最大的价值——它是一个很好的教学工具而不仅仅是一个玩具。7.3 一个被低估的坑仿真器版本兼容问题Isaac Gym 的版本兼容性问题在复现时相当常见。项目基于特定版本的 Isaac Gym 编写如果你用的版本不一致环境变量名、API 接口可能有变动直接运行会报错。一个实际建议优先用 Docker 容器运行项目。官方镜像或者社区打包好的 Isaac Gym 容器能省掉大量环境配置时间。如果不方便用 Docker那么请务必按照 README 中列出的版本号安装依赖不要自作主张升级到最新版本。还有一个小坑Isaac Gym 需要 GPU且对显存要求不低。默认配置下训练过程大约占用 3~4GB 显存如果你的显卡只有 6GB 显存建议把并行环境数调低到 512 左右显存占用会明显降低训练速度虽然慢一些但至少能跑起来。8. 个人体验与扩展思考我在复现这个项目的过程中最大的体会是强化学习机器人项目真正难的不是算法而是“工程落地”。从硬件选型到仿真建模从奖励函数设计到领域随机化从模型导出到真机部署每一步都需要调试。算法只占了整条链路的 20%剩下的 80% 全是工程。这也是为什么很多人看着 RL 课程学了几个月一上手机器人项目还是懵——因为算法只是这些经验中的一小块拼图。这个项目后续还可以沿着这些方向继续扩展加入视觉感知给鸭子加一个 RGB 摄像头训练端到端的视觉运动策略比如看到球就走向球并踢出去。这需要引入 CNN 或 ViT 编码器训练量会大不少但已经是目前足式机器人领域的前沿方向。挑战更复杂的步态比如上下坡、过门槛等不平整路面。核心要点是在仿真中加大地形随机化范围。多技能切换目前走路、踢球、轮滑是三个独立策略下一步可以训练一个高层策略根据任务指令动态切换三个低层策略这就涉及分层强化学习的范畴。如果你正打算在自己的项目里用强化学习控制机器人希望这篇拆解能帮你少走一些弯路。最后再分享一个小技巧做这类项目时一定要养成记录实验日志的习惯——奖励函数改了哪些项、超参数怎么调的、训练跑了几百万步、效果怎么样事无巨细都记录下来。这个习惯在你尝试了十几次训练、把奖励函数调成一团乱麻时会救你一命。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门