Virtual Gantry Extension#
About#
The Virtual Gantry suspends a robot from an anchor point during bring-up and policy testing, like a crane holding the robot so it does not fall over while you test your policy.
It is a runtime constraint only: a one-sided spring-damper “rope” applied as a per-physics-step external wrench to a single articulation body. The rope applies no force until the body drops past the rope length, then it pulls the body back toward the anchor.
This extension is enabled by default. If it is ever disabled, it can be
re-enabled from the Extension Manager
by searching for isaacsim.robot_setup.virtual_gantry and
isaacsim.robot_setup.virtual_gantry.ui.
Suspending a Robot#
Add a robot to the stage.
Create the gantry from the menu:
Create>Robotics>Virtual Gantry. This authors anIsaacVirtualGantryprim, placed above the selected prim by default. The prim is anXform, and its world position is the rope anchor.Note
The gantry prim carries no geometry, so it is not visible in the viewport and cannot be clicked there. Select it in the Stage panel; the transform gizmo then appears at the anchor position, and the anchor can be moved with the gizmo or by editing
Transform > Translatein the property panel. The rope line and anchor marker are only drawn while the simulation is playing.Select the gantry prim and, in the property panel, set the two relationships:
Attach Body - the articulation link the rope pulls on, typically the torso or pelvis.
Articulation - the robot’s articulation-root prim.
Note
If either relationship is unset or cannot be resolved, the gantry prim is skipped silently: no rope is created and no error is reported. If pressing Play produces no rope, check these two relationships first.
Press Play. The robot is caught by the rope once it drops past the rope length.
Properties#
Property |
Description |
|---|---|
|
Slack rope length in meters. |
|
Rope spring stiffness |
|
Rope damping |
|
Attach point offset in the body’s local frame, in meters. Default |
|
Lower clamp for the rope length, in meters. |
|
Smoothing factor for the rope extension-rate estimate. |
|
Whether the rope applies force. Read every physics step. |
|
Draw the rope line and anchor marker as an overlay. |
|
Runtime rope state, written back by the runtime: |
|
The articulation link the rope pulls on. |
|
The robot’s articulation-root prim. |
Edits made in the property panel apply to the running rope immediately; there is no need to stop and restart the timeline.
Hotkeys#
The viewport must have keyboard focus for these to fire.
Key |
Action |
|---|---|
|
Toggle every gantry on the stage on or off. |
|
Shorten the rope by 5 mm. |
|
Lengthen the rope by 5 mm. |
The [ and ] adjustments are transient: they change the running rope
without writing back to the prim. Disabling and re-enabling the gantry
re-derives the rope and catches the robot where it currently is, rather than
restoring the last adjusted height.
Driving the Gantry from Code#
Creating the Gantry Prim#
import omni.usd
from isaacsim.robot_setup.virtual_gantry import create_virtual_gantry
stage = omni.usd.get_context().get_stage()
# Authors an IsaacVirtualGantry prim. Its world position is the rope anchor,
# so place it above the robot. When an articulation is already on the stage it
# is auto-wired; otherwise wire it yourself (see below).
gantry_prim = create_virtual_gantry(stage, parent_path="/", anchor_z=2.0)
print(f"created {gantry_prim.GetPath()}")
Wiring it to a Robot#
The runtime picks up a gantry prim once both relationships resolve, so a prim created before the robot starts driving a rope as soon as it is wired.
import isaacsim.robot_setup.virtual_gantry_schema as gantry_schema
R = gantry_schema.Relations
# The link the rope pulls on (e.g. the torso or pelvis).
gantry_prim.GetRelationship(R.GANTRY_ATTACH_BODY.name).SetTargets(["/Robot/torso_link"])
# The robot's articulation-root prim.
gantry_prim.GetRelationship(R.GANTRY_ARTICULATION.name).SetTargets(["/Robot"])
Tuning the Rope#
A = gantry_schema.Attributes
# Slack rope length in meters; -1 auto-derives from the body's height on the
# first physics step.
gantry_prim.GetAttribute(A.GANTRY_ROPE_LENGTH.name).Set(-1.0)
# Spring stiffness kp (N/m) and damping kd (N*s/m). Damping is one-sided: it
# only acts while the rope is extending.
gantry_prim.GetAttribute(A.GANTRY_STIFFNESS.name).Set(5000.0)
gantry_prim.GetAttribute(A.GANTRY_DAMPING.name).Set(800.0)
# Attach point offset in the body's local frame (m).
gantry_prim.GetAttribute(A.GANTRY_BODY_OFFSET.name).Set((0.0, 0.0, 0.3))
# Draw the rope line and anchor marker.
gantry_prim.GetAttribute(A.GANTRY_VISUALIZE.name).Set(True)
Toggling and Reading State#
# The runtime reads this attribute every physics step, so toggling it takes
# effect on the next step. This is what the Enable / Disable buttons and the
# G hotkey do.
gantry_prim.GetAttribute(A.GANTRY_ENABLED.name).Set(False)
gantry_prim.GetAttribute(A.GANTRY_ENABLED.name).Set(True)
# The runtime writes the rope state back: "Slack", "Taut" or "Disabled".
status = gantry_prim.GetAttribute(A.GANTRY_STATUS.name).Get()
print(f"rope status: {status}")
Adjusting a Running Rope#
Most of the gantry is driven through USD attributes, so no handle to the runtime
is needed. The exception is the transient rope-length adjustment behind the
[ and ] hotkeys, which mutates the live rope without touching the prim.
from isaacsim.robot_setup.virtual_gantry import get_manager
# The live manager, or None when the extension is not running. Resolve it on
# use rather than caching it: it is rebuilt on stage close and timeline stop.
manager = get_manager()
if manager is not None:
# Lengthen every managed rope by 5 mm. This adjustment is transient -- it
# is not written back to the prim, so a disable -> enable re-derives the
# rope and catches the robot where it currently is.
manager.adjust_rope_length_all(0.005)
Notes#
Multiple gantries are supported. The runtime re-scans the stage periodically, so gantries created mid-session are picked up without a stop and restart.
The anchor uses the gantry prim’s position only. Its orientation is reserved for a future 6-DOF “soft fixture” mode.
Every time the gantry is enabled, the anchor prim re-anchors above the attach body’s current position, so a disable → fall → enable sequence catches the robot in place instead of yanking it back to the prim’s original spot.
The rope line and anchor marker are drawn as an ephemeral overlay; nothing is authored into the stage, and they do not appear in renders or in a saved USD.
Disable the rope once a policy is balancing on its own.