验证等级

可见原生 Isaac。 窗口中双关节机械臂依次到达四个目标,终端验证唯一的终态 ChunkResult

前置条件

  • 同一 Python 3.12 环境中的 FastSim 0.1.0a6、UniRoboSim Core 0.10.0unirobosim-isaaclab==0.10.1
  • Isaac Lab 3.0 / Isaac Sim 6.0、NVIDIA GPU 和可用的显示环境。

配置

机器人 manifest 声明 joint_1joint_2arm group。Scenario 别名也叫 arm,但两者含义不同:

  • actor="arm" 选择 scenario.scene.robots.arm
  • group="arm" 选择 manifest 中包含两个关节的执行器资源组。

物理和控制频率均为 60 Hz。配置中的初始关节状态为零,与 path 第一行一致。

每个控制参数

python
await simulation.pause()                         # 冻结在新鲜控制边界。
operation = await simulation.control.submit_joints(
    actor="arm",           # 要控制的 Scenario 机器人。
    group="arm",           # 要申请的执行器资源组。
    path=[                  # 每行依次是 [joint_1, joint_2] 目标。
        [0.0, 0.0],
        [1.0, -0.7],
        [-0.9, 0.8],
        [0.5, -0.4],
    ],
    dt=0.35,               # 相邻目标行之间的模拟秒数。
    timeout=10.0,          # 接纳加终态等待的上限。
)
await simulation.resume()                        # 让物理线程消费 path。
result = await operation.result(timeout=10.0)    # 阻塞等待唯一终态。
await operation.release()                        # 清除已完成记录。

应用仍然会在开始下一 action 前阻塞,但 submission 和等待被拆开放在 resume() 两侧。 这是异步后端的可靠公共用法:在新鲜 paused observation 上创建 chunk,恢复 物理,再等待 ChunkResult。当物理以有节流速度运行时,可以直接使用 await simulation.control.joints(...);在 paused 状态直接用便捷阻塞方法会因为没有物理 消费控制帧而死等。

两个关节在 manifest 中都声明为 rad,所以 path 使用弧度。FastSim 会在命令进入 后端前检查轴数量、单位、有限数、目标范围、session authority 和 generation。

运行

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

预期结果:原生 Isaac 窗口打开,机械臂依次经过全部四个目标;终端输出 Chunk status: succeededApplied frames: 4/4。这只是控制执行结果,并不等价于 pick 等语义任务成功。

常见错误

  • NO_TARGET:actor 别名没有解析到可控 articulation。
  • NO_JOINT_POSITION_SPACE:provider 没发布 joint.position@1
  • 轴数量错误:本例每个 path 行都必须恰好有两个数。
  • chunk observation exceeds session freshness window:按本例在显式 paused 边界提交; 无节流后端可能在 observe 到 submit 的往返间推进过多 tick。
  • timeout:operation 会被取消,避免调用方放弃后隐藏 chunk 仍继续控制机器人。

下一步

继续阅读 05 — 伺服抢占