模式片段#

Isaac Lab 通过 模式片段 将物理属性写入 USD prim。每个片段是一个小型配置类,恰好对应一个 USD 应用模式,并写入单一属性命名空间。片段可以在列表中组合,因此一个资产配置能够并列包含 OpenUSD 物理( physics:* )、PhysX( physx*:* )和 Newton( newton:* / mjc:* )属性,并在任意后端运行。

本页介绍片段模型、将片段定位到 prim 的路径表达式,以及生成器层的配置接口。求解器通用类与后端特有类的分层见 模式配置类 ;完整的类和函数参考见 isaaclab.sim.schemas 。

片段模型#

各片段继承 SchemaFragment ,声明字段写入的 USD 命名空间,以及自己负责的应用模式(如果有)。片段的 func 指定将其应用到 prim 的可调用对象。默认应用函数( apply_namespaced() )将各非 None 字段写为 <namespace>:<camelCase(field)> ,不修改 None 字段(部分更新)。特殊 API 会覆盖 func ,例如 UsdPhysicsDriveCfg 通过 apply_drive() 分发,处理多实例 UsdPhysics.DriveAPI 。

片段分为多个 属性族,每个生成器槽位对应一个属性族。各族有自己的写入器,根据表达式解析目标 prim,再通过各片段的 func 分发。后端片段携带后端特有的应用函数,因此核心包无需导入后端:

生成器字段

属性族写入器

有效目标

rigid_props

apply_rigid_body_properties()

带有 UsdPhysics.RigidBodyAPI 的 prim

collision_props

apply_collision_properties()

带有 UsdPhysics.CollisionAPI 的 prim

mass_props

apply_mass_properties()

带有 UsdPhysics.MassAPI 的 prim

articulation_props

apply_articulation_root_properties()

带有 UsdPhysics.ArticulationRootAPI 的 prim

joint_drive_props

apply_joint_drive_properties()

旋转 / 移动关节 prim

fixed_tendons_props

apply_fixed_tendon_properties()

带有肌腱的 prim(已有肌腱实例)

spatial_tendons_props

apply_spatial_tendon_properties()

肌腱附着点根 prim

volume_deformable_props

apply_volume_deformable_properties()

体积可变形物体 prim( UsdGeom.TetMesh 仿真网格)

surface_deformable_props

apply_surface_deformable_properties()

表面可变形物体 prim(三角仿真网格)

肌腱属性族遵循 只调整、不创建 的原则:肌腱拓扑在源资产中编写,其写入器只调整已有实例,从不创建实例。可变形属性族则相反,参见 可变形物体 。PhysX 肌腱片段使用 instance_names 在每个匹配 prim 上选择一个或多个实例; None (默认值)表示应用到所有已有实例。

固定肌腱按 PhysX 模式的边界拆分:根片段负责整个肌腱的动力学和限制,轴片段负责各关节的贡献。prim 路径匹配选择关节, instance_names 选择这些关节上的肌腱:

from isaaclab_physx.sim.schemas import PhysxTendonAxisCfg, PhysxTendonAxisRootCfg

fixed_tendons_props = {
    "/joints/index_root": [
        PhysxTendonAxisRootCfg(instance_names="index_finger", stiffness=10.0),
        PhysxTendonAxisCfg(instance_names="index_finger", gearing=[1.0], joint_axis=["rotX"]),
    ],
    "/joints/index_distal": [
        PhysxTendonAxisCfg(instance_names="index_finger", gearing=[-0.5], joint_axis=["rotX"]),
    ],
}

目标表达式#

目标 prim 通过 find_matching_prims() 解析。表达式是普通 Python 正则表达式,与 整个 prim 路径匹配,遵循标准正则语义: . 匹配任意字符,包括 / 。因此 /World/Robot/.* 选择任意深度的所有后代, [^/]+ 将通配范围限制为一个路径段, /World/Robot(/.*)? 则选择该 prim 及其后代。遍历包含未激活、未定义的 prim,以及实例代理。

随后按属性族的有效目标过滤匹配集合(见上表):刚体、碰撞、质量和关节体属性族要求目标带有相应 API;关节驱动属性族要求旋转或移动关节 prim;肌腱属性族要求带有肌腱的 prim。关节驱动表达式匹配到的非关节目标会被静默忽略,因为对子树使用表达式时,匹配整棵子树是合理的。

边界情况如下:

  • 实例化的匹配项 不可写入(原型为只读),会被跳过并发出警告。

  • 没有目标 时发出警告,写入器不写入任何内容并返回 False 。

  • 片段列表为空 时不执行写入,返回 True 。

在生成器上配置片段#

生成器配置( UsdFileCfg 、 CuboidCfg 等)为每个属性族提供一个字段。字段接受:目标模式到片段列表的映射;单个片段或片段列表(见下方简写);单个旧式数据类配置(例如 RigidBodyBaseCfg 或后端的 *PropertiesCfg ,分发到旧式写入器);或者 None 。

映射键是正则表达式后缀,附加在 生成器写入该属性族的 prim 之后:USD、URDF 和 MJCF 资产使用生成 prim;形状和网格生成器的碰撞属性族使用几何 prim,刚体和质量属性族使用容器 prim。因此,选择后代时键自身需要带前导 / : "" 选择锚定 prim 本身, "/[^/]+" 选择直接子节点, "/.*" 选择其下方所有节点。整棵子树的规则优先使用 "/.*" :锚点通常是没有属性族 API 的普通 Xform ,包含它不会改变结果;但启用 create_if_missing 时, "(/.*)?" 还会将 API 应用到锚点本身。只有锚点也确实是目标时才使用 "(/.*)?" 。条目按插入顺序应用;两个模式匹配同一 prim 时,后面的片段会覆盖前面写入的属性。

规则无需单独指定目标时,可直接传入片段或片段列表,省略映射。在形状和网格生成器上,这种简写作用于锚定 prim,也是这些生成器唯一编写的 prim。在文件生成器上,它作用于生成 prim 及其后代,因此无论资产将模式放在哪里,都能找到带模式的 prim。如果整棵子树完全没有带该属性族基础 API 的 prim(不含物理模式的美术资产通常如此),文件生成器会将该 API 应用到生成 prim 并在那里写入,将资产变为单个刚体。

从 USD 生成机器人,先应用宽泛规则,再通过更小范围的规则覆盖:

import isaaclab.sim as sim_utils
from isaaclab.sim.schemas import UsdPhysicsDriveCfg, UsdPhysicsRigidBodyCfg
from isaaclab_newton.sim.schemas import MujocoRigidBodyCfg
from isaaclab_physx.sim.schemas import PhysxRigidBodyCfg
from isaaclab.utils.assets import ISAAC_NUCLEUS_DIR

spawn = sim_utils.UsdFileCfg(
    usd_path=f"{ISAAC_NUCLEUS_DIR}/Robots/Franka/franka_instanceable.usd",
    rigid_props={
        # every rigid body: universal + PhysX + MuJoCo attributes side by side
        "/.*": [
            UsdPhysicsRigidBodyCfg(rigid_body_enabled=True),
            PhysxRigidBodyCfg(max_depenetration_velocity=5.0),
            MujocoRigidBodyCfg(gravcomp=1.0),
        ],
        # hand links (and their subtrees) get a tighter depenetration limit
        "/.*_hand/.*": [PhysxRigidBodyCfg(max_depenetration_velocity=1.0)],
    },
    joint_drive_props={
        "/.*": [UsdPhysicsDriveCfg(drive_type="force", stiffness=40.0, damping=4.0)],
    },
)

对于基本形状,各属性族都以锚定 prim 为目标,因此可以完全省略映射:

import isaaclab.sim as sim_utils
from isaaclab.sim.schemas import MassCfg, UsdPhysicsCollisionCfg, UsdPhysicsRigidBodyCfg
from isaaclab_newton.sim.schemas import NewtonCollisionCfg

cuboid = sim_utils.CuboidCfg(
    size=(0.1, 0.1, 0.1),
    rigid_props=UsdPhysicsRigidBodyCfg(),
    mass_props=MassCfg(mass=0.5),
    collision_props=[UsdPhysicsCollisionCfg(collision_enabled=True), NewtonCollisionCfg(contact_margin=0.001)],
)

规则需要作用于锚点以外的目标时,使用映射。从 USD、URDF 或 MJCF 文件生成资产时通常如此:生成 prim 是容器,带模式的 prim 位于其下方。

创建缺失的 API#

默认情况下,属性族写入器只 修改 已带有该族基础 USD API 的 prim。生成器提供三个逐属性族开关: mass_props_create_if_missing 、 articulation_props_create_if_missing 和 joint_drive_props_create_if_missing ,可在写入片段前,为匹配但缺少 API 的 prim 应用基础 API(关节驱动属性族使用适合该轴的 UsdPhysics.DriveAPI 实例)。形状和网格生成器总会为其编写的原始 prim 创建 API,因为新创建的几何体尚无物理 API。

写入器严格按表达式执行:启用创建后,每个匹配 prim 都会得到 API。因此,过宽的模式可能为子树中的每个网格分别设置质量。哪些刚体参与关节体仍由资产的关节决定,而非表达式。请仔细限定创建模式的范围。

可变形物体#

可变形属性族与默认的“修改已有对象”行为相反: volume_deformable_props / surface_deformable_props 写入器( apply_volume_deformable_properties() / apply_surface_deformable_properties() )总会为尚无相应配置的匹配 prim 创建完整的可变形物体,无需额外启用开关。两个槽位的片段都继承 DeformableBodyFragment ;核心包中的 OmniPhysicsDeformableBodyCfg 提供求解器通用字段( deformable_body_enabled 、 kinematic_enabled 、 mass )。PhysX 在 isaaclab_physx.sim.schemas 中增加自己的调整片段: PhysxDeformableBodyCfg 提供共享的求解器/阻尼属性, PhysxSurfaceDeformableBodyCfg 仅用于表面可变形物体。Newton 不需要额外的物体片段。

生成器最多只能设置这两个槽位中的一个:网格要么生成为体积可变形物体(内部四面体划分),要么生成为表面可变形物体(类似布料),不能同时采用两者。槽位的映射键是附加到 生成 prim 后的正则表达式后缀;与其他属性族不同,这对所有生成器类型都成立,包括其他属性族以几何或容器 prim 为锚点的形状和网格生成器。空字符串 "" 同样选择生成 prim 本身, "(/.*)?" 选择它及其子树。

对于没有基础模式的匹配 prim,创建可变形物体配置分为三步:

  1. 仿真网格。 在目标下编写 sim_mesh 子 prim(名称可通过写入器的 sim_mesh_name 参数配置)。表面可变形物体使用可视网格的三角网格副本;体积可变形物体使用经过四面体划分的 UsdGeom.TetMesh 。源资产已有预先划分的 UsdGeom.TetMesh 子节点时,原地复用,不重复划分。

  2. 后端基础模式。 当前物理后端通过 PhysicsManager.setup_deformable_body 应用自己的基础模式。PhysX 在物体 prim 上应用真正的 OmniPhysicsDeformableBodyAPI (两种可变形类型使用同一个模式),并在仿真网格 prim 上根据类型应用 OmniPhysicsVolumeDeformableSimAPI / OmniPhysicsSurfaceDeformableSimAPI 。Newton 应用自己的 Physics* 模式(目前仅为 token)。核心片段没有自己的应用模式; OmniPhysicsDeformableBodyCfg 只在基础模式存在后写入 omniphysics:* 命名空间。

  3. 片段分发。 将匹配槽位中的每个片段按列表顺序应用到目标,与其他属性族完全相同。

可变形物体不读取 UsdPhysics.MassAPI ;请通过 mass 设置质量。

仿真网格创建后已带有 UsdPhysics.CollisionAPI ,因此碰撞偏移使用现有碰撞属性族,而非可变形物体专属属性族:将 collision_props 的键指向仿真网格子节点(默认为 "/sim_mesh" ),与可变形槽位一样,相对于生成 prim 定位。

物理材质也采用同样的扩展方式: physics_material 接受可变形材质片段( isaaclab.sim.spawners.materials 中 DeformableMaterialFragment 的子类,例如 OmniPhysicsDeformableMaterialCfg / OmniPhysicsSurfaceDeformableMaterialCfg ),也接受将刚体材质片段与可变形片段组合的混合列表。只有列表包含刚体材质片段时,才应用 UsdPhysics.MaterialAPI 基础模式;可变形材质片段独立应用自身模式(例如 OmniPhysicsDeformableMaterialAPI ),因为仅绑定到可变形物体的材质 prim 不具有需要该基础模式的刚体材质语义。

将长方体网格生成为体积可变形物体,配置 PhysX 求解器参数、仿真网格上的碰撞偏移,以及混合的 PhysX/Newton 材质:

import isaaclab.sim as sim_utils
from isaaclab_physx.sim.schemas import PhysxCollisionCfg, PhysxDeformableBodyCfg
from isaaclab.sim.spawners.materials import OmniPhysicsDeformableMaterialCfg
from isaaclab_newton.sim.spawners.materials import NewtonVolumeDeformableMaterialCfg

sim_utils.MeshCuboidCfg(
    size=(0.2, 0.2, 0.2),
    volume_deformable_props=[
        sim_utils.schemas.OmniPhysicsDeformableBodyCfg(mass=0.5),
        PhysxDeformableBodyCfg(solver_position_iteration_count=32),
    ],
    collision_props={"/sim_mesh": [PhysxCollisionCfg(contact_offset=0.01)]},
    physics_material=[
        OmniPhysicsDeformableMaterialCfg(youngs_modulus=1.0e6, poissons_ratio=0.45),
        NewtonVolumeDeformableMaterialCfg(k_mu=1.0e5),
    ],
)

另请参阅#