关于 physics-simulation
面向 Isaac Sim 6 和 Kit 110 的物理配置实用技能,涵盖场景参数、单个 Prim 设置、材质、驱动器、传感器及后端选择,并提供脚本和示例。
主要功能
- 01物理场景与求解器配置
- 02刚体和碰撞体设置
- 03接触材质与关节驱动器
- 04Newton 与 PhysX 后端选择
- 05Prim 设置辅助脚本
适用场景
- 01配置刚体和碰撞体
- 02调整高接触或高速场景
- 03为仿真选择物理后端
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ isaac-sim/ isaacsim --skill physics-simulation安装后在 Claude Code 中输入/physics-simulation确认已加载。
附带文件examples.mdscripts/prim_physics_setup.py
详细介绍
Isaac Sim 中的物理仿真
目的
通过示例配置 PhysicsScene 和各个 prim 的刚体、碰撞、材质、关节驱动、求解器选择及物理传感器。
前置条件
- 对于独立物理仿真:需要完成
source/libraries构建,或安装匹配的 wheels/SDKs;大多数单元测试和无头物理测试都不需要 GPU。 - 对于 Kit 设置、扩展自动切换、时间轴或视口操作:需要构建好的 Isaac Sim,以及来自
isaac-sim-orchestrator的 shell 环境。
限制
- 目标版本为 Isaac Sim 6 / Kit 110,除非某节另有说明。
- 本文不能替代 NVIDIA 官方文档,也未涵盖不受支持的边缘情况。
故障排除
| 错误 / 现象 | 原因 | 解决方案 |
|---|---|---|
| 画面黑屏或空白 | 缺少灯光,或渲染模式不是 RTX | 添加穹顶灯 / 主光;确认 RTX / PathTracing 设置 |
| 加载场景或首次渲染时卡住 | MDL 编译或场景过大 | 按照 isaac-sim-troubleshooting 中的隔离步骤操作 |
独立库与 Kit 适配器
对于独立物理仿真实现、后端注册、实体和运行时控制,请使用 source/libraries/isaacsim/physics/{manager,registration,entities,ovsim},以及 source/libraries/isaacsim/physics_engines/{ovnewton,ovphysx} 引擎。isaacsim.physics_engines.ovstage 是私有 OVStage 运行时的进程级设置和原生句柄桥接层,并非物理引擎。
isaacsim.core.simulation_manager 设置、扩展启用和自动切换行为、Kit 时间轴、视口及 SimulationApp 均应使用 Kit 适配器路径。不要将它们的启动标志用于独立模块测试;在未验证使用方工作流前,也不要把库中的 PhysicsManager 当作 Kit SimulationManager 的直接替代品。
对于在公开包文档中注明会在导入时注册的独立引擎,只需导入该包一次,然后通过 PhysicsManager 选择引擎;常规示例不应另外调用 activate() 或 shutdown()。通过管理器执行驱动设置、初始化、步进和失效处理,并传入 Stage 对象返回的场景标识符,而非随意填写的值。如果实体门面支持相应操作,优先使用 RigidBodyEntity 和 ArticulationEntity,而非原始仿真视图和手动张量转换。
测试应在不预先激活后端的情况下,通过示例的常规公开入口执行,以便发现注册缺失和生命周期所有权问题。请以当前检出的引擎 API 文档及匹配的 source/examples 系列为标准语法;不要照搬较旧示例中的兼容生命周期。
目标版本为 Isaac Sim 6.0+ / Kit 110。两个后端都使用 UsdPhysics.*;各节会说明后端特有的行为。
可用脚本
| 脚本 | 用途 | 参数 |
|---|---|---|
scripts/prim_physics_setup.py | Isaac Sim / USD(Kit 110)的各 prim 物理设置辅助工具 | 参见 script --help |
运行脚本
在提供技能执行辅助功能的 Agent 运行时中,使用 run_script() 调用辅助工具:
run_script("scripts/prim_physics_setup.py", args=["--help"])
在已构建的 Isaac Sim 目录中,可从 _build/*/release 使用 ./python.sh(Linux)或 python.bat(Windows)运行同一文件;对于不需要模拟器的 shell 辅助工具,也可以直接执行。
后端选择(Kit 110)
isaacsim.core.simulation_manager 会注册物理引擎并选择当前引擎。其 extension.toml 中的 default_engine 为 "physx",但,isaacsim.physics.newton 扩展默认启用 auto_switch_on_startup = true,因此,任何启用 isaacsim.physics.newton 的应用(标准的 isaacsim.exp.full.kit 就会启用)都会在启动时使用 Newton。
from isaacsim.core.simulation_manager import SimulationManager
SimulationManager.switch_physics_engine("newton") # or "physx"
print(SimulationManager.get_active_physics_engine())
# Inspect what is available
from isaacsim.physics.newton import get_available_physics_engines, get_active_physics_engine
print(get_available_physics_engines())
启动时显式指定引擎:
--/exts/isaacsim.core.simulation_manager/default_engine=newton # or =physx
--/exts/isaacsim.physics.newton/auto_switch_on_startup=false # opt out of auto-switch
Newton 配置类(扩展 Python API;目前尚未收录在用户指南 RST 中——请参阅该扩展的 API 文档页面或 docs/isaacsim/physics/newton_physics.rst):
| 类 | 用途 |
|---|---|
isaacsim.physics.newton.NewtonConfig | 每个仿真的设置(CUDA 图捕获、fabric 同步、接触/关节默认值) |
XPBDSolverConfig | XPBD 求解器(刚体 + 软体) |
MuJoCoSolverConfig | MuJoCo Warp 求解器 |
isaacsim.physics.newton.tensors | NumPy/PyTorch/Warp 前端 |
Newton 和 PhysX 都使用标准的 UsdPhysics.Scene + PhysxSchema.PhysxSceneAPI;在 Newton 下,许多 PhysxSchema.* 属性仍会生效,此外 Newton 还会通过 omni.usd.schema.newton 读取其求解器配置。
技术栈与阅读顺序
- 本技能:场景配置、逐 prim 设置、接触材质、驱动器、传感器、读回、后端选择。
usd-articulation:多连杆关节结构 + Robot Schema 覆盖层。urdf-mjcf-to-usd-conversion:导入器配置(RL 与远程操作驱动器)。isaac-sim-troubleshooting:Kit 110 中物理行为异常时使用。
机构配置示例(冲击、送料器、多米诺骨牌、陀螺、摇篮、摆波、擒纵机构)见示例详解。
第 1 部分 — 场景级配置
PhysicsScene 设置
from pxr import Usd, UsdGeom, UsdPhysics, PhysxSchema, Gf
ps = UsdPhysics.Scene.Define(stage, "/World/PhysicsScene")
ps.CreateGravityDirectionAttr().Set(Gf.Vec3f(0, 0, -1))
ps.CreateGravityMagnitudeAttr().Set(9.81)
px = PhysxSchema.PhysxSceneAPI.Apply(ps.GetPrim())
px.CreateTimeStepsPerSecondAttr().Set(240) # see Hz table below
px.CreateEnableCCDAttr().Set(True)
px.CreateEnableStabilizationAttr().Set(True)
px.CreateSolverTypeAttr().Set("TGS") # TGS or PGS; TGS preferred for articulations
物理 Hz 选择
| 场景 | Hz | 说明 |
|---|---|---|
| 标准刚体场景 | 60–120 | 仓库、通用仿真的默认值 |
| 堆叠/高接触密度场景 | 240 | 提高接触分辨率 |
| 高速冲击 | 120,含 2–4 个子步 | 配合 CCD 使用 |
| 小零件振动(送料器) | ≥ 振动频率的 4 倍,通常为 480 | 正确解析振荡 |
| 旋转物体/陀螺 | 480 | 提高角动量的数值精度 |
| 刚性接触链(摇篮、擒纵机构) | 480 | 求解器需要大量子迭代 |
**经验法则:**物理时间步长必须 > 系统中最高频率(振动、旋转、接触刚度模态)的 4 倍。
求解器迭代次数(逐刚体)
在需要设置的每个刚体上设置 PhysxRigidBodyAPI。数值越高,精度越高,速度越慢。
| 场景 | 位置迭代次数 | 速度迭代次数 |
|---|---|---|
| 简单刚体、翻滚 | 16 | 4 |
| 堆叠 | 32 | 8 |
| 复杂关节/关节结构 | 64 | 16 |
| 刚性接触链(摇篮、擒纵机构) | 64 | 32 |
pxrb = PhysxSchema.PhysxRigidBodyAPI.Apply(prim)
pxrb.CreateSolverPositionIterationCountAttr().Set(32)
pxrb.CreateSolverVelocityIterationCountAttr().Set(8)
pxrb.CreateEnableCCDAttr().Set(True)
何时禁用稳定化
EnableStabilizationAttr 默认启用,有助于堆叠物体稳定下来。它会破坏自由旋转物体的角动量。以下情况应禁用:
- 旋转陀螺、陀螺仪、飞轮
- 摆锤机构(时钟擒纵机构、摆波)
- 任何正确性依赖于角速度守恒的物体
px.CreateEnableStabilizationAttr().Set(False)
第 2 部分 — 逐 Prim 物理设置
RigidBody / Collision / Static / Kinematic
使用 scripts/prim_physics_setup.py 设置动态、静态和运动学刚体。该脚本将 RigidBodyAPI、MassAPI 和 CollisionAPI 的应用顺序集中在一个可执行实现中。
规则:在同一个 prim 上应用 RigidBodyAPI + CollisionAPI。将它们拆分到父级/子级 prim 上会导致间歇性碰撞故障。
带缩放的静态碰撞体 — 先平移模式
直接对已应用 CollisionAPI 的 Cube prim 进行缩放,会导致 PhysX 使用错误的碰撞边界(物体会穿过地面)。使用父级 xform 设置位置,并使用子级网格设置缩放:
# CORRECT
xf = UsdGeom.Xform.Define(stage, "/World/Ground")
UsdGeom.Xformable(xf.GetPrim()).AddTranslateOp().Set(Gf.Vec3d(0, 0, -0.05))
mesh = UsdGeom.Cube.Define(stage, "/World/Ground/Mesh")
mesh.CreateSizeAttr().Set(1.0)
UsdGeom.Xformable(mesh.GetPrim()).AddScaleOp().Set(Gf.Vec3f(50.0, 50.0, 0.1))
UsdPhysics.CollisionAPI.Apply(mesh.GetPrim())
Cube.size=1.0 表示立方体的半边长为 0.5,而不是 1.0。若希望“缩放操作的值等于半边长”,请使用 size=2.0。
质量与惯性
mass_api = UsdPhysics.MassAPI.Apply(prim)
mass_api.CreateMassAttr().Set(0.25) # kg
mass_api.CreateCenterOfMassAttr().Set(Gf.Vec3f(0, 0, 0.05)) # local
mass_api.CreateDiagonalInertiaAttr().Set(Gf.Vec3f(1e-4, 1e-4, 2e-4)) # kg·m²
对于从 URDF 导入的机器人,建议在 config.yaml 中设置 import_inertia_tensor: true,而不是自动计算几何惯性(参见 urdf-mjcf-to-usd-conversion)。
第 3 部分 — 接触材料
def create_contact_material(stage, mat_path, static_friction=0.5,
dynamic_friction=0.4, restitution=0.1):
prim = stage.DefinePrim(mat_path)
mat = UsdPhysics.MaterialAPI.Apply(prim)
mat.CreateStaticFrictionAttr().Set(static_friction)
mat.CreateDynamicFrictionAttr().Set(dynamic_friction)
mat.CreateRestitutionAttr().Set(restitution)
return mat
参考值
| 材料组合 | 静摩擦系数 μ | 动摩擦系数 μ | 恢复系数 |
|---|---|---|---|
| 混凝土与混凝土 | 0.6 | 0.5 | 0.05 |
| 钢与钢 | 0.74 | 0.57 | 0.6 |
| 橡胶与橡胶 | 0.8 | 0.7 | 0.5 |
| 橡胶与混凝土 | 1.0 | 0.8 | 0.3 |
| 木材与木材 | 0.5 | 0.3 | 0.2 |
| 通用金属 | 0.4 | 0.3 | 0.2 |
| 塑料(骰子) | 0.4 | 0.3 | 0.3 |
| 毛毡(赌场) | 0.5 | 0.4 | 0.2 |
| 纸板与钢 | 0.4 | 0.3 | 0.1 |
对于一连串刚性接触(牛顿摆、擒纵机构),在 PhysxMaterialAPI 上设置 restitutionCombineMode=max,使每次接触都采用最高恢复系数。
第 4 部分 — 关节驱动
joint = stage.GetPrimAtPath("/World/Robot/joint_arm")
drive = UsdPhysics.DriveAPI.Apply(joint, "angular") # "angular" | "linear"
drive.CreateTypeAttr().Set("force") # "force" | "acceleration"
drive.CreateStiffnessAttr().Set(1000.0) # Kp (Nm/rad for angular)
drive.CreateDampingAttr().Set(100.0) # Kd (Nm·s/rad)
drive.CreateMaxForceAttr().Set(500.0) # torque/force limit
drive.CreateTargetPositionAttr().Set(0.0) # target (deg or m)
对于 RL 训练,Agent 直接命令扭矩。在 config.yaml 中将 drive_type 设为 none,并将刚度和阻尼设为 0(参见 urdf-mjcf-to-usd-conversion)。启用的 PD 驱动会与 RL Agent 抢夺控制权。
对于转动摆关节(时钟擒纵机构、摆波),将关节摩擦设为 0:
joint_api = PhysxSchema.PhysxJointAPI.Apply(joint)
joint_api.CreateJointFrictionAttr().Set(0.0)
第 5 部分 — 后端选择(Newton 与 PhysX)
快速选择
| 需求 | 使用 |
|---|---|
| 使用数千个环境进行 RL 训练 | Newton(Featherstone 或 MuJoCo) |
| 可微分仿真 | Newton |
| 来自 Isaac Sim 5.x 的旧版 PhysX 场景 | PhysX |
| 软体、布料、可变形物体 | Newton(VBD 或 XPBD) |
| 与 MuJoCo 基准验证 | Newton SolverMuJoCo |
Newton 求解器
| 求解器 | 坐标系 | 可微分 | 最适用于 |
|---|---|---|---|
| SolverFeatherstone | 广义坐标 | 是(Warp) | 关节式机器人(操纵器、腿式机器人的默认选项) |
| SolverMuJoCo | 广义坐标 | 是(mujoco-warp) | 经验证的运动控制、MuJoCo 策略移植 |
| SolverXPBD | 极大坐标 | 部分支持 | 软约束、缆线、绳索 |
| SolverSemiImplicit | 极大坐标 | 是(Warp) | 快速原型设计、简单刚体 |
| SolverVBD | (可变形) | 是 | 软体、可变形物体 |
对于必须同时在 Newton 下运行的现有 PhysX 专用 USD 资产,请参见 physx-to-newton-conversion。
Newton 与 PhysX 的差异
| 方面 | PhysX | Newton |
|---|---|---|
| 后端 | 闭源 C++/CUDA | Warp/CUDA(开源、JIT) |
| 坐标系 | 极大坐标(每个物体 6 DoF) | 广义坐标(Featherstone)或极大坐标 |
| 可微分 | 否 | 是(原生 Warp 自动微分) |
| 多 GPU | 有限 | 是(Warp 设备抽象) |
| USD 集成 | Schema 扩展 | 原生 USD 加载器 |
| 性能上限 | 低于 4096 个环境时表现良好 | 专为 10K+ 个环境设计 |
Newton + Torch — 关键初始化顺序
切勿在 Newton 物理引擎稳定前 import torch——CUDA 上下文冲突会导致 Kit 卡住。将 torch 导入延后至 timeline.play() 和稳定循环之后。如果 VRAM 紧张,策略推理时使用 map_location="cpu"。
Newton 专用配置(Isaac Lab)
# config.yaml for URDF→USD conversion (Isaac Lab)
make_instanceable: true # CRITICAL for RL parallel envs
fix_base: false # true for fixed-base arm; false for mobile/legged
完整 Schema 请参见 urdf-mjcf-to-usd-conversion。
第 6 部分 — 物理传感器
当前命名空间为 isaacsim.sensors.experimental.physics(配对提供配置与运行时类)。旧版 isaacsim.sensors.physics 导入路径仍然可用,但新代码中已弃用。
**迁移:**有关概念映射和更新后的脚本,请参见从
isaacsim.sensors.physics迁移到isaacsim.sensors.experimental.physics。
接触
from isaacsim.sensors.experimental.physics import Contact, ContactSensor
import isaacsim.core.experimental.utils.app as app_utils
contact = Contact.create(
path="/World/Robot/foot/contact",
min_threshold=0.0, max_threshold=1e6, radius=-1, # -1 = use collision shape
)
sensor = ContactSensor(contact)
app_utils.play(commit=True) # required before get_data()
reading = sensor.get_data() # ContactSensorReading
IMU
from isaacsim.sensors.experimental.physics import IMU, IMUSensor
imu = IMU.create(path="/World/Robot/imu", tick_rate=200.0)
sensor = IMUSensor(imu, annotators=["linear_acceleration", "angular_velocity", "orientation"])
app_utils.play(commit=True)
frame = sensor.get_data() # returns IMUSensorReading
力矩 / 关节状态
同一模块中的运行时专用类;没有单独的配置类型——它们通过路径包装现有关节。
from isaacsim.sensors.experimental.physics import EffortSensor, JointStateSensor
effort = EffortSensor("/World/Robot/joint_arm_1")
joint = JointStateSensor("/World/Robot/joint_arm_1")
app_utils.play(commit=True)
reading = effort.get_data() # EffortSensorReading
state = joint.get_data() # JointStateSensorReading
Raycast(场景查询)
import omni.physics.tensors as physics_tensors
sim_view = physics_tensors.create_simulation_view("cuda:0")
hit = sim_view.raycast_closest(origin, direction, max_dist)
如需更高保真度的传感器仿真(LiDAR 扫描模式、多射线、供应商传感器模型、深度/雷达/声学),请参阅 isaac-sim-sensor 和 isaac-camera。它们使用现代的 isaacsim.sensors.experimental.rtx 和 .physics 命名空间。
第 7 部分 — 物理到 USD 回读(重要)
最常见的静默错误:读取已写入的 USD 变换,而不是仿真状态。
| 来源 | 返回值 | 使用时机 |
|---|---|---|
UsdGeom.XformCache.GetLocalToWorldTransform() | 已写入的 USD 变换(初始位姿) | 编辑器阶段查询、播放之前 |
RigidPrim.get_world_pose() | 仿真中的状态 | 仿真期间始终使用 |
Articulation.get_world_poses()(Kit 110) | 关节体的仿真中状态 | 关节机器人 |
Dynamic Control (DC) dc.get_rigid_body_pose() | 仿真中的状态 | 旧版/快速脚本 |
为什么 XformCache 在仿真期间会出错
updateToUsd=True 会将物理状态写入 Fabric,而非 USD 阶段层。XformCache 读取的是 USD 层。结果:它始终返回初始位姿。
RigidPrim / GeomPrim 模式(Kit 110)
from isaacsim.core.experimental.prims import RigidPrim
import isaacsim.core.experimental.utils.app as app_utils
rp = RigidPrim(paths="/World/Dice/Die_*")
app_utils.play(commit=True)
pos_wp, quat_wp = rp.get_world_poses() # warp arrays
positions = pos_wp.numpy() # (N, 3)
quaternions = quat_wp.numpy() # (N, 4) [w, x, y, z]
Articulation 模式(Kit 110)
from isaacsim.core.experimental.prims import Articulation
import isaacsim.core.experimental.utils.app as app_utils
robot = Articulation("/World/Robot")
app_utils.play(commit=True) # required for tensor data
pos_wp, quat_wp = robot.get_world_poses()
dof_positions = robot.get_dof_positions().numpy() # (N, num_dofs)
dof_velocities = robot.get_dof_velocities().numpy()
J = robot.get_jacobian_matrices().numpy() # for IK
旧版 isaacsim.core.api.articulations.Articulation / isaacsim.core.api.prims.RigidPrim 仍可加载,但已被 isaacsim.core.experimental.* 技术栈取代。
**迁移:**有关更全面的
omni.isaac.*→isaacsim.*重命名映射,请参阅扩展重命名。有关实验性 Articulation / RigidPrim API,请参阅 Python 脚本索引。
四元数约定
USD/Isaac 使用 [w, x, y, z];scipy 使用 [x, y, z, w]。转换方式:
from scipy.spatial.transform import Rotation
r = Rotation.from_quat([quat[1], quat[2], quat[3], quat[0]])
euler = r.as_euler('xyz', degrees=True)
第 8 部分 — 常见注意事项
- 仅有
CollisionAPI= 静态碰撞体;RigidBodyAPI+CollisionAPI= 动态碰撞体。 - 必须位于同一 prim 上:两个 API 必须在同一 prim 上。
- 运动学物体:使用
CreateKinematicEnabledAttr().Set(True),不要通过 RigidBodyAPI 启用/禁用。 Cube.size=1.0= 半长为 0.5。若希望缩放操作的值等于半长,请使用size=2.0。- PhysX 运行时会忽略
physics:velocityUSD 属性。请在timeline.play()之后使用RigidPrim.set_linear_velocities()。 physics:angularVelocity的单位是度/秒,不是 rad/s。使用math.degrees()转换。SimulationContext.step(render=True)是唯一可靠的物理与渲染同步推进方式。app.update()不会同步物理。- 实验性传感器需要先调用
app_utils.play(commit=True)(或timeline.play()),再调用get_data();不要在旧版World流程中调用initialize()。 - Isaac Sim 5.1+ 中不存在
get_rigid_body_state();请使用isaacsim.core.experimental.prims中的RigidPrim.get_world_poses()。 - PhysX 无法在同一岛内的接触链中解析连续的动量传递(请参阅示例 4:牛顿摆 — PhysX 对同一岛内接触的限制)。
- 高速旋转时会发生穿透:复合碰撞体在 5–6s 后、角速度超过约 50 rad/s 时会失效。请使用更简单的凸包或提高物理 Hz。
- 诊断控制器之前:请确认存在
PhysicsScene、时间轴处于活动状态,且具备预期的碰撞 API。
实例(冲击、振动给料器、陀螺仪、牛顿摆、擒纵机构)
详情请参阅 examples.md。