DEEP 28 · 第三辑 · 训练代码 · LEARN NOTES

收进学习手册 · 2026-09-11 · duck.whatled.com

解读 28 · sitstand 配置:坐下与站立的对称性

解读对象:microduck-replica/upstream/microduck_rl/src/mjlab_microduck/tasks/microduck_sitstand_env_cfg.py(929 行)
需要的前置:解读 27(standup 的单方向课程)、总纲

在做什么

27 篇的 standup 只会站起来;这个文件把坐与站合成一个策略、两个方向:命令槽 twist 的第一维被征用为姿势标志——cmd = [sit_flag, 0, 0],0=站、1=坐,全零即部署时的怠速态(microduck_sitstand_env_cfg.py:1-8)。命令由 SitStandCommandCfg(:576)以停留时间 POSTURE_DWELL_S = (3.5, 6.5) 秒(:87)为周期重采样翻转,12 秒的一集(EPISODE_LENGTH_S = 12.0,:83)至少含一次完整「坐→歇→起→歇」循环。reset 状态(50% 站 / 50% 坐)与命令独立,四个组合(坐下、站起、保持坐、保持站)都被等概率训练(:619)。

真实符号

对称性体现在每个任务 reward 都是 posture_* 家族:它们读当前命令,逐环境选择目标——坐是 SIT_Z = 0.060 + SITTING_TARGET_OVERRIDES(膝 ±1.35、髋俯仰 ∓0.4079,:101),站是 STAND_Z = 0.115 + HOME。于是 posture_height_gaussian(std 0.04 宽层 :285 / std 0.015 尖层 :295)、posture_height_l1(权重 6.0,取 sit 的 5.0 与 standup 的 7.5 之间,:308)在两个方向上共用同一套形状。

防摔的对称同样成对:MAX_DESCENT_SPEED = 0.05 与 MAX_RISE_SPEED = 0.08(:144-145),下降封顶 descent_speed 从 0 步就是正权重 10(函数自返回负值,:352),上升封顶 rise_speed 权重 0 起步、1500 迭代才 ramp 到 5(:862)——又是 27 篇那条「发现期不上税」的铁律,注释还记录了推后的原因:起身需要几步 vz > 0.08 的蹬地爆发,过早封顶会把半成品的起身卡死在头朝前的折叠姿态里(:855-861)。

最巧妙的机制是 POSTURE_RAMP_S = 2.0(:137):命令项内部把目标在坐/站之间以 2 秒斜坡滑动,posture 奖励追踪的是移动目标。这是防摔的主装置——二值目标下,提前到站可以白吃每步约 7 的目标奖励,摔坐一次只亏约 50 的有限代价,「摔」比「稳」赚 7 倍;有了斜坡,冲到目标前面意味着斜坡剩余时间里高度/合成分全为零,跟踪慢设定点才是 argmax(:128-137)。

设计取舍

另一个隐蔽工程点在物理层:全身碰撞模型的坐姿让躯干、折叠的腿和头同时贴地,默认 nconmax=35、solver 10 次迭代会在坐下的瞬间撑爆接触求解器产生 NaN,而 nan_state 终止等于惩罚「坐下」这个动作本身——策略刚学会又忘掉。修复是 cfg.sim.nconmax = 200、iterations = 30、ls_iterations = 50(:643-645)。这是「训练信号被物理引擎 bug 污染」的典型案例:先确认 NaN 不是任务失败,再去调 reward 就是白费劲。头撞地在这里不罚(sit 环境罚):过渡动作用头当第三支点被显式允许,靠 posture_composite 的 head_std = 0.40 因子(:434)只禁止「歇着时头耷拉到地」。

你带走的收获

延伸

什么鸭 WHATDUCK · 复刻学习笔记 ← 全部手册 · 首页