概览#
本页带你从零开始上手 RP1,分为三条路线,按你手头的条件选择:
| 路线 | 你需要什么 | 完成后你会得到 |
|---|---|---|
| A. 在仿真中查看 RP1 | 一台能安装 Python 的电脑 | 在 MuJoCo 中打开 RP1 模型,并用一段 Python 脚本让它动起来 |
| B. 训练第一个策略 | Linux 或 Windows 工作站、NVIDIA 显卡 | 一个在 Isaac Lab 中训练的行走策略,并在 MuJoCo 中验证它 |
| C. 实机首次运行 | 一台 RP1(24 轴配置)、游戏手柄、安全吊架 | 用部署仓库自带的策略,让 RP1 在手柄控制下行走 |
三条路线互不依赖,可以从任意一条开始。它们最终汇入同一条开发链路:模型 → 训练 → 导出 → Sim2Sim → 实机。
A. 在仿真中查看 RP1#
这条路线不需要机器人,也不需要显卡。你会在 MuJoCo 中打开 RP1 的模型,再运行一段脚本,让它在"吊架"上摆动手臂。
准备条件#
- Python 3(建议 3.10 及以上)
- 能联网安装 pip 包
- macOS、Linux 或 Windows 均可
A1. 安装 MuJoCo#
pip install mujocoA2. 获取 RP1 模型#
RP1_description 是公开仓库,包含 URDF、MJCF 和网格文件:
git clone https://github.com/Roboparty/RP1_description.git
cd RP1_description仓库中的 MuJoCo 模型:
| 文件 | 内容 |
|---|---|
mjcf/rp1_flat.xml |
28 轴机器人 + 平地场景 |
mjcf/rp1_rough.xml |
28 轴机器人 + 起伏地形场景 |
mjcf/robot.xml |
28 轴机器人本体 |
mjcf/robot_24dof.xml |
24 轴机器人本体(不含地面) |
A3. 打开查看器#
python -m mujoco.viewer --mjcf=mjcf/rp1_flat.xml窗口中会出现 RP1 站在平地上,随后倒下。这是正常的:模型的关节执行器都是力矩电机,没有控制器给它们发指令,机器人就像断电一样瘫软。
在查看器里可以:
- 按 空格 暂停或继续仿真;
- 双击选中一个部件,按住 Ctrl + 右键 拖动给它施加推力;
- 在右侧 Joint 面板查看各关节角度,在 Control 面板查看执行器。
想看 24 轴模型,把文件换成 mjcf/robot_24dof.xml 即可。这个文件只有机器人本体、没有地面,机器人会一直下落,适合静态查看结构。
A4. 让它动起来#
下面的脚本模拟一个吊架:把机身固定在初始高度,再用 PD 控制让两侧肩关节前后摆动。把它保存为 rp1_hold_demo.py,放在 RP1_description 仓库根目录:
"""RP1 MuJoCo 演示:把机身固定在初始位置(相当于吊架),用 PD 控制让手臂摆动。
仅用于查看模型和关节运动,增益是仿真演示值,不是实机参数。"""
import math
import sys
import time
import mujoco
import mujoco.viewer
SCENE = sys.argv[1] if len(sys.argv) > 1 else "mjcf/rp1_flat.xml"
KP, KD = 80.0, 2.0 # 仿真演示用增益
m = mujoco.MjModel.from_xml_path(SCENE)
d = mujoco.MjData(m)
mujoco.mj_forward(m, d)
base_qpos = d.qpos[:7].copy() # 自由关节:位置 xyz + 四元数 wxyz
# 每个执行器驱动的关节在 qpos / qvel 中的位置
joint_ids = m.actuator_trnid[:, 0]
qadr = m.jnt_qposadr[joint_ids]
vadr = m.jnt_dofadr[joint_ids]
names = [m.actuator(i).name for i in range(m.nu)]
print(f"{SCENE}: {m.nu} 个执行器")
def target(name: str, t: float) -> float:
"""肩部 pitch 做正弦摆动,其余关节保持零位。"""
if name.endswith("shoulder_pitch_joint"):
return 0.6 * math.sin(2 * math.pi * 0.5 * t)
return 0.0
def step() -> None:
q = d.qpos[qadr]
dq = d.qvel[vadr]
q_ref = [target(n, d.time) for n in names]
d.ctrl[:] = [KP * (r - qi) - KD * dqi for r, qi, dqi in zip(q_ref, q, dq)]
mujoco.mj_step(m, d)
d.qpos[:7] = base_qpos # 固定机身
d.qvel[:6] = 0.0
if "--headless" in sys.argv:
while d.time < 2.0:
step()
i = names.index("left_shoulder_pitch_joint")
print(f"t={d.time:.2f}s left_shoulder_pitch q={d.qpos[qadr[i]]:+.3f} rad, 目标 {target(names[i], d.time):+.3f} rad")
else:
with mujoco.viewer.launch_passive(m, d) as viewer:
while viewer.is_running():
start = time.time()
step()
viewer.sync()
time.sleep(max(0.0, m.opt.timestep - (time.time() - start)))运行:
python rp1_hold_demo.py mjcf/rp1_flat.xml提示 macOS 上需要用
mjpython代替python运行这个脚本,这是 MuJoCo 被动查看器在 macOS 上的要求。
你会看到 RP1 的机身固定在初始位置、双腿保持伸直,两条手臂以 0.5 Hz 的频率前后摆动约 ±0.6 rad。想换成 24 轴模型,把参数改成 mjcf/robot_24dof.xml。
没有图形界面时,可以加 --headless 只跑 2 秒并打印结果:
mjcf/rp1_flat.xml: 28 个执行器
t=2.00s left_shoulder_pitch q=-0.040 rad, 目标 +0.009 rad最后一行的实际值落后于目标值,是演示增益下 PD 跟踪的滞后,属于正常现象。改 target() 函数,就能让任意关节按你想要的轨迹运动。
B. 训练第一个策略#
这条路线在 Isaac Lab 中训练 RP1 的平地行走策略,导出后放进 MuJoCo 检查它能不能在另一个物理引擎里同样工作。
准备条件#
| 项目 | 要求 |
|---|---|
| 操作系统 | Ubuntu 22.04 x64 或 Windows x64 |
| 显卡 | NVIDIA GPU,驱动与 CUDA 满足 Isaac Sim 要求 |
| Python | 3.11 |
| 仿真 | Isaac Sim 5.1.0、Isaac Lab 2.3.2 |
先按 Isaac Lab 官方安装指南 装好 Isaac Sim 和 Isaac Lab。以下所有命令都在 Isaac Lab 使用的 Python 环境中执行。
B1. 获取训练代码#
把仓库克隆到 Isaac Lab 源码目录之外:
git clone https://github.com/Roboparty/RP1_train.git
cd RP1_train仓库包含两个目录:robolab(RoboParty 的 Isaac Lab 扩展、任务和机器人资产)和 rsl_rl(强化学习库)。
B2. 安装#
pip install -e ./robolab
pip install -e ./rsl_rl确认 RP1 的任务已经注册(Linux 下):
grep -rn 'id="RP1.3' robolab/robolab/tasks预期能看到 RP1.3-Flat、RP1.3-Rough、RP1.3-AMP、RP1.3-AMP-Play 和 RP1.3-BeyondMimic。
注意 仓库自带的
list_envs.py只列出名字含 "RPO" 的任务,看不到 RP1 的任务,这不代表安装失败。
B3. 先跑一次链路检查#
用 1 个环境、1 次迭代确认 Isaac Sim 能启动、任务能加载、训练能跑通:
python robolab/scripts/rsl_rl/train.py --task=RP1.3-Flat --headless \
--logger=tensorboard --num_envs=1 --max_iterations=1预期结果:程序正常退出,并在 logs/rsl_rl/rp1.3_flat/ 下生成一个以时间命名的 run 目录。这个 run 只用来检查环境,不用于部署。
B4. 正式训练#
去掉链路检查用的两个参数,使用任务默认配置:
python robolab/scripts/rsl_rl/train.py --task=RP1.3-Flat --headless --logger=tensorboard默认配置为 4096 个并行环境、9001 次迭代,每 1000 次迭代保存一个 checkpoint。显存不够时用 --num_envs 减少并行环境数;用 --max_iterations 调整训练长度。
训练过程中,用 TensorBoard 查看奖励曲线:
tensorboard --logdir logs/rsl_rl/rp1.3_flat每个 run 目录中保存了 checkpoint,以及记录本次训练配置的 params/env.yaml 和 params/agent.yaml。
提示 想在起伏地形上训练,把任务换成
RP1.3-Rough,日志会写入logs/rsl_rl/rp1.3_rough/。
B5. 回放并导出策略#
训练结束后,选一个 checkpoint 回放:
python robolab/scripts/rsl_rl/play.py --task=RP1.3-Flat --num_envs=1 \
--checkpoint logs/rsl_rl/rp1.3_flat/<run 目录>/model_<迭代数>.ptIsaac Sim 窗口中会出现 RP1 按速度指令行走。play.py 同时会自动导出两个文件到 checkpoint 所在目录下的 exported/:
| 文件 | 格式 | 用途 |
|---|---|---|
policy.pt |
TorchScript | MuJoCo Sim2Sim |
policy.onnx |
ONNX | 实机部署 |
观测归一化参数已经打包进这两个文件,不需要另外保存。
B6. 在 MuJoCo 中做 Sim2Sim#
在仓库根目录运行:
python robolab/scripts/mujoco/sim2sim_rp1.3.py \
--load_model logs/rsl_rl/rp1.3_flat/<run 目录>/exported/policy.pt把 --load_model 换成上一步 exported/policy.pt 的实际路径。脚本会打开 MuJoCo 窗口,让你训练的策略控制 24 轴 RP1。
几点说明:
- 默认指令是原地转向。 速度指令写在
robolab/scripts/mujoco/sim2sim_rpo.py的cmd类中,默认vx = 0.0、vy = 0.0、dyaw = 0.8,机器人会以 0.8 rad/s 原地旋转。想让它向前走,就修改这几个值。 - 结果文件。 脚本按配置运行(默认仿真时长 1000 秒),结束后把
joint_positions.png和base_velocities.png保存到当前工作目录;加--headless时不开窗口,并把画面录成当前目录下的simulation.mp4。 - 起伏地形。 加
--terrain换用起伏地形场景。 - 缺少依赖时。 如果提示找不到
mujoco_viewer或cv2,分别安装mujoco-python-viewer和opencv-python。
注意 Sim2Sim 用的
rp1_flat.xml来自 RP1_train 仓库,引用的是 24 轴模型;RP1_description 里同名的文件引用的是 28 轴模型,两者不要混用。
Sim2Sim 能稳定行走,说明策略对物理引擎之间的差异有一定的适应能力,这是上实机前的必要一步。但从仿真到实机还要核对关节方向、零位、IMU 安装方向和反馈延迟等因素,Sim2Sim 通过不等于实机一定能走。
C. 实机首次运行#
这条路线用部署仓库 RP1_deploy 自带的 24 轴策略,让 RP1 在手柄控制下站立和行走。
注意:先读完这一段再上电
- 标零、复位和首次推理都会让电机突然输出力矩。这些操作必须在承重安全吊架上进行,机器人悬空、场地清空、有人看护。
- 运行中出现任何异常抖动、步态偏离或结构干涉,立即按手柄 X 键让电机失能;如果软件没有响应,立即按下物理急停切断电源。
- 手柄的 X 键和
stop_inference服务都是软件停止,不能代替物理急停。开始前确认急停开关在手边且能正常工作。- RoboParty 已发布的 安全操作指南 面向上一代机器人 Roboto Origin,与 RP1 共用同一套部署软件和手柄操作,请一并阅读。
准备条件#
| 项目 | 要求 |
|---|---|
| 机器人 | RP1,24 轴配置(5 自由度手臂),已完成装配 |
| 主控系统 | Ubuntu 22.04 + ROS 2 Humble |
| 手柄 | 支持 XInput 的游戏手柄,接收器插在主控的 USB 口上 |
| 场地 | 承重安全吊架、平整地面、可随手按到的物理急停 |
| 连接 | 用网线或无线网络 SSH 登录主控 |
C1. 安装依赖#
在主控上安装构建与运行依赖:
sudo apt update
sudo apt install -y ccache libfmt-dev libspdlog-dev libeigen3-dev screen
sudo apt install -y ros-humble-joy
sudo apt install -y python3-yaml python3-numpy第二行是手柄驱动,第三行是标零等 Python 脚本的依赖。
为当前用户开放实时优先级。编辑 /etc/security/limits.conf,在末尾加入两行(把 <用户名> 换成你登录主控的用户名):
<用户名> - rtprio 98
<用户名> - memlock unlimited重启主控后检查:
ulimit -r输出 98 即配置成功。
C2. 获取并构建部署代码#
git clone https://github.com/Roboparty/RP1_deploy.git
cd RP1_deploy
source /opt/ros/humble/setup.bash
colcon build --symlink-install
source install/setup.bashinstall/setup.bash 是编译产物,首次编译成功后才会出现。以后每打开一个新终端,都要重新执行两条 source:
source /opt/ros/humble/setup.bash
source install/setup.bashC3. 检查设备接口#
RP1 的电机挂在 4 路 CAN-FD 总线上,IMU 通过独立的 CAN 接口接入。24 轴配置(src/inference/robots/rp1_24dof/robot.yaml)使用以下接口:
| 接口 | 连接的设备 |
|---|---|
can1 |
左腿 6 个电机 + 腰部 Yaw |
can2 |
右腿 6 个电机 + 腰部 Roll |
can0 |
左臂 5 个电机 |
can3 |
右臂 5 个电机 |
can_hipnuc |
IMU(HiPNUC) |
上电后列出网络接口,确认以上 5 个接口都存在:
ip -brief link再查看某个接口的详细状态和收发统计(把 can0 换成要检查的接口):
ip -details -statistics link show can0这两条命令只读取状态,不会给电机发任何指令。
C4. 确认零位#
电机零位决定了软件里的"0 度"对应机器人的哪个姿态,零位不对时策略输出的每个动作都会偏。机器人已经标定过零位时可以跳过本步;首次装机、更换或检修电机、零点丢失时,需要重新标零。
需要逐个电机标零时,把机器人挂上吊架,然后运行:
python3 scripts/set_zero.py脚本按 scripts/config/set_zero.yaml 中的顺序依次处理每个电机(这份配置已经对应 RP1 24 轴的总线和电机 ID),并把电机切到阻尼模式,方便你用手摆姿态。按提示把当前电机摆到零位,按 Enter 写入零点,按 空格 跳过。
注意
robot.yaml中的motor_zero_offset记录了每个电机相对标零姿态的偏移,它与标零时的摆位方式一一对应。重新标零前,先确认你的摆位方式和这组偏移值匹配,否则机器人复位后的姿态会不对。
C5. 启动部署软件#
确认机器人挂在吊架上、电机处于失能状态,然后在仓库根目录运行:
./tools/start_robot.sh --robot rp1_24dof --policy default注意 一定要写
--robot rp1_24dof。脚本和 launch 文件的默认机器人都是rpo(上一代机器人),不指定就会加载错误的配置。
脚本会先编译工作空间,然后在后台启动两个 screen 会话:
| 会话 | 内容 |
|---|---|
inference_session |
推理节点:读取传感器、运行策略、下发关节指令 |
joy_session |
手柄节点 |
最后打印"所有组件已在后台成功启动!"和手柄按键说明。查看推理节点的输出:
screen -r inference_session确认没有报错后,按 Ctrl + A,再按 D 退出查看(节点继续在后台运行)。
C6. 用手柄让 RP1 站起来并行走#
| 按键 | 作用 |
|---|---|
| X | 使能 / 失能电机 |
| A | 复位:关节平滑运动到默认站立姿态 |
| B | 开始 / 暂停推理 |
| 右摇杆 | 前后左右移动 |
| LT / RT | 向左 / 向右转 |
| Y | 切换手柄控制 / /cmd_vel 话题控制 |
按以下顺序操作:
- 使能。 机器人仍挂在吊架上,按 X 使能电机。确认无误后可以再按一次 X 测试失能,然后重新使能。
- 复位。 先用手把机器人大致摆成站立姿态,再按 A。关节会平滑运动到默认站立角度。姿态差得越多,复位时的动作越猛。
- 落地。 复位完成后,把机器人从吊架上平稳放下,确认双脚完全踩实地面、重心居中。吊架绳保持在手边。
- 清零摇杆。 按 B 之前,把左右摇杆各向四个方向推到底再松开,并按几次 LT 和 RT,消除摇杆漂移,避免推理一开始就收到残留指令。
- 开始推理。 按 B。RP1 会在原地保持平衡站立。
- 行走。 轻推右摇杆让它前后左右移动,用 LT / RT 转向。默认策略的指令范围为:前进 0.6 m/s、后退 0.4 m/s、横移 0.4 m/s、转向 0.8 rad/s。
- 停止。 按 B 暂停推理,扶住或挂好机器人后按 X 让电机失能。
C7. 关闭软件#
screen -S inference_session -X quit
screen -S joy_session -X quit这只是结束软件会话。关闭前确认电机已经失能、机器人有支撑。
如果推理过程中机器人突然失能瘫软,先保持现场,用 screen -r inference_session 查看报错,常见原因是触发了软件限幅(关节超限、速度超限)或硬件保护(过载、过热、欠压)。断电前把报错日志保存下来,方便定位问题。
C8. 不用手柄:用 ROS 2 服务控制#
部署软件也提供一组 ROS 2 服务,适合写脚本或远程调试。在新终端加载环境后调用:
source /opt/ros/humble/setup.bash
source install/setup.bash
ros2 service call /init_motors std_srvs/srv/Trigger # 初始化电机
ros2 service call /start_inference std_srvs/srv/Trigger # 开始推理
ros2 service call /stop_inference std_srvs/srv/Trigger # 停止推理
ros2 service call /deinit_motors std_srvs/srv/Trigger # 电机去初始化按 Y 切换到 /cmd_vel 控制后,就可以通过 /cmd_vel 话题(geometry_msgs/msg/Twist)发送速度指令。查看当前关节状态:
ros2 topic echo /joint_statesC9. 试试舞蹈#
部署仓库还附带一个 24 轴动作跟踪策略和一段舞蹈动作,用同样的方式启动:
./tools/start_robot.sh --robot rp1_24dof --policy beyondmimic这个配置同时加载默认行走策略和舞蹈策略。推理开始后,按 LB 在行走和动作跟踪之间切换,按 RB 切换动作序列。第一次运行舞蹈时同样要挂吊架,确认动作幅度后再落地。