机器人与关节体配置#

Isaac Lab 将带有关节的机器人表示为关节体。本指南介绍如何复用已有机器人配置,以及编写新的 ArticulationCfg 。 ArticulationCfg 是定义 Isaac Lab 中 Articulation 属性的配置对象。

备注

在本指南中,我们只涵盖了创建 ArticulationCfg 的过程,但创建任何其他资产配置对象的过程类似。

复用机器人配置#

持续维护的机器人配置位于 source/isaaclab_assets/isaaclab_assets/robots 。从 isaaclab_assets 导入配置后,先复制,再修改生成属性、初始状态或执行器。项目专用配置可放在自己项目的 Python 模块中,无需加入 Isaac Lab。

从 isaaclab.utils 导入 clone 和 replace 。例如, robot_cfg = clone(CARTPOLE_CFG) 创建独立配置。将它添加到 InteractiveSceneCfg 时,使用 replace(robot_cfg, prim_path="{ENV_REGEX_NS}/Robot") 。物理后端与机器人配置分别选择,下文会说明。

我们将使用 Cartpole 示例来演示如何创建 ArticulationCfg 。 Cartpole 是一个简单的机器人,由一个连接到杆的小车组成。 小车可以沿着轨道自由移动,杆可以在小车周围自由旋转。该配置示例的文件为 source/isaaclab_assets/isaaclab_assets/robots/cartpole.py.

Cartpole 配置代码
 1# Copyright (c) 2022-2026, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md).
 2# All rights reserved.
 3#
 4# SPDX-License-Identifier: BSD-3-Clause
 5
 6"""Configuration for a simple Cartpole robot."""
 7
 8from isaaclab_newton.sim.schemas import NewtonArticulationCfg
 9from isaaclab_physx.sim.schemas import PhysxArticulationCfg, PhysxRigidBodyCfg
10
11import isaaclab.sim as sim_utils
12from isaaclab.actuators import ImplicitActuatorCfg
13from isaaclab.assets import ArticulationCfg
14from isaaclab.utils.assets import ISAACLAB_NUCLEUS_DIR
15
16##
17# Configuration
18##
19
20CARTPOLE_CFG = ArticulationCfg(
21    spawn=sim_utils.UsdFileCfg(
22        usd_path=f"{ISAACLAB_NUCLEUS_DIR}/Robots/Classic/Cartpole/cartpole.usd",
23        rigid_props=[
24            sim_utils.UsdPhysicsRigidBodyCfg(rigid_body_enabled=True),
25            PhysxRigidBodyCfg(
26                max_linear_velocity=1000.0,
27                max_angular_velocity=1000.0,
28                max_depenetration_velocity=100.0,
29                enable_gyroscopic_forces=True,
30            ),
31        ],
32        articulation_props=[
33            PhysxArticulationCfg(
34                enabled_self_collisions=False,
35                solver_position_iteration_count=4,
36                solver_velocity_iteration_count=0,
37                sleep_threshold=0.005,
38                stabilization_threshold=0.001,
39            ),
40            NewtonArticulationCfg(self_collision_enabled=False),
41        ],
42    ),
43    init_state=ArticulationCfg.InitialStateCfg(
44        pos=(0.0, 0.0, 2.0), joint_pos={"slider_to_cart": 0.0, "cart_to_pole": 0.0}
45    ),
46    actuators={
47        "cart_actuator": ImplicitActuatorCfg(
48            joint_names_expr=["slider_to_cart"],
49            joint_effort_limit=400.0,
50            stiffness=0.0,
51            damping=10.0,
52        ),
53        "pole_actuator": ImplicitActuatorCfg(
54            joint_names_expr=["cart_to_pole"], joint_effort_limit=400.0, stiffness=0.0, damping=0.0
55        ),
56    },
57)
58"""Configuration for a simple Cartpole robot."""

选择共享设置与后端专用设置#

使用共享的 ArticulationCfg 配置机器人的初始状态与执行器。仿真单独选择物理后端。

通用 USD 属性使用 isaaclab.sim.schemas 中的类,例如 RigidBodyBaseCfg 和 ArticulationRootBaseCfg 。PhysX 调优使用 isaaclab_physx.sim.schemas.Physx*Cfg ;Newton 和 MJWarp 专用设置使用 isaaclab_newton.sim.schemas.Newton*Cfg / Mujoco*Cfg 。 模式配置类 指南解释了可用类及其 USD 命名空间; 模式片段 展示了如何在同一生成配置中写入两个后端的属性。

下文 Cartpole 使用兼容名称 RigidBodyPropertiesCfg 和 ArticulationRootPropertiesCfg 。其中 PhysX 求解迭代次数与休眠阈值不会配置 Newton 求解器。适配 Newton 时,保留共享的初始状态与执行器配置,并单独配置 Newton 求解器。例如,覆盖 Newton 的自碰撞设置:

from isaaclab_assets import CARTPOLE_CFG
from isaaclab_newton.sim.schemas import NewtonArticulationRootPropertiesCfg

from isaaclab.utils import clone

robot_cfg = clone(CARTPOLE_CFG)
robot_cfg.spawn.articulation_props = NewtonArticulationRootPropertiesCfg(self_collision_enabled=False)

求解器设置见 MJWarp 调优 ,资产调优见 为 Newton MJWarp 准备资产 ,转换后的 USD 变体见 多后端资产 。

定义生成配置#

如 生成基本物体到场景中 教程中所述,生成配置定义要生成的资产的属性。此生成可能以程序方式进行,也可能通过现有的资产文件(例如 USD 或 URDF)进行。在本例中,我们将从 USD 文件生成 Cartpole。

从 USD 文件生成资产时,我们定义其 UsdFileCfg 。此配置对象接收以下参数:

最后两个参数是可选的。如果未指定,它们将保持在 USD 文件中的默认值。

spawn=sim_utils.UsdFileCfg(
    usd_path=f"{ISAACLAB_NUCLEUS_DIR}/Robots/Classic/Cartpole/cartpole.usd",
    rigid_props=[
        sim_utils.UsdPhysicsRigidBodyCfg(rigid_body_enabled=True),
        PhysxRigidBodyCfg(
            max_linear_velocity=1000.0,
            max_angular_velocity=1000.0,
            max_depenetration_velocity=100.0,
            enable_gyroscopic_forces=True,
        ),
    ],
    articulation_props=[
        PhysxArticulationCfg(
            enabled_self_collisions=False,
            solver_position_iteration_count=4,
            solver_velocity_iteration_count=0,
            sleep_threshold=0.005,
            stabilization_threshold=0.001,
        ),
        NewtonArticulationCfg(self_collision_enabled=False),
    ],
),

如要从 URDF 文件中导入关节而不是从 USD 文件中导入,你可以用 UrdfFileCfg 替换 UsdFileCfg 。更多详情,请查看 API 文档。

定义初始状态#

每个资产都需要通过其配置在仿真中定义其初始或 默认 状态。此配置存储在资产的默认状态缓冲区中,当需要重置资产状态时,可以访问这些缓冲区。

备注

资产的初始状态是根据其本地环境框架定义的。然后,当重置资产状态时,需要将其转换为全局仿真框架。更多详情,请查看 与关节交互 教程。

对于关节, InitialStateCfg 对象定义了关节根部的初始状态以及所有关节的初始状态。在本例中,我们将在 XY 平面的原点处生成 Cartpole,在 Z 高度为 2.0 米处。同时,关节位置和速度设置为 0.0。

init_state=ArticulationCfg.InitialStateCfg(
    pos=(0.0, 0.0, 2.0), joint_pos={"slider_to_cart": 0.0, "cart_to_pole": 0.0}
),

定义执行器配置#

执行器是关节中的关键组件。通过此配置,可以定义要使用的执行器模型类型。我们可以使用物理引擎提供的内部执行器模型(即隐式执行器模型),也可以使用用户定义的方程系统控制的自定义执行器模型(即显式执行器模型)。有关执行器的更多详情,请参见 执行器 。

cartpole 的关节具有两个执行器,分别对应于它的每个关节:cart_to_pole 和 slider_to_cart 。我们对这些执行器使用两种不同的执行器模型作为示例。但是,由于它们都使用相同的执行器模型,可以将它们组合成一个单独的执行器模型。

使用分开的执行器模型进行执行器模型配置
actuators={
    "cart_actuator": ImplicitActuatorCfg(
        joint_names_expr=["slider_to_cart"],
        joint_effort_limit=400.0,
        stiffness=0.0,
        damping=10.0,
    ),
    "pole_actuator": ImplicitActuatorCfg(
        joint_names_expr=["cart_to_pole"], joint_effort_limit=400.0, stiffness=0.0, damping=0.0
    ),
},
使用单个执行器模型进行执行器模型配置
actuators={
   "all_joints": ImplicitActuatorCfg(
      joint_names_expr=[".*"],
      joint_effort_limit=400.0,
      joint_velocity_limit=100.0,
      stiffness={"slider_to_cart": 0.0, "cart_to_pole": 0.0},
      damping={"slider_to_cart": 10.0, "cart_to_pole": 0.0},
   ),
},

备注

Newton 在构建求解器前,为通过 ImplicitActuatorCfg 配置的关节解析目标模式:仅有刚度时选择位置模式,仅有阻尼时选择速度模式,两项增益都有时选择位置与速度组合模式,零增益时选择驱动力模式。增益为 None 时保留导入的 USD 值;显式执行器配置使用驱动力模式。因此,仅为已配置执行器工作,无需给零增益 USD 驱动添加占位值。 ensure_drives_exist 仍适用的场景见 各物理后端的关节驱动 。

ActuatorCfg 速度/力矩限制考虑#

在执行器配置中使用以下字段。它们选择关节,并在构建关节体时解析;运行时的权威值存放在 ArticulationData 上。归属模型和运行时修改方式见 关节和执行器属性的归属 。

限制配置#

字段

隐式执行器

显式执行器

joint_effort_limit

写入求解器驱动的驱动力上限。

写入求解器驱动力上限;默认值较高,以免模型输出受到第二次限幅。

actuator_effort_limit

不支持。

限制执行器模型的输出幅度。

joint_velocity_limit

请求求解器施加速度约束。

请求求解器施加速度约束。

actuator_velocity_limit

创建软速度限制快照,不向求解器请求约束。

描述执行器额定速度;与速度有关的模型在力矩曲线中使用它。

effort_limit

joint_effort_limit 的已弃用别名。

actuator_effort_limit 的已弃用别名。

velocity_limit

actuator_velocity_limit 的已弃用别名。

actuator_velocity_limit 的已弃用别名。

求解器对速度限制的实施方式因后端而异。 joint_velocity_limit 记录请求的关节状态,但不是独立于后端的安全限幅;参见 验证执行器和限制 。

USD vs. ActuatorCfg 差异解决#

USD 具有默认值,并且 ActuatorCfg 可以指定为 None,或者有时会令人困惑的是覆盖值实际写入仿真中的规则。解决方案遵循这些简单规则,每个关节和每个属性:

USD vs. ActuatorCfg 的分辨率规则#

条件

驱动器配置值

应用

未提供覆盖

未指定

USD 值

提供覆盖

用户的 ActuatorCfg

与 ActuatorCfg 相同

深入研究 USD 有时可能是不方便的,为了帮助弄清所写的确切值,我们设计了一个标志: actuator_value_resolution_debug_print ,以帮助用户弄清楚在仿真中使用了哪个确切值。

每当在用户的 ActuatorCfg(或未指定)中覆盖执行器参数时,我们将其与从 USD 定义中读取的值进行比较,并记录任何差异。对于每个关节和每个属性,如果找到不匹配的值,我们记录下解决方案:

  1. USD 值 USD 资产解析的默认限制或增益。

  2. ActuatorCfg 值 用户提供的覆盖值(如果没有提供则为 “未指定” )。

  3. 应用 实际用于仿真的最终数值: 如果用户没有覆盖它,这将与 USD 值匹配;否则,它将反映用户的设置。

此解决方案信息仅在存在差异时作为警告表格发出。以下是您将看到的示例:

+----------------+------------------------+---------------------+----+-------------+--------------------+----------+
|     Group      |      Property          |         Name        | ID |  USD Value  | ActuatorCfg Value  | Applied  |
+----------------+------------------------+---------------------+----+-------------+--------------------+----------+
| panda_shoulder | joint_velocity_limit   |    panda_joint1     |  0 |    2.17e+00 |   Not Specified    | 2.17e+00 |
|                |                        |    panda_joint2     |  1 |    2.17e+00 |   Not Specified    | 2.17e+00 |
|                |                        |    panda_joint3     |  2 |    2.17e+00 |   Not Specified    | 2.17e+00 |
|                |                        |    panda_joint4     |  3 |    2.17e+00 |   Not Specified    | 2.17e+00 |
|                |     stiffness          |    panda_joint1     |  0 |    2.29e+04 |      8.00e+01      | 8.00e+01 |
|                |                        |    panda_joint2     |  1 |    2.29e+04 |      8.00e+01      | 8.00e+01 |
|                |                        |    panda_joint3     |  2 |    2.29e+04 |      8.00e+01      | 8.00e+01 |
|                |                        |    panda_joint4     |  3 |    2.29e+04 |      8.00e+01      | 8.00e+01 |
|                |      damping           |    panda_joint1     |  0 |    4.58e+03 |      4.00e+00      | 4.00e+00 |
|                |                        |    panda_joint2     |  1 |    4.58e+03 |      4.00e+00      | 4.00e+00 |
|                |                        |    panda_joint3     |  2 |    4.58e+03 |      4.00e+00      | 4.00e+00 |
|                |                        |    panda_joint4     |  3 |    4.58e+03 |      4.00e+00      | 4.00e+00 |
|                |      armature          |    panda_joint1     |  0 |    0.00e+00 |   Not Specified    | 0.00e+00 |
|                |                        |    panda_joint2     |  1 |    0.00e+00 |   Not Specified    | 0.00e+00 |
|                |                        |    panda_joint3     |  2 |    0.00e+00 |   Not Specified    | 0.00e+00 |
|                |                        |    panda_joint4     |  3 |    0.00e+00 |   Not Specified    | 0.00e+00 |
| panda_forearm  | joint_velocity_limit   |    panda_joint5     |  4 |    2.61e+00 |   Not Specified    | 2.61e+00 |
|                |                        |    panda_joint6     |  5 |    2.61e+00 |   Not Specified    | 2.61e+00 |
|                |                        |    panda_joint7     |  6 |    2.61e+00 |   Not Specified    | 2.61e+00 |
|                |     stiffness          |    panda_joint5     |  4 |    2.29e+04 |      8.00e+01      | 8.00e+01 |
|                |                        |    panda_joint6     |  5 |    2.29e+04 |      8.00e+01      | 8.00e+01 |
|                |                        |    panda_joint7     |  6 |    2.29e+04 |      8.00e+01      | 8.00e+01 |
|                |      damping           |    panda_joint5     |  4 |    4.58e+03 |      4.00e+00      | 4.00e+00 |
|                |                        |    panda_joint6     |  5 |    4.58e+03 |      4.00e+00      | 4.00e+00 |
|                |                        |    panda_joint7     |  6 |    4.58e+03 |      4.00e+00      | 4.00e+00 |
|                |      armature          |    panda_joint5     |  4 |    0.00e+00 |   Not Specified    | 0.00e+00 |
|                |                        |    panda_joint6     |  5 |    0.00e+00 |   Not Specified    | 0.00e+00 |
|                |                        |    panda_joint7     |  6 |    0.00e+00 |   Not Specified    | 0.00e+00 |
|                |      friction          |    panda_joint5     |  4 |    0.00e+00 |   Not Specified    | 0.00e+00 |
|                |                        |    panda_joint6     |  5 |    0.00e+00 |   Not Specified    | 0.00e+00 |
|                |                        |    panda_joint7     |  6 |    0.00e+00 |   Not Specified    | 0.00e+00 |
|  panda_hand    | joint_velocity_limit   | panda_finger_joint1 |  7 |    2.00e-01 |   Not Specified    | 2.00e-01 |
|                |                        | panda_finger_joint2 |  8 |    2.00e-01 |   Not Specified    | 2.00e-01 |
|                |     stiffness          | panda_finger_joint1 |  7 |    1.00e+06 |      2.00e+03      | 2.00e+03 |
|                |                        | panda_finger_joint2 |  8 |    1.00e+06 |      2.00e+03      | 2.00e+03 |
|                |      armature          | panda_finger_joint1 |  7 |    0.00e+00 |   Not Specified    | 0.00e+00 |
|                |                        | panda_finger_joint2 |  8 |    0.00e+00 |   Not Specified    | 0.00e+00 |
|                |      friction          | panda_finger_joint1 |  7 |    0.00e+00 |   Not Specified    | 0.00e+00 |
|                |                        | panda_finger_joint2 |  8 |    0.00e+00 |   Not Specified    | 0.00e+00 |
+----------------+------------------------+---------------------+----+-------------+--------------------+----------+

为保持日志的清晰, actuator_value_resolution_debug_print 默认为 False,请在需要时记得将其打开。

示例:配置并运行两个机器人#

可运行示例 scripts/tutorials/01_assets/add_new_robot.py 对比了精简的 Jetbot 配置与较详细的 Dofbot 配置。从导入的 USD 资产开始(见 导入新资产 ),定义生成属性和执行器。Jetbot 将刚度与阻尼设为 None ,保留 USD 中编写的关节增益。即使使用这些 USD 默认值,也必须指定这两个字段:

JETBOT_CONFIG = ArticulationCfg(
    spawn=sim_utils.UsdFileCfg(usd_path=f"{ISAAC_NUCLEUS_DIR}/Robots/NVIDIA/Jetbot/jetbot.usd"),
    actuators={"wheel_acts": ImplicitActuatorCfg(joint_names_expr=[".*"], damping=None, stiffness=None)},
)

Dofbot 还设置了初始关节位置、按名称分组的关节,以及执行器增益和限制。其中求解迭代次数与最大去穿透速度是 PhysX 专用属性;适配 Newton 时参阅 选择共享设置与后端专用设置 。 init_state.joint_pos 中的键标识 USD 关节,而非执行器组。关节名可以用正则表达式匹配,例如 .* 选择所有关节。

可运行示例中的完整 Dofbot 配置
DOFBOT_CONFIG = ArticulationCfg(
    spawn=sim_utils.UsdFileCfg(
        usd_path=f"{ISAAC_NUCLEUS_DIR}/Robots/Yahboom/Dofbot/dofbot.usd",
        rigid_props=PhysxRigidBodyCfg(
            disable_gravity=False,
            max_depenetration_velocity=5.0,
        ),
        articulation_props=[
            PhysxArticulationCfg(
                enabled_self_collisions=True, solver_position_iteration_count=8, solver_velocity_iteration_count=0
            ),
            NewtonArticulationCfg(self_collision_enabled=True),
        ],
    ),
    init_state=ArticulationCfg.InitialStateCfg(
        joint_pos={
            "joint1": 0.0,
            "joint2": 0.0,
            "joint3": 0.0,
            "joint4": 0.0,
        },
        pos=(0.25, -0.25, 0.0),
    ),
    actuators={
        "front_joints": ImplicitActuatorCfg(
            joint_names_expr=["joint[1-2]"],
            joint_effort_limit=100.0,
            joint_velocity_limit=100.0,
            stiffness=10000.0,
            damping=100.0,
        ),
        "joint3_act": ImplicitActuatorCfg(
            joint_names_expr=["joint3"],
            joint_effort_limit=100.0,
            joint_velocity_limit=100.0,
            stiffness=10000.0,
            damping=100.0,
        ),
        "joint4_act": ImplicitActuatorCfg(
            joint_names_expr=["joint4"],
            joint_effort_limit=100.0,
            joint_velocity_limit=100.0,
            stiffness=10000.0,
            damping=100.0,
        ),
    },
)


示例将两个配置添加到 InteractiveSceneCfg ,为各环境中的机器人指定路径,并构建场景。循环依次重置根状态与关节状态、设置关节目标、写入命令、推进物理并更新场景缓冲区。场景构建见 使用交互式场景 ,重置与控制循环见 与关节交互 。

完整的可运行示例
  1# Copyright (c) 2022-2026, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md).
  2# All rights reserved.
  3#
  4# SPDX-License-Identifier: BSD-3-Clause
  5
  6import argparse
  7from typing import TYPE_CHECKING
  8
  9from isaaclab.app import add_launcher_args, launch_simulation
 10from isaaclab.utils import instantiate, replace
 11
 12# add argparse arguments
 13parser = argparse.ArgumentParser(
 14    description="This script demonstrates adding a custom robot to an Isaac Lab environment."
 15)
 16parser.add_argument("--num_envs", type=int, default=1, help="Number of environments to spawn.")
 17# append simulation launcher cli args
 18add_launcher_args(parser)
 19# parse the arguments
 20args_cli = parser.parse_args()
 21
 22import numpy as np
 23import torch
 24from isaaclab_newton.sim.schemas import NewtonArticulationCfg
 25from isaaclab_physx.sim.schemas import PhysxArticulationCfg, PhysxRigidBodyCfg
 26
 27import isaaclab.sim as sim_utils
 28from isaaclab.actuators import ImplicitActuatorCfg
 29from isaaclab.assets import AssetBaseCfg
 30from isaaclab.assets.articulation import ArticulationCfg
 31from isaaclab.scene import InteractiveSceneCfg
 32from isaaclab.utils.assets import ISAAC_NUCLEUS_DIR
 33
 34if TYPE_CHECKING:
 35    from isaaclab.scene import InteractiveScene
 36
 37JETBOT_CONFIG = ArticulationCfg(
 38    spawn=sim_utils.UsdFileCfg(usd_path=f"{ISAAC_NUCLEUS_DIR}/Robots/NVIDIA/Jetbot/jetbot.usd"),
 39    actuators={"wheel_acts": ImplicitActuatorCfg(joint_names_expr=[".*"], damping=None, stiffness=None)},
 40)
 41
 42DOFBOT_CONFIG = ArticulationCfg(
 43    spawn=sim_utils.UsdFileCfg(
 44        usd_path=f"{ISAAC_NUCLEUS_DIR}/Robots/Yahboom/Dofbot/dofbot.usd",
 45        rigid_props=PhysxRigidBodyCfg(
 46            disable_gravity=False,
 47            max_depenetration_velocity=5.0,
 48        ),
 49        articulation_props=[
 50            PhysxArticulationCfg(
 51                enabled_self_collisions=True, solver_position_iteration_count=8, solver_velocity_iteration_count=0
 52            ),
 53            NewtonArticulationCfg(self_collision_enabled=True),
 54        ],
 55    ),
 56    init_state=ArticulationCfg.InitialStateCfg(
 57        joint_pos={
 58            "joint1": 0.0,
 59            "joint2": 0.0,
 60            "joint3": 0.0,
 61            "joint4": 0.0,
 62        },
 63        pos=(0.25, -0.25, 0.0),
 64    ),
 65    actuators={
 66        "front_joints": ImplicitActuatorCfg(
 67            joint_names_expr=["joint[1-2]"],
 68            joint_effort_limit=100.0,
 69            joint_velocity_limit=100.0,
 70            stiffness=10000.0,
 71            damping=100.0,
 72        ),
 73        "joint3_act": ImplicitActuatorCfg(
 74            joint_names_expr=["joint3"],
 75            joint_effort_limit=100.0,
 76            joint_velocity_limit=100.0,
 77            stiffness=10000.0,
 78            damping=100.0,
 79        ),
 80        "joint4_act": ImplicitActuatorCfg(
 81            joint_names_expr=["joint4"],
 82            joint_effort_limit=100.0,
 83            joint_velocity_limit=100.0,
 84            stiffness=10000.0,
 85            damping=100.0,
 86        ),
 87    },
 88)
 89
 90
 91class NewRobotsSceneCfg(InteractiveSceneCfg):
 92    """Designs the scene."""
 93
 94    # Ground-plane
 95    ground = AssetBaseCfg(prim_path="/World/defaultGroundPlane", spawn=sim_utils.GroundPlaneCfg())
 96
 97    # lights
 98    dome_light = AssetBaseCfg(
 99        prim_path="/World/Light", spawn=sim_utils.DomeLightCfg(intensity=3000.0, color=(0.75, 0.75, 0.75))
100    )
101
102    # robot
103    Jetbot = replace(JETBOT_CONFIG, prim_path="{ENV_REGEX_NS}/Jetbot")
104    Dofbot = replace(DOFBOT_CONFIG, prim_path="{ENV_REGEX_NS}/Dofbot")
105
106
107def run_simulator(sim: sim_utils.SimulationContext, scene: "InteractiveScene"):
108    sim_dt = sim.get_physics_dt()
109    sim_time = 0.0
110    count = 0
111
112    # wheel-velocity templates allocated once on the simulation device; the joint
113    # target setters dispatch to GPU Warp kernels and reject CPU tensors.
114    straight_action = torch.tensor([[10.0, 10.0]], device=sim.device).repeat(scene.num_envs, 1)
115    turn_action = torch.tensor([[5.0, -5.0]], device=sim.device).repeat(scene.num_envs, 1)
116
117    while sim.is_running():
118        # reset
119        if count % 500 == 0:
120            # reset counters
121            count = 0
122            # reset the scene entities to their initial positions offset by the environment origins
123            root_jetbot_pose = scene["Jetbot"].data.default_root_pose.torch.clone()
124            root_jetbot_pose[:, :3] += scene.env_origins
125            root_dofbot_pose = scene["Dofbot"].data.default_root_pose.torch.clone()
126            root_dofbot_pose[:, :3] += scene.env_origins
127
128            # copy the default root state to the sim for the jetbot's orientation and velocity
129            scene["Jetbot"].write_root_pose_to_sim_index(root_pose=root_jetbot_pose)
130            root_jetbot_vel = scene["Jetbot"].data.default_root_vel.torch.clone()
131            scene["Jetbot"].write_root_velocity_to_sim_index(root_velocity=root_jetbot_vel)
132            scene["Dofbot"].write_root_pose_to_sim_index(root_pose=root_dofbot_pose)
133            root_dofbot_vel = scene["Dofbot"].data.default_root_vel.torch.clone()
134            scene["Dofbot"].write_root_velocity_to_sim_index(root_velocity=root_dofbot_vel)
135
136            # copy the default joint states to the sim
137            joint_pos, joint_vel = (
138                scene["Jetbot"].data.default_joint_pos.torch.clone(),
139                scene["Jetbot"].data.default_joint_vel.torch.clone(),
140            )
141            scene["Jetbot"].write_joint_position_to_sim_index(position=joint_pos)
142            scene["Jetbot"].write_joint_velocity_to_sim_index(velocity=joint_vel)
143            joint_pos, joint_vel = (
144                scene["Dofbot"].data.default_joint_pos.torch.clone(),
145                scene["Dofbot"].data.default_joint_vel.torch.clone(),
146            )
147            scene["Dofbot"].write_joint_position_to_sim_index(position=joint_pos)
148            scene["Dofbot"].write_joint_velocity_to_sim_index(velocity=joint_vel)
149            # clear internal buffers
150            scene.reset()
151            print("[INFO]: Resetting Jetbot and Dofbot state...")
152
153        # drive around
154        if count % 100 < 75:
155            # Drive straight by setting equal wheel velocities
156            action = straight_action
157        else:
158            # Turn by applying different velocities
159            action = turn_action
160
161        scene["Jetbot"].set_joint_velocity_target_index(target=action)
162
163        # wave
164        wave_action = scene["Dofbot"].data.default_joint_pos.torch.clone()
165        wave_action[:, 0:4] = 0.25 * np.sin(2 * np.pi * 0.5 * sim_time)
166        scene["Dofbot"].set_joint_position_target_index(target=wave_action)
167
168        scene.write_data_to_sim()
169        sim.step()
170        sim_time += sim_dt
171        count += 1
172        scene.update(sim_dt)
173
174
175def main():
176    """Main function."""
177    # Configure the simulation
178    sim_cfg = sim_utils.SimulationCfg(device=args_cli.device)
179    # Launch the simulator runtime that the configuration needs
180    with launch_simulation(sim_cfg, args_cli):
181        # Initialize the simulation context
182        sim = sim_utils.SimulationContext(sim_cfg)
183        sim.set_camera_view([3.5, 0.0, 3.2], [0.0, 0.0, 0.5])
184        # Design scene
185        scene_cfg = NewRobotsSceneCfg(num_envs=args_cli.num_envs, env_spacing=2.0)
186        scene = instantiate(scene_cfg)
187        # Play the simulator
188        sim.reset()
189        # Now we are ready!
190        print("[INFO]: Setup complete...")
191        # Run the simulator
192        run_simulator(sim, scene)
193
194
195if __name__ == "__main__":
196    main()

在 Isaac Sim 视口中运行示例:

uv run isaaclab -p scripts/tutorials/01_assets/add_new_robot.py --viz kit

本例使用 PhysX 物理,需要 Isaac Sim。示例未驱动 Dofbot 夹爪,因此出现关节未配置的警告是预期行为。按 Ctrl+C 停止示例。

Jetbot 和 Dofbot 在示例场景中运行。