Kuavo机器人mjalb框架配置

Kuavo机器人mjalb框架配置

ting-zheng

2026-02-27 发布35 浏览 · 2 点赞 · 0 收藏

Leju Kuavo4 机器人配置指南

本文档详细说明如何为 Leju Kuavo4 机器人配置 Velocity 策略和 Mimic/Tracking 策略


目录

  1. Kuavo4 机器人概述
  2. 文件结构
  3. 机器人资产配置
  4. Velocity 策略配置
  5. Mimic/Tracking 策略配置
  6. 运动数据准备
  7. 训练与验证
  8. 常见问题与解决方案

1. Kuavo4 机器人概述

1.1 机器人参数

参数
自由度 (DOF) 28
腿部关节 12 (每侧6个: hip_roll/yaw/pitch, knee, ankle_pitch/roll)
手臂关节 14 (每侧7个: arm_pitch/roll/yaw, elbow, hand_yaw/roll/pitch)
腰部关节
头部关节 2 (zhead_1, zhead_2)
站立高度 ~0.82m
基座名称 base_link

1.2 关节命名规则

Kuavo4 使用以下关节命名规则:

腿部:
  leg_l1_joint  ~ leg_r1_joint  : 左/右髋 roll
  leg_l2_joint  ~ leg_r2_joint  : 左/右髋 yaw
  leg_l3_joint  ~ leg_r3_joint  : 左/右髋 pitch
  leg_l4_joint  ~ leg_r4_joint  : 左/右膝
  leg_l5_joint  ~ leg_r5_joint  : 左/右踝 pitch
  leg_l6_joint  ~ leg_r6_joint  : 左/右踝 roll

手臂:
  zarm_l1_joint ~ zarm_r1_joint : 左/右肩 pitch
  zarm_l2_joint ~ zarm_r2_joint : 左/右臂 roll
  zarm_l3_joint ~ zarm_r3_joint : 左/右臂 yaw
  zarm_l4_joint ~ zarm_r4_joint : 左/右肘
  zarm_l5_joint ~ zarm_r5_joint : 左/手腕 yaw
  zarm_l6_joint ~ zarm_r6_joint : 左/手腕 roll
  zarm_l7_joint ~ zarm_r7_joint : 左/手腕 pitch

头部:
  zhead_1_joint : 头 yaw
  zhead_2_joint : 头 pitch

1.3 关键链接名称

链接 名称
躯干 base_link
左髋 leg_l1_link
右髋 leg_r1_link
左膝 leg_l4_link
右膝 leg_r4_link
左踝 leg_l6_link
右踝 leg_r6_link
左肩 zarm_l1_link
右肩 zarm_r1_link
左肘 zarm_l4_link
右肘 zarm_r4_link
左腕 zarm_l7_link
右腕 zarm_r7_link

1.4 传感器配置

传感器 名称 用途
陀螺仪 BodyGyro 角速度
速度计 BodyVel 线速度

2. 文件结构

unitree_rl_mjlab/
├── mjlab/
│   ├── asset_zoo/
│   │   └── robots/
│   │       └── leju_kuavo4/
│   │           ├── xml/
│   │           │   └── biped_s100045.xml          # MuJoCo模型文件
│   │           ├── kuavo4_constants.py             # 机器人常量配置
│   │           └── meshes/                         # 网格文件
│   │
│   ├── tasks/
│   │   ├── velocity/config/leju_kuavo4/
│   │   │   ├── __init__.py                         # Velocity任务注册
│   │   │   ├── env_cfgs.py                         # Velocity环境配置
│   │   │   └── rl_cfg.py                           # Velocity RL配置
│   │   │
│   │   └── tracking/config/leju_kuavo4/
│   │       ├── __init__.py                         # Tracking任务注册
│   │       ├── env_cfgs.py                         # Tracking环境配置
│   │       └── rl_cfgs.py                          # Tracking RL配置
│   │
│   └── motions/
│       └── kuavo4/                                  # 运动数据目录
│           └── kuavo4_mimic.npz                    # 转换后的运动数据
│
├── scripts/
│   ├── train.py                                     # 训练脚本
│   ├── play.py                                      # 验证脚本
│   └── csv_to_npz.py                               # CSV转NPZ工具

3. 机器人资产配置

3.1 kuavo4_constants.py 配置详解

文件位置:mjlab/asset_zoo/robots/leju_kuavo4/kuavo4_constants.py

3.1.1 执行器配置

Kuavo4 的执行器按扭矩限制分为四类:

# ========================================
# Actuator config (kuavo4_constants.py)
# ========================================

# Large motor (180 Nm) - 用于大扭矩关节
# 用于:hip roll (leg_l1/r1), knee (leg_l4/r4)
ROTOR_INERTIAS_LARGE = (0.489e-4, 0.109e-4, 0.738e-4)
GEARS_LARGE = (1, 4.5, 5)
ARMATURE_LARGE = reflected_inertia_from_two_stage_planetary(
  ROTOR_INERTIAS_LARGE, GEARS_LARGE
)

# Medium motor (100 Nm) - 用于中等扭矩关节
# 用于:hip yaw/pitch (leg_l2/l3/r2/r3), ankle pitch (leg_l5/r5)
#       arm pitch (zarm_l1/r1)
ROTOR_INERTIAS_MEDIUM = (0.489e-4, 0.098e-4, 0.533e-4)
GEARS_MEDIUM = (1, 4.5, 1 + (48 / 22))
ARMATURE_MEDIUM = reflected_inertia_from_two_stage_planetary(
  ROTOR_INERTIAS_MEDIUM, GEARS_MEDIUM
)

# Small motor (50 Nm) - 用于小扭矩关节
# 用于:ankle roll (leg_l6/r6), arm roll/yaw (zarm_l2/l3/r2/r3), elbow
ROTOR_INERTIAS_SMALL = (0.139e-4, 0.017e-4, 0.169e-4)
GEARS_SMALL = (1, 1 + (46 / 18), 1 + (56 / 16))
ARMATURE_SMALL = reflected_inertia_from_two_stage_planetary(
  ROTOR_INERTIAS_SMALL, GEARS_SMALL
)

# Tiny motor (12 Nm) - 用于微小扭矩关节
# 用于:hand joints (zarm_l5/l6/l7/r5/r6/r7), head (zhead_1/2)
ROTOR_INERTIAS_TINY = (0.068e-4, 0.0, 0.0)
GEARS_TINY = (1, 5, 5)
ARMATURE_TINY = reflected_inertia_from_two_stage_planetary(
  ROTOR_INERTIAS_TINY, GEARS_TINY
)

3.1.2 关节执行器定义

# ========================================
# Joint actuator configs
# ========================================

# 腿部执行器
KUAVO_ACTUATOR_HIP_ROLL = BuiltinPositionActuatorCfg(
  target_names_expr=(r"leg_[lr]1_joint",),  # 匹配 leg_l1_joint, leg_r1_joint
  stiffness=STIFFNESS_LARGE,
  damping=DAMPING_LARGE,
  effort_limit=180.0,
  armature=ACTUATOR_LARGE.reflected_inertia,
)

KUAVO_ACTUATOR_HIP_YAW = BuiltinPositionActuatorCfg(
  target_names_expr=(r"leg_[lr]2_joint",),
  stiffness=STIFFNESS_MEDIUM,
  damping=DAMPING_MEDIUM,
  effort_limit=100.0,
  armature=ACTUATOR_MEDIUM.reflected_inertia,
)

KUAVO_ACTUATOR_HIP_PITCH = BuiltinPositionActuatorCfg(
  target_names_expr=(r"leg_[lr]3_joint",),
  stiffness=STIFFNESS_MEDIUM,
  damping=DAMPING_MEDIUM,
  effort_limit=100.0,
  armature=ACTUATOR_MEDIUM.reflected_inertia,
)

KUAVO_ACTUATOR_KNEE = BuiltinPositionActuatorCfg(
  target_names_expr=(r"leg_[lr]4_joint",),
  stiffness=STIFFNESS_LARGE,
  damping=DAMPING_LARGE,
  effort_limit=180.0,
  armature=ACTUATOR_LARGE.reflected_inertia,
)

KUAVO_ACTUATOR_ANKLE_PITCH = BuiltinPositionActuatorCfg(
  target_names_expr=(r"leg_[lr]5_joint",),
  stiffness=STIFFNESS_SMALL,
  damping=DAMPING_SMALL,
  effort_limit=50.0,
  armature=ACTUATOR_SMALL.reflected_inertia,
)

KUAVO_ACTUATOR_ANKLE_ROLL = BuiltinPositionActuatorCfg(
  target_names_expr=(r"leg_[lr]6_joint",),
  stiffness=STIFFNESS_SMALL,
  damping=DAMPING_SMALL,
  effort_limit=50.0,
  armature=ACTUATOR_SMALL.reflected_inertia,
)

# 手臂执行器
KUAVO_ACTUATOR_ARM_PITCH = BuiltinPositionActuatorCfg(
  target_names_expr=(r"zarm_[lr]1_joint",),
  stiffness=STIFFNESS_MEDIUM,
  damping=DAMPING_MEDIUM,
  effort_limit=100.0,
  armature=ACTUATOR_MEDIUM.reflected_inertia,
)

KUAVO_ACTUATOR_ARM_ROLL = BuiltinPositionActuatorCfg(
  target_names_expr=(r"zarm_[lr]2_joint",),
  stiffness=STIFFNESS_SMALL,
  damping=DAMPING_SMALL,
  effort_limit=50.0,
  armature=ACTUATOR_SMALL.reflected_inertia,
)

KUAVO_ACTUATOR_ARM_YAW = BuiltinPositionActuatorCfg(
  target_names_expr=(r"zarm_[lr]3_joint",),
  stiffness=STIFFNESS_SMALL,
  damping=DAMPING_SMALL,
  effort_limit=50.0,
  armature=ACTUATOR_SMALL.reflected_inertia,
)

KUAVO_ACTUATOR_ELBOW = BuiltinPositionActuatorCfg(
  target_names_expr=(r"zarm_[lr]4_joint",),
  stiffness=STIFFNESS_SMALL,
  damping=DAMPING_SMALL,
  effort_limit=50.0,
  armature=ACTUATOR_SMALL.reflected_inertia,
)

KUAVO_ACTUATOR_HAND_YAW = BuiltinPositionActuatorCfg(
  target_names_expr=(r"zarm_[lr]5_joint",),
  stiffness=STIFFNESS_TINY,
  damping=DAMPING_TINY,
  effort_limit=12.0,
  armature=ACTUATOR_TINY.reflected_inertia,
)

KUAVO_ACTUATOR_HAND_ROLL = BuiltinPositionActuatorCfg(
  target_names_expr=(r"zarm_[lr]6_joint",),
  stiffness=STIFFNESS_TINY,
  damping=DAMPING_TINY,
  effort_limit=12.0,
  armature=ACTUATOR_TINY.reflected_inertia,
)

KUAVO_ACTUATOR_HAND_PITCH = BuiltinPositionActuatorCfg(
  target_names_expr=(r"zarm_[lr]7_joint",),
  stiffness=STIFFNESS_TINY,
  damping=DAMPING_TINY,
  effort_limit=12.0,
  armature=ACTUATOR_TINY.reflected_inertia,
)

# 头部执行器
KUAVO_ACTUATOR_HEAD_YAW = BuiltinPositionActuatorCfg(
  target_names_expr=("zhead_1_joint",),
  stiffness=STIFFNESS_TINY,
  damping=DAMPING_TINY,
  effort_limit=1.5,
  armature=ACTUATOR_TINY.reflected_inertia,
)

KUAVO_ACTUATOR_HEAD_PITCH = BuiltinPositionActuatorCfg(
  target_names_expr=("zhead_2_joint",),
  stiffness=STIFFNESS_TINY,
  damping=DAMPING_TINY,
  effort_limit=ACTUATOR_TINY.effort_limit,
  armature=ACTUATOR_TINY.reflected_inertia,
)

3.1.3 初始姿态配置

# ========================================
# Keyframe config (HOME_KEYFRAME)
# ========================================

HOME_KEYFRAME = EntityCfg.InitialStateCfg(
  pos=(0, 0, 0.82),  # 站立高度
  joint_pos={
    # 腿部 - 直立姿态
    r"leg_[lr]1_joint": 0.0,      # Hip roll
    r"leg_[lr]2_joint": 0.0,      # Hip yaw
    r"leg_[lr]3_joint": -0.1,     # Hip pitch
    r"leg_[lr]4_joint": 0.3,      # Knee
    r"leg_[lr]5_joint": -0.15,    # Ankle pitch
    r"leg_[lr]6_joint": 0.0,      # Ankle roll

    # 手臂 - 自然下垂姿态
    # 注意:roll关节需要左右相反的值
    r"zarm_[lr]1_joint": 0.3,     # Arm pitch
    r"zarm_l2_joint": 0.2,        # Left arm roll
    r"zarm_r2_joint": -0.2,       # Right arm roll (负值!)
    r"zarm_[lr]3_joint": 0.0,     # Arm yaw
    r"zarm_[lr]4_joint": -0.5,    # Elbow
    r"zarm_[lr]5_joint": 0.0,     # Hand yaw
    r"zarm_l6_joint": 0.0,        # Left wrist roll
    r"zarm_r6_joint": 0.0,        # Right wrist roll
    r"zarm_[lr]7_joint": 0.0,     # Hand pitch

    # 头部 - 中性位置
    r"zhead_[12]_joint": 0.0,     # Head joints
  },
  joint_vel={".*": 0.0},
)

3.1.4 碰撞配置

# ========================================
# Collision config
# ========================================

# 训练模式:只启用脚与地面碰撞(提高效率)
FULL_COLLISION_WITHOUT_SELF = CollisionCfg(
  geom_names_expr=(r".*_collision$",),
  contype=0,                         # 禁用自身接触
  conaffinity=1,                      # 只与terrain接触
  condim={
    r"^(left|right)_foot[1-7]_collision$": 3,  # 脚部3D摩擦
    r".*_collision$": 1,                        # 其他1D摩擦
  },
  priority={
    r"^(left|right)_foot[1-7]_collision$": 1,  # 脚部高优先级
  },
  friction={
    r"^(left|right)_foot[1-7]_collision$": (0.6,),  # 脚部摩擦系数
  },
)

# Play模式:启用所有碰撞(包括自碰撞)
FULL_COLLISION = CollisionCfg(
  geom_names_expr=(r".*_collision$",),
  condim={
    r"^(left|right)_foot[1-7]_collision$": 3,  # 脚部
    r".*_collision$": 1,                        # 其他
  },
  priority={
    r"^(left|right)_foot[1-7]_collision$": 1,
  },
  friction={
    r"^(left|right)_foot[1-7]_collision$": (0.6,),
  },
)

3.1.5 机器人配置函数

# ========================================
# Final config
# ========================================

KUAVO4_ARTICULATION = EntityArticulationInfoCfg(
  actuators=(
    KUAVO_ACTUATOR_HIP_ROLL,
    KUAVO_ACTUATOR_HIP_YAW,
    KUAVO_ACTUATOR_HIP_PITCH,
    KUAVO_ACTUATOR_KNEE,
    KUAVO_ACTUATOR_ANKLE_PITCH,
    KUAVO_ACTUATOR_ANKLE_ROLL,
    KUAVO_ACTUATOR_ARM_PITCH,
    KUAVO_ACTUATOR_ARM_ROLL,
    KUAVO_ACTUATOR_ARM_YAW,
    KUAVO_ACTUATOR_ELBOW,
    KUAVO_ACTUATOR_HAND_YAW,
    KUAVO_ACTUATOR_HAND_ROLL,
    KUAVO_ACTUATOR_HAND_PITCH,
    KUAVO_ACTUATOR_HEAD_YAW,
    KUAVO_ACTUATOR_HEAD_PITCH,
  ),
  soft_joint_pos_limit_factor=0.9,
)


def get_kuavo4_robot_cfg() -> EntityCfg:
  """获取Kuavo4机器人配置实例

  每次调用返回新实例,避免配置共享导致的变异问题。
  """
  return EntityCfg(
    init_state=HOME_KEYFRAME,
    collisions=(FULL_COLLISION_WITHOUT_SELF,),  # 默认训练用
    spec_fn=get_spec,
    articulation=KUAVO4_ARTICULATION,
  )


# 计算action scale
KUAVO4_ACTION_SCALE: dict[str, float] = {}
for a in KUAVO4_ARTICULATION.actuators:
  assert isinstance(a, BuiltinPositionActuatorCfg)
  e = a.effort_limit
  s = a.stiffness
  names = a.target_names_expr
  assert e is not None
  for n in names:
    KUAVO4_ACTION_SCALE[n] = 0.25 * e / s

3.2 XML配置要点

文件位置:mjlab/asset_zoo/robots/leju_kuavo4/xml/biped_s100045.xml

3.2.1 Contact配置(自碰撞)

<!-- 在compiler标签后添加contact配置 -->
<contact>
  <!-- 排除父子关节间的碰撞检测 -->
  <exclude body1="base_link" body2="leg_l1_link" />
  <exclude body1="base_link" body2="leg_r1_link" />
  <exclude body1="base_link" body2="zarm_l1_link" />
  <exclude body1="base_link" body2="zarm_r1_link" />
  <exclude body1="base_link" body2="zhead_1_link" />

  <!-- 腿部父子关节 -->
  <exclude body1="leg_l1_link" body2="leg_l2_link" />
  <exclude body1="leg_l2_link" body2="leg_l3_link" />
  <exclude body1="leg_l3_link" body2="leg_l4_link" />
  <exclude body1="leg_l4_link" body2="leg_l5_link" />
  <exclude body1="leg_l5_link" body2="leg_l6_link" />

  <exclude body1="leg_r1_link" body2="leg_r2_link" />
  <exclude body1="leg_r2_link" body2="leg_r3_link" />
  <exclude body1="leg_r3_link" body2="leg_r4_link" />
  <exclude body1="leg_r4_link" body2="leg_r5_link" />
  <exclude body1="leg_r5_link" body2="leg_r6_link" />

  <!-- 手臂父子关节 -->
  <exclude body1="zarm_l1_link" body2="zarm_l2_link" />
  <exclude body1="zarm_l2_link" body2="zarm_l3_link" />
  <exclude body1="zarm_l3_link" body2="zarm_l4_link" />
  <exclude body1="zarm_l4_link" body2="zarm_l5_link" />
  <exclude body1="zarm_l5_link" body2="zarm_l6_link" />
  <exclude body1="zarm_l6_link" body2="zarm_l7_link" />

  <exclude body1="zarm_r1_link" body2="zarm_r2_link" />
  <exclude body1="zarm_r2_link" body2="zarm_r3_link" />
  <exclude body1="zarm_r3_link" body2="zarm_r4_link" />
  <exclude body1="zarm_r4_link" body2="zarm_r5_link" />
  <exclude body1="zarm_r5_link" body2="zarm_r6_link" />
  <exclude body1="zarm_r6_link" body2="zarm_r7_link" />

  <!-- 头部父子关节 -->
  <exclude body1="zhead_1_link" body2="zhead_2_link" />
</contact>

3.2.2 传感器配置

<!-- IMU传感器 -->
<gyro name="BodyGyro" site="imu_site"/>
<accelerometer name="BodyAcc" site="imu_site"/>
<velocimeter name="BodyVel" site="root_site"/>

4. Velocity 策略配置

4.1 环境配置 (env_cfgs.py)

文件位置:mjlab/tasks/velocity/config/leju_kuavo4/env_cfgs.py

"""Leju Kuavo4 velocity environment configurations."""

from mjlab.asset_zoo.robots import (
  KUAVO4_ACTION_SCALE,
  get_kuavo4_robot_cfg,
)
from mjlab.asset_zoo.robots.leju_kuavo4.kuavo4_constants import FULL_COLLISION
from mjlab.envs import ManagerBasedRlEnvCfg
from mjlab.envs import mdp as envs_mdp
from mjlab.envs.mdp.actions import JointPositionActionCfg
from mjlab.managers.event_manager import EventTermCfg
from mjlab.managers.reward_manager import RewardTermCfg
from mjlab.sensor import ContactMatch, ContactSensorCfg
from mjlab.tasks.velocity import mdp
from mjlab.tasks.velocity.mdp import UniformVelocityCommandCfg
from mjlab.tasks.velocity.velocity_env_cfg import make_velocity_env_cfg


def Leju_kuavo4_rough_env_cfg(play: bool = False) -> ManagerBasedRlEnvCfg:
  """Create Leju Kuavo4 rough terrain velocity configuration.

  Args:
    play: 如果为True,使用FULL_COLLISION启用自碰撞
  """
  cfg = make_velocity_env_cfg()

  # Play模式使用FULL_COLLISION,训练模式使用默认配置
  if play:
    robot_cfg = get_kuavo4_robot_cfg()
    robot_cfg.collisions = (FULL_COLLISION,)
    cfg.scene.entities = {"robot": robot_cfg}
  else:
    cfg.scene.entities = {"robot": get_kuavo4_robot_cfg()}

  # ========================================
  # 传感器配置
  # ========================================
  # Kuavo4没有foot sites,使用body模式
  feet_ground_cfg = ContactSensorCfg(
    name="feet_ground_contact",
    primary=ContactMatch(
      mode="subtree",
      pattern=r"^(leg_l6_link|leg_r6_link)$",  # 踝关节body
      entity="robot",
    ),
    secondary=ContactMatch(mode="body", pattern="terrain"),
    fields=("found", "force"),
    reduce="netforce",
    num_slots=1,
    track_air_time=True,
  )

  self_collision_cfg = ContactSensorCfg(
    name="self_collision",
    primary=ContactMatch(mode="subtree", pattern="base_link", entity="robot"),
    secondary=ContactMatch(mode="subtree", pattern="base_link", entity="robot"),
    fields=("found",),
    reduce="none",
    num_slots=1,
  )

  cfg.scene.sensors = (feet_ground_cfg, self_collision_cfg)

  # 地形课程学习
  if cfg.scene.terrain is not None and cfg.scene.terrain.terrain_generator is not None:
    cfg.scene.terrain.terrain_generator.curriculum = True

  # ========================================
  # Action配置
  # ========================================
  joint_pos_action = cfg.actions["joint_pos"]
  assert isinstance(joint_pos_action, JointPositionActionCfg)
  joint_pos_action.scale = KUAVO4_ACTION_SCALE

  # ========================================
  # Viewer配置
  # ========================================
  cfg.viewer.body_name = "base_link"

  # 速度命令可视化高度
  twist_cmd = cfg.commands["twist"]
  assert isinstance(twist_cmd, UniformVelocityCommandCfg)
  twist_cmd.viz.z_offset = 1.15

  # ========================================
  # 传感器名称修正(关键!)
  # ========================================
  # Kuavo4使用BodyGyro而非imu_ang_vel
  cfg.observations["policy"].terms["base_ang_vel"].params["sensor_name"] = "robot/BodyGyro"
  cfg.observations["critic"].terms["base_lin_vel"].params["sensor_name"] = "robot/BodyVel"

  # ========================================
  # 事件配置
  # ========================================
  cfg.events["base_com"].params["asset_cfg"].body_names = ("base_link",)

  # 脚部摩擦事件
  cfg.events["foot_friction"].params["asset_cfg"].geom_names = r"^(left|right)_foot[1-7]_collision$"

  # ========================================
  # 奖励函数调整
  # ========================================

  cfg.rewards["body_ang_vel"].params["asset_cfg"].body_names = ("base_link",)

  # 姿态奖励 - 根据Kuavo4关节特点调整
  cfg.rewards["pose"].params["std_standing"] = {".*": 0.05}

  cfg.rewards["pose"].params["std_walking"] = {
    # 下肢 - 放松hip roll允许更宽的侧向步幅
    r"leg_[lr]3_joint": 0.5,     # Hip pitch
    r"leg_[lr]1_joint": 0.2,     # Hip roll - 放宽
    r"leg_[lr]2_joint": 0.15,    # Hip yaw
    r"leg_[lr]4_joint": 0.5,     # Knee
    r"leg_[lr]5_joint": 0.15,    # Ankle pitch
    r"leg_[lr]6_joint": 0.1,     # Ankle roll

    # 手臂 - 限制自由度保持稳定
    r"zarm_[lr]1_joint": 0.15,   # Arm pitch
    r"zarm_l2_joint": 0.05,      # Left arm roll - 严格
    r"zarm_r2_joint": 0.05,      # Right arm roll - 严格
    r"zarm_[lr]3_joint": 0.08,   # Arm yaw - 严格
    r"zarm_[lr]4_joint": 0.1,    # Elbow
    r"zarm_[lr]5_joint": 0.12,   # Hand yaw - 严格
    r"zarm_[lr]6_joint": 0.12,   # Hand roll - 严格
    r"zarm_[lr]7_joint": 0.12,   # Hand pitch - 严格

    # 头部
    r"zhead_[12]_joint": 0.3,
  }

  cfg.rewards["pose"].params["std_running"] = {
    # 下肢 - 更宽松的活动范围
    r"leg_[lr]3_joint": 0.5,
    r"leg_[lr]1_joint": 0.3,     # Hip roll - 更宽
    r"leg_[lr]2_joint": 0.2,
    r"leg_[lr]4_joint": 0.5,
    r"leg_[lr]5_joint": 0.2,
    r"leg_[lr]6_joint": 0.1,

    # 手臂
    r"zarm_[lr]1_joint": 0.2,
    r"zarm_l2_joint": 0.05,
    r"zarm_r2_joint": 0.05,
    r"zarm_[lr]3_joint": 0.08,
    r"zarm_[lr]4_joint": 0.1,
    r"zarm_[lr]5_joint": 0.15,
    r"zarm_[lr]6_joint": 0.15,
    r"zarm_[lr]7_joint": 0.15,

    # 头部
    r"zhead_[12]_joint": 0.4,
  }

  # 脚部奖励 - Kuavo4没有foot sites,使用body名称
  cfg.rewards["foot_clearance"].params["asset_cfg"].body_names = ("leg_l6_link", "leg_r6_link")
  cfg.rewards["foot_slip"].params["asset_cfg"].body_names = ("leg_l6_link", "leg_r6_link")

  # 禁用不可用的奖励(Kuavo4 XML缺少相应传感器)
  cfg.rewards.pop("angular_momentum", None)
  cfg.rewards.pop("soft_landing", None)

  # 自碰撞惩罚
  cfg.rewards["self_collisions"] = RewardTermCfg(
    func=mdp.self_collision_cost,
    weight=-1.0,
    params={"sensor_name": self_collision_cfg.name},
  )

  # 禁用依赖geom名称的事件
  cfg.events.pop("body_friction", None)

  # ========================================
  # Play模式配置
  # ========================================
  if play:
    cfg.episode_length_s = int(1e9)  # 无限episode长度
    cfg.observations["policy"].enable_corruption = False
    cfg.events.pop("push_robot", None)

    cfg.events["randomize_terrain"] = EventTermCfg(
      func=envs_mdp.randomize_terrain,
      mode="reset",
      params={},
    )

    if cfg.scene.terrain is not None:
      if cfg.scene.terrain.terrain_generator is not None:
        cfg.scene.terrain.terrain_generator.curriculum = False
        cfg.scene.terrain.terrain_generator.num_cols = 5
        cfg.scene.terrain.terrain_generator.num_rows = 5
        cfg.scene.terrain.terrain_generator.border_width = 10.0

  return cfg


def Leju_kuavo4_flat_env_cfg(play: bool = False) -> ManagerBasedRlEnvCfg:
  """Create Leju Kuavo4 flat terrain velocity configuration."""
  cfg = Leju_kuavo4_rough_env_cfg(play=play)

  # 切换到平面地形
  assert cfg.scene.terrain is not None
  cfg.scene.terrain.terrain_type = "plane"
  cfg.scene.terrain.terrain_generator = None

  # 禁用地形课程
  assert "terrain_levels" in cfg.curriculum
  del cfg.curriculum["terrain_levels"]

  return cfg

4.2 RL配置 (rl_cfg.py)

"""RL configuration for Leju Kuavo4 velocity task."""

from mjlab.rl import (
  RslRlOnPolicyRunnerCfg,
  RslRlPpoActorCriticCfg,
  RslRlPpoAlgorithmCfg,
)


def Leju_kuavo4_ppo_runner_cfg() -> RslRlOnPolicyRunnerCfg:
  """Create RL runner configuration for Leju Kuavo4 velocity task."""
  return RslRlOnPolicyRunnerCfg(
    policy=RslRlPpoActorCriticCfg(
      init_noise_std=1.0,
      actor_obs_normalization=True,
      critic_obs_normalization=True,
      actor_hidden_dims=(512, 256, 128),
      critic_hidden_dims=(512, 256, 128),
      activation="elu",
    ),
    algorithm=RslRlPpoAlgorithmCfg(
      value_loss_coef=1.0,
      use_clipped_value_loss=True,
      clip_param=0.2,
      entropy_coef=0.01,
      num_learning_epochs=5,
      num_mini_batches=4,
      learning_rate=1.0e-3,
      schedule="adaptive",
      gamma=0.99,
      lam=0.95,
      desired_kl=0.01,
      max_grad_norm=1.0,
    ),
    experiment_name="kuavo4_velocity",
    save_interval=100,
    num_steps_per_env=24,
    max_iterations=10001,
  )

4.3 任务注册 (init.py)

"""Velocity task registration for Leju Kuavo4."""

from mjlab.tasks.registry import register_mjlab_task
from mjlab.tasks.velocity.rl import VelocityOnPolicyRunner

from .env_cfgs import (
  Leju_kuavo4_flat_env_cfg,
  Leju_kuavo4_rough_env_cfg,
)
from .rl_cfg import Leju_kuavo4_ppo_runner_cfg

# 注册Rough地形任务
register_mjlab_task(
  task_id="Mjlab-Velocity-Rough-Leju-Kuavo4",
  env_cfg=Leju_kuavo4_rough_env_cfg(),
  play_env_cfg=Leju_kuavo4_rough_env_cfg(play=True),
  rl_cfg=Leju_kuavo4_ppo_runner_cfg(),
  runner_cls=VelocityOnPolicyRunner,
)

# 注册Flat地形任务
register_mjlab_task(
  task_id="Mjlab-Velocity-Flat-Leju-Kuavo4",
  env_cfg=Leju_kuavo4_flat_env_cfg(),
  play_env_cfg=Leju_kuavo4_ppo_runner_cfg(play=True),
  rl_cfg=Leju_kuavo4_ppo_runner_cfg(),
  runner_cls=VelocityOnPolicyRunner,
)

5. Mimic/Tracking 策略配置

5.1 环境配置 (env_cfgs.py)

文件位置:mjlab/tasks/tracking/config/leju_kuavo4/env_cfgs.py

"""Leju Kuavo4 motion tracking environment configurations."""

from mjlab.asset_zoo.robots import (
  KUAVO4_ACTION_SCALE,
  get_kuavo4_robot_cfg,
)
from mjlab.asset_zoo.robots.leju_kuavo4.kuavo4_constants import FULL_COLLISION
from mjlab.envs import ManagerBasedRlEnvCfg
from mjlab.envs.mdp.actions import JointPositionActionCfg
from mjlab.managers.observation_manager import ObservationGroupCfg
from mjlab.sensor import ContactMatch, ContactSensorCfg
from mjlab.tasks.tracking.mdp import MotionCommandCfg
from mjlab.tasks.tracking.tracking_env_cfg import make_tracking_env_cfg


def Leju_kuavo4_flat_tracking_env_cfg(
  has_state_estimation: bool = True,
  play: bool = False,
) -> ManagerBasedRlEnvCfg:
  """Create Leju Kuavo4 flat terrain tracking configuration.

  Args:
    has_state_estimation: 是否包含状态估计(position observation)
    play: 是否为play模式(启用自碰撞)
  """
  cfg = make_tracking_env_cfg()

  # Play模式使用FULL_COLLISION启用自碰撞
  if play:
    robot_cfg = get_kuavo4_robot_cfg()
    robot_cfg.collisions = (FULL_COLLISION,)
    cfg.scene.entities = {"robot": robot_cfg}
  else:
    cfg.scene.entities = {"robot": get_kuavo4_robot_cfg()}

  # 自碰撞传感器
  self_collision_cfg = ContactSensorCfg(
    name="self_collision",
    primary=ContactMatch(mode="subtree", pattern="base_link", entity="robot"),
    secondary=ContactMatch(mode="subtree", pattern="base_link", entity="robot"),
    fields=("found",),
    reduce="none",
    num_slots=1,
  )
  cfg.scene.sensors = (self_collision_cfg,)

  # ========================================
  # Action配置
  # ========================================
  joint_pos_action = cfg.actions["joint_pos"]
  assert isinstance(joint_pos_action, JointPositionActionCfg)
  joint_pos_action.scale = KUAVO4_ACTION_SCALE

  # ========================================
  # 运动命令配置(关键!)
  # ========================================
  motion_cmd = cfg.commands["motion"]
  assert isinstance(motion_cmd, MotionCommandCfg)
  motion_cmd.anchor_body_name = "base_link"

  # Kuavo4有26个训练用DOF(无头部关节)
  # 配置用于追踪的body名称
  motion_cmd.body_names = (
    "base_link",                # 躯干
    "leg_l1_link",              # 左髋roll
    "leg_l4_link",              # 左膝
    "leg_l6_link",              # 左踝roll
    "leg_r1_link",              # 右髋roll
    "leg_r4_link",              # 右膝
    "leg_r6_link",              # 右踝roll
    "zarm_l1_link",             # 左肩pitch
    "zarm_l4_link",             # 左肘
    "zarm_l7_link",             # 左腕
    "zarm_r1_link",             # 右肩pitch
    "zarm_r4_link",             # 右肘
    "zarm_r7_link",             # 右腕
  )

  # 脚部摩擦事件
  cfg.events["foot_friction"].params[
    "asset_cfg"
  ].geom_names = r"^(left|right)_foot[1-7]_collision$"

  # 质心随机化
  cfg.events["base_com"].params["asset_cfg"].body_names = ("base_link",)

  # 终止条件 - 末端执行器body名称
  cfg.terminations["ee_body_pos"].params["body_names"] = (
    "leg_l6_link",              # 左踝
    "leg_r6_link",              # 右踝
    "zarm_l7_link",             # 左腕
    "zarm_r7_link",             # 右腕
  )

  # Viewer配置
  cfg.viewer.body_name = "base_link"

  # ========================================
  # 传感器名称修正(关键!)
  # ========================================
  # Kuavo4使用BodyGyro而非imu_ang_vel
  cfg.observations["policy"].terms["base_ang_vel"].params["sensor_name"] = "robot/BodyGyro"
  cfg.observations["critic"].terms["base_ang_vel"].params["sensor_name"] = "robot/BodyGyro"

  # base_lin_vel只在critic中使用
  if "base_lin_vel" in cfg.observations["critic"].terms:
    cfg.observations["critic"].terms["base_lin_vel"].params["sensor_name"] = "robot/BodyVel"

  # ========================================
  # 自碰撞nconmax限制(关键!)
  # ========================================
  # Kuavo4启用FULL_COLLISION后,接触点数量增加
  cfg.sim.nconmax = 500

  # ========================================
  # 无状态估计模式
  # ========================================
  if not has_state_estimation:
    new_policy_terms = {
      k: v
      for k, v in cfg.observations["policy"].terms.items()
      if k not in ["motion_anchor_pos_b"]
    }
    cfg.observations["policy"] = ObservationGroupCfg(
      terms=new_policy_terms,
      concatenate_terms=True,
      enable_corruption=True,
    )
    # 重新应用传感器名称修正
    cfg.observations["policy"].terms["base_ang_vel"].params["sensor_name"] = "robot/BodyGyro"

  # ========================================
  # Play模式配置
  # ========================================
  if play:
    cfg.episode_length_s = int(1e9)  # 无限episode长度
    cfg.observations["policy"].enable_corruption = False
    cfg.events.pop("push_robot", None)

    # 禁用RSI随机化
    motion_cmd.pose_range = {}
    motion_cmd.velocity_range = {}

    motion_cmd.sampling_mode = "start"

  return cfg

5.2 RL配置 (rl_cfgs.py)

"""Leju Kuavo4 tracking RL configuration."""

from mjlab.rl import (
  RslRlOnPolicyRunnerCfg,
  RslRlPpoActorCriticCfg,
  RslRlPpoAlgorithmCfg,
)


def Leju_kuavo4_tracking_ppo_runner_cfg() -> RslRlOnPolicyRunnerCfg:
  """Create RL runner configuration for Leju Kuavo4 tracking task."""
  return RslRlOnPolicyRunnerCfg(
    policy=RslRlPpoActorCriticCfg(
      init_noise_std=1.0,
      actor_obs_normalization=True,
      critic_obs_normalization=True,
      actor_hidden_dims=(512, 256, 128),
      critic_hidden_dims=(512, 256, 128),
      activation="elu",
    ),
    algorithm=RslRlPpoAlgorithmCfg(
      value_loss_coef=1.0,
      use_clipped_value_loss=True,
      clip_param=0.2,
      entropy_coef=0.005,  # 比velocity稍低,因为动作多样性来自运动数据
      num_learning_epochs=5,
      num_mini_batches=4,
      learning_rate=1.0e-3,
      schedule="adaptive",
      gamma=0.99,
      lam=0.95,
      desired_kl=0.01,
      max_grad_norm=1.0,
    ),
    experiment_name="kuavo4_tracking",
    save_interval=500,
    num_steps_per_env=24,
    max_iterations=30001,  # Mimic通常需要更多iteration
  )

5.3 任务注册 (init.py)

"""Tracking task registration for Leju Kuavo4."""

from mjlab.tasks.registry import register_mjlab_task
from mjlab.tasks.tracking.rl import MotionTrackingOnPolicyRunner

from .env_cfgs import Leju_kuavo4_flat_tracking_env_cfg
from .rl_cfgs import Leju_kuavo4_tracking_ppo_runner_cfg

# 标准mimic任务
register_mjlab_task(
  task_id="Mjlab-Tracking-Flat-Leju-Kuavo4",
  env_cfg=Leju_kuavo4_flat_tracking_env_cfg(),
  play_env_cfg=Leju_kuavo4_flat_tracking_env_cfg(play=True),
  rl_cfg=Leju_kuavo4_tracking_ppo_runner_cfg(),
  runner_cls=MotionTrackingOnPolicyRunner,
)

# 无状态估计版本
register_mjlab_task(
  task_id="Mjlab-Tracking-Flat-Leju-Kuavo4-No-State-Estimation",
  env_cfg=Leju_kuavo4_flat_tracking_env_cfg(has_state_estimation=False),
  play_env_cfg=Leju_kuavo4_flat_tracking_env_cfg(has_state_estimation=False, play=True),
  rl_cfg=Leju_kuavo4_tracking_ppo_runner_cfg(),
  runner_cls=MotionTrackingOnPolicyRunner,
)

6. 运动数据准备

6.1 CSV格式要求

Kuavo4的CSV运动数据格式:

# 格式: px, py, pz, qx, qy, qz, qw, joint1, joint2, ..., joint28
# 注意: 四元数是xyzw顺序
0.0, 0.0, 0.82, 0, 0, 0, 1, 0.0, 0.0, -0.1, 0.3, -0.15, 0.0, 0.0, ..., 0.0
...
  • 前7列: 基座位置(px,py,pz)和四元数(qx,qy,qz,qw)
  • 后28列: 所有28个关节(包含2个头部关节)

6.2 关节顺序

CSV中的关节顺序(28个):
1-6:   leg_l1-6_joint   (左腿)
7-12:  leg_r1-6_joint   (右腿)
13-19: zarm_l1-7_joint  (左臂)
20-26: zarm_r1-7_joint  (右臂)
27-28: zhead_1,2_joint  (头部) - 训练时跳过

6.3 csv_to_npz.py中的Kuavo4配置

# scripts/csv_to_npz.py

def main(
  # ... 参数 ...
  robot: str = "g1",
):
  # ...

  # Kuavo4配置
  if robot == "kuavo4":
    env_cfg = Leju_kuavo4_flat_tracking_env_cfg()
    motion_dir = "kuavo4"
    csv_dof_skip = 2  # 跳过2个头部关节 (28->26 DOF)


def get_joint_names(robot: str) -> list[str]:
  """Get joint names for the specified robot type."""
  if robot == "kuavo4":
    # Kuavo4有26个训练用DOF(无头部关节)
    # CSV有28个关节,跳过最后2个头部关节
    return [
      # 腿部 (12个)
      "leg_l1_joint",  # 左髋roll
      "leg_l2_joint",  # 左髋yaw
      "leg_l3_joint",  # 左髋pitch
      "leg_l4_joint",  # 左膝
      "leg_l5_joint",  # 左踝pitch
      "leg_l6_joint",  # 左踝roll
      "leg_r1_joint",  # 右髋roll
      "leg_r2_joint",  # 右髋yaw
      "leg_r3_joint",  # 右髋pitch
      "leg_r4_joint",  # 右膝
      "leg_r5_joint",  # 右踝pitch
      "leg_r6_joint",  # 右踝roll
      # 手臂 (14个)
      "zarm_l1_joint",  # 左臂pitch
      "zarm_l2_joint",  # 左臂roll
      "zarm_l3_joint",  # 左臂yaw
      "zarm_l4_joint",  # 左肘
      "zarm_l5_joint",  # 左手腕yaw
      "zarm_l6_joint",  # 左手腕roll
      "zarm_l7_joint",  # 左手腕pitch
      "zarm_r1_joint",  # 右臂pitch
      "zarm_r2_joint",  # 右臂roll
      "zarm_r3_joint",  # 右臂yaw
      "zarm_r4_joint",  # 右肘
      "zarm_r5_joint",  # 右手腕yaw
      "zarm_r6_joint",  # 右手腕roll
      "zarm_r7_joint",  # 右手腕pitch
      # 跳过头部关节 (zhead_1_joint, zhead_2_joint)
    ]
  # ...

6.4 转换命令

# 基本转换
python scripts/csv_to_npz.py \
  --input-file /path/to/kuavo4_motion.csv \
  --output-name kuavo4_mimic.npz \
  --input-fps 30 \
  --output-fps 50 \
  --robot kuavo4

# 转换部分数据(例如第100-500行)
python scripts/csv_to_npz.py \
  --input-file /path/to/kuavo4_motion.csv \
  --output-name kuavo4_mimic.npz \
  --input-fps 30 \
  --output-fps 50 \
  --robot kuavo4 \
  --line-range 100 500

# 使用CPU(如果CUDA有问题)
python scripts/csv_to_npz.py \
  --input-file /path/to/kuavo4_motion.csv \
  --output-name kuavo4_mimic.npz \
  --input-fps 30 \
  --output-fps 50 \
  --robot kuavo4 \
  --device cpu

6.5 放置运动数据

正常转换完成,会自动保存在该路径下

# 创建目录
mkdir -p mjlab/motions/kuavo4/

# 移动转换后的NPZ文件
mv kuavo4_mimic.npz mjlab/motions/kuavo4/

7. 训练与验证

7.1 Velocity策略

训练命令

# Flat地形训练(推荐从flat开始)
python scripts/train.py \
  Mjlab-Velocity-Flat-Leju-Kuavo4 \
  --env.scene.num-envs=4096

# Rough地形训练
python scripts/train.py \
  Mjlab-Velocity-Rough-Leju-Kuavo4 \
  --env.scene.num-envs=4096

# 减少环境数量(如果GPU内存不足)
python scripts/train.py \
  Mjlab-Velocity-Flat-Leju-Kuavo4 \
  --env.scene.num-envs=2048

Play/验证命令

# 加载训练好的模型
python scripts/play.py \
  Mjlab-Velocity-Flat-Leju-Kuavo4 \
  --checkpoint_file=logs/rsl_rl/kuavo4_velocity/2026-02-01_20-48-02/model_2500.pt

乐聚kuavo机器人mjlab适配_哔哩哔哩_bilibili

7.2 Mimic/Tracking策略

训练命令

# mimic训练
python scripts/train.py \
  Mjlab-Tracking-Flat-Leju-Kuavo4  \
  --motion-file mjlab/motions/kuavo4/Kuavo_mjlab.npz  \
  --env.scene.num-envs=4096

Play/验证命令

# 加载训练好的模型
python scripts/play.py Mjlab-Tracking-Flat-Leju-Kuavo4  \
  --motion-file mjlab/motions/kuavo4/Kuavo_mjlab.npz  \
  --checkpoint_file=logs/rsl_rl/kuavo4_tracking/2026-02-04_18-08-48/model_2000.pt

Kuavo舞蹈(mimic)_哔哩哔哩_bilibili

7.3 训练监控

# 启动TensorBoard
tensorboard --logdir=logs/

8. 常见问题与解决方案

8.1 Velocity任务问题

问题1: 自碰撞不工作

症状: 评测时机器人自穿模

解决方案:

# 在 env_cfgs.py 中检查
if play:
    robot_cfg = get_kuavo4_robot_cfg()
    robot_cfg.collisions = (FULL_COLLISION,)  # 确保使用FULL_COLLISION
    cfg.scene.entities = {"robot": robot_cfg}

同时检查XML文件中是否有contact配置:

<contact>
  <exclude body1="base_link" body2="leg_l1_link" />
  <!-- ... 28个排除配置 ... -->
</contact>

问题2: nconmax溢出

错误信息:

ValueError: nconmax must be >= 36, got 35

解决方案:

# 在 env_cfgs.py 中增加
cfg.sim.nconmax = 500

问题3: 传感器名称错误

错误信息:

KeyError: "Scene element 'robot/imu_ang_vel' not found"

解决方案:

# Kuavo4使用BodyGyro而非imu_ang_vel
cfg.observations["policy"].terms["base_ang_vel"].params["sensor_name"] = "robot/BodyGyro"
cfg.observations["critic"].terms["base_lin_vel"].params["sensor_name"] = "robot/BodyVel"

8.2 Mimic/Tracking任务问题

问题1: 运动数据维度不匹配

错误信息:

RuntimeError: The size of tensor a (26) must match the size of tensor b (28)

原因: NPZ文件关节数与机器人不一致

解决方案:

# 重新转换CSV,指定正确的robot参数
python scripts/csv_to_npz.py \
  --input-file motion.csv \
  --output-name kuavo4_mimic.npz \
  --robot kuavo4 \  # 关键!
  --csv-dof-skip 2

问题2: Body名称不匹配

错误信息:

KeyError: 'zarm_l7_link' not found

解决方案:

  1. 检查XML中的实际body名称:
    grep 'body name=' mjlab/asset_zoo/robots/leju_kuavo4/xml/biped_s100045.xml | grep zarm_l7
    
  2. env_cfgs.py 中修正:
    motion_cmd.body_names = (
        # ... 使用实际的body名称 ...
    )
    cfg.terminations["ee_body_pos"].params["body_names"] = (
        # ... 使用实际的body名称 ...
    )
    

8.3 调试技巧

检查机器人配置

# test_kuavo4.py
from mjlab.entity.entity import Entity
from mjlab.asset_zoo.robots.leju_kuavo4 import get_kuavo4_robot_cfg

robot = Entity(get_kuavo4_robot_cfg())
print(f"关节数: {robot.data.num_joints}")
print(f"执行器数: {robot.data.num_actuators}")
print(f"关节名称: {robot.joint_names}")
print(f"Body名称: {robot.body_names}")

检查运动数据

# check_motion.py
import numpy as np

data = np.load("mjlab/motions/kuavo4/kuavo4_mimic.npz")
print(f"FPS: {data['fps']}")
print(f"帧数: {data['joint_pos'].shape[0]}")
print(f"关节数: {data['joint_pos'].shape[1]}")
print(f"持续时间: {data['joint_pos'].shape[0] / data['fps'][0]:.1f}秒")

查看XML信息

# 查看所有关节
grep 'joint name=' mjlab/asset_zoo/robots/leju_kuavo4/xml/biped_s100045.xml

# 查看传感器
grep '<gyro>\|<accelerometer>\|<velocimeter>' mjlab/asset_zoo/robots/leju_kuavo4/xml/biped_s100045.xml

# 查看body名称
grep 'body name=' mjlab/asset_zoo/robots/leju_kuavo4/xml/biped_s100045.xml | head -20

8.4 训练问题

问题: 训练不稳定

症状: reward持续下降或episode_length很短

可能原因及解决方案:

  1. 初始姿态不合理

    • 检查 HOME_KEYFRAME 中的关节位置
    • 特别是手臂roll关节的左右对称性
  2. 奖励权重不合理

    • 调整 cfg.rewards 中的权重
    • 降低惩罚项的权重
  3. 学习率过高

    • 降低 learning_rate 从 1.0e-3 到 5.0e-4
  4. 环境数量过少

    • 增加 num_envs 从 2048 到 4096 或更高

问题: GPU内存不足

错误信息:

CUDA out of memory

解决方案:

# 减少环境数量
python scripts/train.py Mjlab-Velocity-Flat-Leju-Kuavo4 --env.scene.num-envs=2048

9. 配置总结

9.1 Kuavo4配置关键点

配置项 说明
训练DOF 28 包含头部关节
硬件DOF 28 包含头部关节
基座名称 base_link 躯干链接
传感器 BodyGyro, BodyVel 注意命名差异
nconmax 500 支持自碰撞
站立高度 0.82m 初始姿态

9.2 Velocity vs Tracking配置差异

配置项 Velocity Tracking
输入 速度命令 运动数据
entropy_coef 0.01 0.005
max_iterations 10001 30001
save_interval 100 500
传感器需求 基础传感器 需要运动数据

9.3 文件检查清单

  • [ ] kuavo4_constants.py - 执行器配置完整
  • [ ] biped_s100045.xml - contact配置存在
  • [ ] velocity/env_cfgs.py - 传感器名称正确
  • [ ] tracking/env_cfgs.py - body名称正确
  • [ ] csv_to_npz.py - kuavo4配置存在
  • [ ] 运动数据NPZ文件存在

9.4 快速参考

# 常用命令速查

# 查看关节数
grep 'joint name=' mjlab/asset_zoo/robots/leju_kuavo4/xml/biped_s100045.xml | wc -l

# 查看传感器
grep '<gyro>\|<velocimeter>' mjlab/asset_zoo/robots/leju_kuavo4/xml/biped_s100045.xml

# Velocity训练
python scripts/train.py Mjlab-Velocity-Flat-Leju-Kuavo4 --env.scene.num-envs=4096

# Velocity play
python scripts/play.py Mjlab-Velocity-Flat-Leju-Kuavo4 \
  --checkpoint_file=logs/rsl_rl/kuavo4_velocity/2026-02-01_20-48-02/model_2500.pt

# 转换运动数据
python scripts/csv_to_npz.py \
  --input-file ../GMR/motions/Kuavo_mjalb/csv/Kuavo_mjalb.csv \
  --output-name Kuavo_mjlab.npz --input-fps 30 --output-fps 50 \
  --robot kuavo4 --device cpu

# Tracking训练
python scripts/train.py Mjlab-Tracking-Flat-Leju-Kuavo4 --motion-file mjlab/motions/kuavo4/Kuavo_mjlab.npz --env.scene.num-envs=4096

# Tracking play
python scripts/play.py Mjlab-Tracking-Flat-Leju-Kuavo4  \
  --motion-file mjlab/motions/kuavo4/Kuavo_mjlab.npz    \
  --checkpoint_file=logs/rsl_rl/kuavo4_tracking/2026-02-04_18-08-48/model_2000.pt

致谢

请前往 登录/注册 即可发表您的看法…