问题背景
爬楼梯比平地走路难很多,因为它不只是“速度跟踪”问题,还同时要求机器人:
看见或感知台阶高度 |
所以如果四足机器人在楼梯上训练失败,常见现象会比较多:
- 前脚撞到台阶立面;
- 脚抬不够高,卡在台阶边缘;
- 脚抬太高,动作很夸张,能耗大;
- 身体没有跟着抬升,腹部或腿部碰撞;
- 只会冲上去,速度一慢就失败;
- 上楼能走,下楼直接摔;
- 仿真能走,真机落脚不准或接触力过大。
这篇专门整理:针对爬楼梯任务,四足强化学习里哪些 reward、terrain curriculum、observation 和 reset 条件最值得调整。
先看官方基线里的楼梯训练
legged_gym 的 terrain curriculum 里包含 stairs:
terrain_proportions = [0.1, 0.1, 0.35, 0.25, 0.2] |
在 terrain 生成里,楼梯高度随 difficulty 增加:
step_height = 0.05 + 0.18 * difficulty |
其中上楼和下楼通过 step_height 正负号区分。
Isaac Lab 的 rough locomotion 配置也保留了几个关键设计:
- terrain generator + terrain levels curriculum;
- height scanner / height scan observation;
- foot contact sensor,并 track air time;
- velocity tracking reward;
feet_air_time;undesired_contacts;- base contact termination;
- friction、base mass、COM、push 等 randomization。
这些设计共同说明:爬楼梯不能只改 reward,还要同时看地形课程、感知输入、接触检测和终止条件。
一句话结论
爬楼梯 reward 调参的优先级,我会这样排:
1. 先保证 terrain curriculum 合理:台阶高度/宽度从简单到困难 |
1. Terrain curriculum:先别一上来训练高台阶
爬楼梯最容易犯的错误是:reward 还没调清楚,就直接给很难的楼梯。
这会导致 policy 早期大量失败,最后学到一些奇怪策略,比如撞上去、跳上去、趴着蹭上去。
推荐调法
1)台阶高度从低到高
可以参考 legged_gym 的思路:
step_height = 0.05 + 0.18 * difficulty |
对应大概是:
简单:5 cm |
真机如果是 Go2 / A1 / 小型四足,建议先从 3~8 cm 开始,不要直接用很高台阶。
2)台阶宽度不要过窄
legged_gym 里 stairs 示例的 step_width=0.31m。如果机器人步长、足端尺寸或控制频率不匹配,台阶太窄会导致踩空非常频繁。
建议先用宽台阶:
step_width: 0.30 ~ 0.40 m 起步 |
等策略稳定后再缩窄。
3)上楼和下楼分开调
上楼和下楼不是同一个问题:
- 上楼需要足端 clearance 和身体抬升;
- 下楼需要落脚控制、接触力控制和防俯冲。
建议先训练上楼,再混入下楼;或者至少分别看两组 eval 视频。
2. Observation:没有高度信息,reward 很难救
爬楼梯强依赖地形感知。如果 policy 只看到 proprioception:
base velocity |
它可能能在固定楼梯上记住一种节奏,但泛化到不同台阶高度、宽度、起点相位时会很差。
推荐加入
1)height scan / terrain height measurements
legged_gym 默认 rough terrain observation 会加入机器人前方和周围的高度采样点:
measured_points_x = [-0.8, ..., 0.8] |
Isaac Lab rough config 里也使用 height_scanner:
height_scanner = RayCasterCfg( |
爬楼梯建议保留这类高度观测。
2)重点覆盖前方落脚区域
爬楼梯主要需要知道前方台阶,所以高度点不要只覆盖身体正下方。
建议:
x 方向覆盖:身体前方 0.2 ~ 1.0 m |
如果高度 scan 太稀疏,台阶边缘会被漏掉。
3. feet clearance:爬楼梯需要,但不能无限奖励
和平地不同,爬楼梯必须鼓励摆动腿抬高,否则脚会撞台阶立面。
但 clearance reward 最忌讳写成:
脚越高 reward 越大 |
这样 policy 很容易学成夸张高抬腿,速度慢、能耗大、真机危险。
推荐写法:目标高度,而不是越高越好
swing = foot_not_in_contact |
对于楼梯,target_clearance 最好不是固定值,而是跟地形高度相关:
目标脚高 = 当前/前方地形高度 + 安全余量 |
安全余量可以先从:
3 ~ 8 cm |
开始试。
如果没有足端目标高度怎么办
可以先用简化版:
reward_clearance = exp(-(foot_height_in_base_frame - target)^2 / sigma) * swing * moving |
但这对不同台阶高度泛化会差一些。
4. feet_air_time:爬楼梯可以比平地更重要,但要门控
爬楼梯时脚需要离地一段时间完成跨台阶,所以 feet_air_time 可以保留。
但要注意:
- 低速/站立时不要奖励原地抬脚;
- 离地太久不应该继续加奖励;
- 上楼和下楼的合适 air time 不同;
- 只奖励 first contact 通常比每步持续奖励更稳。
推荐调法
feet_air_time = 0.2 ~ 0.6 # 起步范围,按量级看曲线 |
并加门控:
moving = norm(command_xy) > 0.15 |
如果出现“楼梯上高抬腿但前进慢”,降低 air time,增强 velocity tracking 和 action cost。
如果出现“脚总撞台阶”,不要只加 air time,更应该加 terrain-aware clearance。
5. collision / stumble / undesired contacts:爬楼梯的核心安全项
楼梯任务里,碰撞惩罚比平地更关键。
需要区分:
允许:足端接触台阶平面 |
1)undesired contacts
Isaac Lab rough cfg 中有:
undesired_contacts = RewTerm( |
爬楼梯建议把 thigh / calf / base 的非期望接触都监控起来。
undesired_contacts: |
2)feet_stumble:防止脚撞立面
legged_gym 里有 feet_stumble 思路:如果足端水平接触力远大于竖直接触力,说明可能在撞垂直面。
norm(contact_force_xy) > k * abs(contact_force_z) |
楼梯上这个项很有用,因为脚撞台阶立面时水平冲击会明显变大。
建议:
feet_stumble = -0.2 ~ -1.0 |
如果这个项太强,机器人可能不敢靠近台阶;要和 clearance / curriculum 一起调。
3)base contact termination
机身碰楼梯通常应该直接 reset。
base_contact -> done |
否则 policy 可能学到“用肚子蹭上去”。
6. base height / orientation:身体要跟着台阶走,不是平地高度固定
平地里 base_height 可以设固定目标,但爬楼梯时地形高度在变化。
如果仍然用固定世界高度目标,机器人上楼时会被错误惩罚。
推荐:相对地形高度
base_height_relative = base_z - terrain_height_under_base |
也就是身体高度目标应该相对于脚下/身体下方地形,而不是世界坐标固定 z。
orientation 不要过强
楼梯上身体可能需要轻微 pitch 调整。orientation / flat_orientation_l2 太强,会让机器人不愿意前倾或调整姿态。
建议:
平地:orientation 可以强一点 |
可以把 roll 和 pitch 分开:
roll 稳定更重要 |
7. velocity tracking:爬楼梯不要一开始追高速
如果速度跟踪奖励太强,policy 会为了追速度冲台阶,导致撞击、跳步、接触力过大。
推荐命令范围
上楼早期:
lin_vel_x = [0.1, 0.4] |
稳定后再扩:
lin_vel_x = [0.0, 0.8] |
爬楼梯初期不建议混太多横向速度和转向,否则问题很难定位。
8. contact forces:下楼尤其重要
下楼时最容易出现:
- 前脚重重砸地;
- base 俯冲;
- 接触力尖峰很大;
- 真机冲击大,电机和减速器压力大。
所以建议打开:
feet_contact_forces |
逻辑:只惩罚超过阈值的接触力。
penalty = sum(clip(norm(contact_force) - max_contact_force, min=0)) |
不要惩罚所有接触力,否则机器人会不敢落脚。
9. action_rate / dof_acc / torques:最后用来收敛动作质量
爬楼梯需要足够大的动作幅度,所以动作代价不能太早太强。
推荐顺序:
先解决能不能上楼 |
调参建议
action_rate = -0.01 ~ -0.03 |
如果机器人脚抬不起来,先不要加大这些惩罚。
如果机器人能上楼但动作抽搐,再增加 action_rate / dof_acc。
10. 推荐 reward 配方:上楼 debug 起点
下面是一个偏工程 debug 的起点,不是标准答案:
class rewards: |
如果使用 Isaac Lab 风格,可以对应到:
track_lin_vel_xy_exp |
并额外自定义 terrain-aware feet_clearance、feet_stumble、feet_slide。
11. 推荐训练流程
Phase 1:低台阶,只上楼
step_height: 3~8 cm |
目标:脚能稳定抬过台阶,机身不碰撞。
Phase 2:增加台阶高度和随机起点
step_height: 5~15 cm |
目标:不靠固定节奏死记硬背。
Phase 3:混入下楼
stairs up + stairs down |
目标:下楼不砸地、不俯冲。
Phase 4:扩展速度和转向
lin_vel_y 小范围打开 |
目标:更接近真实部署。
12. 看曲线时重点看什么
不要只看总 reward,爬楼梯一定要看分项和视频。
关键分项
rew_tracking_lin_vel:是否真的前进 |
视频检查清单
脚是否踩在台阶平面,而不是边缘 |
常见问题与调参方向
1)脚总撞台阶立面
优先调:
增加 terrain-aware feet_clearance |
2)脚抬太高、动作夸张
优先调:
clearance 改成目标高度型 |
3)机身碰台阶
优先调:
base_contact termination |
4)上楼能走,下楼摔
优先调:
单独训练/评估 stairs down |
5)仿真能走,真机不稳
优先查:
台阶尺寸是否随机化 |
总结
爬楼梯不是简单把平地 reward 里的 feet_air_time 调大。更靠谱的思路是:
terrain curriculum 先让任务可学 |
我的建议是先做一个很小的上楼任务:低台阶、低速、无横移、无转向。等它稳定后,再逐步增加台阶高度、随机起点、下楼、转向和 sim2real 随机化。
参考资料
- Nikita Rudin et al., Learning to Walk in Minutes Using Massively Parallel Deep Reinforcement Learning, CoRL 2021 / arXiv:2109.11978.
leggedrobotics/legged_gym:rough terrain locomotion task、terrain curriculum、reward scale 机制。legged_gym/utils/terrain.py:pyramid_stairs_terrain、step_width=0.31、step_height=0.05+0.18*difficulty、stairs up/down terrain generation。legged_gym/envs/base/legged_robot_config.py:rough terrain 的 reward scales、height measurements、terrain proportions。legged_gym/envs/base/legged_robot.py:feet_air_time、stumble、base_height、feet_contact_forces、tracking_lin_vel等 reward 实现。- Isaac Lab locomotion velocity rough config:terrain generator、height scanner、contact sensor、feet air time、undesired contacts、terrain levels curriculum。