可变形物体#

可变形物体是在仿真中形状会发生变化的资产。与刚体不同,它没有刚性的根坐标系;其状态由仿真网格中每个节点的位置和速度组成。

Isaac Lab 支持三类可变形体:

属性

体积

表面

线缆

模拟对象

软质实体:橡胶块、泰迪熊、器官

布料、薄片、膜

绳索、软管、电线、线束

仿真几何体

四面体网格( UsdGeom.TetMesh )

三角网格( UsdGeom.Mesh )

开放曲线( UsdGeom.BasisCurves ),以胶囊体线段模拟

资产类

DeformableObject

DeformableObject

CableObject

运行时状态

节点位置和速度

节点位置和速度

各线段的位姿和速度

体积和表面可变形物体使用同一资产类和编写方式,区别仅在于所分配的物理材质。线缆使用独立的资产类,具有自己的生成器、材质和状态布局,详见 线缆 。

流体和颗粒介质等基于粒子的材料不属于这里所说的可变形物体。它们使用独立的资产和求解器;参见 隐式 MPM 。

备注

这三类物体都仍在持续开发。在 Newton 上,可变形物体与刚体物体和关节体一起实现在 isaaclab_newton.assets 中。线缆支持尤其处于实验阶段,其生成器配置、资产类和材质默认值仍可能变化。

后端支持情况#

类型

PhysX

Newton

OvPhysX

体积

Yes

支持,仅限 VBD 求解器

支持,仅限 CUDA 设备

表面

Yes

支持,仅限 VBD 求解器

支持,仅限 CUDA 设备

线缆

No

支持,仅限 VBD 求解器

No

Newton 的可变形体需要使用 VBD 求解器。配置与调优见 VBD 求解器;包含刚性机器人和可变形体的混合场景见 耦合求解器。

OvPhysX 的可变形体还存在节点数量和启动开销方面的限制,详见 OvPhysX 。

体积和表面可变形物体#

编写资产#

可变形物体使用网格生成器,并增加两个字段:

  • volume_deformable_props 或 surface_deformable_props,即可变形体的 Schema 片段。设置其中一个字段才会将网格定义为可变形体,所选字段决定它是体积还是表面可变形体。即使传入空列表,也会使用默认属性创建可变形体。

  • physics_material,与可变形体类型匹配的材质配置。

每个片段写入一个 USD 命名空间,因此同一后端的属性分布在多个片段中:OmniPhysicsDeformableBodyCfg 包含 omniphysics:* 物体属性(mass、kinematic_enabled、deformable_body_enabled),PhysxDeformableBodyCfg 包含 PhysX 求解器属性,PhysxSurfaceDeformableBodyCfg 则包含 PhysX 表面可变形体专用属性。字段为空列表时,按当前后端的默认值创建可变形体;仅需为要修改的属性添加片段。后端会应用自身的可变形体锚定 Schema。

将生成器放入 DeformableObjectCfg ,即可创建运行时资产。

import isaaclab.sim as sim_utils
from isaaclab.assets import DeformableObjectCfg
from isaaclab_physx.sim.spawners.materials import PhysxDeformableBodyMaterialCfg

cfg = DeformableObjectCfg(
    prim_path="/World/env_.*/Cube",
    spawn=sim_utils.MeshCuboidCfg(
        size=(0.2, 0.2, 0.2),
        volume_deformable_props=[],
        physics_material=PhysxDeformableBodyMaterialCfg(
            youngs_modulus=1.0e5, poissons_ratio=0.4, density=1000.0
        ),
    ),
)

同一对象在 Newton 下只需更换材质:

import isaaclab.sim as sim_utils
from isaaclab.assets import DeformableObjectCfg
from isaaclab_newton.sim.spawners.materials import NewtonDeformableBodyMaterialCfg

cfg = DeformableObjectCfg(
    prim_path="/World/env_.*/Cube",
    spawn=sim_utils.MeshCuboidCfg(
        size=(0.2, 0.2, 0.2),
        volume_deformable_props=[],
        physics_material=NewtonDeformableBodyMaterialCfg(
            k_mu=3.5714e4, k_lambda=1.4286e5, density=1000.0
        ),
    ),
)

这两个后端采用不同的弹性参数:PhysX 使用 youngs_modulus 和 poissons_ratio ,Newton 使用拉梅参数 k_mu 和 k_lambda 。上述值表示同一种材料,通过 k_mu = E / (2 * (1 + nu)) 和 k_lambda = E * nu / ((1 + nu) * (1 - 2 * nu)) 转换。

表面可变形体的定义方式相同,但使用二维网格生成器、表面可变形体字段和表面材质:

from isaaclab_newton.sim.spawners.materials import NewtonSurfaceDeformableBodyMaterialCfg

cloth = DeformableObjectCfg(
    prim_path="{ENV_REGEX_NS}/Cloth",
    spawn=sim_utils.MeshRectangleCfg(
        size=(0.2, 0.2),
        edge_refinement=8,
        surface_deformable_props=[],
        visual_material=sim_utils.PreviewSurfaceCfg(diffuse_color=(0.95, 0.85, 0.1)),
        physics_material=NewtonSurfaceDeformableBodyMaterialCfg(
            density=1.0, particle_radius=0.002, tri_ke=5e2, tri_ka=5e2, edge_ke=0.5
        ),
    ),
    init_state=DeformableObjectCfg.InitialStateCfg(pos=(0.4, 0.0, 0.1)),
)

上述材质值来自 Isaac-Lift-Cloth-Franka 调整后的配置,而非默认值。各参数的作用和默认值见 VBD 求解器 ,其中也介绍了布料自接触。自接触默认关闭,因此启用前布料可以穿过自身。

edge_refinement 设置这两类物体的仿真分辨率:最大表面边长为包围盒对角线长度除以该值,体积可变形物体也将其作为四面体划分的目标。默认值为 4.0 ,且必须至少为 1.0 。接近 1.0 的值会显著减慢四面体划分。

网格生成器会拒绝不兼容的组合:同时设置多个可变形体字段,或将可变形体字段与 rigid_props、mass_props 同时设置,都会在生成时抛出 ValueError。可变形体通过仿真网格参与碰撞,因此 collision_props 必须由碰撞片段构成,这些片段会应用到仿真网格上。

从 USD 加载#

可变形体也可以来自预先制作的资产。向 UsdFileCfg 传入可变形体字段和 physics_material,生成器便会将相应 Schema 应用到加载的 prim;如果 prim 已有该 Schema,则原地修改。

from isaaclab.sim.schemas import OmniPhysicsDeformableBodyCfg
from isaaclab_physx.sim.schemas import PhysxDeformableBodyCfg

cfg_usd = sim_utils.UsdFileCfg(
    usd_path=f"{ISAACLAB_NUCLEUS_DIR}/Objects/Teddy_Bear/teddy_bear.usd",
    volume_deformable_props=[
        OmniPhysicsDeformableBodyCfg(kinematic_enabled=False),
        PhysxDeformableBodyCfg(solver_position_iteration_count=16),
    ],
    physics_material=PhysxDeformableBodyMaterialCfg(),
    scale=[0.05, 0.05, 0.05],
)

体积还是表面#

布料没有单独的资产类。创建时,由字段决定类型:volume_deformable_props 创建体积可变形体,surface_deformable_props 创建表面可变形体。这决定了写入 USD 的内容:体积类型使用 UsdGeom.TetMesh 仿真网格,表面类型则将可视网格复制为三角形 UsdGeom.Mesh。旧的 deformable_props 字段不携带类型信息,因此根据材质配置判断类型:材质派生自 SurfaceDeformableBodyMaterialBaseCfg 时生成表面可变形体,否则生成体积可变形体。

初始化时,资产从舞台重新判断类型。PhysX 和 OvPhysX 读取绑定物理材质上应用的模式;无法确定时,再根据网格拓扑判断。Newton 只使用拓扑,将 prim 下的 UsdGeom.TetMesh 视为体积,将普通 UsdGeom.Mesh 视为表面。

因此,使用旧的 deformable_props 字段时,材质配置会直接影响类型:将体积材质与布料形状的网格配对,生成的是四面体化实体,而非薄片。新的两个字段不依赖材质来判断类型。

四面体划分#

体积可变形物体需要四面体仿真网格。如果生成的 prim 尚未包含 UsdGeom.TetMesh ,Isaac Lab 会生成一个;各后端都需要可选的 tetrahedralization 依赖:

uv sync --inexact --extra tetrahedralization

表面可变形物体无需该依赖;从 USD 加载、且可变形 prim 下已包含预先划分的 UsdGeom.TetMesh 的体积物体也不需要。

运行时状态#

可变形物体的状态定义在节点上,以仿真世界坐标系表示。下文的 N 为 max_sim_vertices_per_body 。

  • data.nodal_pos_w 和 data.nodal_vel_w :形状为 (num_instances, N) ,元素类型为 vec3f ,分别表示位置 [m] 和速度 [m/s]。

  • data.nodal_state_w :相同数据,形状为 (num_instances, N) ,元素类型为 vec6f 。

  • data.default_nodal_state_w :生成时的状态,用于重置。

  • data.root_pos_w 和 data.root_vel_w :形状为 (num_instances,) 。它们是 派生量,由仿真节点的平均值计算得到。不存在根方向。

通过带索引的设置方法写回状态。 transform_nodal_pos() 相对于当前节点均值应用位姿偏移,从而将生成状态缓冲区分配到各环境原点。

nodal_state = cube.data.default_nodal_state_w.torch[env_ids].clone()
nodal_state[..., :3] = cube.transform_nodal_pos(nodal_state[..., :3], pos, quat)
cube.write_nodal_state_to_sim_index(nodal_state, env_ids=env_ids)
cube.reset(env_ids=env_ids)

与其他资产一样, DeformableObject 可与 InteractiveScene 、 scene.get_state / scene.reset_to 和 reset_scene_to_default 事件项集成。

备注

不带后缀的写入方法( write_nodal_state_to_sim 等)已弃用,应使用 _to_sim_index 和 _to_sim_mask 变体。掩码变体支持 CUDA 图捕获。

线缆#

线缆是一维杆:单个开放的 UsdGeom.BasisCurves prim,带有 PhysicsCurvesDeformableSimAPI 模式,以一串通过线缆关节连接的胶囊体线段进行模拟。

编写线缆#

线缆由 CableCfg 和 CableMaterialCfg 配置。 positions 中相邻的点构成线段,每段生成直径为 thickness 的胶囊体,并通过线缆关节与相邻线段连接。 N 个控制点产生 N-1 个线段刚体和 N-2 个关节;根线段自由悬浮。

参数

描述

positions

线缆局部坐标系中的控制点 [m]。至少需要 三个 坐标值有限的点,且相邻点间距必须大于 1e-8 m。

physics_material

必需的 CableMaterialCfg ;见 线缆材质参数 。厚度也会写入曲线的 widths 属性,使可视半径与物理半径一致。

collision_props

可选的碰撞属性。省略时,线缆不发生碰撞;设置后(通常为 [UsdPhysicsCollisionCfg(collision_enabled=True)] ),线缆会与地面和其他线缆碰撞。见 线缆碰撞 。

visual_material

可选的 VisualMaterialCfg ,用于设置曲线外观。

visual_material_path

可视材质在线缆几何 prim 下的子路径,默认为 "material" 。

physics_material_path

物理材质在线缆几何 prim 下的子路径,默认为 "physics_material" 。

import isaaclab.sim as sim_utils
from isaaclab.assets import CableObject, CableObjectCfg

cable = CableObject(
    cfg=CableObjectCfg(
        prim_path="/World/Env_0/Cable",
        spawn=sim_utils.CableCfg(
            positions=[(index * 0.1, 0.0, 0.0) for index in range(10)],
            visual_material=sim_utils.PreviewSurfaceCfg(diffuse_color=(0.7, 0.2, 0.2)),
            physics_material=sim_utils.CableMaterialCfg(
                thickness=0.03,
                density=1000.0,
                stretch_stiffness=1.0e9,
                bend_stiffness=1.0e6,
            ),
            collision_props=[sim_utils.UsdPhysicsCollisionCfg(collision_enabled=True)],
        ),
        init_state=CableObjectCfg.InitialStateCfg(pos=(0.0, 0.0, 0.5)),
    )
)

这会沿线缆局部 x 轴生成一条 0.9 m 长的红色直线缆:9 个胶囊体线段(每段长 0.1 m,直径 0.03 m),通过 8 个线缆关节连接。继承的 init_state 设置线缆根节点在各环境中的初始位姿。

线缆材质参数#

CableMaterialCfg 定义线缆的几何和刚度。编写时会验证所有值;非有限值或超出范围的值会在创建任何 prim 前抛出 ValueError 。

刚度字段是弹性模量,不是关节刚度。每个杆关节都有自己的离散化刚度,使用该关节的对偶静止长度 L = 0.5 * (L_parent + L_child) 计算,其中 L_parent 和 L_child 是它连接的两个线段的静止长度。

参数

描述

thickness

线缆完整厚度(直径)[m],必须有限且为正。以 radius = thickness / 2 用于胶囊体截面、弯曲截面二次矩和碰撞半径。默认 0.001 。

density

线缆密度 [kg/m^3],必须有限且为正。各线段质量由密度和胶囊体体积计算得到。默认 1000.0 。

stretch_stiffness

轴向(拉伸)弹性模量 E [Pa],必须有限且非负。转换为各关节的轴向刚度 E * A / L ,其中 A 是圆形截面积。值越高,伸长越小。默认 1.0e9 。

bend_stiffness

弯曲弹性模量 E [Pa],必须有限且非负。转换为各关节的弯曲刚度 E * I / L ,其中 I 是圆形截面的二次矩。 0.0 表示柔软的绳索;增大该值可模拟较硬的软管或电线。默认 1.0e6 。

shear_stiffness

横向剪切弹性模量 [Pa],必须有限且非负。可选:保留 None 时不写入该属性,求解器复用 stretch_stiffness 。默认 None 。

twist_stiffness

扭转弹性模量 [Pa],必须有限且非负。可选:保留 None 时不写入该属性,求解器复用弯曲 结构 刚度。默认 None 。

备注

线缆关节具有四种自由度:线性的拉伸和剪切,以及角向的弯曲和扭转。未设置 shear_stiffness 或 twist_stiffness 并不 表示线缆没有剪切或扭转阻力,而是由求解器回退到拉伸和弯曲值。显式设置 0.0 与不设置不同:前者会去除该阻力。

这两种回退并不对称。剪切复用拉伸模量,作用于同一截面积;扭转复用弯曲 结构 刚度 E * I / L ,而显式设置的 twist_stiffness 作用于极惯性矩 J = 2 * I 。因此,设置 twist_stiffness = bend_stiffness 会得到回退刚度的两倍,而不是相同值。

未提供阻尼配置。杆关节具有阻尼,但 Isaac Lab 编写的 USD 曲线材质模式中没有对应属性。

如果需要指定轴向 E * A 或弯曲 E * I ,可反解这些关系来确定模量; examples/cables.py 演示了如何根据目标刚度和线段几何计算。

线缆碰撞#

碰撞需通过 collision_props 显式启用。启用后,导入器采用 仅过滤相邻线段 的规则:直接连接的线段共享关节锚点,不过滤会产生抖动,因此将其过滤;其他所有线段对都发生碰撞。由此:

  • 线缆会与地面和其他线缆碰撞。

  • 同一 线缆的不相邻线段会碰撞,因此线缆回绕自身时可以通过自接触阻止继续运动。

省略 collision_props 时,线缆作为仅参与动力学的杆导入,不发生碰撞。

线缆运行时状态#

CableObject 提供各线段的世界状态,并与 InteractiveScene 、 scene.get_state / scene.reset_to 和 reset_scene_to_default 事件项集成。

  • cable.data.segment_pose_w :形状为 (num_instances, num_segments) ,元素类型为 wp.transformf ,位置 [m] 在前,四元数 (x, y, z, w) 在后。Torch 视图最后一维的长度为 7。

  • cable.data.segment_velocity_w :形状为 (num_instances, num_segments) ,元素类型为 wp.spatial_vectorf ,线速度 [m/s] 在前,角速度 [rad/s] 在后。Torch 视图最后一维的长度为 6。

  • cable.data.default_segment_pose_w 和 default_segment_velocity_w :生成时的状态。

通过索引或掩码设置方法写回各线段状态;掩码形式支持 CUDA 图捕获。

cable.write_segment_pose_to_sim_index(segment_pose=cable.data.default_segment_pose_w)
cable.write_segment_velocity_to_sim_index(segment_velocity=cable.data.default_segment_velocity_w)

写入会直接更新两个仿真状态中的最大坐标刚体状态,并将受影响的环境标记为需要重置求解器。

从 USD 加载线缆#

物理属性直接写在曲线上: spawn_cable() 应用 PhysicsCurvesDeformableSimAPI 模式并绑定可变形曲线材质,曲线随后以原生方式导入。拓扑来自曲线自身的 points 和 curveVertexCounts ,无需自定义边属性。

因此,也可以通过 UsdFileCfg 从外部 USD 加载线缆,例如在 DCC 工具中编写的资产,前提是曲线已经具备:

  • 加载的 prim 下有单个开放、线性、非周期的 UsdGeom.BasisCurves ;

  • 已应用 PhysicsCurvesDeformableSimAPI 模式;以及

  • 已绑定可变形曲线材质( PhysicsCurvesDeformableMaterialAPI ),在 physics: 命名空间中提供 thickness 、 density 、 stretchStiffness 和 bendStiffness 。

这对应两种失败情况。没有仿真模式的曲线不属于可变形物体导入范围,会被静默跳过。具有该模式但无法解析厚度的曲线会使用默认半径导入,并发出警告。请通过 spawn_cable() 编写线缆,或在构造前将模式和材质应用到导入的 prim 上。

线缆渲染#

线缆在 Kit 视口中以 UsdGeom.BasisCurves 渲染。每次渲染更新时,根据线缆各线段端点刷新曲线点,使渲染形状始终与仿真一致。

备注

曲线点通过 CPU Fabric 同步,因为 RTX Hydra 委托不会读取 BasisCurves 的 GPU Fabric 数组(NVBug 6502662)。同步时会跳过周期曲线。

线缆限制#

  • 每个对象只能包含一条独立、未与其他线缆焊接的线缆。 CableObject 要求 prim_path 下恰好有一个带 PhysicsCurvesDeformableSimAPI 的 BasisCurves prim,其中包含一条未与其他线缆焊接的开放曲线。多曲线 BasisCurves prim、周期(闭合)曲线,以及曲线之间硬性重合的 PhysicsAttachment 焊接,都会在初始化时失败。

  • 线缆端点可以铰接固定,不能夹紧固支。 连接到 xform 目标的 PhysicsAttachment 会转换为球关节,因此只约束位置,线缆可以在锚点处自由转动。无法表示需要传递方向约束的刚性插头和端部接头。

  • 没有阻尼调节参数。 提供了四种刚度模量,但没有对应的阻尼参数。

  • 渲染同步仅使用 CPU (NVBug 6502662);周期曲线不会同步。

备注

只有附件刚度未设置或为无穷大时,才会创建附件关节。有限刚度仅保留为元数据,不创建关节。这两种情况均以导入警告而非错误报告,因此线缆仍会正常初始化,即使附件实际缺失。如果附件似乎不起作用,请检查导入器输出。

备注

运行时对象拒绝的拓扑仍会参与仿真:物理模型从整个 USD 舞台构建,因此每条带 PhysicsCurvesDeformableSimAPI 的曲线都会导入,无论是否由 CableObject 包装。可通过 NewtonManager 的 get_model() / get_state_0() 和自行创建的 newton.selection.ArticulationView 控制它们。这些情况没有对应的 Isaac Lab 资产包装器。

材质参数的实际效果#

下方每个动画都将同一场景运行三次,只改变一个材质参数,其余保持不变。标签给出各次运行使用的值。

体积#

三种杨氏模量下,软球落到桌面上的效果

杨氏模量 :控制整体刚度。设为 1e3 Pa 时,球体撞击后压成扁饼;设为 1e5 Pa 时,几乎不变形。软体过软或过硬时,应首先调整此参数。#

三种泊松比下,软球落到桌面上的效果

泊松比 :控制材料受压时保持体积的程度。设为 0.10 时,球体压扁但不向四周展开;设为 0.49 时,材料近乎不可压缩,同样的压缩会使其向外明显鼓起。#

三种粒子半径下,软球静置于桌面上的效果

粒子半径 :各仿真节点周围的接触厚度,并非材质属性。半径越大,越早在远离表面的位置检测到接触,因此球体会明显浮在桌面上方,也无法压得很薄。半径过小可能漏检接触或检测过晚;相对网格分辨率过大,则会过早产生接触。#

表面#

三种拉伸刚度下,布料垂覆在滚筒上的效果

拉伸刚度 :抵抗面内伸长的能力。较低值使布料在自重下拉伸和下垂,较高值则使其保持接近静止长度。#

三种弯曲刚度下,布料从滚筒上落下的效果

弯曲刚度 :抵抗折叠的能力。设为 1e-2 时,布料揉皱成松散的一堆;设为 1e0 时,会保持较大、较硬的褶皱,并继续垂覆在滚筒上。这类似丝绸与帆布的区别。#

线缆#

三种弯曲刚度下,线缆跨在两根支柱之间的效果

弯曲刚度 :设为 1e0 时,线缆像松绳一样在支撑点之间下垂;设为 1e2 时,则像较硬的软管一样保持平直。#

三种扭转刚度下,带配重的悬挂线缆在顶端扭转的效果

扭转刚度 :在锚点处扭转带配重的线缆。设为 1e-1 时,扭转在局部被吸收,线缆仍直垂;设为 1e1 时,扭转沿杆传递,直到发生屈曲并卷成螺旋。如果线缆需要抵抗缠绕,应显式设置该值;未设置时会按前述规则回退到弯曲值。#

示例与任务#

先运行示例,确认生成器、求解器和可视化器都能在当前环境中正常工作。

类型

示例

任务

体积

deformables

Isaac-Lift-Soft-Franka, Isaac-Lift-Soft-Franka-Camera

表面

deformables

Isaac-Lift-Cloth-Franka, Isaac-Lift-Cloth-Franka-Camera

线缆

cables

Isaac-Lift-Cable-Franka, Isaac-Lift-Cable-Franka-Camera

# Volume and surface deformables falling onto a ground plane.
uv run --extra tetrahedralization isaaclab example deformables

# A pile of cables that collide and settle. Newton VBD only.
uv run isaaclab example cables

# A larger cable pile, stopping after a fixed number of steps.
uv run isaaclab example cables --num_cables 40 --num_segments 15 --max_steps 500

可先试用 VBD 线缆弯曲 浏览器示例:调整一根固定端 VBD 杆的弯曲刚度和末端向下载荷,观察瞬态响应。线缆堆叠及定量测量对比请使用原生示例。

若想体验通过学习实现的操作任务,可试用 软体 和 布料 浏览器策略。您可以调整材质、移动目标,或在手动模式下用键盘控制末端执行器。

scripts/environments/state_machine/lift_franka_soft.py 使用脚本状态机驱动 Isaac-Lift-Soft-Franka ,可作为可变形物体操作任务的起点。

进一步阅读#