Verification level
Visible native Isaac. The window shows the two-joint arm visiting four targets in
order, while the terminal verifies the one terminal ChunkResult.
Prerequisites
- FastSim
0.1.0a6, UniRoboSim Core0.10.0, andunirobosim-isaaclab==0.10.1in one Python 3.12 environment. - Isaac Lab 3.0 / Isaac Sim 6.0, an NVIDIA GPU, and a working display.
Configuration
The robot manifest declares joints joint_1, joint_2 and group arm. The Scenario
alias is also arm, but these names mean different things:
actor="arm"selectsscenario.scene.robots.arm.group="arm"selects the manifest's actuator group containing both joints.
physics_hz and control_hz are both 60 Hz. The configured joint initial state is
zero, matching the first target in the path.
Every control argument
await simulation.pause() # Freeze one fresh control boundary.
operation = await simulation.control.submit_joints(
actor="arm", # Which Scenario robot to command.
group="arm", # Which actuator resource group to lease.
path=[ # Rows are ordered [joint_1, joint_2] targets.
[0.0, 0.0],
[1.0, -0.7],
[-0.9, 0.8],
[0.5, -0.4],
],
dt=0.35, # Simulated seconds between adjacent target rows.
timeout=10.0, # Upper bound for admission plus terminal completion.
)
await simulation.resume() # Let physics consume the path.
result = await operation.result(timeout=10.0) # Block until one terminal result.
await operation.release() # Drop the completed record.
The application still blocks before moving to its next action, but submission and
waiting are split around resume(). This is the reliable public pattern for an
asynchronous backend: create the chunk from a fresh paused observation, resume
physics, then wait for its terminal ChunkResult. A simple
await simulation.control.joints(...) is useful while physics is already running at
a paced rate; it would deadlock while paused because frames cannot be consumed.
The path uses radians because both manifest joints declare unit rad. FastSim checks
axis count, units, finite values, target scope, session authority, and generation
before commands reach the backend.
Run it
cd demo/fundamentals/04_blocking_joint_path
fastsim config validate run.yaml --json
python main.py
Expected result: the native Isaac window opens and the arm moves through all four
targets in order. The terminal prints Chunk status: succeeded and
Applied frames: 4/4. This is a control-execution result; it does not claim that a
semantic task such as pick succeeded.
Common errors
NO_TARGET: the actor alias does not resolve to a controllable articulation.NO_JOINT_POSITION_SPACE: the provider did not publishjoint.position@1.- Axis-count error: every path row must contain exactly two values for this group.
chunk observation exceeds session freshness window: submit at the explicit paused boundary as shown; an unthrottled backend may outrun an observe-then-submit round trip.- Timeout: the operation is cancelled so an unseen chunk cannot continue driving the robot after the caller has given up.
Next
Continue with 05 — Servo preemption.