4. 人形机器人建模

在 Isaac Lab 中训练人形机器人,第一步不是写奖励函数,而是把机器人“正确地”放进仿真世界。Isaac Lab 基于 Omniverse 与 PhysX,其原生资产格式是 USD(Universal Scene Description),而学术界与厂商发布的人形机器人模型绝大多数是 URDF(Unified Robot Description Format)。因此,建模工作的核心链路是:URDF 描述 → 导入与转换 → USD 资产 → 物理属性校验 → 训练可用。这一节围绕格式转换、关节层级、刚体与碰撞体、惯性参数与视觉网格五个关键点展开。

一、URDF 与 USD:两种描述哲学

URDF 是 XML 文本格式,以 <link> 和 <joint> 为基本单元,描述的是“树状运动学 + 简单几何 + 惯性”。它轻量、可读、被 ROS 生态广泛支持,但只支持单机器人、无场景组合能力、材质与渲染信息薄弱。USD 则是场景描述格式,支持分层组合(Layer)、引用(Reference)、变体(Variant)、实例化(Instance)与物理 Schema,天然适合大规模并行训练。

Isaac Lab 提供的转换入口是 UrdfConverter,其本质是把 URDF 的 link/joint 树映射为 USD 的 Xform 层级,并附加 PhysicsRigidBodyAPI、PhysicsMassAPI、PhysicsCollisionAPI 等物理 Schema。转换不是“一次性翻译”,而是需要人工校验的工程步骤。

# 在 Isaac Lab 中执行 URDF → USD 转换(示意)
from isaaclab.sim.converters import UrdfConverter, UrdfConverterCfg

cfg = UrdfConverterCfg(
    asset_path="/assets/humanoid/h1.urdf",
    usd_dir="/assets/humanoid/h1_usd",
    fix_base=False,              # 人形机器人通常浮动基座
    joint_drive=UrdfConverterCfg.JointDriveCfg(
        drive_type="force",
        target_type="position",
        gains=UrdfConverterCfg.JointDriveCfg.PDGainsCfg(stiffness=200.0, damping=20.0),
    ),
    collider_type="convex_hull", # 凸包近似,兼顾精度与速度
)
converter = UrdfConverter(cfg)
print(converter.usd_path)

二、关节层级:从 URDF 树到 USD 变换链

人形机器人的关节层级决定了运动学求解顺序。典型结构为:pelvis(浮动基座)→ torso → head / left_arm / right_arm,以及 pelvis → left_leg / right_leg。URDF 中每个 joint 的 parent 与 child 定义了父子关系,origin 定义相对位姿,axis 定义旋转轴。

转换到 USD 后,关节被表示为 PhysicsRevoluteJoint 或 PhysicsPrismaticJoint,并挂在对应刚体之下。需要特别注意的是:URDF 的 joint origin 是相对父 link 的,而 USD 的 local pose 是相对父 Xform 的,若层级被扁平化,关节位置会整体错位。因此转换后必须检查 pelvis 到 torso、torso 到 shoulder 的变换是否与原始模型一致。

人形机器人 URDF 关节层级 → USD 刚体/关节映射 URDF 描述(XML 树) pelvis(base_link) torso left_arm right_arm left_leg right_leg head joint: origin / axis / limit / parent-child URDF Converter USD 资产(PhysX Schema) /World/h1/pelvis RigidBody + Mass /World/h1/torso RevoluteJoint left_arm right_arm left_leg right_leg head Xform 层级 + PhysicsJoint + CollisionAPI

三、刚体与碰撞体:物理正确性的关键

URDF 中每个 <link> 通常同时包含 <visual>、<collision> 和 <inertial>。转换到 USD 后,视觉网格与碰撞网格是分离的:视觉网格用于渲染,碰撞网格用于 PhysX 碰撞检测。人形机器人常见的错误是直接用视觉网格做碰撞体,导致三角面片过多、接触不稳定、训练速度骤降。

正确做法是:为每个 link 指定简化碰撞体,如 convex_hull、convex_decomposition 或基本几何体(box/capsule/sphere)。足部、手部等接触频繁的部位建议使用凸包或胶囊体;躯干等大体积部件可用凸分解。Isaac Lab 的 collider_type 参数控制这一行为。

常见误区:把 collision 与 visual 设为同一网格,或忘记给浮动基座设置 fix_base=False,会导致机器人“钉”在空中或直接穿透地面。转换后务必在 Isaac Sim 中打开物理调试视图,检查碰撞体是否与视觉网格对齐。

四、惯性参数与视觉网格配置

惯性参数决定动力学行为。URDF 的 <inertial> 包含 mass、origin(质心位置)和 inertia(3×3 惯性张量,通常只给 ixx/iyy/izz/ixy/ixz/iyz)。若厂商模型缺失惯性参数,PhysX 会使用默认值,导致机器人“轻飘飘”或抖动。此时应根据几何形状与密度估算,或使用 CAD 工具导出。

视觉网格方面,URDF 的 <mesh> 通常引用 STL/DAE/OBJ。转换时需确保网格路径正确、单位一致(URDF 默认米,STL 常为毫米)。USD 中视觉网格挂在 Geometry 下,材质通过 Material 绑定。若网格缺失,机器人会“隐形”但仍参与物理仿真,容易造成排障困惑。

配置项 URDF 位置 USD/PhysX 对应 校验要点
质量 <inertial><mass> PhysicsMassAPI.mass 总质量与实物一致,单腿约 8–12 kg
质心 <inertial><origin> PhysicsMassAPI.centerOfMass 质心应在几何中心附近,避免偏移过大
惯性张量 <inertia> PhysicsMassAPI.diagonalInertia 正定、对称,量级与质量×尺寸²匹配
碰撞体 <collision> PhysicsCollisionAPI 凸包/胶囊,避免视觉网格直接碰撞
视觉网格 <visual><mesh> UsdGeom.Mesh 路径、单位、材质绑定正确
关节驱动 <joint><limit> PhysicsDriveAPI stiffness/damping 与关节惯量匹配

五、案例:H1 人形机器人转换与校验流程

以 Unitree H1 为例,完整流程如下:

  1. 获取 h1.urdf 与配套 mesh 目录,确认单位与坐标系(Z 轴向上)。
  2. 运行 UrdfConverter,设置 fix_base=False、collider_type="convex_hull"、关节驱动为 position。
  3. 在 Isaac Sim 中加载生成的 USD,打开 Physics Debug,检查碰撞体与视觉网格对齐。
  4. 用 Articulation 接口读取关节数、刚体数、总质量,与 URDF 原始数据比对。
  5. 执行“自由落体 + 站立”测试:机器人应稳定落地,关节不抖动、不穿透。
# 校验:读取 USD 资产的物理信息(示意)
from isaaclab.assets import Articulation
robot = Articulation(cfg)
print("num_joints:", robot.num_joints)
print("num_bodies:", robot.num_bodies)
print("total_mass:", robot.root_physx_view.get_masses().sum())
print("joint_names:", robot.joint_names[:6])
复盘建议:转换后先做“静态校验”(质量、关节数、碰撞体),再做“动态校验”(落地、站立、单关节摆动)。若训练中出现抖动、滑步或关节超限,优先回查惯性参数与碰撞体,而不是先调奖励函数。

总结来说,URDF 到 USD 的转换不是格式搬运,而是物理资产的再工程。关节层级决定运动学,刚体与碰撞体决定接触稳定性,惯性参数决定动力学真实性,视觉网格决定可观测性。四者齐备,人形机器人才能在 Isaac Lab 中稳定训练。