Isaac Sim 快速入门:三种工作流程示例
简介
如果是NVIDIA Isaac Sim的新用户,可以按照本文的两个示例来体验Isaac Sim。本文主要提供Isaac Sim基础使用教程、机器人基础教程。
在快速入门教程中,所有可通过 GUI 执行的操作同样也能用 Python 实现。您可以在 GUI 操作与 Python 脚本之间自由切换。您在 GUI 中创建的所有内容都能保存为 USD 文件的一部分。
例如,您可以通过图形界面创建世界,并为机器人添加所需动作。随后将整个 USD 文件导入独立的 Python 脚本中,根据需求系统性地修改属性。
基础使用教程
本教程涵盖 Isaac Sim 的基础操作,包括界面导航、场景对象添加、查看对象基本属性以及运行模拟等内容。
通过本教程,您将从空白场景开始,根据三种不同工作流程的选择,最终实现机器人运动控制。提供三种不同工作流程的目的是展示 Isaac Sim 可根据需求以多种方式灵活使用。
可以查看两种工作流中的脚本以了解它们的差异。通过对比分析,有助于掌握如何执行完全相同的任务:
- 扩展脚本可在Window > Examples > Robotics Examples中找到,然后单击浏览器右上角的**Open Script **按钮。
- 独立脚本位于 \<isaac-sim-root-dir>/standalone_examples/tutorials/ 文件夹内。
可以通过编辑扩展示例中的任意脚本来体验”hot-reloading”功能。保存文件后,无需关闭模拟器即可立即看到变更生效。
在官方教程中有3个标签页,三个标签页执行相同操作并达成相同结果。
- GUI: 图形用户界面
- Extensions:扩展功能
- Standalone Python:独立Python环境
GUI方式
步骤1:启动Isaac Sim
- linux:cd ~/isaacsim && ./isaac-sim.selector.sh
- windows:双击isaac-sim.selector.bat
模拟器完全加载后,创建新场景:
从顶部菜单栏点击File > New。首次启动 Isaac Sim 时,可能需要 5-10 分钟完成初始化。
步骤2: 添加地平面
为场景添加地平面:从顶部菜单栏点击Create > Physics > Ground Plane。
步骤3:添加光源
可以为场景添加光源以照亮其中的物体。如果场景中有光源但没有物体反射光线,场景仍会显得昏暗。
在顶部菜单栏中,点击Create > Lights > Distant Light。
步骤4:添加视觉立方体
“视觉”立方体是指没有附加物理属性的立方体,例如没有质量、没有碰撞体积。这种立方体不会受重力影响下落,也不会与其他物体发生碰撞。
从顶部菜单栏中,依次点击Create > Shape > Cube.
在用户界面最左侧找到箭头图标并点击Play。运行模拟时立方体不会有任何动作。
步骤5:移动、旋转与缩放立方体
使用左侧工具栏上的各种操控工具来操作立方体。
- 按下”W”键或点击移动工具即可拖拽移动立方体。通过点击箭头并拖拽可单轴移动,点击彩色方块并拖拽可双轴移动,点击工具中心的圆点并拖拽则可三轴自由移动。
- 按下“E”键或点击旋转控制器来旋转立方体。
- 按下“R”键或点击缩放控制器来调整立方体大小。点击箭头并拖动可单维度缩放,点击彩色方块并拖动可双维度缩放,点击控制器中心的圆圈并拖动则可实现三维同步缩放。
- 按下“esc”键取消选中立方体。
对于“移动”和“旋转”操作,可选择基于局部坐标系或世界坐标系进行操作。长按控制器即可查看选项。
可以通过立方体的Property属性面板进行更精确的修改,只需在对应输入框中输入具体数值即可。点击输入框旁的蓝色方块可将数值重置为默认值。
步骤6:添加物理与碰撞属性
常见的物理属性包括质量和惯性矩阵,这些属性使物体能够在重力作用下下落。碰撞属性则决定了物体能否与其他物体发生碰撞。
物理和碰撞属性可以分别添加,因此你可以创建一个能与其他物体碰撞但不受重力影响的物体,或是受重力影响但不会与其他物体碰撞的物体。但在多数情况下,这两个属性会同时添加。
为立方体添加物理和碰撞属性:
- 在场景树中找到对象(”/World/Cube”)并高亮显示它。
- 从工作区右下角的Property属性面板中,点击”Add”按钮并在下拉菜单中选择Physics。这将显示可添加到对象的一系列属性选项。
- 选择Rigid Body with Colliders Preset“带碰撞器的刚体预设”可为对象同时添加物理和碰撞网格。
- 按下播放Play按钮,观察立方体在重力作用下坠落并与地平面发生碰撞。
教程结束,记得保存你的工作。
扩展功能方式
通过一个名为”脚本编辑器”的现有扩展模块来演示扩展工作流的特性。脚本编辑器允许用户通过 Python 与场景进行交互。主要使用与独立 Python 工作流相同的 Python API。当我们开始与模拟时间轴交互时,特别是下一个教程中,这两种工作流的区别将变得清晰。
步骤1:启动
启动一个新的 Isaac Sim 实例,转到顶部菜单栏并点击Window > Script Editor。
步骤2:添加地平面
要通过交互式 Python 添加地平面,请将以下代码片段复制粘贴到脚本编辑器中,然后点击底部的运行Run按钮执行。
from isaacsim.core.api.objects.ground_plane import GroundPlane
GroundPlane(prim_path="/World/GroundPlane", z_position=0)
步骤3:添加光源
可以为场景添加光源以照亮其中的物体。如果场景中有光源但没有物体反射光线,场景仍会显得昏暗。
- 在脚本编辑器中新建一个标签页(Tab > Add Tab)。
- 在脚本编辑器中复制粘贴以下代码片段并运行,即可添加光源。
import omni.usd
from pxr import Sdf, UsdLux
stage = omni.usd.get_context().get_stage()
distantLight = UsdLux.DistantLight.Define(stage, Sdf.Path("/DistantLight"))
distantLight.CreateIntensityAttr(300)
步骤4:添加视觉立方体
- 在脚本编辑器中新建一个标签页 (Tab > Add Tab)。
- 在脚本编辑器中复制粘贴以下代码片段并运行,即可添加两个立方体。我们将保留其中一个作为纯视觉对象,同时为另一个添加物理和碰撞属性以便对比。
import numpy as np
from isaacsim.core.api.objects import VisualCuboid
VisualCuboid(
prim_path="/visual_cube",
name="visual_cube",
position=np.array([0, 0.5, 0.5]),
size=0.3,
color=np.array([255, 255, 0]),
)
VisualCuboid(
prim_path="/test_cube",
name="test_cube",
position=np.array([0, -0.5, 0.5]),
size=0.3,
color=np.array([0, 255, 255]),
)
Isaac Sim 核心 API 是对原生 USD 和物理引擎 API 的封装。您可以使用原生 USD API 添加一个视觉立方体(不含物理和颜色属性)。请注意原生 USD API 更为冗长,但能提供对每个属性的更精细控制。
from pxr import UsdPhysics, PhysxSchema, Gf, PhysicsSchemaTools, UsdGeom
import omni
# USD api for getting the stage
stage = omni.usd.get_context().get_stage()
# Adding a Cube
path = "/visual_cube_usd"
cubeGeom = UsdGeom.Cube.Define(stage, path)
cubePrim = stage.GetPrimAtPath(path)
size = 0.5
offset = Gf.Vec3f(1.5,-0.2,1.0)
cubeGeom.CreateSizeAttr(size)
if not cubePrim.HasAttribute("xformOp:translate"):
UsdGeom.Xformable(cubePrim).AddTranslateOp().Set(offset)
else:
cubePrim.GetAttribute("xformOp:translate").Set(offset)
步骤5:添加物理与碰撞属性
在 Isaac Sim 核心 API 中,我们为常用对象编写了封装器,这些封装器附带所有物理和碰撞属性。您可以通过以下代码片段添加一个具有物理和碰撞属性的立方体。
import numpy as np
from isaacsim.core.api.objects import DynamicCuboid
DynamicCuboid(
prim_path="/dynamic_cube",
name="dynamic_cube",
position=np.array([0, -1.0, 1.0]),
scale=np.array([0.6, 0.5, 0.2]),
size=1.0,
color=np.array([255, 0, 0]),
)
另外,如果想修改现有对象使其具备物理和碰撞属性,可以使用以下代码片段。
from isaacsim.core.prims import RigidPrim
RigidPrim("/test_cube")
from isaacsim.core.prims import GeometryPrim
prim = GeometryPrim("/test_cube")
prim.apply_collision_apis()
点击播放Play按钮,观察立方体在重力作用下坠落并与地平面碰撞。
步骤6: 移动、旋转与缩放立方体
使用核心 API 移动物体:
import numpy as np
from isaacsim.core.prims import XFormPrim
translate_offset = np.array([[1.5,1.2,1.0]])
orientation_offset = np.array([[0.7,0.7,0,1]]) # note this is in radians
scale = np.array([[1,1.5,0.2]])
stage = omni.usd.get_context().get_stage()
cube_in_coreapi = XFormPrim(prim_paths_expr="/test_cube")
cube_in_coreapi.set_world_poses(translate_offset, orientation_offset)
cube_in_coreapi.set_local_scales(scale)
使用原始 USD API 移动物体:
from pxr import UsdGeom, Gf
import omni.usd
stage = omni.usd.get_context().get_stage()
cube_prim = stage.GetPrimAtPath("/visual_cube_usd")
translate_offset = Gf.Vec3f(1.5,-0.2,1.0)
rotate_offset = Gf.Vec3f(90,-90,180) # note this is in degrees
scale = Gf.Vec3f(1,1.5,0.2)
# translation
if not cube_prim.HasAttribute("xformOp:translate"):
UsdGeom.Xformable(cube_prim).AddTranslateOp().Set(translate_offset)
else:
cube_prim.GetAttribute("xformOp:translate").Set(translate_offset)
# rotation
if not cube_prim.HasAttribute("xformOp:rotateXYZ"): # there are also "xformOp:orient" for quaternion rotation, as well as "xformOp:rotateX", "xformOp:rotateY", "xformOp:rotateZ" for individual axis rotation
UsdGeom.Xformable(cube_prim).AddRotateXYZOp().Set(rotate_offset)
else:
cube_prim.GetAttribute("xformOp:rotateXYZ").Set(rotate_offset)
# scale
if not cube_prim.HasAttribute("xformOp:scale"):
UsdGeom.Xformable(cube_prim).AddScaleOp().Set(scale)
else:
cube_prim.GetAttribute("xformOp:scale").Set(scale)
独立python环境方式
脚本位于standalone_examples/tutorials/getting_started.py,要运行该脚本,请打开终端,导航至 Isaac Sim 安装根目录,并执行以下命令:
./python.sh standalone_examples/tutorials/getting_started.py
机器人基础教程
本小节介绍如何将机器人添加到场景中、移动机器人以及检查机器人状态。在开始教程前,请确保已经完成了上一章节isaac sim基础使用教程。
GUI方式
步骤1:向场景中添加机器人
- 新建场景:通过File > New Stage.。
- 添加机器人:向场景添加机器人,从顶部菜单栏点击Create > Robots > Franka Emika Panda Arm。
步骤2:检查机器人
使用物理检查器查看机器人关节属性。
- 前往Tools > Physics > Physics Inspector.。右侧将打开一个窗口。
- 选择 Franka 进行检查。窗口默认会显示关节信息,例如上下限位及默认位置。
- 点击右上角的三横线图标可查看更多选项,例如关节刚度和阻尼系数。
- 可选)修改这些数值,观察舞台上机器人随参数变化的运动。修改成功后会出现绿色对勾标记。
- 点击绿色对勾按钮,将当前参数设为机器人新的默认值。
步骤3:控制机器人
基于图形界面的机器人控制器位于 Omniverse 可视化编程工具 OmniGraphs 中。OmniGraph 相关章节提供了更深入的教程指导。本教程将通过快捷工具生成控制图,然后在 OmniGraph 编辑器中查看该控制图。
- 通过菜单栏选择 Tools > Robotics > Omnigraph Controllers > Joint Position.来打开控制图生成器。。
- 在新弹出的关节位置控制器**Articulation Position Controller Inputs **输入窗口中,点击 Robot Prim 字段旁的添加”Add”按钮。
- 选择 Franka 作为目标对象。
- 点击确定生成图表。
要移动机器人的话按照下面步骤
- 在右上角的“舞台”选项卡中,选择Graph > Position_Controller.。
- 选择 JointCommandArray 节点。您可以通过在舞台树中选择该节点,或在图表编辑器中选择该节点来完成此操作。
- 在右下角的Property选项卡中,可以看到关节命令值。构造数组节点Construct Array Node下的输入Inputs项对应机器人上的关节,从基座关节开始。
- 点击+按住+拖动不同的数值字段,或输入不同的值,可以看到机械臂位置发生变化。
- 点击Play开始模拟。
要生成可视化的图标
- 打开图表编辑器窗口:**Window > Graph Editors > Action Graph. **。该编辑器窗口会在包含机器人的视口选项卡下方以新选项卡形式打开。
- 调出新打开的浏览器标签页。
- 点击位于图形编辑器窗口中央的Edit Action Graph选项。
- 从列表中选择唯一存在的图形。
- 选择一个数组并查看Stage和Property选项卡,以了解每个数组节点关联的值。
- 在图形中选择”关节控制器”Articulation Controller对象以查看其属性。
Extension方式
步骤1:向场景添加机器人
新建一个场景(File > New)。要将机器人添加到场景中,请将以下代码片段复制粘贴到脚本编辑器中并运行。
import carb
from isaacsim.core.prims import Articulation
from isaacsim.core.utils.stage import add_reference_to_stage
from isaacsim.storage.native import get_assets_root_path
import numpy as np
assets_root_path = get_assets_root_path()
if assets_root_path is None:
carb.log_error("Could not find Isaac Sim assets folder")
usd_path = assets_root_path + "/Isaac/Robots/FrankaRobotics/FrankaPanda/franka.usd"
prim_path = "/World/Arm"
add_reference_to_stage(usd_path=usd_path, prim_path=prim_path)
arm_handle = Articulation(prim_paths_expr=prim_path, name="Arm")
arm_handle.set_world_poses(positions=np.array([[0, -1, 0]]))
步骤2:检查机器人
Isaac Sim 核心 API 提供了许多函数调用来获取机器人相关信息。以下是查询关节数量与名称、各类关节属性以及关节状态的示例代码。
在脚本编辑器中新建标签页,复制粘贴以下代码片段。该操作需在上一步添加机器人完成后执行(此时 arm_handle 已创建)。运行代码前需先点击播放Play按钮,这些命令需在物理引擎运行状态下才能生效。
# Get the number of joints
num_joints = arm_handle.num_joints
print("Number of joints: ", num_joints)
# Get joint names
joint_names = arm_handle.joint_names
print("Joint names: ", joint_names)
# Get joint limits
joint_limits = arm_handle.get_dof_limits()
print("Joint limits: ", joint_limits)
# Get joint positions
joint_positions = arm_handle.get_joint_positions()
print("Joint positions: ", joint_positions)
请注意,点击”运行”时仅会打印一次状态信息,即使模拟正在持续运行。如需查看最新状态,需反复点击”运行”按钮。若希望在每个物理步长都打印信息,需要将这些命令插入到每个物理步长都会执行的回调函数中。在章节”工作流程“中详细讲解时间步进机制。
要将命令插入物理回调中,请在脚本编辑器的单独标签页中运行以下代码片段。
import asyncio
from isaacsim.core.api.simulation_context import SimulationContext
async def test():
def print_state(dt):
joint_positions = arm_handle.get_joint_positions()
print("Joint positions: ", joint_positions)
simulation_context = SimulationContext()
await simulation_context.initialize_simulation_context_async()
await simulation_context.reset_async()
simulation_context.add_physics_callback("printing_state", print_state)
asyncio.ensure_future(test())
按下播放键启动模拟,然后运行该代码片段。您将看到终端在每个物理步骤打印出的信息。
如果不再需要每个物理步骤都打印信息,可以通过运行以下代码片段来移除物理回调。
simulation_context = SimulationContext()
simulation_context.remove_physics_callback("printing_state")
步骤3:控制机器人
在 Isaac Sim 中有多种控制机器人的方式。最底层是直接发送关节指令来设置位置、速度和力矩。以下是通过关节层级的 Articulation API 控制机器人的示例。
在脚本编辑器中新建一个标签页,复制粘贴以下代码片段。该代码需在前述添加机器人步骤完成后运行(此时 arm_handle 已建立)。运行代码片段前请先点击播放键Play。这些指令需在物理引擎运行状态下生效。我们将提供两个位置供您切换。若您已将上述打印状态代码片段添加至每个物理步骤,当机器人移动时您应能看到打印的关节编号发生变化。
# Set joint position randomly
arm_handle.set_joint_positions([[-1.5, 0.0, 0.0, -1.5, 0.0, 1.5, 0.5, 0.04, 0.04]])
# Set all joints to 0
arm_handle.set_joint_positions([[0.0, 0.0, 0.0 , 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]])
与前述 get_joint_positions 功能类似,此处的 set_joint_positions 仅在您点击”运行”时执行一次。若您希望在每个物理步骤发送指令,则需将这些命令插入到每个物理步骤都会执行的物理回调函数中。
独立Python方式
脚本位于 standalone_examples/tutorials/getting_started_robot.py 。要运行该脚本,请打开终端,导航至 Isaac Sim 安装的根目录,并执行以下命令:
./python.sh standalone_examples/tutorials/getting_started_robot.py
到此就完成了基本的操作了,接下来就是一系列的教程可以参考:《机器人设置教程系列》。