第 2 章:代码漫步 — 每个文件做什么

打开项目不迷路。这章带你走一遍关键文件,讲清楚每个文件的作用和修改时机。

2.1 项目目录树

unitree_rl_gym_study/
├── unitree_rl_gym/                      ← 宇树官方 RL 框架(已克隆)
│   ├── legged_gym/                      ← ★ 核心代码
│   │   ├── envs/
│   │   │   ├── base/
│   │   │   │   ├── base_task.py         ← 最底层:创建仿真环境、地形
│   │   │   │   ├── legged_robot.py      ← 机器人基类:step()、奖励计算、观测
│   │   │   │   └── legged_robot_config.py ← 基类配置(所有机器人共享)
│   │   │   ├── g1/
│   │   │   │   ├── g1_config.py         ← ★ G1 专属配置(改奖励权重在这里)
│   │   │   │   └── g1_env.py            ← ★ G1 专属逻辑(加新奖励在这里)
│   │   │   ├── h1/                      ← H1 机器人
│   │   │   ├── h1_2/                    ← H1_2 机器人
│   │   │   └── go2/                     ← Go2 四足
│   │   ├── scripts/
│   │   │   ├── train.py                 ← ★ 训练入口
│   │   │   └── play.py                  ← ★ 可视化入口(含 JIT 模型导出)
│   │   └── utils/
│   │       ├── helpers.py               ← 工具函数、参数解析
│   │       ├── math.py                  ← 数学工具(角度转换等)
│   │       └── task_registry.py         ← 任务注册(根据 --task=g1 加载对
│   │
│   ├── deploy/
│   │   ├── deploy_mujoco/               ← ★ MuJoCo Sim2Sim 验证(目标2重点)
│   │   │   ├── deploy_mujoco.py         ← 用 MuJoCo 加载 JIT 策略运行
│   │   │   └── configs/                 ← 部署 YAML 配置(g1.yaml等)
│   │   ├── deploy_real/                 ← 真机 SDK2 部署
│   │   │   ├── deploy_real.py
│   │   │   ├── common/                  ← 命令/旋转/遥控器辅助
│   │   │   └── configs/
│   │   └── pre_train/                   ← 官方预训练模型
│   │
│   ├── resources/robots/g1_description/ ← G1 机器人模型文件
│   │   ├── g1_12dof.urdf                ← 12 自由度(仅腿)URDF 模型
│   │   ├── g1_29dof.xml                 ← 29 自由度 MJCF 模型
│   │   └── meshes/                      ← 3D 模型网格 (.stl)
│   ├── doc/                             ← 安装文档
│   └── logs/                            ← 训练输出(自动生成)
│       └── g1/                          ← experiment_name=g1
│           └── <日期时间>_<run_name>/    ← 每次训练一个文件夹
│               ├── model_<iter>.pt      ← 模型检查点
│               └── train_logs/          ← TensorBoard 事件文件
│
├── rsl_rl/                              ← PPO 算法库(已克隆, v1.0.2)
│   └── rsl_rl/
│       ├── algorithms/ppo.py            ← PPO 算法实现
│       ├── modules/                     ← Actor-Critic 网络模块
│       ├── storage/                     ← Rollout 经验存储
│       ├── runners/                     ← OnPolicyRunner 训练循环
│       ├── env/                         ← VecEnv 抽象接口
│       └── utils/                       ← 轨迹分割/填充工具
│
├── CLAUDE.md
├── DEPLOY_PLAN.md
└── README.md

2.2 核心文件详解

train.py — 训练入口

# 就是这么简单,整个训练就这三行
def train(args):
    env, env_cfg = task_registry.make_env(name=args.task, args=args)
    ppo_runner, train_cfg = task_registry.make_alg_runner(env=env, name=args.task, args=args)
    ppo_runner.learn(num_learning_iterations=train_cfg.runner.max_iterations,
                     init_at_random_ep_len=True)

解释

  1. make_env — 根据 --task=g1 创建 256 个 G1 仿真环境
  2. make_alg_runner — 创建 PPO 训练器,把环境和神经网络连起来
  3. learn — 开始训练循环

什么时候改:基本不需要改,它做的事就是搭积木。


g1_config.py — 配置文件(最常改的文件)

这是训练的核心配置,每个参数都影响训练效果:

class G1RoughCfg(LeggedRobotCfg):
    # ===== 初始化状态 =====
    class init_state:
        pos = [0.0, 0.0, 0.8]           # 机器人出生位置 (x, y, 高度0.8m)
        default_joint_angles = {         # 默认关节角度(action=0 时的姿态)
            'left_hip_pitch_joint': -0.1,  # 髋俯仰稍后倾
            'left_knee_joint': 0.3,        # 膝微弯 17°
            'left_ankle_pitch_joint': -0.2, # 踝微俯
            # ... 左右对称
        }

    # ===== 观测/动作维度 =====
    class env:
        num_observations = 47    # 神经网络输入大小
        num_privileged_obs = 50  # 特权观测(训练用,真机没有)
        num_actions = 12         # 神经网络输出大小(12个腿部关节)

    # ===== 域随机化(让策略更鲁棒) =====
    class domain_rand:
        randomize_friction = True        # 随机地面摩擦
        friction_range = [0.1, 1.25]     # 从冰面到橡胶
        randomize_base_mass = True       # 随机机身质量
        added_mass_range = [-1., 3.]     # 轻1kg到重3kg
        push_robots = True               # 随机推机器人
        max_push_vel_xy = 1.5            # 最大推速1.5m/s

    # ===== 控制参数 =====
    class control:
        control_type = 'P'               # P控制(只有比例项,没有微分项)
        stiffness = {'knee': 150, ...}   # PD 比例增益(刚度)
        damping = {'knee': 4, ...}       # PD 阻尼增益
        action_scale = 0.25              # 动作缩放(输出×0.25=实际角度偏移)
        decimation = 4                   # 每4步物理仿真发一次动作

    # ===== 奖励权重(最常调试的部分) =====
    class rewards:
        base_height_target = 0.78        # 目标身高
        class scales:
            tracking_lin_vel = 1.0       # 速度跟踪奖励
            base_height = -10.0          # 身高惩罚(摔了扣分)
            alive = 0.15                 # 存活奖励
            # ... 共 15 个奖励项

class G1RoughCfgPPO(LeggedRobotCfgPPO):
    class policy:
        init_noise_std = 0.8            # 初始探索噪声
        actor_hidden_dims = [32]        # Actor 隐藏层大小
        critic_hidden_dims = [32]       # Critic 隐藏层大小
        rnn_hidden_size = 64            # LSTM 记忆大小
    class runner:
        policy_class_name = "ActorCriticRecurrent"  # 使用带记忆的网络
        max_iterations = 10000          # 总训练轮数
        experiment_name = 'g1'          # 实验名称

什么时候改

  • 想调奖励 → 改 class rewards.scales
  • 想改训练轮数 → 改 max_iterations
  • 想改动作幅度 → 改 action_scale
  • 想让机器人更鲁棒 → 改 domain_rand

g1_env.py — 机器人专属逻辑

继承 LeggedRobot,添加 G1 特有的功能:

class G1Robot(LeggedRobot):
    # 1. 步态相位 — 控制左右脚交替迈步
    def _post_physics_step_callback(self):
        period = 0.8                     # 步态周期 0.8 秒
        offset = 0.5                     # 左右脚相位差 50%
        self.phase = ...                 # 计算左右脚的步态相位

    # 2. 观测打包 — 把各种传感器数据拼成 47 维向量
    def compute_observations(self):
        self.obs_buf = torch.cat((
            self.base_ang_vel,            # [0:3] 身体角速度
            self.projected_gravity,       # [3:6] 重力方向
            self.commands[:, :3],         # [6:9] 速度指令
            self.dof_pos,                 # [9:21] 关节角度
            self.dof_vel,                 # [21:33] 关节速度
            self.actions,                 # [33:45] 上一步动作
            sin_phase, cos_phase,         # [45:47] 步态相位
        ), dim=-1)

    # 3. 定制奖励函数
    def _reward_contact(self):           # 脚着地奖励
    def _reward_feet_swing_height(self): # 抬脚高度奖励
    def _reward_alive(self):             # 存活奖励
    def _reward_contact_no_vel(self):    # 接触时无速度惩罚
    def _reward_hip_pos(self):           # 髋关节位置惩罚

什么时候改:加新奖励函数、改观测内容、改步态逻辑时改这个文件。


legged_robot.py — 机器人基类

所有机器人(G1、H1、Go2)共享的通用逻辑都在这里。核心是 step() 函数:

def step(self, actions):
    # 1. 裁剪动作(防止神经网络输出太离谱的值)
    self.actions = torch.clip(actions, -clip_actions, clip_actions)

    # 2. 用 PD 控制器把目标角度转为电机力矩
    for _ in range(decimation):          # decimation=4
        self.torques = self._compute_torques(self.actions)
        self.gym.set_dof_actuation_force_tensor(...)
        self.gym.simulate(self.sim)      # 物理仿真一步

    # 3. 算奖励、检查终止、重置死亡机器人
    self.post_physics_step()
    return obs, privileged_obs, rewards, dones, extras

什么时候改:基本不用改。这是框架代码,除非要改整个训练逻辑。


play.py — 可视化验证

def play(args):
    # 1. 创建环境(和训练一样,但只有 100 个)
    env, _ = task_registry.make_env(name=args.task, ...)

    # 2. 加载训练好的模型
    ppo_runner, train_cfg = task_registry.make_alg_runner(env=env, ..., resume=True)
    policy = ppo_runner.get_inference_policy(device=env.device)

    # 3. 循环:观测 → 策略推理 → 动作 → 仿真
    for i in range(10 * env.max_episode_length):
        actions = policy(obs.detach())    # 神经网络输出动作(不训练)
        obs, _, rews, dones, infos = env.step(actions)

deploy_mujoco.py — MuJoCo 验证策略

训练完用 MuJoCo 再跑一遍,确认策略不只在 Isaac Gym 里有效:

# 1. 加载 ONNX/PT 模型
policy = torch.jit.load(policy_path)

# 2. MuJoCo 仿真循环
while True:
    obs = get_robot_obs(model, data)      # 从 MuJoCo 读取观测
    action = policy(obs)                  # 网络推理
    target_angles = action * action_scale + default_angles
    torques = pd_control(target_angles, q, kp, kd)  # PD 控制
    data.ctrl[:] = torques
    mujoco.mj_step(model, data)           # 物理步进

ppo.py — PPO 算法

RSL-RL 库的 PPO 实现。你不需要看代码细节,理解这些参数即可:

参数 默认值 含义
learning_rate 1e-3 每次更新网络权重的步长
gamma 0.998 未来奖励的打折率(越接近 1 越看重长远)
lam 0.95 GAE 优势估计参数
clip_param 0.2 PPO 裁剪范围(防止更新太激进)
entropy_coef 0.01 探索奖励系数(越大越敢尝试新动作)

2.3 修改指引速查

你想做什么 改哪个文件 改哪里
调快/调慢训练 g1_config.py max_iterations
让机器人走得更快 g1_config.py rewards.scales.tracking_lin_vel
减少摔倒 g1_config.py rewards.scales.base_height ↑(更负)
改变动作幅度 g1_config.py control.action_scale
加新的奖励项 g1_env.py _reward_xxx() 函数 + g1_config.py 里加权重
改用 29 关节全身 g1_config.py asset.file 改成 g1_29dof.urdf
调整显存用量 命令行 --num_envs=128(减半)
从某个检查点继续训 命令行 --resume --load_run=<run_name>

→ 下一章:03unitree_rl_gym新手教程第3章动手实践

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐