解读 27 · standup 配置:起身的课程设计
解读对象:
microduck-replica/upstream/microduck_rl/src/mjlab_microduck/tasks/microduck_standup_env_cfg.py(1159 行)
需要的前置:解读 24(velocity 的 reward 栈)、总纲
在做什么
这个文件定义「从坐姿关键帧 gently 站起来」的任务:reset 在坐姿(躯干高度 SIT_Z = 0.060,microduck_standup_env_cfg.py:88),目标是站姿(STAND_Z = 0.115,:94,注释强调这是仿真实测的自然平衡高度,旧值 0.120 比机械可达高 5 mm,逼出过还债式的后仰)。策略从 t=0 就只追一个固定目标——没有轨迹路标、没有阶段时钟,起身的路径让策略自己发现。课程(curriculum,即按训练迭代分阶段改参数的机制)不是用来切分动作的,而是用来编排难度和惩罚的出场顺序。
真实符号
入场姿态由 set_ground_state 事件控制(microduck_standup_env_cfg.py:701),四类开局按概率混合:坐姿 0.40、站立 0.40、俯卧(face_down)0.20、仰卧(face_up)0.00。课程 ground_state_mix(:861)用 event_param_curriculum 按 0/600/1500/2500 迭代(每迭代 24 步)把混合推到最终的 0.15/0.20/0.30/0.35——难的姿态后出场、且后期占比更高。
reward 栈分两层。目标层:height_stand(std=0.04 宽高斯,:302)+ height_stand_sharp(std=0.015,提供最后一厘米的梯度,:311)+ height_stand_l1(权重 7.5,注释说明是把旧值 30 除以 4 后的结果,:324)+ standing_composite(高度×直立×姿态的乘法合成分,权重 3.75,:441)。动作层:com_upward_velocity(权重 0.75,只在 0.125 m 以下奖励向上速度——为「起身的动作本身」付钱,防止坐着不动成为局部最优,:351)。
最讲究的是惩罚的定时引信。arrival_damping(到站阻尼,惩罚站定后的躯干角速度)权重从 0 开始,课程 arrival_damping_weight 在 3000 迭代才给 -0.025(:969)。注释记录了两次失败运行的结论:任何在「发现期」就生效的动作税,都会让翻身尝试净收益为负,策略学会躺平——解药是时机,不是数值。同一引信模式还用在 head_pose_bias、joint_torque_rate_l2 和 body_pose_tracking(2500 迭代起 ramp 到 4.0,:1022)上。
设计取舍
两处值得咀嚼。其一,2026-07 的「÷4 迁移修复」(:222):任务项总权重从约 49 降到约 12,与 velocity 环境的约 11 对齐——PPO 会归一化优势,绝对刻度无所谓,但正则项(action_rate 等)与任务项的相对强度决定 sim2real 质量,此前等权正则在这里实际上弱了 4 倍,导致真机上抖动几乎免费。其二,符号约定陷阱:gentle_rise 用的 trunk_vertical_accel_penalty 本身返回负值,权重必须写正 0.005(:373)——曾经写成负数,双重否定变成「奖励摔震」。这类「函数自带负号」的约定是奖励代码里最容易埋雷的地方。
你带走的收获
- 课程不只能调难度,还能调度惩罚的生效时刻:先让技能被发现,再收紧执行质量。
- 多层高斯(宽 std 拉启动 + 窄 std 给末段梯度)是对付「奖励饱和、梯度消失」的标准手法。
- 换任务环境时,正则项权重相对任务权重的比例比绝对值重要——对齐总任务质量是可操作的迁移手法。
- 起身奖励还引入了命令化的身体控制(6D 命令槽只跟踪 z/roll/pitch 三轴,:466),为真机运行时接口留位。