机器人与关节体配置#
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."""
定义生成配置#
如 生成基本物体到场景中 教程中所述,生成配置定义要生成的资产的属性。此生成可能以程序方式进行,也可能通过现有的资产文件(例如 USD 或 URDF)进行。在本例中,我们将从 USD 文件生成 Cartpole。
从 USD 文件生成资产时,我们定义其 UsdFileCfg 。此配置对象接收以下参数:
usd_path: 要生成的 USD 文件路径rigid_props:关节体各刚体连杆的属性。articulation_props:关节体根的属性。
最后两个参数是可选的。如果未指定,它们将保持在 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_velocity_limit 记录请求的关节状态,但不是独立于后端的安全限幅;参见 验证执行器和限制 。
USD vs. ActuatorCfg 差异解决#
USD 具有默认值,并且 ActuatorCfg 可以指定为 None,或者有时会令人困惑的是覆盖值实际写入仿真中的规则。解决方案遵循这些简单规则,每个关节和每个属性:
条件 |
驱动器配置值 |
应用 |
|---|---|---|
未提供覆盖 |
未指定 |
USD 值 |
提供覆盖 |
用户的 ActuatorCfg |
与 ActuatorCfg 相同 |
深入研究 USD 有时可能是不方便的,为了帮助弄清所写的确切值,我们设计了一个标志: actuator_value_resolution_debug_print ,以帮助用户弄清楚在仿真中使用了哪个确切值。
每当在用户的 ActuatorCfg(或未指定)中覆盖执行器参数时,我们将其与从 USD 定义中读取的值进行比较,并记录任何差异。对于每个关节和每个属性,如果找到不匹配的值,我们记录下解决方案:
USD 值 USD 资产解析的默认限制或增益。
ActuatorCfg 值 用户提供的覆盖值(如果没有提供则为 “未指定” )。
应用 实际用于仿真的最终数值: 如果用户没有覆盖它,这将与 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 停止示例。