PhysX 后端(Isaac Sim)#
PhysX 后端在基于 Omniverse Kit 运行时的 Isaac Sim 内运行 NVIDIA PhysX,其集成代码位于 isaaclab_physx 软件包。本页介绍该软件包如何启动 Kit、管理仿真生命周期、配置 PhysX 场景,以及向 Isaac Lab 资产和传感器提供原生 PhysX 数据。求解器选择与调优见 PhysX 和 PhysX 求解器调优 。不依赖 Kit 的 PhysX 路径见 OvPhysX 后端 。
选择后端#
在 isaaclab.sim.SimulationCfg.physics 中设置 PhysxCfg ,即可配置该后端。如果任务提供相应预设,也可以通过命令行参数 physics=isaacsim_physx 选择它:
from isaaclab.sim import SimulationCfg
from isaaclab_physx.physics import PhysxCfg
sim_cfg = SimulationCfg(physics=PhysxCfg())
physx 选择器会自动选择后端。它选用的 PhysxAutoCfg 包含一个 PhysxCfg;任务支持时,还会包含 OvPhysxCfg 。启动仿真时,如果运行需要 Kit,自动配置会解析为 Isaac Sim PhysX;否则,在配置了 OvPhysX 的情况下会解析为 OvPhysX。使用 isaacsim_physx 可明确指定 Isaac Sim 路径。
运行时:Isaac Sim 与 Kit#
启动#
PhysxCfg 通过类属性 launcher_type 指定启动器,其值为 isaaclab_physx.app:KitLauncher。launch_simulation() 遍历解析后的配置,收集物理和渲染器配置指定的启动器,然后依次启动,Kit 最先启动。脚本无需自行创建启动器。
KitLauncher 创建 Isaac Sim 的 SimulationApp。未传入 --experience 时,它会根据无界面运行、相机渲染、视频流和 XR 设置,从仓库的 apps/ 目录中选择 Isaac Lab experience 文件,例如 isaaclab.python.headless.kit 或 isaaclab.python.rendering.kit。启动后,它会发布 /isaaclab/has_gui 等 Isaac Lab 设置,供仿真上下文和渲染器读取。启动器的环境变量和参数见 isaaclab_physx.app 。
USD 场景#
USD 场景由 Isaac Lab 管理。PhysX、其张量视图和视口等 Kit 扩展则从 Kit 的 USD 上下文中读取场景。Kit 运行时,SimulationContext 注册 KitStageBackendCfg ,由 KitStageBackend 将仿真场景接入 omni.usd 上下文。关闭该后端时,会先关闭 Kit 场景,再由仿真清理场景缓存。
与 Isaac Sim 仿真管理器的交互#
仿真生命周期统一由 PhysxManager 管理。Isaac Sim 自带的 isaacsim.core.simulation_manager.SimulationManager 会注册默认的时间线和场景回调。其中,停止回调会使共享的 omni.physics.tensors 仿真视图失效,连带使 Isaac Lab 资产持有的视图失效。KitLauncher 在启动时通过 /exts/isaacsim.core.simulation_manager/enable_default_callbacks 设置,要求 Isaac Sim 跳过这些回调。较新的 Isaac Sim 版本会遵循该设置,Isaac Lab 因而无需修改其管理器。对于较旧的版本,PhysxManager.initialize() 会禁用这些回调,并将模块中的 SimulationManager 重定向到 PhysxManager。如果之后才启用 Isaac Sim 扩展,PhysxManager 会重新应用这一补丁。
仿真生命周期#
PhysxManager 基于 omni.physx、omni.physics.tensors 和 omni.timeline 接口,实现公共的 PhysicsManager 接口约定:
initialize() Kit physics settings, PhysxSceneAPI attributes, Fabric
│
reset() first call: attach stage, warm start, create the tensor view,
│ dispatch PHYSICS_READY (assets and sensors create their views)
│
step() omni.physx simulate(dt) + fetch_results()
│
close() detach stage, invalidate views, release the tensor view
- 初始化
设置 CUDA 设备、是否禁止 GPU 数据回读等 Kit 物理选项,写入 场景配置 中介绍的 PhysX 场景属性,绑定默认物理材质,并加载或卸载 PhysX Fabric 扩展。
- 首次重置
将场景接入 PhysX;在 CPU 模式下,PhysX 会直接从 USD 加载场景。随后执行一次热启动更新并触发预热事件,再向仿真上下文注册
PhysxBackendCfg。由此创建的PhysxBackend管理omni.physics.tensors仿真视图,该视图针对当前场景创建,使用 Warp 前端。最后,管理器触发PHYSICS_READY,资产和传感器据此从仿真视图创建各自类型的视图。- 仿真步进
通过
omni.physx仿真接口推进 PhysX:先调用simulate(dt),再调用fetch_results()。物理步进不会驱动 Kit 应用更新,渲染由仿真上下文单独驱动。仅当写入位姿使关节系统的运动学状态被标记为需要更新时,forward()才会通过张量视图刷新这些状态。- 时间线与资源释放
play()、pause()和stop()驱动omni.timeline,并执行一次 Kit 更新,使时间线回调同步运行。停止时间线会使所有张量视图失效。下一次播放或重置会重新预热 PhysX 并创建视图。close()会先将 PhysX 从场景中分离,再使视图失效并删除 prim。
生命周期事件#
与后端无关的代码通过 PhysicsEvent 注册回调。PhysxManager 将这些事件映射到 PhysX 专用的 IsaacEvents ;后者仍保留,以兼容旧版代码:
|
|
触发时机 |
|---|---|---|
|
|
热启动更新完成后 |
|
|
张量视图创建完成后 |
|
|
时间线停止时 |
IsaacEvents 还通过 omni.physx 的步进订阅提供 PRE_PHYSICS_STEP 和 POST_PHYSICS_STEP,并在释放资源时触发 PRIM_DELETION。新代码应优先使用 PhysicsEvent。
场景配置#
PhysxCfg 字段会写入 physics_prim_path 指定的物理场景 prim。管理器应用 PhysxSceneAPI,将其余字段转换为驼峰命名的 physxScene: 属性,例如将 gpu_max_rigid_contact_count 写为 physxScene:gpuMaxRigidContactCount。部分字段会进行转换,而非直接复制:
solver_type转换为physxScene:solverType``("TGS"`` 或"PGS")。bounce_threshold_velocity转换为physxScene:bounceThreshold。时间步长转换为
physxScene:timeStepsPerSecond。GPU 仿真启用 GPU 动力学和 GPU 粗略碰撞检测;CPU 仿真使用 MBP 粗略碰撞检测。
enable_ccd仅在 CPU 模式下生效。启用 GPU 动力学时,CCD 会被禁用,并给出警告。与后端无关的
deterministic选项会启用enable_enhanced_determinism。场景查询遵循
SimulationCfg.enable_scene_query_support设置;Kit 以图形界面模式运行时,会强制开启场景查询。
各 prim 的物理属性不属于 PhysxCfg,而是通过 模式配置类 中介绍的 USD schema 配置写入。PhysxRigidBodyPropertiesCfg 等 PhysX 专用 schema 配置位于 isaaclab_physx.sim.schemas 。
Fabric#
use_fabric 为 True 时(默认值),管理器启用 omni.physx.fabric 扩展,并关闭 PhysX 向 USD 回写数据的设置(/physics/updateToUsd 及相关选项)。因此,仿真变换通过 Fabric 而非 USD 传递给渲染器。设置 use_fabric=False 时,PhysX 会将仿真结果回写到 USD,在大型场景中会更慢。
张量视图与原生接口访问#
PhysX 张量 API 为需要引擎原生访问的数据路径和功能提供类型化视图。
除 SurfaceGripper 外,isaaclab_physx 中的所有 PhysX 资产和传感器都基于相应类型的视图实现,这些视图从共享的 omni.physics.tensors 仿真视图创建:
Isaac Lab 类 |
原生视图 |
|---|---|
关节系统、关节力旋量传感器 |
关节系统视图 |
刚体对象、刚体对象集合 |
刚体视图 |
可变形对象 |
表面或体积可变形体视图,以及可变形材质视图 |
接触传感器 |
刚体视图和刚体接触视图 |
IMU、坐标系变换器、射线投射器等传感器 |
所跟踪刚体的刚体视图 |
资产通过 root_view 提供自身的视图,接触传感器通过 contact_view 提供刚体接触视图。首次重置后,可以用 get_physics_sim_view() 获取仿真视图本身。
环境克隆使用 PhysxReplicateContext ,通过 omni.physx 的复制器接口执行克隆计划。
基本概念#
API 从 SimulationView 开始,为选定物理对象创建类型化视图。访问完全通过方法进行:getter 从视图读取数据,独立的 setter 将数据写回。返回的缓冲区不是实时指针,因此修改 getter 的返回值不会更新仿真。原始视图通过 PhysX 张量 API 通配模式选择对象。
生命周期前提#
PhysxManager 使用 Warp 前端创建 SimulationView 。底层代码只能在物理初始化和仿真重置之后运行,此时 PhysX 张量 API 视图已经创建:
from isaaclab_physx.physics import PhysxManager
simulation_view = PhysxManager.get_physics_sim_view()
if simulation_view is None:
raise RuntimeError("PhysX Tensor API is not ready; initialize and reset the simulation first.")
复用 Isaac Lab 持有的访问对象#
如果 Isaac Lab 资源已经包含所需选择,复用它的 root_view ,不要再创建第二个视图:
robot = scene["robot"]
articulation_view = robot.root_view
joint_positions = articulation_view.get_dof_positions()
root_view 是后端专用的类型化视图。关节体、刚体对象、刚体对象集合或可变形体可能暴露不同的原生 PhysX 视图类型,应使用与返回视图匹配的方法,不要假定它们具有同一种接口。
创建底层访问#
只有现有 Isaac Lab 选择无法匹配所需对象或功能时,才直接创建视图。在以下 Tensor API 模式中, * 选择每个克隆环境下的匹配对象:
rigid_body_view = simulation_view.create_rigid_body_view(
"/World/envs/env_*/Object"
)
读写语义#
每个 getter 和 setter 都是独立操作。本地修改前,先克隆返回的 Warp 缓冲区,再调用对应 setter 写回结果:
import warp as wp
poses = wp.clone(rigid_body_view.get_transforms())
indices = wp.array(
range(poses.shape[0]),
dtype=wp.int32,
device=poses.device,
)
rigid_body_view.set_transforms(poses, indices)
克隆使所有权明确。调用方可在 setter 之前通过 Warp 修改克隆副本,但本地缓冲区的修改不会自动写回。 indices 数组选择完整视图,且符合 setter 要求的 int32 数据类型和设备;实际写入由 setter 完成。如果当前 Tensor API 约定要求关节状态写入后刷新连杆变换,请调用 update_articulations_kinematic() 。并非每个 setter 都需要刷新,应遵循上游参考文档中各方法的行为。
访问接触视图#
PhysX 接触传感器通过 contact_view 暴露原生 RigidContactView 。公共传感器数据无法提供所需接触细节时,可以使用此视图:
contact_sensor = scene["contact_sensor"]
friction_forces, _, buffer_counts, buffer_start_indices = (
contact_sensor.contact_view.get_friction_data(dt=sim.cfg.dt)
)
其他 Isaac Lab 传感器内部可能使用普通刚体或关节体视图,但这些视图不是传感器专用的底层接口。
所有权、同步与失效#
为 setter 提供值时,保持视图要求的选择顺序、设备、数据类型和张量形状。硬重置、对象移除、舞台重新加载或管理器清理后,应检查并重新获取视图。如果不需要直接访问原生接触或运动数据,应优先使用 Isaac Lab 公共传感器数据。