Go1 RL-Gym 45 维部署说明
本目录包含:
policy_15k.onnx:RoboGauge Go1 RL-Gym 的 ONNX 策略deploy_go1_onnx_mujoco.py:MuJoCo 调试脚本deploy_go1_rlgym_pro_sdk.py:真机 Go1 PRO 低层部署脚本
该 ONNX 策略使用 45 维单帧观测,以及 5 帧、共 225 维的历史输入,按观测项分组堆叠:
[角速度历史, 重力投影历史, 指令历史, 关节位置历史, 关节速度历史, 上一动作历史]
关节顺序为 FR, FL, RR, RL,与 go1_pro_sdk 的电机顺序一致。
安全说明
直接低层控电机是危险操作。
- 第一次测试必须悬空
- 低层控制前先杀掉 sport 进程
- sport 被杀后,要保留拔电池作为最终停机手段
- 真机状态机中,
L2会返回IDLE阻尼 Ctrl+C会通过safe_stop()退出- 只有显式加
--enable-rl才允许真正进入 RL 发电机目标 - 脚本启动连接 MCU 前会自动检查 SDK 电机顺序是否为
FR, FL, RR, RL - 遥控器速度指令默认只保留 deadzone,不再做低通和变化率限制;日志中仍会同时保存原始
commands_raw和实际输入策略的commands - RL 刚进入时会先 warmup,只预热观测历史和动作历史;warmup 期间仍保持默认站姿,结束后再按
max_target_step从默认站姿逐步进入 RL 目标
环境准备
cd /Users/chenyouyuan/cyy_ws/deploy_go1_pro
conda activate free_dog_sdk
杀掉机器人上的 sport 进程:
ssh pi@192.168.123.161 "sudo pkill -9 -f keep_sport_alive; sudo pkill -9 -f Legged_sport; sudo pkill -9 -f appTransit"
或者在部署脚本里直接加 --kill-sport。
脚本执行 --kill-sport 时,会打印并执行等价的 SSH 命令。如果不加
--kill-sport,请务必手动执行上面的命令。
启动前电机顺序检查
真机脚本启动连接 MCU 前会自动检查:
SDK 顺序必须是:
FR_0 FR_1 FR_2
FL_0 FL_1 FL_2
RR_0 RR_1 RR_2
RL_0 RL_1 RL_2
策略顺序对应:
FR_hip FR_thigh FR_calf
FL_hip FL_thigh FL_calf
RR_hip RR_thigh RR_calf
RL_hip RL_thigh RL_calf
如果 SDK 顺序不一致,脚本会直接报错并停止,不会继续连接机器人。
检查通过时会打印类似:
[INFO] Joint order check passed: SDK and policy both use FR, FL, RR, RL.
[00] FR_0 -> FR_hip default=-0.100
[01] FR_1 -> FR_thigh default=+0.800
[02] FR_2 -> FR_calf default=-1.500
...
[11] RL_2 -> RL_calf default=-1.500
连接成功后,脚本还会逐项打印当前电机角度和默认角度:
[INFO] Initial joint positions (rad):
[00] FR_0: q=..., default=-0.100
...
[11] RL_2: q=..., default=-1.500
第 1 步:只取数据
只读 LowState、IMU、关节和遥控器数据,不发任何电机命令。
mjpython deploy_45dim_rl_gym/deploy_go1_rlgym_pro_sdk.py \
--monitor \
--kill-sport \
--log-dir logs
检查:
- 电量正常
- 机器人姿态变化时,RPY 会跟着变化
- 12 个关节位置不是全 0
- 遥控器按键和摇杆变化能正常打印
第 2 步:测试遥控器
继续用 --monitor,依次测试:
- 按
R2 - 按
L2 - 左摇杆前后、左右
- 右摇杆左右
期望结果:
pressed、rising、falling会正确变化lx、ly、rx会正确变化- 不会有任何电机动作
第 3 步:测试观测构建
只构建 45 维观测和 225 维 ONNX 历史输入,不做 RL 控制。
mjpython deploy_45dim_rl_gym/deploy_go1_rlgym_pro_sdk.py \
--obs-check \
--kill-sport \
--log-dir logs
检查:
- 站立时重力投影接近
[0, 0, -1] - 指令观测会随遥控器变化
q-qd max在合理范围内- ONNX 输入形状是
(1, 225)
第 4 步:只测试 ONNX 推理
只跑 ONNX 推理,不发 RL 电机目标。
mjpython deploy_45dim_rl_gym/deploy_go1_rlgym_pro_sdk.py \
--infer-check \
--kill-sport \
--log-dir logs
检查:
action_raw max不会突然爆大- 零指令时动作应比较稳定
- 长时间给 yaw 指令时,动作不应持续发散
第 5 步:测试状态机和退出
不加 --enable-rl,这样只会走校准、保持、观测和推理层,不会真正进入 RL 电机控制。
mjpython deploy_45dim_rl_gym/deploy_go1_rlgym_pro_sdk.py \
--kill-sport \
--log-dir logs
遥控器操作步骤
先把机器人悬空,四条腿下方不要站人,手指始终放在 L2 上。每按一次 R2 后都要等终端打印出对应状态,并观察 5 到 10 秒再按下一次。
启动后:
状态应为 IDLE
电机处于阻尼/空闲,不应主动站立
第 1 次按 R2:
IDLE -> CALIBRATE -> HOLD
机器人会缓慢回到默认站姿
等终端打印 [STATE] HOLD
第 2 次按 R2:
HOLD -> OBS_TEST
电机仍保持默认站姿
只构建观测,不使用 ONNX 动作控制电机
第 3 次按 R2:
OBS_TEST -> INFER_TEST
电机仍保持默认站姿
只运行 ONNX 推理,动作只写日志,不控制电机
第 4 次按 R2:
未加 --enable-rl 时会被守卫拦住
终端应打印 RL blocked
任意激活状态按 L2:
立即回到 IDLE 阻尼
Ctrl+C:
调用 safe_stop() 并退出脚本
必须确认:
R2 每次只前进一层
L2 在 HOLD / OBS_TEST / INFER_TEST 都能回到 IDLE
松开 R2/L2 后,日志里 rising/falling 不应连续乱跳
摇杆不动时,lx/ly/rx/ry 应接近 0
检查:
- 校准会缓慢回到默认站姿
HOLD会保持默认站姿L2能回到IDLECtrl+C会正常打印Safe stopping...并退出
第 6 步:悬空 RL 测试
只有前 1 到 5 步都稳定后,才加 --enable-rl 进行悬空 RL。第一轮必须先隔离遥控器摇杆输入,用 --no-rc 固定零指令,只用遥控器按键切状态:
mjpython deploy_45dim_rl_gym/deploy_go1_rlgym_pro_sdk.py \
--kill-sport \
--enable-rl \
--no-rc \
--cmd-x 0 --cmd-y 0 --cmd-yaw 0 \
--log-dir logs \
--kp 60 --kd 1.0 \
--kp-cal 20 --kd-cal 1.0 \
--power-factor 6 \
--position-protect-limit 0.8 \
--action-clip 2.5 \
--action-trip-limit 8.0 \
--max-target-step 0.04 \
--max-roll-deg 25 \
--max-pitch-deg 25
RL 遥控器操作步骤
第一轮带 --no-rc,摇杆不会进入策略,只用 R2 和 L2 切状态。每一步都等终端状态确认后再继续。
启动后:
状态应为 IDLE
第 1 次按 R2:
IDLE -> CALIBRATE -> HOLD
等站姿稳定
第 2 次按 R2:
HOLD -> OBS_TEST
等 5 到 10 秒,确认 RPY、q 和 dq 稳定
第 3 次按 R2:
OBS_TEST -> INFER_TEST
等 5 到 10 秒,确认 action_raw_max 不突然变大
第 4 次按 R2:
INFER_TEST -> RL
先只观察 10 到 20 秒,不推摇杆
RL 中再按 R2:
RL -> HOLD
用来从 RL 平稳退回保持站姿
任意异常立即按 L2:
回到 IDLE 阻尼
需要退出脚本:
先按 L2 回 IDLE
再 Ctrl+C
悬空 RL 时:
- 先用
--no-rc保持零指令 - 零指令稳定后,再取消
--no-rc并用很小的摇杆比例 - 观察
action_raw_max、action_safe_max、RPY 和关节目标 - 刚进入 RL 的前
warmup_steps帧不会真正发送 RL 目标,之后目标应按max_target_step平滑变化 - 一旦动作或姿态不对,立刻按
L2
参数逐层强化
建议先用小参数,再逐层加到当前目标值。前一层如果还不稳定,不要跳层。每层至少稳定 1 到 2 分钟再升级。
第 0 层:完全不控电机
先跑:
mjpython deploy_45dim_rl_gym/deploy_go1_rlgym_pro_sdk.py --monitor --kill-sport --log-dir logs
mjpython deploy_45dim_rl_gym/deploy_go1_rlgym_pro_sdk.py --obs-check --kill-sport --log-dir logs
mjpython deploy_45dim_rl_gym/deploy_go1_rlgym_pro_sdk.py --infer-check --kill-sport --log-dir logs
只有在状态、遥控、观测和动作日志都正常时,才进入下一层。
第 1 层:弱校准和保持
先不进 RL,只测试起立、保持、R2、L2 和 Ctrl+C。
mjpython deploy_45dim_rl_gym/deploy_go1_rlgym_pro_sdk.py \
--kill-sport \
--log-dir logs \
--kp 20 --kd 0.7 \
--kp-cal 10 --kd-cal 0.7 \
--power-factor 3 \
--position-protect-limit 0.4
只有在校准平滑、能稳定保持、L2 能可靠回到 IDLE 时才升级。
第 2 层:中等校准和保持
仍然不进 RL。
mjpython deploy_45dim_rl_gym/deploy_go1_rlgym_pro_sdk.py \
--kill-sport \
--log-dir logs \
--kp 40 --kd 0.8 \
--kp-cal 15 --kd-cal 0.8 \
--power-factor 5 \
--position-protect-limit 0.6
只有在保持姿态稳定、关节不抖时才继续。
第 3 层:保守悬空 RL,固定零指令
开始允许 RL,但固定零指令,先确认策略本体能悬空稳定,不测试摇杆速度指令。
mjpython deploy_45dim_rl_gym/deploy_go1_rlgym_pro_sdk.py \
--kill-sport \
--enable-rl \
--no-rc \
--cmd-x 0 --cmd-y 0 --cmd-yaw 0 \
--log-dir logs \
--kp 60 --kd 1.0 \
--kp-cal 20 --kd-cal 1.0 \
--power-factor 6 \
--position-protect-limit 0.8 \
--action-clip 2.5 \
--action-trip-limit 8.0 \
--max-target-step 0.04 \
--max-roll-deg 25 \
--max-pitch-deg 25
只有在悬空 RL 零指令稳定时才进入下一层。
第 3.5 层:保守悬空 RL,小遥控比例
取消 --no-rc,但先把摇杆比例限制到小范围。脚本默认还会对遥控器命令做 deadzone、低通和变化率限制。
如果加 --swap-vy-yaw,遥控映射会变成:
左摇杆前后 ly -> vx
左摇杆左右 lx -> yaw
右摇杆左右 rx -> vy
mjpython deploy_45dim_rl_gym/deploy_go1_rlgym_pro_sdk.py \
--kill-sport \
--enable-rl \
--log-dir logs \
--kp 60 --kd 1.0 \
--kp-cal 20 --kd-cal 1.0 \
--power-factor 6 \
--position-protect-limit 0.8 \
--action-clip 2.5 \
--action-trip-limit 8.0 \
--max-target-step 0.06 \
--max-roll-deg 25 \
--max-pitch-deg 25 \
--swap-vy-yaw \
--rc-vx-scale 0.3 \
--rc-vy-scale 0.15 \
--rc-wz-scale 0.5
这一层不要直接长时间满杆。建议按下面顺序测,每次给很短的摇杆脉冲,松杆回中后等姿态稳定再继续:
进入 RL 后先零摇杆观察 10 秒
左摇杆前后:
ly 轻推到约 1/3 行程,保持 0.5 到 1 秒,松开
观察 roll/pitch、qvel、action_raw_max
左摇杆左右:
加 --swap-vy-yaw 后控制 yaw
lx 轻推到约 1/3 行程,保持 0.5 到 1 秒,松开
如果 yaw 仍慢,可以逐步把 --rc-wz-scale 从 0.5 提到 0.7
右摇杆左右:
加 --swap-vy-yaw 后控制 vy
rx 轻推到约 1/3 行程,保持 0.5 到 1 秒,松开
观察横向动作是否明显发散
任何时候:
action_raw_max 接近 2.0、qvel 明显变大、roll/pitch 持续变大,立即按 L2
这一层重点检查 commands_raw 和 commands:默认无命令滤波时两者应基本一致。如果手动启用了 --cmd-ema-alpha 或 --max-cmd-step-*,则 commands 会比 commands_raw 更慢变化。
第 4 层:当前目标参数
这是当前想要的正式参数。只有第 3 层和第 3.5 层都稳定后再用。
mjpython deploy_45dim_rl_gym/deploy_go1_rlgym_pro_sdk.py \
--kill-sport \
--enable-rl \
--log-dir logs \
--kp 80 --kd 1.0 \
--kp-cal 20 --kd-cal 1.0 \
--power-factor 7 \
--position-protect-limit 1.0 \
--action-clip 4.0 \
--action-trip-limit 12.0 \
--max-target-step 0.08 \
--swap-vy-yaw \
--rc-vx-scale 0.5 \
--rc-vy-scale 0.25 \
--rc-wz-scale 0.7
这些值仍低于全遥控比例,用来逐步靠近正式测试;不要直接用满 1.0/0.5/1.0。
第 7 步:上地面测试
只有悬空 RL 稳定后,才能落地。
- 把机器人放到平地上
- 零指令进入 RL
- 先让它站稳
- 再给小指令
建议起始范围:
ly <= 0.2
lx <= 0.1
rx <= 0.2
如果出现以下情况,立即按 L2:
- 动作越来越大
- roll 或 pitch 持续变大
- 腿乱甩
- 机器人开始摔倒或打滑
15 cm 台阶测试参数
stairs_3.xml 的单级高度约 0.14 m。从 MuJoCo 采样和真机日志看,上台阶时 pitch 到 25 deg 以上、roll 短时超过 35 deg 都可能出现。台阶测试不要继续用平地/悬空的 25 deg 或 35 deg 姿态保护。
建议台阶第一轮用下面这组。它比平地测试放开姿态和动作幅度,但仍保留目标位置变化率限制,避免单帧目标跳变太大:
mjpython deploy_45dim_rl_gym/deploy_go1_rlgym_pro_sdk.py \
--kill-sport \
--enable-rl \
--log-dir logs \
--kp 40 --kd 0.8 \
--kp-cal 20 --kd-cal 1.0 \
--power-factor 6 \
--position-protect-limit 1.2 \
--action-clip 4.0 \
--action-trip-limit 9.0 \
--max-target-step 0.15 \
--max-roll-deg 45 \
--max-pitch-deg 45 \
--swap-vy-yaw \
--rc-vx-scale 0.5 \
--rc-vy-scale 0.5 \
--rc-wz-scale 1.0
如果动作幅度仍明显不够,再把 --max-target-step 从 0.15 加到 0.20。只有确认目标变化率限制确实挡住抬腿时,才短时间对照测试 --max-target-step 0。
--action-trip-limit 9.0 只是把 raw action 的异常停机阈值从 8.0 放宽到 9.0;实际发给关节目标的动作仍会先被 --action-clip 4.0 裁剪,所以它不会直接增加腿部动作幅度。如果 raw action 经常超过 9.0,说明观测或姿态已经明显偏离训练分布,应按 L2 退回而不是继续放大阈值。
--max-target-step 0 的意思是关闭单步目标变化率限制,不是关闭关节硬限位、action clip 或 SDK 安全保护。真机日志 rlgym_go1_deploy_20260724_172122 里,max_target_step=0、position_protect_limit=1.5、power_factor=9 时触发的是实测扭矩保护:tauEst 已超过 SDK 的 TAU_MAX,所以脚本会进入 FAULT 并阻尼停机。
这只是放宽姿态保护,不是关闭全部安全保护。action_trip_limit、max_dof_vel、max_gyro、position_protect_limit、实测扭矩保护和 L2 急停仍然保留。
注意:--power-factor 主要限制命令力矩 tau 的比例;这个部署脚本发送的是位置控制,命令 tau=0。实测 tauEst 超过 SDK TAU_MAX 时,即使 power_factor=9 也会停机。遇到这种停机,优先减小瞬时目标跳变或速度指令,不要继续只增大 power_factor。
目前台阶实测后的建议顺序:
第一轮: position_protect_limit=1.2, max_target_step=0.15, power_factor=6
第二轮: position_protect_limit=1.2, max_target_step=0.20, power_factor=6
第三轮: position_protect_limit=1.5, max_target_step=0.20, power_factor=6 或 7
短时对照: position_protect_limit=1.5, max_target_step=0, power_factor=6 或 7
如果出现 PowerProtectViolation,说明已经是实测扭矩过载边缘。下一轮建议回退到上一层参数,或者降低 --rc-vx-scale / 避免连续满前进杆。
MuJoCo 键盘 sim2sim
键盘控制测试直接用本目录的 deploy_go1_onnx_mujoco.py。它加载同一个 policy_15k.onnx,使用 45 维观测和 5 帧 ONNX 历史,在 MuJoCo 里做位置 PD 控制。
平地启动:
cd /Users/chenyouyuan/cyy_ws/deploy_go1_pro
conda activate free_dog_sdk
mjpython deploy_45dim_rl_gym/deploy_go1_onnx_mujoco.py \
--clip-actions 4.0 \
--max-target-step 0.15
楼梯 level 3 启动:
cd /Users/chenyouyuan/cyy_ws/deploy_go1_pro
conda activate free_dog_sdk
mjpython deploy_45dim_rl_gym/deploy_go1_onnx_mujoco.py \
--terrain terrains/stairs/stairs_3.xml \
--spawn-x -0.6 \
--spawn-z 0.34 \
--clip-actions 4.0 \
--max-target-step 0.15
如果你想对照策略原始动作能力,可以短时间把 --max-target-step 改成 0.0:
mjpython deploy_45dim_rl_gym/deploy_go1_onnx_mujoco.py \
--terrain terrains/stairs/stairs_3.xml \
--spawn-x -0.6 \
--spawn-z 0.34 \
--clip-actions 4.0 \
--max-target-step 0.0
键盘控制:
方向键 ↑ / ↓ : 前进 / 后退
方向键 ← / → : 左转 / 右转 yaw
, / . : 左移 / 右移 vy
K : 零速度指令
R : 重置机器人
Esc : 退出
如果键盘没有响应,先点一下 MuJoCo 窗口或终端,让当前窗口获得焦点。macOS 第一次使用 pynput 可能需要给终端或 Python 辅助功能权限。
MuJoCo 楼梯采样
可以先在 MuJoCo 里固定前进指令采样楼梯 level 3。stairs_3.xml 的单级高度约 0.14 m,接近 15 cm 台阶。
默认前进速度、真机放开动作幅度、但保留较严格目标步长限制:
conda activate free_dog_sdk
mjpython deploy_45dim_rl_gym/deploy_go1_onnx_mujoco.py \
--sample-stairs-level 3 \
--sample-seconds 10 \
--sample-cmd-x 1.0 \
--sample-cmd-y 0 \
--sample-cmd-yaw 0 \
--clip-actions 4.0 \
--max-target-step 0.08 \
--sample-log-dir logs
如果 0.08 在楼梯上动作太小,可以用下面这个对照测试策略原始能力:
mjpython deploy_45dim_rl_gym/deploy_go1_onnx_mujoco.py \
--sample-stairs-level 3 \
--sample-seconds 10 \
--sample-cmd-x 1.0 \
--sample-cmd-y 0 \
--sample-cmd-yaw 0 \
--clip-actions 4.0 \
--max-target-step 0.0 \
--sample-log-dir logs
采样日志会保存:
logs/mujoco_stairs_sample_YYYYMMDD_HHMMSS/
metadata.json
steps.jsonl
summary.json
重点看:
fallenbase_x_progressrpy_min_deg/rpy_max_degaction_raw_maxabsaction_applied_maxabstarget_offset_maxabsdof_vel_maxabs
日志
日志会保存在:
logs/rlgym_go1_deploy_YYYYMMDD_HHMMSS/
metadata.json
steps.jsonl
常看字段:
commandscommands_rawobs_singleaction_rawaction_safejoint_targetsdof_posdof_velbase_ang_velprojected_gravityimu_rpy_degstate_reason
常用默认值
真机部署脚本使用的默认值如下:
kp = 80.0
kd = 1.0
kp_cal = 20.0
kd_cal = 1.0
power_factor = 7
position_protect_limit = 1.0
action_ema_alpha = 0.0
rc_deadzone = 0.05
cmd_ema_alpha = 1.0
max_cmd_step_x = 0.0
max_cmd_step_y = 0.0
max_cmd_step_yaw = 0.0
rate_hz = 50.0
这些值来自之前成功的 Go1 PRO 低层部署经验。rlgym_go1_deploy_20260724_193128 和 rlgym_go1_deploy_20260724_193318 对照显示,当前 45 维策略在真机上关闭遥控器命令低通/变化率限制更稳定;如需重新启用滤波,应只作为单独变量短时对照测试。
RoboGauge 策略自己的参数不要照搬旧的 57 维策略:
action_scale = 0.25
default_dof_pos = FR, FL, RR, RL 顺序下的 [-0.1/0.1, 0.8/1.0, -1.5]
history_len = 5
onnx_input_dim = 225