1. 项目概述:Unitree G1机器人垂直跳跃训练
在机器人控制领域,让四足机器人实现稳定的垂直跳跃一直是个具有挑战性的任务。最近我在Unitree G1 29自由度机器人上成功实现了这个功能,整个过程涉及从环境配置到强化学习训练的全流程。这个项目最有趣的地方在于,我们需要让机器人在没有任何水平移动的情况下,仅通过关节协调就能产生足够的垂直爆发力。
传统四足机器人的运动控制通常关注水平移动的稳定性,而垂直跳跃需要完全不同的动力学考量。G1机器人的29个自由度提供了丰富的控制可能性,但也带来了更高的控制复杂度。通过这个项目,我探索了如何利用Isaac Gym的物理仿真环境和PPO算法,让机器人学会高效地完成这个特定动作。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 环境配置详解
2.1 基础环境搭建
创建跳跃训练环境的第一步是建立合适的仿真场景。与常规的移动任务不同,跳跃环境需要特别注意几个关键点:
python复制@configclass
class RobotSceneCfg(InteractiveSceneCfg):
# 平坦地形配置
terrain = TerrainImporterCfg(
prim_path="/World/ground",
terrain_type="plane",
collision_group=-1,
physics_material=sim_utils.RigidBodyMaterialCfg(
friction_combine_mode="multiply",
restitution_combine_mode="multiply",
static_friction=1.0,
dynamic_friction=1.0,
),
)
这里选择完全平坦的地形,因为跳跃任务不需要复杂的地形交互。摩擦系数设置为1.0可以确保机器人有足够的抓地力进行起跳,同时避免落地时打滑。接触传感器的配置尤为关键:
python复制contact_forces: ContactSensorCfg = ContactSensorCfg(
prim_path="{ENV_REGEX_NS}/Robot/.*",
track_air_time=True,
history_length=1,
)
这个传感器会监测机器人脚部与地面的接触情况,这是我们判断跳跃周期和落地稳定性的主要依据。由于G1机器人的足部命名不统一,我们使用正则表达式".*"来匹配所有可能的足部链接。
2.2 观测空间设计
跳跃任务的观测空间需要特别关注垂直方向的运动信息:
python复制@configclass
class ObservationsCfg:
@configclass
class PolicyCfg(ObsGroup):
base_ang_vel = ObsTerm(func=mdp.base_ang_vel, scale=0.2, noise=Unoise(n_min=-0.2, n_max=0.2))
projected_gravity = ObsTerm(func=mdp.projected_gravity, noise=Unoise(n_min=-0.05, n_max=0.05))
joint_pos_rel = ObsTerm(func=mdp.joint_pos_rel, noise=Unoise(n_min=-0.01, n_max=0.01))
joint_vel_rel = ObsTerm(func=mdp.joint_vel_rel, scale=0.05, noise=Unoise(n_min=-1.5, n_max=1.5))
last_action = ObsTerm(func=mdp.last_action)
观测空间包含了基座角速度、重力投影、关节相对位置和速度等关键信息。特别值得注意的是,我们移除了常规移动任务中的速度命令观测,因为跳跃任务是自驱动的,不需要外部速度指令。
3. 奖励函数设计
3.1 核心奖励组件
跳跃任务的成功关键在于精心设计的奖励函数。我们的奖励系统由多个组件构成:
python复制@configclass
class RewardsCfg:
# 主要跳跃奖励
jump_height = RewTerm(
func=mdp.jump_height_reward,
weight=2.0,
params={"target_height": 0.2, "std": 0.1}
)
# 垂直速度奖励
vertical_velocity = RewTerm(
func=mdp.vertical_velocity_reward,
weight=1.0,
params={"min_vel": 0.5, "max_vel": 2.0}
)
跳跃高度奖励是最核心的部分,它鼓励机器人达到目标高度0.2米。垂直速度奖励则确保机器人能快速起跳,避免缓慢的蠕动式跳跃。这两个奖励的权重设置很关键,经过多次实验,2.0和1.0的比例能产生最佳效果。
3.2 稳定性约束
为了防止机器人在跳跃过程中失去平衡,我们设置了多个稳定性约束:
python复制# 水平速度惩罚
horizontal_velocity = RewTerm(
func=mdp.horizontal_velocity_penalty,
weight=-1.0,
params={"max_vel": 0.1}
)
# 垂直姿态奖励
vertical_orientation = RewTerm(
func=mdp.vertical_orientation_reward,
weight=0.5
)
水平速度惩罚确保机器人基本保持原地跳跃,最大允许水平速度设为0.1m/s。垂直姿态奖励则鼓励机器人保持直立,这对落地稳定性至关重要。
4. 训练配置与优化
4.1 PPO算法参数
我们使用RSL-RL实现的PPO算法进行训练,关键配置如下:
python复制# 在rsl_rl_ppo_cfg.py中的配置
@configclass
class BasePPORunnerCfg:
experiment_name = "g1_jump"
run_name = ""
resume = False
max_iterations = 1000
save_interval = 50
log_interval = 10
device = "cuda:0"
num_steps_per_env = 24
num_minibatches = 4
learning_rate = 1e-3
entropy_coef = 0.01
gamma = 0.99
lam = 0.95
clip_param = 0.2
max_grad_norm = 1.0
这些参数经过特别调整以适应跳跃任务:
- 较短的num_steps_per_env(24)适合跳跃这种短周期动作
- 较高的learning_rate(1e-3)加快收敛速度
- 适中的entropy_coef(0.01)平衡探索与利用
4.2 并行环境设置
python复制@configclass
class RobotEnvCfg(ManagerBasedRLEnvCfg):
scene: RobotSceneCfg = RobotSceneCfg(num_envs=4096, env_spacing=2.0)
decimation: int = 4
episode_length_s: float = 5.0
使用4096个并行环境可以大幅提高样本收集效率。每个episode长度为5秒,这足够完成多次跳跃循环。decimation=4表示每4个物理步执行一次策略推理,这平衡了控制精度和计算效率。
5. 关键实现细节
5.1 跳跃周期检测
准确检测跳跃周期对奖励计算至关重要。我们通过接触传感器实现:
python复制landing = RewTerm(
func=mdp.landing_reward,
weight=1.0,
params={
"sensor_cfg": SceneEntityCfg("contact_forces", body_names=".*ankle_roll.*"),
"target_height": 0.0,
"height_tolerance": 0.05,
},
)
这个奖励项会在机器人足部接触地面时触发,配合air_time参数可以精确计算跳跃高度和滞空时间。
5.2 动作空间设计
python复制@configclass
class ActionsCfg:
JointPositionAction = mdp.JointPositionActionCfg(
asset_name="robot",
joint_names=[".*"],
scale=0.25,
use_default_offset=True,
)
我们使用关节位置控制,scale=0.25限制动作幅度,避免过于剧烈的运动。use_default_offset=True让机器人在初始时保持站立姿势,这是起跳的理想起始状态。
6. 训练过程与调优
6.1 训练曲线分析
在训练过程中,我们观察到几个关键阶段:
- 初期(0-100迭代):机器人学习基本的腿部收缩动作,但还无法离地
- 中期(100-300迭代):开始出现不协调的跳跃动作,高度不稳定
- 后期(300+迭代):发展出流畅的跳跃模式,高度和稳定性显著提升
奖励曲线显示,垂直速度奖励通常比高度奖励更早开始上升,这表明机器人先学会快速发力,再学会控制发力时机以达到更高跳跃。
6.2 关键调优经验
-
奖励权重平衡:初期过度强调跳跃高度会导致机器人做出夸张但不稳定的动作。逐步调整各奖励项的权重是关键。
-
动作幅度限制:发现某些关节过度弯曲会导致机械结构碰撞,通过调整scale参数和关节限制惩罚来解决。
-
随机化策略:适度的质量随机化(±10%)和摩擦系数随机化(0.8-1.2)有助于策略的鲁棒性,但过度随机化会阻碍学习。
7. 测试与部署
7.1 环境测试脚本
python复制task = "Unitree-G1-29dof-Jump"
env_cfg = parse_env_cfg(task, device=getattr(args, "device", "cuda:0"), num_envs=1)
env = gym.make(task, cfg=env_cfg)
obs, info = env.reset()
for _ in range(10):
action_np = env.action_space.sample()
action = torch.as_tensor(action_np, device=env_device, dtype=torch.float32)
obs, reward, terminated, truncated, info = env.step(action)
这个测试脚本验证了环境的基本功能,包括重置、步进和观测空间等。在部署到真实机器人前,建议先在仿真中运行这个测试。
7.2 真实机器人部署注意事项
-
安全限制:在真实机器人上运行时,需要设置更严格的关节位置和速度限制,防止损坏硬件。
-
延迟补偿:真实系统存在控制延迟,可能需要调整策略网络的结构或增加观测历史长度。
-
校准检查:确保仿真和现实的关节零位一致,重力方向和大小设置正确。
