作者:张新红 出品:车路漫漫
做机器人仿真的话估计你肯定知道IsaacSim这个软件。
今天来跟大家分享一下IsaacSim的使用技巧,主要是IsaacSim是一个需要大量UI操作来进行仿真的软件,但是我们测试开发人员往往需要进行批量化大规模运行,因此,本文分享的是如何通过代码来进行配置已实现批量化运行,本文仅以立方体为例进行演示,机器人同理。
照例先交代下我的运行环境:
· 操作系统:ubuntu 20.04
· 编程语言:python 3.6
· 仿真软件:isaacsim 6.0.0
以下是完整代码(my_application.py)。能看懂的盆友看这个就行,看不明白的我后面有挨个片段说明。
# Launch Isaac Sim before any other imports
# Default first two lines in any standalone application
# 导入 SimulationApp 类,而不是整个模块,或者从模块中导入类
from isaacsim.simulation_app import SimulationApp
# 创建实例,注意变量名不要与导入的类名或模块名混淆(虽然这里用 simulation_app 做变量名也可以,但最好区分开)
# 推荐做法:实例化 SimulationApp 类
simulation_app = SimulationApp({"headless": False}) # we can also run as headless
# Now import Isaac Sim modules
import isaacsim.core.experimental.utils.stage as stage_utils
import numpy as np
import omni.timeline
from isaacsim.core.experimental.materials import PreviewSurfaceMaterial
from isaacsim.core.experimental.objects import Cube
from isaacsim.core.experimental.prims import GeomPrim, RigidPrim
from isaacsim.core.simulation_manager import SimulationManager
from isaacsim.storage.native import get_assets_root_path
# Add ground plane
ground_plane = stage_utils.add_reference_to_stage(
usd_path=get_assets_root_path() + "/Isaac/Environments/Grid/default_environment.usd",
path="/World/ground",
)
# Create a blue visual material for the cube
visual_material = PreviewSurfaceMaterial("/World/Materials/blue")
visual_material.set_input_values("diffuseColor", [0.0, 0.0, 1.0])
# Create the cube geometry
cube_shape = Cube(
paths="/World/fancy_cube",
positions=np.array([[0.0, 0.0, 1.0]]),
sizes=[1.0],
scales=np.array([[0.5, 0.5, 0.5]]),
reset_xform_op_properties=True,
)
# Apply collision and rigid body
GeomPrim(paths=cube_shape.paths, apply_collision_apis=True)
cube = RigidPrim(paths=cube_shape.paths)
# --- [修正] 自定义物理属性 ---
# 获取 stage 和 prim 来设置阻尼
stage = omni.usd.get_context().get_stage()
prim_path = cube_shape.paths[0] # 获取字符串路径
prim = stage.GetPrimAtPath(prim_path)
if prim.IsValid():
# 设置线性阻尼 (0.0 ~ 1.0+, 默认通常为 0.0)
# 属性名称可能因版本略有不同,但 physxRigidBody:linearDamping 是标准名称
attr_lin = prim.GetAttribute("physxRigidBody:linearDamping")
if attr_lin.IsValid():
attr_lin.Set(0.1)
print(f"Set linear damping to 0.1")
# 设置角阻尼
attr_ang = prim.GetAttribute("physxRigidBody:angularDamping")
if attr_ang.IsValid():
attr_ang.Set(0.1)
print(f"Set angular damping to 0.1")
# 可选:设置质量 (Mass)
# attr_mass = prim.GetAttribute("physics:mass")
# if attr_mass.IsValid():
# attr_mass.Set(1.0)
# -------------------------
cube_shape.apply_visual_materials(visual_material)
# Start the timeline (physics simulation)
omni.timeline.get_timeline_interface().play()
simulation_app.update()
# Run the simulation loop
for i in range(50000):
# Only query when physics is actively simulating
if SimulationManager.is_simulating():
positions, orientations = cube.get_world_poses()
linear_velocities, angular_velocities = cube.get_velocities()
# Will be shown on terminal
print("Cube position is : " + str(positions.numpy()[0]))
print("Cube's orientation is : " + str(orientations.numpy()[0]))
print("Cube's linear velocity is : " + str(linear_velocities.numpy()[0]))
# Step the app (physics + rendering)
simulation_app.update()
# simulation_app.close() # close Isaac Sim 上述代码执行方式为:
me@Linux:/data/code/IsaacSim/_build/linux-x86_64/release$ ./python.sh ./exts/isaacsim.examples.interactive/isaacsim/examples/interactive/user_examples/my_application.py 导入 SimulationApp 类,而不是整个模块,或者从模块中导入类。
代码:
# Launch Isaac Sim before any other imports
# Default first two lines in any standalone application
from isaacsim.simulation_app import SimulationApp 解释:从 isaacsim.simulation_app 模块中导入 SimulationApp 类。这是启动 Isaac Sim 引擎的核心类。注意:必须在导入其他 Omniverse/Isaac 模块之前执行此操作。
创建实例,注意变量名不要与导入的类名或模块名混淆(虽然这里用 simulation_app 做变量名也可以,但最好区分开)。推荐做法:实例化 SimulationApp 类。
代码:
simulation_app = SimulationApp({"headless": False}) # we can also run as headless 解释:实例化 SimulationApp 对象。
{"headless": False}:表示启动带有图形用户界面(GUI)的窗口。如果设为 True,则只在后台运行,不显示画面,适合服务器环境。
这行代码执行后,Isaac Sim 引擎正式加载,窗口弹出。
代码:
# 导入舞台(Stage)工具模块。stage_utils 提供了方便的方法来操作 USD 舞台,例如添加参考模型。
import isaacsim.core.experimental.utils.stage as stage_utils
import numpy as np
# 导入 Omniverse 时间线模块。用于控制仿真的播放、暂停和步进。
import omni.timeline
# 导入预览表面材质类。用于创建简单的视觉材质(如颜色、粗糙度)。
from isaacsim.core.experimental.materials import PreviewSurfaceMaterial
# 导入立方体几何体类。这是一个高级封装,用于快速创建立方体形状。
from isaacsim.core.experimental.objects import Cube
# 导入原始对象(Prim)处理类。
# GeomPrim:用于处理几何属性,如添加碰撞体(Collision)。
# RigidPrim:用于处理刚体属性,如质量、速度、受力。
from isaacsim.core.experimental.prims import GeomPrim, RigidPrim
# 导入仿真管理器。用于查询仿真状态(如是否正在模拟、当前时间步等)。
from isaacsim.core.simulation_manager import SimulationManager
# 获取 Isaac Sim 本地资源库的根路径。用于定位内置的资源文件(如地面、机器人模型等)。
from isaacsim.storage.native import get_assets_root_path 代码:
# Add ground plane
ground_plane = stage_utils.add_reference_to_stage(
usd_path=get_assets_root_path() + "/Isaac/Environments/Grid/default_environment.usd",
path="/World/ground",
) 解释:向舞台添加一个参考模型。
usd_path:指定资源文件的路径。这里加载的是默认的网格环境,包含一个无限大的地面平面。
path:指定该模型在 USD 舞台中的层级路径为 /World/ground。
ground_plane:返回创建的 Prim 对象引用。
# Create a blue visual material for the cube
visual_material = PreviewSurfaceMaterial("/World/Materials/blue") 解释:创建一个名为 PreviewSurfaceMaterial 的材质对象,并将其放置在舞台路径 /World/Materials/blue 下。
visual_material.set_input_values("diffuseColor", [0.0, 0.0, 1.0]) 解释:设置材质的输入参数。
"diffuseColor":漫反射 颜色。
[0.0, 0.0, 1.0]:RGB 值,代表纯蓝色。
# Create the cube geometry
cube_shape = Cube(
paths="/World/fancy_cube",
positions=np.array([[0.0, 0.0, 1.0]]),
sizes=[1.0],
scales=np.array([[0.5, 0.5, 0.5]]),
reset_xform_op_properties=True,
) 解释:创建立方体几何体。
paths:立方体在舞台中的路径 /World/fancy_cube。
positions:初始位置坐标 (x=0, y=0, z=1),即离地面 1 米高。
sizes:立方体的原始尺寸为 1x1x1 米。
scales:缩放比例为 0.5,所以最终显示大小为 0.5x0.5x0.5 米。
reset_xform_op_properties:重置变换属性,确保位置和大小的设置生效,不受默认变换影响。
代码:
# Apply collision and rigid body
GeomPrim(paths=cube_shape.paths, apply_collision_apis=True) 解释:为立方体添加碰撞属性。
apply_collision_apis=True:自动添加 PhysxCollisionAPI,使立方体能够与其他物体(如地面)发生碰撞检测,防止穿透。
代码:
cube = RigidPrim(paths=cube_shape.paths) 解释:为立方体添加刚体属性。
这会添加 PhysxRigidBodyAPI,使立方体成为受物理引擎控制的刚体,具有质量、速度,并受重力影响。
cube 是一个 RigidPrim 对象,后续可以通过它查询或设置物理状态。
代码:
# --- [修正] 自定义物理属性 ---
# 获取 stage 和 prim 来设置阻尼
stage = omni.usd.get_context().get_stage()
prim_path = cube_shape.paths[0] # 获取字符串路径
prim = stage.GetPrimAtPath(prim_path) # Stage中的逻辑路径 解释:获取底层的 USD Stage 和 Prim 对象,以便直接修改底层属性。
cube_shape.paths[0]:因为 paths 可能是一个列表,这里取第一个路径字符串。
stage.GetPrimAtPath(...):根据路径获取具体的 USD Prim 对象。
代码:
if prim.IsValid():
# 设置线性阻尼 (0.0 ~ 1.0+, 默认通常为 0.0)
# 属性名称可能因版本略有不同,但 physxRigidBody:linearDamping 是标准名称
attr_lin = prim.GetAttribute("physxRigidBody:linearDamping")
if attr_lin.IsValid():
attr_lin.Set(0.1)
print(f"Set linear damping to 0.1")
# 设置角阻尼
attr_ang = prim.GetAttribute("physxRigidBody:angularDamping")
if attr_ang.IsValid():
attr_ang.Set(0.1)
print(f"Set angular damping to 0.1")
# 可选:设置质量 (Mass)
# attr_mass = prim.GetAttribute("physics:mass")
# if attr_mass.IsValid():
# attr_mass.Set(1.0)
# ------------------------- 解释:通过 USD 属性接口设置物理参数。
linearDamping:线性阻尼,模拟空气阻力。值越大,物体移动越慢。
angularDamping:角阻尼,模拟旋转阻力。值越大,物体旋转停止得越快。
IsValid() 检查确保属性存在且可写,避免报错。
代码:
cube_shape.apply_visual_materials(visual_material) 解释:将之前创建的蓝色材质应用到立方体上。这样立方体在渲染时就会显示为蓝色。
代码:
# Start the timeline (physics simulation)
omni.timeline.get_timeline_interface().play()
解释:获取时间线接口并调用 play()。这会启动物理引擎,开始计算重力、碰撞等物理效果。
Python
simulation_app.update() 解释:触发一次应用更新。这会渲染第一帧画面,并让物理引擎迈出第一步。
代码:
# Run the simulation loop
for i in range(50000):
# Only query when physics is actively simulating
# 检查仿真管理器是否处于“正在仿真”状态。这是一种安全检查,确保在物理引擎就绪时才读取数据。
if SimulationManager.is_simulating():
# 从 RigidPrim 对象 cube 中读取当前状态。
positions, orientations = cube.get_world_poses() # 返回世界坐标系下的位置(Position)和方向(Orientation,四元数)。
linear_velocities, angular_velocities = cube.get_velocities() # 返回线性速度(Linear Velocity)和角速度(Angular Velocity)。
# Will be shown on terminal
print("Cube position is : " + str(positions.numpy()[0]))
print("Cube's orientation is : " + str(orientations.numpy()[0]))
print("Cube's linear velocity is : " + str(linear_velocities.numpy()[0]))
# Step the app (physics + rendering)
# 推进物理引擎一步(计算下一时刻的位置和速度)。
# 渲染引擎绘制当前帧的画面。
# 处理窗口事件(如点击关闭按钮)。
# 如果没有这行代码,仿真不会前进,画面也不会刷新。
simulation_app.update() # # close Isaac Sim
