🤖 roboto_origin_03 Wiki
首页 / 项目根 / AMP模仿学习与动作数据集

本项目在 IsaacLab 框架之上实现了 Adversarial Motion Priors (AMP) 模仿学习管线,使 ATOM01 双足机器人能够从人类动作捕捉数据中学习自然、流畅的运动风格。与纯强化学习策略相比,AMP 通过对抗性判别器为策略提供隐式的动作先验约束,在不牺牲任务完成度的前提下显著改善运动的生物拟真度。本页涵盖动作数据集的完整制备流程、AMP 环境架构、对抗训练算法核心以及训练配置参数。

AMP 核心原理与系统架构

AMP 的核心思想源自生成对抗网络(GAN):一个 判别器(Discriminator) 学习区分真实的人类示范动作与策略生成的动作,而 策略网络(Policy) 则通过最大化判别器的"欺骗得分"来获得风格奖励(Style Reward)。该风格奖励与任务奖励(Task Reward)通过线性插值融合,驱动策略既完成任务指令又模仿人类动作特征。

系统整体数据流遵循"环境产出观测 → 判别器计算风格奖励 → 联合优化策略与判别器"的闭环。具体而言,AnimationEnv 在常规物理仿真的基础上增加了动作数据管理器(MotionDataManager)与动画管理器(AnimationManager),前者加载并采样 .pkl 格式的动作片段,后者按时间步推进参考动画并填充观测缓存。AmpEnv 进一步重写了 step 方法,确保在环境重置前保留用于判别器训练的观测历史。

flowchart TB
    subgraph 动作数据集层
        GMR[GMR原始动作数据 .pkl] --> RETARGET[Retarget工具链<br/>gmr_to_lab.py]
        RETARGET --> LAB[Lab格式动作数据<br/>root_pos / root_rot / dof_pos / key_body_pos]
    end

    subgraph 环境层
        LAB --> MDM[MotionDataManager<br/>加载 / 采样 / 插值]
        MDM --> AM[AnimationManager<br/>时间推进 / 观测缓存]
        AM --> AMP_ENV[AmpEnv<br/>step重写 / 观测保留]
    end

    subgraph 训练层
        AMP_ENV --> POLICY[Policy网络<br/>Actor-Critic]
        AMP_ENV --> DISC[AMPDiscriminator<br/>风格判别]
        POLICY --> PPOAMP[PPOAMP算法<br/>PPO + AMP联合更新]
        DISC --> PPOAMP
        PPOAMP --> AMP_ENV
    end

    style PPOAMP fill:#e1f5fe
    style DISC fill:#fff3e0

Sources: amp_env.py, animation_env.py

动作数据集制备与重定向

AMP 训练的前提是高质量、与机器人本体匹配的动作数据集。本项目的数据来源为 GMR 动作捕捉管线,输出格式包含 fpsroot_posroot_rot(xyzw 四元数)、dof_pos 等字段。由于 GMR 的关节顺序与 IsaacLab 的机器人模型不一致,项目提供了完整的重定向(Retarget)工具链将原始数据转换为 Lab 格式。

重定向流程分为两个主要步骤:关节重排序关键体位置计算gmr_to_lab.py 中的 extract_gmr_data 函数依据 YAML 配置文件中的 gmr_dof_nameslab_dof_names 的映射表对自由度数组进行重排;随后 run_simulator 在 Isaac Sim 中逐帧回放动作,驱动机器人模型运动并记录 key_body_pos(关键连杆在世界坐标系下的位置)。输出字典还包含 loop_mode 字段(0CLAMP1WRAP),用于控制动画在末端是冻结还是循环。

flowchart LR
    A[GMR .pkl] --> B{YAML配置<br/>atom01.yaml}
    B --> C[extract_gmr_data<br/>关节映射 / 裁剪]
    C --> D[run_simulator<br/>物理回放 / 关键体记录]
    D --> E[Lab .pkl<br/>wxyz四元数 / key_body_pos]

项目中已预置的动作数据集位于 data/motions/atom01_lab/,涵盖行走、跑步、转向、站立等 16 组动作片段,数据来源包括 CMU、ACCAD 以及 GVHMR:

动作类别 文件示例 数据来源 说明
行走转跑步 127_04.pkl CMU 过渡动作
跑步 127_06.pkl CMU 直线奔跑
站立 A1-_Stand_stageii.pkl ACCAD 静止站姿
左转90度 B9_-__Walk_turn_left_90_stageii.pkl ACCAD 行走转向
后退 move_back.pkl GVHMR 后退步态
左平移 move_l.pkl GVHMR 侧向移动

Sources: gmr_to_lab.py, dataset_retarget.py, atom01.yaml

批量重定向命令

对于批量处理,使用 dataset_retarget.py 可以一次性转换整个目录:

python scripts/tools/retarget/dataset_retarget.py \
    --robot atom01 \
    --input_dir robolab/data/motions/atom01_gmr \
    --output_dir robolab/data/motions/atom01_lab \
    --config_file robolab/scripts/tools/retarget/config/atom01.yaml \
    --loop clamp

Sources: dataset_retarget.py

AMP 环境架构详解

AMP 环境采用三层继承结构:ManagerBasedRLEnvAnimationEnvAmpEnv。每层分别负责基础强化学习逻辑、参考动画驱动、以及 AMP 特有的观测保留机制。

AnimationEnv 与动画管理器

AnimationEnvload_managers 阶段实例化了两个专属管理器:MotionDataManager 负责从磁盘加载 .pkl 动作文件并进行帧级插值;AnimationManager 则为每个并行环境维护一条参考动画时间线,按 step_dt 推进并缓存最近 num_steps_to_use 步的参考观测。当环境触发重置(reset_buf)时,AnimationManager.reset 会依据动作权重分布重新采样 motion_id,并随机初始化时间相位,从而保证训练初期的状态多样性。

MotionDataTerm 是底层的数据加载单元。它通过 joblib 读取动作文件,在初始化阶段预计算 root 速度与关节速度的数值微分,并将所有动作张量沿帧维度拼接存储。运行时通过 get_motion_state 执行帧索引查找与线性插值:先调用 calc_phase 将时间映射到 [0, 1] 相位(支持 WRAP 循环模式),再转换为帧索引并做 lerp 插值。关键体位置从世界系转换到机体系,使用 root 四元数的逆旋转完成。

Sources: motion_data_manager.py, animation_manager.py

AmpEnv 的 Step 重写

标准 ManagerBasedRLEnv 在环境终止后会先执行重置再计算观测,这会导致 AMP 判别器丢失终止前一帧的观测历史。AmpEnv.step 保留了父类的大部分逻辑,但将观测计算延后到重置完成之后,确保 observation_manager.compute(update_history=True) 捕获到正确的时序数据。该设计对于依赖历史窗口(history_length=310)的判别器观测至关重要。

Sources: amp_env.py

观测组配置

AMP 环境定义了四组观测:policycriticdisc(判别器策略观测)、disc_demo(判别器示范观测)。策略组包含机身角速度、投影重力、速度指令、关节位置与速度、上一动作,维度精简以利于实时推理。判别器组则捕捉更具风格辨识度的特征,如关节位置、关节速度、机身角速度,历史长度默认为 10 步。示范观测组 disc_demoAnimationManager 的缓存中读取对应时刻的参考值,确保判别器在相同状态空间下比较策略与示范。

flowchart LR
    subgraph PolicyObs["policy (history_length=1)"]
        P1[base_ang_vel]
        P2[projected_gravity]
        P3[velocity_commands]
        P4[joint_pos_rel]
        P5[joint_vel_rel]
        P6[last_action]
    end

    subgraph DiscObs["disc / disc_demo (history_length=10)"]
        D1[base_ang_vel]
        D2[joint_pos]
        D3[joint_vel]
    end

Sources: amp_env_cfg.py

对抗训练算法实现

项目的 AMP 训练后端基于 rsl_rl 库扩展,核心组件包括 PPOAMP 算法、AMPDiscriminator 判别器、AMPRunner 训练运行器以及 CircularBuffer 环形缓存。

AMPDiscriminator 判别器网络

AMPDiscriminator 是一个 MLP 二分类器,输入为展平后的时序观测(disc_obs_dim × disc_obs_steps),经过若干隐藏层后输出标量判别分数。网络支持三种损失模式:

损失类型 公式特点 风格奖励计算 适用场景
GAN 二元交叉熵 -log(1 - sigmoid(disc_score)) 标准对抗训练
LSGAN 最小二乘 clamp(1 - 0.25×(disc_score - 1)², 0) 训练更稳定,本项目默认
WGAN 无界分数 经输出归一化后的分数 需配合梯度惩罚使用

判别器包含一个 EmpiricalNormalization 输入归一化层,在训练过程中在线更新均值与方差。compute_grad_penalty 对示范数据施加梯度惩罚(默认缩放系数 10.0),促使判别器在真实数据附近的梯度趋近于零,有效抑制模式崩溃。

Sources: amp.py

PPOAMP 联合优化

PPOAMP 继承自标准 PPO,在 process_env_step 阶段执行以下操作:首先提取当前策略观测 disc_obs 与参考动画观测 disc_demo_obs,调用判别器计算 style_rewards,再将任务奖励与风格奖励按 task_style_lerp 插值得到最终奖励 rewards_lerp。两组观测分别追加到独立的 CircularBuffer 中,供后续判别器训练批次采样。

update 方法实现了策略与判别器的交替梯度更新。每轮 mini-batch 迭代中,PPO 损失(surrogate + value + entropy)与判别器损失独立计算、独立反向传播。判别器损失由策略数据的分类损失、示范数据的分类损失以及梯度惩罚项组成。优化器层面,策略使用 self.optimizer,判别器使用独立的 disc_optimizer(Adam),两者的学习率与梯度裁剪阈值分别配置。

Sources: ppo_amp.py

AMPRunner 与模型持久化

AMPRunner 继承自 OnPolicyRunner,重写了 learnsaveloadtrain_modeeval_mode 五个方法。learn 在 rollout 阶段额外提取 style_rewardstotal_rewards 并送入 LoggerAMP 记录。save 将判别器网络状态、判别器归一化状态以及判别器优化器状态一并写入 checkpoint,保证训练中断后可完整恢复。load 则对称地恢复上述全部状态。

Sources: amp_runner.py, amp_logger.py

CircularBuffer 环形缓存

CircularBuffer 为每个并行环境维护一个固定长度的时序数据缓存,支持按 mini-batch 随机采样。其内部以 (max_len, batch_size, ...) 的张量存储数据,通过 _pointer 循环写入。mini_batch_generator 方法在每个 epoch 内将缓存数据随机打乱后切分为多个 mini-batch,满足判别器对非时序独立同分布采样的需求。

Sources: circular_buffer.py

训练配置参数解析

ATOM01 的 AMP 训练配置集中在 atom01_amp_agent_cfg.py 中,分为网络结构、PPO 超参数、AMP 超参数三个层次。

网络与算法配置

policy = RslRlPpoActorCriticCfg(
    init_noise_std=1.0,
    actor_hidden_dims=[512, 256, 128],
    critic_hidden_dims=[512, 256, 128],
    activation="elu",
)
algorithm = RslRlPpoAmpAlgorithmCfg(
    class_name="PPOAMP",
    learning_rate=1.0e-4,
    num_learning_epochs=5,
    num_mini_batches=4,
    schedule="adaptive",
    desired_kl=0.01,
    symmetry_cfg=...,
    amp_cfg=...,
)

策略与价值网络均采用 [512, 256, 128] 的三层 MLP,激活函数为 elu。学习率启用自适应调度:当 KL 散度超过 0.02 时除以 1.5,低于 0.005 时乘以 1.5。对称增强(Symmetry)开启数据增强与镜像损失,镜像损失系数为 0.2,通过 atom01.compute_symmetric_states 实现左右肢体的状态镜像。

AMP 专属超参数

参数 默认值 作用
disc_obs_buffer_size 100 判别器观测缓存长度
grad_penalty_scale 10.0 梯度惩罚系数
disc_trunk_weight_decay 1.0e-4 判别器主干网络 L2 正则
disc_linear_weight_decay 1.0e-2 判别器输出层 L2 正则
disc_learning_rate 1.0e-4 判别器学习率
disc_max_grad_norm 1.0 判别器梯度裁剪阈值
style_reward_scale 2.0 风格奖励全局缩放
task_style_lerp 0.3 任务奖励与风格奖励插值系数
loss_type "LSGAN" 判别器损失类型

判别器网络结构为 [1024, 512],大于策略网络,以提供充足的表示能力来捕捉动作风格的细微差异。task_style_lerp=0.3 意味着最终奖励中 30% 来自风格奖励、70% 来自任务奖励,该平衡在跟踪指令与自然步态之间取得折中。

Sources: atom01_amp_agent_cfg.py

动作数据权重与课程

Atom01AmpEnvCfg 中,通过 motion_data_weights 字典为每个动作片段分配采样权重。所有权重在初始化时归一化为概率分布,供 MotionDataTerm.sample_motions 进行多项式采样。当前配置中 CMU、ACCAD、GVHMR 三类数据权重均为 1,实现均匀混合。如需侧重某一类动作风格,可直接调整对应权重值。

环境奖励函数在 AMP 模式下进行了简化:任务跟踪奖励(track_lin_vel_xy_exptrack_ang_vel_z_exp)的权重设为 0,因为风格奖励已隐式编码了速度模式;保留的惩罚项包括非期望接触(undesired_contacts)与存活奖励(alive),用于维持基本的物理可行性。

Sources: atom01_amp_env_cfg.py

训练与推理

启动 AMP 训练

cd modules/atom01_train/robolab
python scripts/rsl_rl/train.py --task=Atom01-Amp-v0 --headless --logger=tensorboard --num_envs=8192

训练默认使用 8192 个并行环境,单步环境步长 24,总迭代次数 5000。每 100 次迭代保存一次模型 checkpoint。

播放与导出策略

# 可视化策略
python scripts/rsl_rl/play_amp.py --task=Atom01-Amp-v0 --num_envs=1 --load_run <run_dir> --checkpoint <model.pt>

# Sim2Sim 迁移到 MuJoCo
python scripts/mujoco/sim2sim_atom01_amp.py --load_model <exported/policy.pt>

play_amp.py 支持将策略导出为 ONNX 格式,便于后续在 OrangePi 主控板上通过 ONNX Runtime 部署。sim2sim_atom01_amp.py 专门用于验证 AMP 策略在 MuJoCo 物理引擎上的零样本迁移能力。

Sources: play_amp.py, sim2sim_atom01_amp.py

进阶话题与调参建议

判别器输入设计

判别器观测的选择直接决定 AMP 能捕捉到的风格维度。当前配置使用 base_ang_veljoint_posjoint_vel,舍弃了 root 线速度与关键体位置。若发现策略无法复现特定的躯干倾斜或摆臂风格,可在 amp_env_cfg.py 中取消注释 base_lin_velkey_body_pos_b 项,并同步更新 disc_obs_dim

风格奖励与任务奖励的平衡

task_style_lerp 是控制策略"服从指令"还是"模仿风格"的关键旋钮。当 lerp=0 时,策略完全依赖任务奖励,退化为普通 PPO;当 lerp=1 时,策略完全模仿动作数据,可能忽视速度指令。对于需要精确跟踪速度指令的足式机器人,建议保持在 0.2 ~ 0.4 区间。

梯度惩罚与训练稳定性

若观察到判别器损失剧烈震荡或风格奖励收敛到极值,可尝试:1) 增大 grad_penalty_scale20.0;2) 降低 disc_learning_rate5.0e-5;3) 切换为 WGAN 损失并启用 disc_output_normalizer。LSGAN 在本项目中表现最为稳定,是推荐的默认配置。

阅读衔接

完成 AMP 训练后,若希望进一步扩展至多技能切换与注意力机制,请参阅 BeyondMimic多技能与注意力策略。若需将训练好的策略迁移至 MuJoCo 并进行硬件部署前的验证,请参阅 Sim2Sim迁移与MuJoCo验证。AMP 环境依赖 IsaacLab 的 Manager-based 架构,若对环境配置原理尚不熟悉,建议先回顾 IsaacLab环境搭建与训练流程基础Locomotion策略训练