mcpField
P
physics-simulation

physics-simulation

github.com/isaac-sim其他4.4k58 次安装6 天前更新
代码仓库

关于 physics-simulation

面向 Isaac Sim 6 和 Kit 110 的物理配置实用技能,涵盖场景参数、单个 Prim 设置、材质、驱动器、传感器及后端选择,并提供脚本和示例。

主要功能

  1. 01物理场景与求解器配置
  2. 02刚体和碰撞体设置
  3. 03接触材质与关节驱动器
  4. 04Newton 与 PhysX 后端选择
  5. 05Prim 设置辅助脚本

适用场景

  1. 01配置刚体和碰撞体
  2. 02调整高接触或高速场景
  3. 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.pyIsaac 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 同步、接触/关节默认值)
XPBDSolverConfigXPBD 求解器(刚体 + 软体)
MuJoCoSolverConfigMuJoCo Warp 求解器
isaacsim.physics.newton.tensorsNumPy/PyTorch/Warp 前端

Newton 和 PhysX 都使用标准的 UsdPhysics.Scene + PhysxSchema.PhysxSceneAPI;在 Newton 下,许多 PhysxSchema.* 属性仍会生效,此外 Newton 还会通过 omni.usd.schema.newton 读取其求解器配置。

技术栈与阅读顺序

  1. 本技能:场景配置、逐 prim 设置、接触材质、驱动器、传感器、读回、后端选择。
  2. usd-articulation:多连杆关节结构 + Robot Schema 覆盖层。
  3. urdf-mjcf-to-usd-conversion:导入器配置(RL 与远程操作驱动器)。
  4. 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。数值越高,精度越高,速度越慢。

场景位置迭代次数速度迭代次数
简单刚体、翻滚164
堆叠328
复杂关节/关节结构6416
刚性接触链(摇篮、擒纵机构)6432
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.60.50.05
钢与钢0.740.570.6
橡胶与橡胶0.80.70.5
橡胶与混凝土1.00.80.3
木材与木材0.50.30.2
通用金属0.40.30.2
塑料(骰子)0.40.30.3
毛毡(赌场)0.50.40.2
纸板与钢0.40.30.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 的差异
方面PhysXNewton
后端闭源 C++/CUDAWarp/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 部分 — 常见注意事项

  1. 仅有 CollisionAPI = 静态碰撞体;RigidBodyAPI + CollisionAPI = 动态碰撞体。
  2. 必须位于同一 prim 上:两个 API 必须在同一 prim 上。
  3. 运动学物体:使用 CreateKinematicEnabledAttr().Set(True),不要通过 RigidBodyAPI 启用/禁用。
  4. Cube.size=1.0 = 半长为 0.5。若希望缩放操作的值等于半长,请使用 size=2.0。
  5. PhysX 运行时会忽略 physics:velocity USD 属性。请在 timeline.play() 之后使用 RigidPrim.set_linear_velocities()。
  6. physics:angularVelocity 的单位是度/秒,不是 rad/s。使用 math.degrees() 转换。
  7. SimulationContext.step(render=True) 是唯一可靠的物理与渲染同步推进方式。app.update() 不会同步物理。
  8. 实验性传感器需要先调用 app_utils.play(commit=True)(或 timeline.play()),再调用 get_data();不要在旧版 World 流程中调用 initialize()。
  9. Isaac Sim 5.1+ 中不存在 get_rigid_body_state();请使用 isaacsim.core.experimental.prims 中的 RigidPrim.get_world_poses()。
  10. PhysX 无法在同一岛内的接触链中解析连续的动量传递(请参阅示例 4:牛顿摆 — PhysX 对同一岛内接触的限制)。
  11. 高速旋转时会发生穿透:复合碰撞体在 5–6s 后、角速度超过约 50 rad/s 时会失效。请使用更简单的凸包或提高物理 Hz。
  12. 诊断控制器之前:请确认存在 PhysicsScene、时间轴处于活动状态,且具备预期的碰撞 API。

实例(冲击、振动给料器、陀螺仪、牛顿摆、擒纵机构)

详情请参阅 examples.md。

评论

支持 Markdown