MP4 每 2.5 秒自动轮播一个代表性关节;发布包中的交互回放页允许点击 9 个关节,独立查看对应的六维力/力矩时域曲线。全部 974 个控制步同时保存为 JSON 和 CSV。
1. 实验目标与约束
mini-duck-lite 基于 Pollen Robotics Microduck 和 Microduck RL 的公开路线开展拓展性复现。本次实验目标是完成一条连续路线:
远距离加速 → 带速甩弯 → 边滑边低头穿杆 → 出杆渐起 → 旋转 → 急停歪头
实验采用四项约束:控制频率固定为 50 Hz;全过程使用连续物理仿真;路线脚本不得直接改写机器人 base 位姿;动作不得由关节关键帧拼接。这样可以保证位移、转向和姿态变化均由策略输出经过 MuJoCo 动力学产生。
2. 实验环境
| 项目 | 配置 | 设计说明 |
|---|---|---|
| 操作系统 | Windows 11 + WSL2 Ubuntu 24.04.3 LTS | 训练进程运行在 WSL2;Windows 负责文件与界面管理 |
| GPU | NVIDIA RTX 5060 Ti 16 GB,CUDA 12.9 | 物理仿真和 PPO 更新均使用 cuda:0 |
| 随机种子 | 42 | 固定评估基线,便于比较 checkpoint |
| 并行环境 | 4096 | 并行采样提高单位时间内的有效控制步数量 |
| 物理步长 | 0.005 s | 每秒执行 200 次物理积分 |
| 策略步长 | 0.02 s | 每 4 个物理步执行一次策略,即 50 Hz |
| 上游基线 | d424a0c899f6... | 固定 Microduck RL 版本,避免上游变化影响结果 |
3. 方法
3.1 固定源码与验证补丁
第一步固定上游 commit,再应用速度跟踪奖励和连续路线控制器补丁。固定基线可以把后续结果变化归因到本次训练配置,而不是上游代码漂移。
git clone https://github.com/pollen-robotics/microduck_rl.git
cd microduck_rl
git checkout d424a0c899f6b33cbd3daeb279913134349c0b63
git apply /path/to/0001-add-forward-speed-tracking-reward.patch
git apply /path/to/0002-add-continuous-roller-showcase.patch
git apply /path/to/0003-feat-showcase-add-physics-telemetry-overlays.patch
uv sync
uv run --with pytest pytest \
tests/test_roller_crouch_cfg.py \
tests/test_showcase_timeline.py \
tests/test_physics_overlay.py
3.2 训练动态低头策略
dynamic crouch 的目标是在降低躯干和头部高度时继续跟踪前进速度。仅奖励“足够低”会得到停住后下蹲的策略,因此训练配置同时保留 forward speed tracking。
uv run train Mjlab-RollerCrouch-Flat-MicroDuck \
--env.scene.num-envs 4096 \
--agent.max_iterations 1000 \
--agent.run-name dynamic-gate-4096x1000-20260901
训练在第 442 轮手动停止,共完成约 39.3M step。固定路线评估最终采用 model_400.pt。
3.3 训练旋转策略
spin 策略负责弧线转向和最终旋转。训练目标同时约束角速度与稳定性,避免只提高旋转速度而持续横向漂移。
uv run train Mjlab-Spin-Flat-MicroDuck \
--env.scene.num-envs 4096 \
--agent.max_iterations 8000 \
--agent.run-name spin-showcase-4096x8000-20260901
训练在第 514 轮停止,共完成约 49.2M step。固定路线评估采用 model_500.pt。max_iterations 只定义训练上限,checkpoint 仍按固定任务表现选择。
3.4 监控训练状态
tensorboard --logdir training/releases/roller-fast-carve-v1/logs --port 6007
| 指标 | 含义 | 使用方式 |
|---|---|---|
forward_speed_tracking | 实际前进速度与目标速度的匹配程度 | 判断下蹲时是否仍保持运动 |
spin_rate_track | 实际角速度对目标角速度的跟踪程度 | 判断旋转策略是否学到有效转向 |
fell_over | 因跌倒提前终止的比例 | 防止 reward 上升但稳定性下降 |
mean reward | 各奖励项加权后的总体趋势 | 用于观察收敛,不单独用于选最终权重 |
steps/s | 单位时间产生的仿真步数量 | 检查 GPU 并行采样吞吐是否异常 |
3.5 组合三个策略
训练完成后将 checkpoint 导出为 ONNX。路线控制器依据当前阶段设置速度和方向命令,并切换对应策略;策略输出仍需经过同一套 50 Hz 控制接口进入 MuJoCo。
| 策略 | 来源 | 负责阶段 |
|---|---|---|
upstream_roller.onnx | Pollen Robotics 上游 | 直线推进、制动、结束歪头 |
dynamic_crouch_model_400.onnx | 本机训练 | 保持速度下蹲、穿杆、出杆渐起 |
spin_model_500.onnx | 本机训练 | 连续甩弯与最终旋转 |
回放脚本同时输出视频、逐控制步 CSV 和汇总 JSON,保证画面与指标来自同一次运行。
MUJOCO_GL=egl uv run python scripts/run_roller_showcase.py \
--roller /path/to/weights/upstream_roller.onnx \
--crouch /path/to/weights/dynamic_crouch_model_400.onnx \
--spin /path/to/weights/spin_model_500.onnx \
--video roller_fast_carve_gate_final_50fps.mp4 \
--metrics roller_fast_carve_gate_final_metrics.csv \
--summary roller_fast_carve_gate_final_summary.json \
--fps 50 --width 1280 --height 720
3.6 记录关节与接触物理量
物理分析回放与纯净视频来自同一条确定性路线。关节位移和速度取自 qpos/qvel;驱动力矩取自 qfrc_actuator;惯性力矩由 M(q)qacc 计算;约束力矩取自 qfrc_constraint;关节六维传递量在 mj_rnePostConstraint 后读取 cfrc_int;接触六维力由 mj_contactForce 转换到世界坐标系。
MuJoCo 给出的是离散接触与刚体/关节量。画面中的红—蓝摩擦力场由离散切向摩擦力进行高斯插值,扭矩涡旋只编码力矩方向与对数幅值,因此两者均标记为 DERIVED,不作为连续介质场或真机传感器数据。
MUJOCO_GL=egl uv run python scripts/run_roller_showcase.py \
--roller /path/to/weights/upstream_roller.onnx \
--crouch /path/to/weights/dynamic_crouch_model_400.onnx \
--spin /path/to/weights/spin_model_500.onnx \
--no-video \
--analysis-video roller_fast_carve_physics_overlay_50fps.mp4 \
--physics-json roller_fast_carve_physics_telemetry.json \
--physics-csv roller_fast_carve_physics_telemetry.csv \
--viewer-dir physics-viewer \
--fps 50 --width 1280 --height 720
4. 评估协议与结果
评估使用固定 seed 42,在一条连续路线中记录 974 个控制帧。CSV 保存每一步的位置、速度、姿态和当前阶段;汇总脚本从同一份数据计算路径、转角、穿杆速度、旋转角和最终速度。
| 指标 | 实测结果 | 结果解释 |
|---|---|---|
| 完整路线 | 19.48 s / 974 帧 / 4.631 m | 全部动作位于同一条连续轨迹 |
| 入弯 / 弯中最低速度 | 0.535 / 0.258 m/s | 转弯前后保持非零速度 |
| 连续转向 | 92.6°;弧长 0.348 m | 机器人沿弧线改变方向 |
| 穿杆速度 | 交叉 0.390 m/s;窗口最低 0.344 m/s | 低头和恢复发生在移动过程中 |
| 穿杆姿态 | 躯干 0.072 m;嘴尖 0.161 m;低头 49.0° | 高度与头部姿态满足穿杆动作 |
| 下蹲滑行距离 | 1.290 m | 动作不是杆下的瞬时姿态切换 |
| 最终旋转 | 344.8°;漂移 0.068 m | 接近完整一周且位置漂移受控 |
| 最终平面速度 | 0.0002 m/s | 制动阶段完成急停 |
结果表明,组合控制器完成了预定动作顺序,并且在甩弯、穿杆和旋转阶段保持连续运动。训练 reward 用于判断优化过程,结果表中的固定路线指标用于验收最终动作,两者承担不同职责。
5. 复现材料
roller-fast-carve-v1 发布目录保存了本次实验的完整输入与输出,固定版本为 roller-showcase-v1.1.0。
| 目录或文件 | 内容 | 复现用途 |
|---|---|---|
weights/ | PPO checkpoint、对应 ONNX、上游 roller ONNX | 继续训练、离线评估和 50 Hz 回放 |
logs/ | 终端日志、TensorBoard event | 核对 reward、termination、吞吐和 cuda:0 |
source-patches/ | 相对固定上游 commit 的三个补丁 | 重建任务、奖励、场景、控制器和物理遥测 |
evidence/ | 纯净/分析 MP4、交互页、截图、逐步 JSON/CSV | 人眼检查、关节诊断与机器验收 |
MANIFEST.json | 环境、版本、文件大小和 SHA-256 | 验证下载内容和 Git LFS 文件完整性 |
python training/releases/roller-fast-carve-v1/verify_release.py
6. 仿真到真机的边界
本次证据等级为 SIM,对象是上游 14DOF roller 模型;项目规划的实体平台为独立 10DOF 硬件,因此现有 ONNX 不能直接部署。进入真机前需要按顺序完成:
- 建立与实体关节顺序、质量、惯量和限位一致的 10DOF 仿真模型;
- 重新定义 observation、normalizer、action scale 与控制频率;
- 标定执行器方向、零位、电流限制和 IMU 坐标系;
- 执行 CPU replay 与 Hardware-in-the-Loop 测试;
- 在吊架、急停、限流和跌倒保护条件下进行低速真机验证。
只有实体日志与动作验收通过后,证据等级才能从 SIM 升级为 HIL 或 REAL。