1. FastSim 实际创建了哪些实体?
  2. 在同一个已提交的仿真边界上,这些实体的状态是什么?

场景包含三类实体:刚体、普通铰接物体和机器人。门与机器人在物理上都属于 articulation,读取关节状态时使用的是同一套通用模型。

前置条件

请把 FastSim 和 Isaac Lab provider 安装到同一个 Python 环境。本 Run 使用 Isaac Lab 3.0 / Isaac Sim 6.0,并明确要求打开真实可见窗口。

文件

  • run.yaml 创建红色方块、铰链门和双关节机械臂。
  • main.py 读取公共 Scene Catalog 及其对应的实时状态。
  • ../../_shared/components/ 保存可复用的组件清单。

逐项理解配置

yaml
schema: fastsim/2                    # 选择 FastSim vNext Run 配置规范。
name: demo-scene-entities-and-state  # Run 检查工具显示的稳定名称。
backend: isaaclab                    # 选择组件的 Isaac Lab 变体。

runtime:
  launch_profile: visible            # 打开仿真器的真实可见窗口。
  physics_hz: 60                     # 每秒推进 60 个物理步。
  control_hz: 60                     # 以 60 Hz 接收控制帧。
  seed: 31                           # 让 reset 行为可以复现。

scenario:
  scene:
    objects:                         # 不包含关节的物理对象。
      red_cube:                      # 本场景内供人阅读和 API 使用的别名。
        use: object://fastsim/demo-cube
        pose:                        # 世界位姿;单位为 SI,四元数顺序为 XYZW。
          xyz_m: [0.0, -0.65, 0.5]
          quat_xyzw: [0.0, 0.0, 0.0, 1.0]
    articulations:                   # 非机器人的任意铰接资产。
      door:
        use: articulation://fastsim/demo-door
        pose:
          xyz_m: [0.85, 0.0, 0.0]
          quat_xyzw: [0.0, 0.0, 0.0, 1.0]
        initial_state:
          joints:
            door_hinge: 0.0          # 铰链初始角,单位弧度。
    robots:                          # 机器人也使用同一套物理关节模型。
      arm:
        use: robot://fastsim/demo-two-joint-arm
        pose:
          xyz_m: [-0.85, 0.0, 0.0]
          quat_xyzw: [0.0, 0.0, 0.0, 1.0]
        initial_state:
          joints:
            joint_1: 0.0
            joint_2: 0.0

use 是 Registry 身份,不是文件路径。共享 Registry 会选择各组件的 Isaac Lab 资源,并把准确选择冻结进 ExecutionPlan。

逐行理解 Python

  1. 文件开头的 docstring 说明程序要得到什么结果。
  2. asyncio 运行 FastSim 异步 API,math 拒绝非有限状态;Path 保证从任意 工作目录都能找到 Run。
  3. import fastsim 只使用 FastSim 的公共入口。
  4. RUN_FILE 指向同目录的 run.yamlVISIBLE_HOLD_SECONDS 让可见结果短暂停留。
  5. AUTHORED_ENTITY_IDS 列出本例三个实体;EXPECTED_JOINT_NAMESINITIAL_JOINT_TOLERANCE_RAD 定义明确的初始状态门禁,同时排除 provider 自己发布的系统实体。
  6. async def main() 定义异步应用流程。
  7. fastsim.app(..., planning_reads=True) 显式开启 Scene、Frame 和 Geometry 发布路径。不需要规划数据的普通控制或相机程序默认不会承担这部分开销。
  8. async with 负责完整清理;中途查询报错时也不会遗留仿真进程。
  9. start() 构建真实 Isaac Lab 世界;pause() 在不销毁场景的前提下冻结清晰的 读取边界。
  10. scene.catalog() 返回不可变结构,包括实体类型、link、joint、frame、几何 ID 和控制资源组。
  11. scene.state() 返回同一 generation 和 tick 上的实时位姿、速度及关节值。
  12. 字典推导式用稳定 ID 索引不可变快照,并建立 joint 稳定 ID 到手工命名的映射; 它们不会持有仿真器原生 handle。
  13. 第一个循环先拒绝非有限根位置,再打印每个实体的类型、根位置和控制资源组。
  14. 第二个循环用 zip(..., strict=True) 对齐 joint ID 与位置,再用 Catalog 中的 手工命名打印结果;同时要求关节集合严格匹配,且所有初始值有限并落在 +/-0.02 rad 内,失败时返回非零退出码。
  15. asyncio.sleep(...) 让暂停后的真实场景保留三秒,同时不要求用户手动输入。
  16. 最后两行只在直接运行本文件时调用 main()

验收门禁

  • 三个配置实体 ID 必须全部存在,所有根位置必须有限。
  • 门必须发布 door_hinge,机械臂必须发布 joint_1joint_2
  • 所有初始关节值必须有限,并且距离配置的零位不超过 0.02 rad
  • 2026-08-25 的可见 Isaac Lab 真机验收中,三个轴分别约为 000.0000041 rad,退出码为 0。

运行

从本案例目录运行:

bash
cd demo/fundamentals/07_scene_entities_and_state
fastsim config validate run.yaml --json
python main.py

输出应包含 objects.red_cubearticulations.doorrobots.arm 三个规范 ID, 并显示门和机械臂的关节值。打印完成后,Isaac Lab 可见窗口会短暂停留。

验证等级

真实可见 Isaac 已通过。 真机运行满足上述全部门禁,正常退出,并且没有遗留 Isaac worker 进程。

常见错误

  • SERVICE_ACCESS_DENIED:保留 planning_reads=True;场景发布是显式按需开启的。
  • COMPONENT_NO_MATCHING_VARIANT:更新 Isaac Lab provider,并使用仓库内的共享组件。
  • 没有可见窗口:确认 Run 仍有 runtime.launch_profile: visible,并确认当前机器有显示环境。