前置条件

请把 FastSim 和 Isaac Lab provider 安装到同一个环境。本 Run 会以可见模式启动 Isaac Lab 3.0 / Isaac Sim 6.0。

逐项理解配置

yaml
schema: fastsim/2                  # FastSim vNext Run 配置规范。
name: demo-frame-transforms        # 稳定的 Run 名称。
backend: isaaclab                  # 选择机械臂的 Isaac Lab USD 资源。

runtime:
  launch_profile: visible          # 打开仿真器原生窗口。
  physics_hz: 60                   # 物理积分频率。
  control_hz: 60                   # 控制帧接收频率。
  seed: 41                         # 可复现的 reset 随机种子。

scenario:
  scene:
    robots:
      arm:                         # Scenario 别名;规范 ID 为 robots.arm。
        use: robot://fastsim/demo-two-joint-arm
        pose:
          xyz_m: [0.25, -0.20, 0.0] # 非零世界平移,单位米。
          quat_xyzw: [0.0, 0.0, 0.2588190451, 0.9659258263] # 绕 Z 轴 30 度。
        initial_state:
          joints:
            joint_1: 0.35          # 转动关节位置,单位弧度。
            joint_2: -0.50

非零根位姿和关节值可以证明返回的是实际组合变换,而不是写死的单位变换。

逐行理解 Python

  1. Docstring 明确说明程序执行可移植 Frame 查询。
  2. asynciomathPathfastsim 分别提供异步运行器、有限数检查、 相邻 Run 定位和公共 API。
  3. RUN_FILE 指向 run.yamlVISIBLE_HOLD_SECONDS 控制短暂的可视检查时间。
  4. main() 定义异步应用流程。
  5. fastsim.app(..., planning_reads=True) 显式开启按需付费的 Frame 发布路径。
  6. async with 保证后端被完整清理。
  7. start() 构建真实场景;pause() 在稳定的变换边界保留场景。
  8. frames.catalog() 返回当前 generation 的不可变 Frame Graph。
  9. 第一个 next(...) 查找类型为 world 的唯一 descriptor。代码不假设 provider 使用什么世界坐标系字符串。
  10. 第一个列表推导式选择规范实体 robots.arm 的全部 frame,第二个列表只保留 link frame。
  11. parent_frame_ids 收集所有拥有子节点的 frame;程序要求机械臂恰好只有一个 叶子 link,再选择这个真实末端 link,不依赖不透明的哈希 frame ID 排序。 生产代码也可以改成选择组件显式声明的 named frame。
  12. frames.transform(source, target) 返回 target_T_source。因此先传 link、后传 world,查询的正是 world_T_link
  13. 验证块要求平移和四元数全部有限,且四元数模长与 1 的误差不超过 1e-4; 否则返回非零退出码。
  14. 打印内容包括每个 Frame 及其父节点、选中的叶子 link、明确的变换方向、SI 平移、四元数和实测模长。
  15. 最后的等待让暂停后的可见场景保留三秒。
  16. asyncio.run(main()) 在直接运行文件时执行程序。

验收门禁

  • 机械臂 Frame Graph 必须恰好有一个叶子 link。
  • 所有变换分量必须有限,四元数模长误差不得超过 1e-4
  • 2026-08-25 的可见 Isaac Lab 真机验收选中的末端 link 约位于 (0.25, -0.20, 0.50) m,四元数模长为 1.000000,退出码为 0。

运行

从本案例目录运行:

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

预期输出至少一个属于 robots.arm 的 link frame,并以 world_T_<link> 形式打印 查询方向,随后输出有限的平移和四元数数值。

验证等级

真实可见 Isaac 已通过。 真机运行选择了真实叶子 link,返回的变换全部有限, 四元数模长为 1.000000;程序正常退出,并且没有遗留 Isaac worker 进程。

变换记法

A_T_B 把坐标从 frame B 变换到 frame A。因此:

python
await simulation.frames.transform(source_frame, target_frame)

返回 target_frame_T_source_frame。始终明确这个顺序,可以避免常见的位姿取逆错误。

常见错误

  • SERVICE_ACCESS_DENIED:Frame 读取要求 planning_reads=True
  • FRAME_NOT_FOUND:从 frames.catalog() 发现 ID,禁止根据后端路径自己拼接。
  • arm_links 为空:provider 没有发布组件声明的 link;应把它当作组件/provider 不匹配处理,而不是猜一个 Frame。