unitree_rl_gym 实物部署实战:在 Unitree G1 / H1 / H1_2 真机上运行强化学习策略

unitree_rl_gym 实物部署实战:在 Unitree G1 / H1 / H1_2 真机上运行强化学习策略 unitree_rl_gym 实物部署实战在 Unitree G1 / H1 / H1_2 真机上运行强化学习策略【免费下载链接】unitree_rl_gym项目地址: https://gitcode.com/GitHub_Trending/un/unitree_rl_gym本文以仓库deploy/deploy_real模块为主体完整讲解如何把 legged_gym 训练好的网络策略部署到 Unitree G1、H1、H1_2 实物机器人上从启动命令、网卡配置、遥控器操作流程到 DDS 通信、状态机与观测构造的源码级原理。读完本文你将掌握一套可直接照做的真机部署操作手册并理解deploy_real.py内部零力矩 → 默认位姿 → 运动控制 → 阻尼退出的完整控制闭环。一、部署模块概览支持机型与目录结构该模块的目标是把训练好的强化学习策略部署到实物机器人上目前仓库明确支持的机型为 Unitree G1、H1、H1_2对应三份预训练权重与三份部署配置机型配置文件预训练策略权重DDS 消息类型IMU 安装位置G1configs/g1.yamldeploy/pre_train/g1/motion.pthgpelvis骨盆H1configs/h1.yamldeploy/pre_train/h1/motion.ptgotorso躯干H1_2configs/h1_2.yamldeploy/pre_train/h1_2/motion.pthgtorso躯干部署代码的核心入口为 deploy/deploy_real/deploy_real.py其主要目录结构如下deploy/deploy_real/ ├── deploy_real.py # 主程序状态机 策略推理 指令下发 ├── config.py # Config 类加载并解析 yaml 配置 ├── configs/ # 三份机型配置 │ ├── g1.yaml │ ├── h1.yaml │ └── h1_2.yaml └── common/ ├── command_helper.py # 零力矩/阻尼指令、LowCmd 初始化、电机模式定义 ├── remote_controller.py # 遥控器按键/摇杆解码KeyMap └── rotation_helper.py # 重力朝向提取、IMU 坐标系变换配套的预训练权重位于 deploy/pre_train/ 下每个机型一份motion.ptTorchScript 格式由torch.jit.load直接加载推理。仓库内还提供了基于 C 的部署实现deploy/deploy_real/cpp_g1/本文以官方文档对应的 Python 部署流程为主线展开。二、启动用法命令行参数说明部署程序通过命令行传入两个位置参数启动完整命令格式为python deploy_real.py {net_interface} {config_name}两个参数的含义与 deploy_real.py 中的argparse定义一一对应参数含义示例说明net_interface与机器人直连的网卡名称enp3s0用ifconfig命令查看作为 DDS 通信的网卡绑定参数config_name配置文件名g1.yaml程序会在deploy/deploy_real/configs/目录下查找该文件以 G1 机器人为例假设当前连接真机的网卡名为enp3s0python deploy_real.py enp3s0 g1.yaml程序内部会通过LEGGED_GYM_ROOT_DIR拼出配置文件完整路径{LEGGED_GYM_ROOT_DIR}/deploy/deploy_real/configs/{config_name}再由 config.py 中的Config类以yaml.FullLoader加载并解析见 deploy_real.py。也就是说配置文件名必须与configs/目录下的文件名完全一致否则会因文件不存在而启动失败。三、配置文件逐项解读以 g1.yaml 为例三份配置的结构完全一致差异仅在于具体数值。这里以 configs/g1.yaml 为蓝本逐项拆解并指出各参数在源码中的消费位置control_dt: 0.02 # 控制周期秒即 50Hz 控制频率 msg_type: hg # DDS 消息类型hg 或 go imu_type: pelvis # IMU 坐标系torso 或 pelvis lowcmd_topic: rt/lowcmd # 指令发布主题 lowstate_topic: rt/lowstate # 状态订阅主题 policy_path: {LEGGED_GYM_ROOT_DIR}/deploy/pre_train/g1/motion.pt # 策略权重路径 # 腿部关节电机索引 → 关节索引映射 leg_joint2motor_idx: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] kps: [100, 100, 100, 150, 40, 40, 100, 100, 100, 150, 40, 40] # 位置增益 kds: [2, 2, 2, 4, 2, 2, 2, 2, 2, 4, 2, 2] # 速度增益 default_angles: [-0.1, 0.0, 0.0, 0.3, -0.2, 0.0, -0.1, 0.0, 0.0, 0.3, -0.2, 0.0] # 默认关节角rad # 手臂与腰部关节电机索引 → 关节索引映射 arm_waist_joint2motor_idx: [12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28] arm_waist_kps: [300, 300, 300, 100, 100, 50, 50, 20, 20, 20, 100, 100, 50, 50, 20, 20, 20] arm_waist_kds: [3, 3, 3, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 1, 1, 1] arm_waist_target: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] # 手臂/腰部目标角 # 观测与动作缩放对应训练时 sim 侧的配置 ang_vel_scale: 0.25 # 角速度观测缩放 dof_pos_scale: 1.0 # 关节位置观测缩放 dof_vel_scale: 0.05 # 关节速度观测缩放 action_scale: 0.25 # 策略输出 → 关节位置增量 的缩放 cmd_scale: [2.0, 2.0, 0.25] # 摇杆指令缩放 num_actions: 12 # 动作维度腿部关节数 num_obs: 47 # 观测维度 max_cmd: [0.8, 0.5, 1.57] # 指令上限[x 速度, y 速度, yaw 角速度]各参数的消费位置梳理如下源码佐证msg_type决定使用哪套 DDS 消息结构。hg使用unitree_hg_msg_dds__LowCmd_/LowState_G1、H1_2go使用unitree_go_msg_dds__LowCmd_/LowState_H1分支逻辑见 deploy_real.py非法值会抛出ValueError(Invalid msg_type)。imu_type决定是否需要对 IMU 数据做坐标系变换。pelvis直接使用torsoH1、H1_2需借助腰部偏航角把躯干 IMU 数据变换到骨盆坐标系见 deploy_real.py 与 rotation_helper.py。weak_motor仅 h1.yaml 存在H1 使用go消息时这些电机索引会被设置为弱控制模式mode 1其余电机使用mode 0x0A的位置模式见 command_helper.py。policy_path其中{LEGGED_GYM_ROOT_DIR}占位符会被替换为仓库根目录绝对路径见 config.py。default_angles/kps/kds既用于默认位置状态的位姿保持也作为策略动作叠加的基准target_dof_pos default_angles action * action_scale。max_cmd与cmd_scale共同决定摇杆指令的幅值——观测中的指令项为cmd * cmd_scale * max_cmd。3.1 三份配置的差异速览配置项g1.yamlh1.yamlh1_2.yamlmsg_typehggohgimu_typepelvistorsotorsoweak_motor无[10..19]无num_actions121012num_obs474147腿关节映射顺序 0–11交叉映射[7,3,4,5,10,8,0,1,2,11]顺序 0–11默认关节角[-0.1, 0, 0, 0.3, -0.2, 0]×2[0, 0, -0.1, 0.3, -0.2]×2[0, -0.16, 0, 0.36, -0.2, 0]×2注意 H1 的leg_joint2motor_idx是非顺序的交叉映射电机索引与关节索引不对应部署时务必使用对应机型的配置不可混用。四、启动流程四步实操指南官方文档给出的启动流程分为四步每一步都有明确的机器人状态要求与操作动作下面按顺序展开。4.1 第一步启动机器人将机器人置于吊装状态下启动并等待机器人进入零力矩模式关节完全放松、可自由活动。吊装的意义在于在正式控制前机器人的腿不承受自身重力可避免误动作造成危险。4.2 第二步进入调试模式确认机器人处于零力矩模式后按下遥控器的L2 R2组合键机器人进入调试模式。在调试模式下机器人关节处于阻尼状态有阻尼力矩但无主动位置控制方便人工掰动机器人腿并保持姿态。4.3 第三步连接机器人使用网线将电脑与机器人机身上的网口直连并修改电脑的网络配置为固定 IP使电脑与机器人处于同一网段具体配置可参考原文档插图。随后执行ifconfig查看与机器人相连的网卡名称例如enp3s0记录该名称——它将作为启动命令的第一个参数传入。这一步是 DDS 通信的基础程序启动时会调用ChannelFactoryInitialize(0, args.net)见 deploy_real.py把 DDS 通信绑定到该网卡上。4.4 第四步启动程序以 G1 为例python deploy_real.py enp3s0 g1.yaml程序启动后会先通过wait_for_low_state()循环等待低层状态数据deploy_real.py直到low_state.tick ! 0才打印Successfully connected to the robot.并继续随后按以下四个阶段依次推进。五、程序状态机与源码级原理deploy_real.py的主流程是一个清晰的四阶段状态机其执行顺序见 deploy_real.pyzero_torque_state → move_to_default_pos → default_pos_state → run循环 → create_damping_cmd → 退出5.1 零力矩状态zero torque state启动后机器人所有关节处于零力矩状态kp0, kd0, tau0见 command_helper.py 的create_zero_cmd。程序在此阶段循环等待遥控器start按键期间持续下发零力矩指令。可以用手晃动机器人关节确认零力矩生效。5.2 默认位置状态default pos state按下start键后机器人会先平滑过渡到默认关节位置move_to_default_pos耗时 2 秒、按alpha线性插值见 deploy_real.py随后进入默认位置保持状态。此时机器人双腿由default_angles 腿部kps/kds支撑手臂/腰部由arm_waist_targetarm_waist_kps/kds保持。关键操作在机器人运动到默认关节位置后缓慢下放吊装机构让机器人的脚与地面接触。这步要慢让机器人逐步承重观察其是否稳定。5.3 运动控制模式motion control默认位置状态下按下遥控器A键机器人进入运动控制模式开始原地踏步。在机器人状态稳定后可逐渐降低吊装绳给机器人留出活动空间。此时进入run()主循环deploy_real.py每个控制周期control_dt0.02s即 50Hz执行一轮读取状态 → 构造观测 → 策略推理 → 下发指令。控制循环的核心调用链读取关节状态从low_state.motor_state[leg_joint2motor_idx[i]]读取各腿关节位置q与速度dq读取 IMU 数据取四元数quaternion顺序w,x,y,z与陀螺仪角速度imu_type torso时经transform_imu_data变换到骨盆系见 rotation_helper.py构造观测向量num_obs47维见 deploy_real.py观测槽位内容计算方式0–2角速度ang_vel * ang_vel_scale3–5重力朝向get_gravity_orientation(quat)见 rotation_helper.py6–8速度指令cmd * cmd_scale * max_cmd9–20关节位置(qj - default_angles) * dof_pos_scale21–32关节速度dqj * dof_vel_scale33–44上一帧动作action45相位正弦sin(2π·phase)周期0.8s46相位余弦cos(2π·phase)策略推理torch.jit.load(config.policy_path)加载 TorchScript 模型deploy_real.pyself.action self.policy(obs_tensor)输出动作动作 → 关节位置target_dof_pos default_angles action * action_scale下发指令send_cmd中先计算 CRC 校验再lowcmd_publisher_.Write(cmd)deploy_real.py保证指令帧完整可靠。遥控器摇杆映射运动控制模式下通过遥控器双摇杆控制机器人代码见 deploy_real.py按键/摇杆解码见 remote_controller.py操作控制内容源码映射左摇杆前后x 方向运动速度cmd[0] ly左摇杆左右y 方向运动速度cmd[1] -lx右摇杆左右偏航角 yaw 角速度cmd[2] -rx5.4 退出控制exit运动控制模式下有两种退出方式按下遥控器select键主循环检测到KeyMap.select 1后跳出循环deploy_real.py终端CtrlC捕获KeyboardInterrupt跳出循环。无论哪种方式退出前都会下发一次create_damping_cmd——将所有关节设置为阻尼模式kd8, kp0, tau0见 command_helper.py机器人会因失去主动支撑而自然倒下随后程序打印Exit结束。安全提示原文重点本示例部署并非稳定的控制程序仅用于演示目的。控制过程中请尽量不要给机器人施加外部扰动如果出现任何意外情况请及时退出控制以免发生危险。这也解释了为什么整个流程始终围绕吊装、阻尼、零力矩这些软着陆手段展开。六、通信层原理DDS 与两种消息协议部署程序依赖unitree_sdk2py与机器人底层通过DDSData Distribution Service通信主题为rt/lowcmd下行指令与rt/lowstate上行状态hg消息族G1、H1_2unitree_hg_msg_dds__LowCmd_/LowState_初始化时需设置mode_machine与mode_prMotorMode.PR 0对应俯仰/滚转关节串联控制见 command_helper.py所有电机mode 1go消息族H1unitree_go_msg_dds__LowCmd_/LowState_初始化时写入帧头0xFE 0xEF、level_flag 0xFF位置/速度停止位使用大数值哨兵值PosStopF 2.146e9、VelStopF 16000.0弱电机与普通电机使用不同mode见 command_helper.py。低层状态通过订阅回调LowStateHgHandler/LowStateGoHandler更新deploy_real.py同一回调内还会把wireless_remote原始字节流喂给RemoteController.set()解码出 16 个按键位与 4 个摇杆轴值——这正是遥控器控制的底层数据来源。七、视频教程与进一步阅读原文档还提供了三个机型各自完整的部署演示视频G1 / H1 / H1_2视频链接收录于 deploy/deploy_real/README.md 末尾的 Video tutorial 一节部署前建议先观看对应机型的完整操作过程。若希望深入理解训练侧如何产出这些策略可继续阅读训练入口 legged_gym/scripts/train.py 与推理入口 legged_gym/scripts/play.py环境配置 legged_gym/envs/g1/g1_config.py、legged_gym/envs/h1/h1_config.py、legged_gym/envs/h1_2/h1_2_config.py其中观测维度、缩放系数与部署配置一一对应环境实现 legged_gym/envs/base/legged_robot.py训练时观测/奖励的计算方式另外 deploy/deploy_real/README.md 提供了部署在 G1 上的 C 版本实现deploy/deploy_real/cpp_g1/适合对实时性有更高要求的二次开发场景。【免费下载链接】unitree_rl_gym项目地址: https://gitcode.com/GitHub_Trending/un/unitree_rl_gym创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考