IsaacLab Parkour是Extreme Parkour (Cheng et al., ICRA 2024) 的 IsaacLab 复现,在此基础上进行的新探索
以及IsaacLab→MuJoCo sim2sim 部署研究
| ID | 改动 | 关键参数 | 指标 | 判定 |
|---|---|---|---|---|
| A1 特权正则提前衰减 | 让 encoder 表征更早稳定下来, 不被持续的特权监督拖住 | priv_reg衰减提早 |
terrain 6.39 / base 5.18 | ✗ 短预算取巧 |
| A2 加大 goal 速度奖励 | 引导更强朝 waypoint 推进 | tracking_goal_vel1.5 → 2.5 |
terrain 5.77 | ✗ 弃用 |
| A3 抬熵系数 | 策略更倾向探索 | entropy_coef0.01 → 0.025 |
terrain 0.00 (训练崩) | ✗ 弃用 |
| A4 提升学习率 | — | learning_rate2e-4 → 5e-4 |
terrain 5.62 | ✗ 弃用 |
| A5 软化 collision | 容忍轻微碰撞换更激进通过姿态 | 碰撞惩罚-10 → -5 | terrain 6.39 | ✗ 弃用 |
| A6 Critic LN | critic 每层后插 LayerNorm (NeurIPS 2024 抗 plasticity loss) | — | waypoints 0.91 / base 0.90 | ≈ 不显著 |
| A7 Estimator detach | PPO 主回路切断 estimator 输出梯度 | — | waypoints 0.99 | ⚠ 事后推翻 |
| A8 Cosine latent | student 蒸馏加余弦损失, depth latent 对齐 teacher scan latent | 权重0.2, 3 seed | waypoints 0.80 → 0.87 | ✓ 正向倾向 |
| A9 ELU → SELU | 把激活函数换成 SELU (自归一化) | — | waypoints 0.90 | ≈ 无效 |
📌 4 种 parkour 地形并排: 训练侧 IsaacLab vs 部署侧 MuJoCo. 唯一变量是仿真器, 其余维度全对齐:
| 摩擦 μ | 0.4 – 1.9 (演示 1.0) | ckpt | 对应对齐 |
| 初始姿态 | 固定 / 随机 | waypoint 位置 | 对齐 |
| 地形尺寸 | 精确对齐 | 速度指令 | 对齐 |
训练 (PhysX) 和部署 (MuJoCo) 是两个不同物理引擎. policy 同一个, 但跑出来的轨迹常常不一样. 真正的工程量是把各个维度逐个对齐
| # | 对齐维度 | 状态 | 本质 / 备注 |
|---|---|---|---|
| 1 | DoF / Joint 顺序 |
✅ done | 关节编号映射. 错位则"左前腿指令"跑到"右后腿", 一动就翻车. |
| 2 | PD / 控制频率 / Decimation |
✅ done | 控制节奏 (sim dt / policy 周期 / delay). 对不上则快动作抖、慢动作卡. |
| 3 | Obs 753 维 · 五段布局 |
✅ done | 神经网络输入张量布局. 任一段错位整张读错, 后果不可预测. |
| 4 | Action Scale + Filter |
✅ done | 输出力度 + 滤波平滑. 太大乱抖、太小走不动, 滤波不一致响应滞后. |
| 5 | Contact / 接触动力学 |
🟡 部分 | 引擎差异 (MJ Coulomb vs PhysX TGS). sim2sim 最隐蔽杀手, 靠 per-box 重建 + DR 吸收. |
| 6 | Heightmap (Raycast / 几何) |
✅ done | 机器人看地面的眼睛. 高度图偏一点, 前面是坑变前面是地, 直接踩空. |
| 7 | Latency / 时序 |
✅ done | 时序延迟. 命令到转动有 delay, 不一致快一拍或慢一拍. |
📌 5 ckpt 主成绩单 + 平地基准 + 4 地形 × 6 摩擦切片. 数据来自 480-case 批跑.
progress = 机器狗在跑酷方向走过的距离, 除以整段路程长. 取值 0~1, 1 就是走到终点.
阈值 0.86 取自 8 个地形配置 (4 种 × 2 高度) 的实测下界 — 每个配置"刚跨过最后障碍"瞬时的 progress 落在 0.864 ~ 0.898 区间:
| 地形 | h scale | 跨过瞬时 progress |
|---|---|---|
| 🪨 parkour (踏石) | 0.08 | 0.876 |
| 🪨 parkour (踏石) | 0.10 | 0.864 ← 最低 |
| 🪜 step (上下阶) | 0.08 | 0.889 |
| 🪜 step (上下阶) | 0.10 | 0.884 |
| 🦘 hurdle (跨栏) | 0.08 | 0.886 |
| 🦘 hurdle (跨栏) | 0.10 | 0.875 |
| 🌉 gap (跳缝) | 0.08 | 0.893 |
| 🌉 gap (跳缝) | 0.10 | 0.898 ← 最高 |
综合取 0.86 作为通过标准
测试集: 1 个 ckpt 跑 4 地形 × 6 摩擦 × 2 关节扰动 = 48 case, 5 个 ckpt 合 240 case/仿真器. 难度 d=0.6, seed=42, episode 20 s. 原始数据 TSV (480 行) 在仓库 sim2sim/ 下.
只跑纯平面 + 各种参数 hardcode. IsaacLab 5 次取分布, MuJoCo 单次. teacher 50k 数据:
每种地形单独看, 哪种最难 (踏石 / 跳缝) 哪种最易 (上下阶).
pass% 是二元判定, student 10k 两个变体在 MuJoCo 上都接近 0%, 看不出谁更接近收敛. 引入 maxgoal (平均通过 waypoint 数, 满分 7) 这个连续计数区分 student 间差别.
teacher 在 MuJoCo 上前进速度锁在 0.65 m/s, estimator 估出来的速度比真值低 13–29%, 步态节奏不稳, 出现明显跳跃式触地.
scandot 采样栅格的 x 方向前向偏移设得不够, 132 个采样点的栅格盖在机身正下方而非机身前方; 向下发射的射线大量被自身腿部遮挡, 回传的"地面高度"实为"到腿顶的距离", scandots 整体失真.
把 scandot 栅格的 x-offset 调到与训练端一致, 让采样落在机身前方目标地形上; 射线起点同步从 5 m 抬至 20 m 对齐训练端规范. 修后 estimator 误差收敛至 +3%, 速度指令恢复线性跟随.
同一 policy, 在 IsaacLab 上四种跑酷地形通过率较高, 迁到 MuJoCo 后大幅掉点. 排除观测与动力学后, 定位到地形几何两端不一致.
对比脚本验证: 四地形几何 max 误差全 0.000, 训练端与部署端字节级一致. 同期修复三个细项: 格子与顶点 off-by-one 错位, 桥位置偏半个 gap, 地形高度配置参数被覆盖.
student 策略迁入 MuJoCo, 起步即栽倒, 无法越过第一块石头. 任何速度指令都不响应. 同 ckpt 的 teacher 在同地形 100% 通过, student 直接 0 通过.
配置文件写"相机俯角 70°", 字面理解为接近垂直俯视. 但训练端代码里有一步隐藏操作: 算完相机姿态后, 将其中一项翻转正负号. 该步执行后, 相机实际仅下倾 20°, 视野落在前方 3-5 m 地面.
部署代码未跟进此步, 按字面 70° 装相机, 实际接近垂直俯视, 仅能看到机身前 12 cm 一小片地面. 网络训练时见"远视野", 部署时输入"近脚下视野", 两套画面完全错位. 输出失常, actor 不敢迈步.
部署不再字面采用"70°", 改为完整复现训练端的相机姿态计算 (含翻转正负号步骤), 再转成 MuJoCo 的相机坐标格式. 验收: 单帧渲染, 视野中心应落在前方 3-5 m, 而非脚下 0.5 m.
student 在 4 个 parkour 地形: 修前 0 / 4 通过 → 修后 3 / 4 完整穿越. 机身高度 0.27-0.31 m 与训练端 0.26-0.34 m 接近, 步态恢复正常. 是项目中"配置字面值 ≠ 实际行为"最典型的一例.
📌 三例之外还有 33 项 silent bug, 按 6 层分类. 大头不在物理引擎, 在 obs / 几何 / cfg drift.
除上面 3 例, 整个项目还积了大概 33 项 silent bug, 按层分类:
| 分类 | 条数 | 典型例 |
|---|---|---|
| 几何 / 接触 | 7 | <mesh> 自动凸包 → 浮空 wedge / <hfield> off-by-one / per-box 重建避 wedge |
| 观测 pipeline | 7 | raycast miss token 符号反 / 相机 pitch 70° 实际 20° / depth buffer 旧帧 1 cycle 延迟 |
| 运行时 cache | 1 | friction cache 启动后不更新, CLI 覆盖 model 没覆盖 Python 端 |
| Metric pipeline | 7 | regex 缺正号丢行 / pass 阈值 cliff 漏算 / auto-reset 跨 episode 污染 |
| 测量窗口 | 4 | post-goal fall 拖死指标 / vx_mean plateau-stuck 时误读为"在走" |
| 训练 / 部署 cfg drift | 7+ | DR 漏抄 (质心扰动紧 10× / 电机增益注释掉) / hist_encoding 训练动态部署硬编码 / hscale 三层取整 |