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

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

解读 26 · mdp.py(下):reward 与事件函数库

解读对象:microduck-replica/upstream/microduck_rl/src/mjlab_microduck/tasks/mdp.py(7188 行),抽读 reward / event / curriculum 相关
需要的前置:解读 24(这些函数在配置里被谁引用);event term = reset/interval 时机执行的事件项

模块级补丁:给 RewardManager 打 NaN 疫苗

mdp.py 开头就干了件大事:32–40 行把 RewardManager.compute 整体替换为
_nan_safe_reward_compute——mjlab 在重置之前算奖励,物理爆炸那一步的奖励是 NaN,
会沿"奖励→优势→损失→梯度→std 变负→torch.normal 崩溃"传播;补丁对结果和 _episode_sums
就地 nan_to_num_。50 行起对 PPO.compute_returns 做第二层补丁:课程跳变时优势归一化
可能爆掉,先清 NaN/Inf 再归一化。猴子补丁(monkeypatch = 运行时替换库函数)写在模块顶部,
import 即生效,所有任务共享。

终止与重置事件

robot_state_is_nan(963–1014 行):检查 joint_pos/joint_vel 加根体四个状态量是否有限,
再按 sensor_names 检查接触力——注释里写明这是 2026-08-21 一次真实崩溃的修复(接触力先于
关节状态爆炸,而 critic 的 foot_contact_forces 观测吃到了它)。reset_action_history
(229–313 行)是 reset 模式事件,把 _prev_leg_actions、_prev_neck_actions 及加速度用的
两级缓存重置为当前动作——不重置的话,回合开头的 action_rate 惩罚会凭空出现尖峰。

面向 BAM 执行器的域随机化

randomize_delayed_actuator_gains(3146–3194 行)不碰 MuJoCo 模型,而是调执行器自己的
reset_gains/set_gains,每关节采样后按环境平均成单标量(执行器只接受全局缩放);
randomize_bam_friction(3212–3240 行)对 FrictionDRBamActuator 先复位再采样
friction_scale——两者都遵守"先恢复标称、再采新值"防累积。expand_bam_friction_fields
(3197–3209 行)是个带装饰器的空函数:@requires_model_fields("dof_frictionloss", "dof_damping") 的唯一作用是让 mjlab 把这两个模型字段按世界展开,BAM 每步要写它们。

两个明星奖励函数

head_pose_tracking(5128–5192 行):mean(exp(-(err/std)²)) 对 4 个颈/头关节取均值——
均值而非平方和,单关节误差大时其余关节仍有梯度;可选 fine_std 混入窄高斯定价小误差;
测量角在齿隙模型上读输出侧(+ qpos[backlash]),与编码器观测一致。它还会把关节 id 缓存到
env._head_pose_neck_ids 等属性,与 head_pose_bias_penalty(5229–5317 行)共享。
后者是 2026-08-20"头部下垂修复":对 1 s EMA 后的误差取 L1(-mean(|EMA(err)|)),
让走路不可避免的振荡在平均中抵消,只罚可逃逸的直流偏垂;可选的 smoothstep 门控
(gate_height_low/gate_tilt_full_deg=20.0/gate_tilt_zero_deg=45.0)让摔倒/起身阶段
不预充误差,5309–5310 行还在回合头两步清零 EMA。

课程函数:改"活着的"cfg,不是 env.cfg

reward_weight(3442–3461 行)按 weight_stages 分档改奖励权重;com_range_curriculum
(3464–3501 行)改事件范围;standing_envs_curriculum(3295–3332 行)改站立环境比例。
三者的注释是同一课:EventManager/RewardManager 初始化时 deepcopy 了配置,改
env.cfg.events 是无效操作,必须通过 get_term_cfg 拿经理持有的活配置。
VelocityCommandCommandOnly._resample_command(4508–4533 行)则展示命令类怎么当奖励
基础设施用:按 rel_turn_in_place_envs 抽签,把这些环境的线速度清零、偏航强制
[0.4·max, max],并从站立集合里摘除。

你带走的收获

延伸

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