生成基本物体到场景中#

本教程探讨了如何从Python在Isaac Lab中将各种对象(或基本物体)生成到场景中。它基于先前的教程,演示了如何从独立脚本运行模拟器,并演示了如何生成地面平面、灯光、基本形状和来自USD文件的网格。

代码#

该教程对应于 source/standalone/tutorials/00_sim 目录中的 spawn_prims.py 脚本。让我们看一下Python脚本:

spawn_prims.py的代码
  1# Copyright (c) 2022-2024, The Isaac Lab Project Developers.
  2# All rights reserved.
  3#
  4# SPDX-License-Identifier: BSD-3-Clause
  5
  6"""This script demonstrates how to spawn prims into the scene.
  7
  8.. code-block:: bash
  9
 10    # Usage
 11    ./isaaclab.sh -p source/standalone/tutorials/00_sim/spawn_prims.py
 12
 13"""
 14
 15"""Launch Isaac Sim Simulator first."""
 16
 17
 18import argparse
 19
 20from omni.isaac.lab.app import AppLauncher
 21
 22# create argparser
 23parser = argparse.ArgumentParser(description="Tutorial on spawning prims into the scene.")
 24# append AppLauncher cli args
 25AppLauncher.add_app_launcher_args(parser)
 26# parse the arguments
 27args_cli = parser.parse_args()
 28# launch omniverse app
 29app_launcher = AppLauncher(args_cli)
 30simulation_app = app_launcher.app
 31
 32"""Rest everything follows."""
 33
 34import omni.isaac.core.utils.prims as prim_utils
 35
 36import omni.isaac.lab.sim as sim_utils
 37from omni.isaac.lab.utils.assets import ISAAC_NUCLEUS_DIR
 38
 39
 40def design_scene():
 41    """Designs the scene by spawning ground plane, light, objects and meshes from usd files."""
 42    # Ground-plane
 43    cfg_ground = sim_utils.GroundPlaneCfg()
 44    cfg_ground.func("/World/defaultGroundPlane", cfg_ground)
 45
 46    # spawn distant light
 47    cfg_light_distant = sim_utils.DistantLightCfg(
 48        intensity=3000.0,
 49        color=(0.75, 0.75, 0.75),
 50    )
 51    cfg_light_distant.func("/World/lightDistant", cfg_light_distant, translation=(1, 0, 10))
 52
 53    # create a new xform prim for all objects to be spawned under
 54    prim_utils.create_prim("/World/Objects", "Xform")
 55    # spawn a red cone
 56    cfg_cone = sim_utils.ConeCfg(
 57        radius=0.15,
 58        height=0.5,
 59        visual_material=sim_utils.PreviewSurfaceCfg(diffuse_color=(1.0, 0.0, 0.0)),
 60    )
 61    cfg_cone.func("/World/Objects/Cone1", cfg_cone, translation=(-1.0, 1.0, 1.0))
 62    cfg_cone.func("/World/Objects/Cone2", cfg_cone, translation=(-1.0, -1.0, 1.0))
 63
 64    # spawn a green cone with colliders and rigid body
 65    cfg_cone_rigid = sim_utils.ConeCfg(
 66        radius=0.15,
 67        height=0.5,
 68        rigid_props=sim_utils.RigidBodyPropertiesCfg(),
 69        mass_props=sim_utils.MassPropertiesCfg(mass=1.0),
 70        collision_props=sim_utils.CollisionPropertiesCfg(),
 71        visual_material=sim_utils.PreviewSurfaceCfg(diffuse_color=(0.0, 1.0, 0.0)),
 72    )
 73    cfg_cone_rigid.func(
 74        "/World/Objects/ConeRigid", cfg_cone_rigid, translation=(-0.2, 0.0, 2.0), orientation=(0.5, 0.0, 0.5, 0.0)
 75    )
 76
 77    # spawn a blue cuboid with deformable body
 78    cfg_cuboid_deformable = sim_utils.MeshCuboidCfg(
 79        size=(0.2, 0.5, 0.2),
 80        deformable_props=sim_utils.DeformableBodyPropertiesCfg(),
 81        visual_material=sim_utils.PreviewSurfaceCfg(diffuse_color=(0.0, 0.0, 1.0)),
 82        physics_material=sim_utils.DeformableBodyMaterialCfg(),
 83    )
 84    cfg_cuboid_deformable.func("/World/Objects/CuboidDeformable", cfg_cuboid_deformable, translation=(0.15, 0.0, 2.0))
 85
 86    # spawn a usd file of a table into the scene
 87    cfg = sim_utils.UsdFileCfg(usd_path=f"{ISAAC_NUCLEUS_DIR}/Props/Mounts/SeattleLabTable/table_instanceable.usd")
 88    cfg.func("/World/Objects/Table", cfg, translation=(0.0, 0.0, 1.05))
 89
 90
 91def main():
 92    """Main function."""
 93
 94    # Initialize the simulation context
 95    sim_cfg = sim_utils.SimulationCfg(dt=0.01, device=args_cli.device)
 96    sim = sim_utils.SimulationContext(sim_cfg)
 97    # Set main camera
 98    sim.set_camera_view([2.0, 0.0, 2.5], [-0.5, 0.0, 0.5])
 99
100    # Design scene by adding assets to it
101    design_scene()
102
103    # Play the simulator
104    sim.reset()
105    # Now we are ready!
106    print("[INFO]: Setup complete...")
107
108    # Simulate physics
109    while simulation_app.is_running():
110        # perform step
111        sim.step()
112
113
114if __name__ == "__main__":
115    # run the main function
116    main()
117    # close sim app
118    simulation_app.close()

代码解释#

Omniverse中的场景设计是建立在名为USD(Universal Scene Description)的软件系统和文件格式周围的。它允许以层次结构方式描述3D场景,类似于文件系统。由于USD是一个全面的框架,我们建议阅读 USD文档 以了解更多信息。

为了完整起见,在本教程中我们介绍USD的必要概念。

  • 基本形状(Prims): 这些是USD场景的基本构建块。它们可以被视为场景图中的节点。每个节点可以是网格、光源、相机或变换。它也可以是其下其他基本物体的组。

  • 属性: 这些是基本物体的属性。可以将它们看作是键-值对。例如,一个基本物体可以有一个名为 color 的属性,其值为 red

  • 关系: 这些是基本物体之间的连接。可以将它们视为指向其他基体的指针。例如,一个网格基本体可以与一个用于着色的材质基本体建立关系。

这些基本物体、其属性和关系的集合被称为一个 USD阶段 。可以将其看作是场景中所有基本物体的容器。当我们说我们正在设计一个场景时,我们实际上正在设计一个USD阶段。

使用直接的USD API提供了很大的灵活性,但学习和使用起来可能很麻烦。为了更轻松地设计场景,Isaac Lab建立在USD API之上,提供了一个基于配置的接口来将基本物体生成到场景中。这些包含在 sim.spawners 模块中。

当将基本物体生成到场景中时,每个基本物体都需要一个定义其属性和关系(通过材质和着色信息)的配置类实例。然后将配置类传递给其相应的函数,其中指定了基本物体名称和变换。该函数然后将基本物体生成到场景中。

在高层次上,它是如何工作的:

# Create a configuration class instance
cfg = MyPrimCfg()
prim_path = "/path/to/prim"

# Spawn the prim into the scene using the corresponding spawner function
spawn_my_prim(prim_path, cfg, translation=[0, 0, 0], orientation=[1, 0, 0, 0], scale=[1, 1, 1])
# OR
# Use the spawner function directly from the configuration class
cfg.func(prim_path, cfg, translation=[0, 0, 0], orientation=[1, 0, 0, 0], scale=[1, 1, 1])

在本教程中,我们演示将各种不同的基本物体生成到场景中。有关可用的生成器的更多信息,请参考Isaac Lab中的 sim.spawners 模块 .

注意

所有的场景设计必须在仿真开始之前进行。一旦仿真开始,我们建议保持场景冻结,并仅更改基本物体的属性。这对于GPU仿真特别重要,因为在仿真过程中添加新的基本物体可能会改变GPU上的物理仿真缓冲区,并导致意外行为。

生成地面平面#

GroundPlaneCfg 配置了一个类似网格的地面平面,其外观和大小等属性可修改。

    # Ground-plane
    cfg_ground = sim_utils.GroundPlaneCfg()
    cfg_ground.func("/World/defaultGroundPlane", cfg_ground)

生成灯光#

可以将 不同类型的灯光基本体 生成到场景中。这些包括远光灯、球形灯、圆盘灯和圆柱灯。在本教程中,我们生成一个远光灯,这是一种远离场景无限远的灯,只朝一个方向发光。

    # spawn distant light
    cfg_light_distant = sim_utils.DistantLightCfg(
        intensity=3000.0,
        color=(0.75, 0.75, 0.75),
    )
    cfg_light_distant.func("/World/lightDistant", cfg_light_distant, translation=(1, 0, 10))

生成基本形状#

在生成基本形状之前,我们介绍了一个变换基本体或Xform的概念。变换基本体是一个仅包含变换属性的基本体。它用于将其他基本体分组,并作为一个组对其进行变换。在这里,我们创建一个Xform基本体,将所有的基本形状分组在其中。

    # create a new xform prim for all objects to be spawned under
    prim_utils.create_prim("/World/Objects", "Xform")

接下来,我们使用 ConeCfg 类生成一个圆锥体。可以指定圆锥体的半径、高度、物理属性和材质属性。默认情况下,物理和材质属性是禁用的。

我们生成的前两个圆锥 Cone1Cone2 是视觉元素,不启用物理属性。

    # spawn a red cone
    cfg_cone = sim_utils.ConeCfg(
        radius=0.15,
        height=0.5,
        visual_material=sim_utils.PreviewSurfaceCfg(diffuse_color=(1.0, 0.0, 0.0)),
    )
    cfg_cone.func("/World/Objects/Cone1", cfg_cone, translation=(-1.0, 1.0, 1.0))
    cfg_cone.func("/World/Objects/Cone2", cfg_cone, translation=(-1.0, -1.0, 1.0))

对于第三个圆锥 ConeRigid ,我们在配置类中设置刚体物理属性。通过这些属性,我们可以指定圆锥体的质量、摩擦力和弹性。如果未指定,它们将默认为USD Physics设置的默认值。

    # spawn a green cone with colliders and rigid body
    cfg_cone_rigid = sim_utils.ConeCfg(
        radius=0.15,
        height=0.5,
        rigid_props=sim_utils.RigidBodyPropertiesCfg(),
        mass_props=sim_utils.MassPropertiesCfg(mass=1.0),
        collision_props=sim_utils.CollisionPropertiesCfg(),
        visual_material=sim_utils.PreviewSurfaceCfg(diffuse_color=(0.0, 1.0, 0.0)),
    )
    cfg_cone_rigid.func(
        "/World/Objects/ConeRigid", cfg_cone_rigid, translation=(-0.2, 0.0, 2.0), orientation=(0.5, 0.0, 0.5, 0.0)
    )

最后,我们生成一个长方体 CuboidDeformable ,其中包含可变形体物理属性。与刚体模拟不同,可变形体可以在其顶点之间具有相对运动。这对于模拟软体如布料、橡胶或果冻非常有用。需要注意的是,可变形体仅在GPU模拟中受支持,并且需要生成一个带有可变形体物理属性的网格对象。

    # spawn a blue cuboid with deformable body
    cfg_cuboid_deformable = sim_utils.MeshCuboidCfg(
        size=(0.2, 0.5, 0.2),
        deformable_props=sim_utils.DeformableBodyPropertiesCfg(),
        visual_material=sim_utils.PreviewSurfaceCfg(diffuse_color=(0.0, 0.0, 1.0)),
        physics_material=sim_utils.DeformableBodyMaterialCfg(),
    )
    cfg_cuboid_deformable.func("/World/Objects/CuboidDeformable", cfg_cuboid_deformable, translation=(0.15, 0.0, 2.0))

从另一个文件生成#

最后,可以从其他文件格式生成基本体,例如其他USD、URDF或OBJ文件。在本教程中,我们将一个表的USD文件生成到场景中。这个表是一个网格基本体,并且有一个与之关联的材质基本体。所有这些信息都存储在其USD文件中。

    # spawn a usd file of a table into the scene
    cfg = sim_utils.UsdFileCfg(usd_path=f"{ISAAC_NUCLEUS_DIR}/Props/Mounts/SeattleLabTable/table_instanceable.usd")
    cfg.func("/World/Objects/Table", cfg, translation=(0.0, 0.0, 1.05))

上面的表被添加为场景的一个引用。简单来说,这意味着表实际上并没有添加到场景中,而是添加了一个指向表资产的 指针 。这允许我们修改表资产,并使更改以非破坏性的方式反映在场景中。例如,我们可以更改表的材质,而不实际修改表资产的底层文件。只有更改存储在USD阶段中。

执行脚本#

与之前的教程类似,要运行脚本,请执行以下命令:

./isaaclab.sh -p source/standalone/tutorials/00_sim/spawn_prims.py

一旦仿真开始,您应该看到一个具有地面平面、灯光、一些圆锥体和一个表的窗口。启用刚体物理属性的绿色圆锥体应该会掉落并与表和地面平面碰撞。其他圆锥体是视觉元素,不应该移动。要停止仿真,您可以关闭窗口,或在终端中按 Ctrl+C

spawn_prims.py 的结果

本教程为在Isaac Lab中生成各种基本体提供了一个基础。虽然简单,但它展示了在Isaac Lab中设计场景的基本概念以及如何使用生成器。在接下来的教程中,我们将看看如何与场景和仿真进行交互。