在足式机器人强化学习中,马尔可夫决策过程(MDP)的设计直接决定了策略能学到什么样的行为。本项目围绕 Isaac Lab 框架,构建了覆盖 Direct RL 与 Manager-based 两种范式的 MDP 体系,支持速度跟踪、运动模仿(AMP / BeyondMimic)等多种任务。本章将从架构全景出发,逐层拆解状态空间、奖励函数、终止条件与指令系统的设计逻辑,并给出可落地的配置与调参方法。
MDP 架构全景
本项目的 MDP 遵循标准向量化的演员-评论家(Actor-Critic)接口。在每个时间步,环境并行执行物理推演,随后由各个管理器(Manager)分别计算观测、奖励与终止信号。整体数据流可以用下图概括:
graph TD
A[指令系统<br/>UniformVelocityCommand / MotionCommand] --> B[物理环境<br/>Isaac Sim + 域随机化]
B --> C[观测管理器<br/>Policy / Critic / Discriminator]
B --> D[奖励管理器<br/>Task + Regularization + Contact]
B --> E[终止管理器<br/>Timeout / Bad Pose / Contact]
C --> F[Actor-Critic 网络]
F --> G[动作输出<br/>JointPositionAction]
G --> B
H[事件管理器<br/>Push / Mass Randomization] --> B
图中的每一条边都对应着具体的配置类与函数实现。对 Direct RL 环境而言,这些逻辑被显式编码在 BaseEnv.step() 中;而对 Manager-based 环境,Isaac Lab 的 RewardManager、ObservationManager、TerminationManager 等组件通过配置类自动组装。Sources: base_env.py, amp_env.py, vec_env.py
双范式实现对比
项目同时维护 Direct RL 与 Manager-based 两条 MDP 实现路径,二者在代码组织方式上存在显著差异,但底层数学形式完全一致。下表从开发者视角对比了两者的核心差异:
| 维度 | Direct RL(direct/base) |
Manager-based(manager_based) |
|---|---|---|
| 环境基类 | DirectRLEnv |
ManagerBasedRLEnv |
| 奖励组织 | RewardManager 在 BaseEnv.__init__ 中手动实例化 |
由配置类 RewardsCfg 自动注入 |
| 观测计算 | compute_current_observations() 手写拼接 actor/critic 张量 |
ObservationGroupCfg 声明式配置 |
| 奖励函数签名 | func(env: BaseEnv, ...) -> torch.Tensor |
func(env: ManagerBasedRLEnv, ...) -> torch.Tensor |
| 适用任务 | 注意力编码器直接训练、中断恢复训练 | AMP 模仿学习、BeyondMimic 运动克隆 |
Direct RL 路径更适合需要高度自定义观测历史、动作缓冲或中断逻辑的场景,所有张量操作都在 BaseEnv 中显式完成。Manager-based 路径则充分利用 Isaac Lab 的声明式配置能力,新增奖励项只需在配置类中增加一行 RewTerm 即可。Sources: base_env.py, beyondmimic_env_cfg.py
奖励函数设计体系
本项目的奖励函数按语义分为三大类:任务奖励(驱动行为目标)、正则化惩罚(约束能量与平滑性)、接触与足端奖励(塑造足式步态)。所有奖励项均采用纯 PyTorch 实现,支持向量化并行计算。
任务奖励
任务奖励是策略学习的“北极星”。在 AMP 与 Direct RL 的速度跟踪任务中,核心奖励为指数核跟踪项:
track_lin_vel_xy_exp = torch.exp(-lin_vel_error / std**2)
track_ang_vel_z_exp = torch.exp(-ang_vel_error / std**2)
值得注意的是,这些奖励均乘以了重力投影调制因子 clamp(-projected_gravity_b[:, 2], 0, 0.7) / 0.7,使得机器人在接近摔倒时任务奖励自然衰减,从而隐式鼓励保持平衡。Sources: amp/mdp/rewards.py
在 BeyondMimic 任务中,任务奖励转向运动克隆,通过比对参考运动(motion clip)与机器人实际状态计算多维度跟踪误差:
| 奖励项 | 数学形式 | 物理含义 |
|---|---|---|
motion_global_anchor_position_error_exp |
exp(-‖p_ref - p_robot‖² / std²) |
根节点位置跟踪 |
motion_global_anchor_orientation_error_exp |
exp(-quat_error² / std²) |
根节点姿态跟踪 |
motion_relative_body_position_error_exp |
exp(-mean(‖body_ref - body_robot‖²) / std²) |
全身关键连杆位置跟踪 |
motion_relative_body_orientation_error_exp |
exp(-mean(quat_error²) / std²) |
全身关键连杆姿态跟踪 |
motion_global_body_linear_velocity_error_exp |
exp(-mean(‖v_ref - v_robot‖²) / std²) |
线速度跟踪 |
motion_global_body_angular_velocity_error_exp |
exp(-mean(‖ω_ref - ω_robot‖²) / std²) |
角速度跟踪 |
这些函数统一接收 command_name="motion",从 MotionCommand 管理器中获取当前帧的参考运动数据。Sources: beyondmimic/mdp/rewards.py
正则化惩罚
正则化项防止策略过拟合到高能耗、高抖动或极限关节姿态的捷径解。本项目采用的正则化核函数以 L2 平方 为主,少数项使用 L1 绝对值:
- L2 平方核:
joint_vel_l2、joint_acc_l2、joint_torques_l2、action_rate_l2、lin_vel_z_l2、ang_vel_xy_l2、flat_orientation_l2。平方惩罚对小幅偏离宽容,对大幅偏离严厉。 - L1 绝对值核:
joint_deviation_l1、stand_still。绝对值惩罚在整个区间上线性增长,更稳定地约束关节偏移。 - 能耗惩罚:
joint_energy = Σ|qvel · qfrc|,直接度量关节瞬时功率,抑制无效做功。Sources: amp/mdp/rewards.py, direct/base/mdp/rewards.py
接触与足端奖励
足式机器人的步态质量高度依赖接触逻辑。项目实现了多组足端专用奖励:
| 奖励项 | 类型 | 作用机制 |
|---|---|---|
feet_air_time |
正奖励 | 鼓励单脚支撑期(single stance)的空中时间,零速指令时自动关闭 |
feet_air_time_positive_biped |
正奖励 | 双足专用:仅当恰好有一只脚接触地面时奖励,鼓励交替步态 |
feet_slide |
负奖励 | 接触状态下惩罚足端横向滑移速度 |
feet_stumble |
负奖励 | 当水平接触力大于竖直方向 3~4 倍时触发,惩罚踢到垂直面 |
feet_orientation_l2 |
负奖励 | 接触状态下惩罚足端非水平姿态 |
feet_height |
正奖励 | 摆动相足端离地高度奖励,基于 RayCaster 测距 |
sound_suppression_acc_per_foot |
负奖励 | 接触时惩罚足端竖直方向加速度,用于抑制触地冲击噪声 |
undesired_contacts |
负奖励 | 惩罚非足端部位的异常接触 |
feet_slide 的实现具有代表性:它先通过 contact_sensor.data.net_forces_w_history 判断接触,再将足端世界速度转换到机体坐标系,提取水平分量后求和。这一设计确保只有在真实接触地面时才产生惩罚。Sources: amp/mdp/rewards.py, direct/base/mdp/rewards.py
终止惩罚
在 Direct RL 中,termination_penalty = RewTerm(func=mdp.is_terminated, weight=-200.0) 会在环境因非超时原因终止时施加大额负奖励,迫使策略避免摔倒。AMP 与 BeyondMimic 则更多依赖终止条件本身的截断机制,不额外设置终止惩罚。Sources: atom01_attn_enc_env_cfg.py
指令系统与状态空间
MDP 的转移动力不仅来自物理仿真,还受指令系统驱动。不同任务使用不同的指令生成器:
均匀速度指令(Uniform Velocity Command)
AMP 与 Direct RL 环境采用 UniformVelocityCommand,定期从预设区间重新采样线速度 v_x, v_y 与偏航角速度 ω_z。配置参数包括重采样周期、站立环境比例、航向控制刚度等。策略的观测中包含该指令,形成标准的“指令-跟踪”范式。Sources: amp_env_cfg.py, base_config.py
运动指令(Motion Command)
BeyondMimic 环境使用自定义的 MotionCommand,它从 .npz 运动片段中按帧读取参考关节位置、根节点位姿与全身连杆速度。其核心创新在于自适应采样(Adaptive Sampling):将整个运动序列划分为若干时间桶(bin),根据各桶的历史失败率动态调整采样概率,从而增加难帧的曝光度。当参考运动播放完毕后,可选择重置环境,或停留在末帧并激活 motion_ended 标志,此时 stand_still_after_motion 奖励会引导机器人回到默认姿态。Sources: beyondmimic/mdp/commands.py, beyondmimic/mdp/commands.py, beyondmimic/mdp/rewards.py
观测空间构造
观测空间按用途分为 Policy、Critic 和 Discriminator(AMP 专用)三组:
- Policy 观测通常包含:机体角速度、投影重力向量、指令、相对关节位置、相对关节速度、上一帧动作。开启噪声腐蚀(
enable_corruption=True)以提升泛化性。 - Critic 观测在 Policy 基础上扩展特权信息:根节点线速度、足端接触状态、足端接触力、足端高度、关节加速度、关节力矩等。历史长度通常设为 3~10 帧。
- Discriminator 观测(AMP)包含机体角速度、关节位置、关节速度,以及参考运动对应的若干历史帧,用于判别器区分策略轨迹与专家轨迹。
Direct RL 的观测则在 BaseEnv.compute_current_observations() 中手写拼接,并通过 CircularBuffer 维护历史序列。Sources: beyondmimic_env_cfg.py, amp_env_cfg.py, base_env.py
终止条件设计
终止管理器决定一个 episode 何时结束。本项目的终止条件兼顾了任务语义与物理可行性:
| 终止项 | 触发条件 | 适用环境 |
|---|---|---|
time_out |
达到最大 episode 时长 | 通用 |
bad_anchor_pos / bad_anchor_pos_z_only |
根节点位置偏离参考运动超过阈值 | BeyondMimic |
bad_anchor_ori |
投影重力向量 z 轴差异超过阈值 | BeyondMimic |
bad_motion_body_pos |
任意关键连杆位置偏离超过阈值 | BeyondMimic |
undesired_contacts |
非足端部位产生大接触力 | AMP / Direct |
BeyondMimic 的终止条件尤其严格,因为运动克隆任务要求全身姿态与参考运动保持高度一致。bad_anchor_ori 通过比较参考运动与机器人的投影重力向量判断跌倒,而不是直接比较四元数,从而对航向差异更宽容,对俯仰/横滚差异更敏感。Sources: beyondmimic/mdp/terminations.py, beyondmimic_env_cfg.py
事件与域随机化
事件管理器在 startup、reset、interval 三个时机注入随机扰动,属于 MDP 的隐性状态转移机制。本项目配置了丰富的域随机化策略:
- 启动随机化(startup):刚体摩擦系数、关节默认位置偏差、躯干质量与质心偏移、连杆质量缩放、执行器刚度/阻尼缩放、关节摩擦与电枢缩放。
- 重置随机化(reset):根节点位姿与速度、关节位置与速度。
- 间隔推送(interval):以 1~10 秒为周期随机施加速度扰动(push),模拟外部冲击。
在 BeyondMimic 中,randomize_joint_default_pos 会在启动时轻微扰动关节默认位置,并同步更新动作管理器的 offset,确保策略对校准误差具有鲁棒性。Sources: beyondmimic/mdp/events.py, beyondmimic_env_cfg.py, amp_env_cfg.py
配置与调参实践
在实际开发中,新增或调整奖励项只需修改对应环境的配置类。以下是一个典型示例,展示如何在 AMP 配置中组合奖励:
@configclass
class Atom01AmpRewards:
track_lin_vel_xy_exp = RewTerm(
func=mdp.track_lin_vel_xy_exp, weight=1.0,
params={"command_name": "base_velocity", "std": math.sqrt(0.25)}
)
joint_torques_l2 = RewTerm(func=mdp.joint_torques_l2, weight=-1.0e-5)
feet_slide = RewTerm(
func=mdp.feet_slide, weight=-0.5,
params={
"sensor_cfg": SceneEntityCfg("contact_forces", body_names=".*_ankle_roll_link"),
"asset_cfg": SceneEntityCfg("robot", body_names=".*_ankle_roll_link"),
},
)
调参时建议遵循以下原则:
- 先任务后正则:先确保
weight > 0的任务奖励能驱动基本行为,再逐步增加正则项权重抑制抖动。 - 指数核调
std:std决定奖励的敏感区间,过小会导致优化过于尖锐,过大则信号稀疏。通常从目标误差的期望量级开始。 - 重力调制一致性:若奖励函数包含
projected_gravity_b[:, 2]调制,确保同类任务统一使用,避免策略在边界状态接收到矛盾信号。 - 零指令屏蔽:足端相关奖励(如
feet_air_time)应通过(cmd_norm > threshold).float()屏蔽零速指令场景,防止静止时产生无效激励。
Sources: atom01_amp_env_cfg.py, atom01_attn_enc_env_cfg.py
延伸阅读
- 如需了解 Direct RL 与 Manager-based 的底层环境架构差异,请参阅 Direct RL 环境架构 与 Manager-based 环境架构。
- 如需深入 AMP 的判别器机制与模仿学习训练流程,请参阅 AMP 对抗运动先验算法 与 AMP Runner 与模仿学习训练。
- 如需了解注意力编码器如何改变观测空间,请参阅 注意力编码器感知机制。