Using Cables#
Isaac Lab exposes 1D cable / rod assets on the Newton backend. A cable is
authored as a single open UsdGeom.BasisCurves prim carrying the
PhysicsCurvesDeformableSimAPI schema, and is simulated by Newton’s VBD
solver as a chain of per-segment capsule bodies joined by JointType.CABLE
joints, with thickness, density, stretch stiffness, and bend stiffness.
Cable support is experimental. The spawner cfg, asset class, and material defaults may change while Newton cable support is under active development.
Note
Cables are only supported on the Newton backend, and only under its VBD
solver. CableObject is a backend-dispatched
factory: selecting PhysX or OpenUSD PhysX raises the factory import error at
construction, so a misconfigured scene fails fast instead of loading the
curve as inert geometry.
Quick Start: The Cable Demo#
Before adding cables to a task, run the standalone demo to confirm that the spawner, the VBD solver, collision, and the Kit / Fabric viewport sync all work in your environment:
# Default Newton VBD physics with the Kit visualizer.
uv run python scripts/demos/cables.py
# Explicit Newton VBD physics with the Newton visualizer.
uv run python scripts/demos/cables.py --physics newton_vbd --visualizer newton
# No visualizer and a larger cable pile.
uv run python scripts/demos/cables.py --visualizer none --num_cables 40 --num_segments 15
The demo accepts newton_vbd as its only --physics option. Its
--visualizer option accepts kit, newton, rerun, viser, and
none; when omitted, the demo uses kit. Use --num_cables and
--num_segments to change the pile size and cable resolution. Use
--max_steps to stop after a fixed number of simulation steps; its negative
default runs until the selected visualizer closes or the process is interrupted.
The demo spawns a pile of randomly oriented cables onto a ground plane under
standalone Newton VBD, lets them collide and settle, and periodically restores
them to their spawn state. Source: scripts/demos/cables.py.
Picking a Solver#
Cables can only be simulated under Newton’s VBD solver, which is the only
solver that steps JointType.CABLE joints. A cable-only scene uses a
standalone VBDSolverCfg:
from isaaclab_newton.physics import NewtonCfg
from isaaclab_contrib.deformable import VBDSolverCfg
sim_cfg = sim_utils.SimulationCfg(
dt=0.01,
device=args_cli.device,
physics=NewtonCfg(solver_cfg=VBDSolverCfg(iterations=20), num_substeps=8),
)
Mixed rigid + cable scenes (for example a robot manipulating a cable) run the
cable under a CouplerProxyCfg entry: define a
named VBD entry that owns the cable segments and couple it to the rigid entry.
See VBD Solver.
Cable Material Parameters#
CableMaterialCfg defines the cable’s
geometry and stiffness. All values are validated at author time; nonfinite or
out-of-range values raise ValueError before any prim is created. The
attributes are authored in the standard physics: namespace and read back by
Newton’s importer.
Parameter |
Description |
|---|---|
|
Full cable thickness (diameter) [m]. Must be finite and positive.
Newton uses |
|
Cable density [kg/m^3]. Must be finite and positive. Newton derives
per-segment mass from the density and the capsule volume. Default
|
|
Axial (stretch) elastic modulus |
|
Bending elastic modulus |
|
Transverse shear elastic modulus [Pa]. Must be finite and nonnegative.
Optional: when left at |
|
Torsional elastic modulus [Pa]. Must be finite and nonnegative. Optional:
when left at |
Note
A Newton cable joint has four degrees of freedom: linear stretch and shear, and
angular bend and twist. Leaving shear_stiffness or twist_stiffness
unset does not mean the cable has no shear or twist resistance; it means the
solver reuses the stretch and bend moduli for them. Set them explicitly to decouple
torsion from bending, for example a hose that bends easily but resists twisting.
Authoring 0.0 is distinct from leaving them unset: it removes that resistance.
Damping is not exposed. The AOUSD deformable schema defines damping alongside the moduli, but Isaac Lab does not author it.
To target a specific axial E * A or bending E * I, invert these
relations to pick the modulus; scripts/demos/cables.py does this from a
target stiffness and the segment geometry.
Warning
Newton derives one stretch/bend stiffness pair for the whole cable, using the
mean segment length as L. Author positions with roughly uniform
spacing: with a strongly uneven spacing the per-joint stiffness is wrong for the
outlier segments, since stiffness scales as 1 / L. A segment much longer than
the mean comes out too stiff, and a much shorter one too soft.
Collision#
Collision is opt-in through collision_props. When enabled, the importer
applies adjacent-segment-only collision filtering: directly connected
segments (which share a joint anchor and would otherwise jitter) are filtered,
while every other pair collides. As a result:
The cable collides with the ground and with other cables.
Non-adjacent segments of the same cable collide, so a cable can self-arrest when it loops back on itself.
Only immediate neighbours are filtered, matching Newton’s cable-pile behaviour.
When collision_props is omitted, the cable imports as a dynamics-only rod
and does not collide.
Runtime State#
CableObject exposes per-segment world state through its
data container and integrates with InteractiveScene,
scene.get_state / scene.reset_to, and the reset_scene_to_default
event term.
cable.data.segment_pose_wshape(num_instances, num_segments, 7), position [m] followed by quaternion(x, y, z, w).cable.data.segment_velocity_wshape(num_instances, num_segments, 6), linear [m/s] followed by angular [rad/s].cable.data.default_segment_pose_w/default_segment_velocity_wcapture the spawn state for restoration.
Write per-segment state back with the indexed or masked setters. The masked form is CUDA-graph capturable:
cable.write_segment_pose_to_sim_index(
segment_pose=cable.data.default_segment_pose_w,
)
cable.write_segment_velocity_to_sim_index(
segment_velocity=cable.data.default_segment_velocity_w,
)
Writes update Newton’s maximal-coordinate body state directly (both simulation states) and flag the affected environments for a solver reset, without running forward kinematics.
Kit / Fabric Visualization#
Cables render in the Kit viewport as UsdGeom.BasisCurves. At render cadence
the curve points are refreshed from Newton’s cable segment endpoints so the
rendered shape always matches the simulation. Use the default
--visualizer kit flag, as in the demo.
Note
Curve points are synchronized through CPU Fabric because the RTX Hydra
delegate does not read GPU-backed Fabric arrays for BasisCurves
(NVBug 6502662). The on-device sync path can be restored once that bug is
fixed. Periodic curves are skipped by the sync.
Loading Cables from USD#
Physics is authored in place on the curve:
spawn_cable() applies the
PhysicsCurvesDeformableSimAPI schema and binds a deformable-curve material,
and Newton imports the curve natively through ModelBuilder.add_usd. Topology
comes from the curve’s own points and curveVertexCounts; no custom edge
attribute is required, and imported and replicated cables use the same path.
A cable can therefore also be loaded from an external USD (for example one
authored in a DCC tool) via
UsdFileCfg, provided the curve in that
USD already carries:
a single open, linear, nonperiodic
UsdGeom.BasisCurvesunder the loaded prim,the
PhysicsCurvesDeformableSimAPIapplied schema, anda bound deformable-curve material (
PhysicsCurvesDeformableMaterialAPI) supplyingthickness,density,stretchStiffness, andbendStiffnessin thephysics:namespace.
A raw exported curve without the physics schema and material will not be
recognized as a cable (the importer falls back to a default radius and warns, or
skips the curve). Author it through
spawn_cable(), or apply the schema and
material to the imported prim before construction.
Limitations#
Newton + VBD only. Other backends and other Newton solvers are not supported.
One standalone, unwelded cable per object.
CableObjectrequires “one standalone, unwelded cable articulation per simulation world”: exactly oneBasisCurvesprim carryingPhysicsCurvesDeformableSimAPIunderprim_path, holding a single open curve that is not welded to another cable. Multi-curveBasisCurvesprims, periodic (closed) curves, and hard coincident curve-to-curvePhysicsAttachmentwelds all fail during initialization.Cable ends can be pinned, not clamped. A
PhysicsAttachmentto an xform target lowers to a ball joint, so it constrains position only and the cable pivots freely at the anchor. Rigid plugs and end fittings that must transfer orientation are not representable. The joint is also created only when the attachment stiffness is unauthored or infinite; a finite stiffness is kept as metadata and no joint is created. Both cases are import warnings rather than errors, so the cable initializes normally with the attachment missing. Check the importer output when an attachment appears to have no effect.No damping knobs. The four stiffness moduli are exposed; their damping counterparts are not.
Uniform point spacing assumed. One stiffness pair is derived from the mean segment length, so uneven spacing mistunes the outlier segments.
CPU-only render sync (NVBug 6502662); periodic curves are not synced.
Note
Topologies the runtime object rejects still simulate: the Newton model is
built from the whole USD stage, so every curve carrying
PhysicsCurvesDeformableSimAPI is imported whether or not a
CableObject wraps it. Drive them through
NewtonManager get_model() /
get_state_0() and your own newton.selection.ArticulationView. There
is no Isaac Lab asset wrapper for those cases.
For the public API, see CableObject,
CableCfg, and
CableMaterialCfg.