Joint motors
Basics
Three arms driven to the same angle with different torque limits.
steel preset (the default), recordedon an NVIDIA RTX PRO 6000 Blackwell.Run it
cd examples# the default preset (steel), then the othersuv run shelf play drivesuv run shelf play drives --solver steel_off# change solver settings liveuv run shelf tune drivesSource: examples/shelf/00_basics/drives/ · ported from steel-webgpu tools/scenes.py drives() @ ad03e49
Presets
| Preset | Solver | Status | Checked |
|---|---|---|---|
steeldefault | steel | works | 2026-11-10, newton f6fc82a8b, NVIDIA RTX PRO 6000 Blackwell Server Edition |
steel_off | steel variant | works | 2026-11-10, newton f6fc82a8b, NVIDIA RTX PRO 6000 Blackwell Server Edition |
Solvers with no row are untested on this example. The full settings are inpresets.toml.
Code
# SPDX-FileCopyrightText: Copyright (c) 2026 Skild AI and the Steel contributors# SPDX-License-Identifier: Apache-2.0# Direct source: steel-webgpu; see presets.toml and THIRD_PARTY.md.# Modified for Steel Shelf: preset-driven execution and shared runner integration.
############################################################################ Example Joint motors## Drive rows (drive_mode="rows"): arms stepping to 1.2 rad with effort limits 3, 10 and 60 N m, capped at 2 rad/s.## Ported from steel-webgpu's tools/scenes.py (drives); the scene builds# as it does there and the shelf's preset drives the solver.## Command: python -m shelf run drives############################################################################
import math
import numpy as npimport warp as wp
import newtonimport newton.examplesfrom common.steel_scenes import BLUE, GOLD, GREY, RED, TEAL, SceneExample, cfg, tf
class Example(SceneExample): file = __file__ camera = {'eye': (0.6, -1.6, 0.9), 'target': (0.2, 0.0, 0.5)}
def build(self): """Drive rows (drive_mode="rows"): arms stepping to 1.2 rad with effort limits 3, 10 and 60 N m, capped at 2 rad/s.""" b = newton.ModelBuilder() b.add_ground_plane() joints = [] for i, effort in enumerate((3.0, 10.0, 60.0)): y = (i - 1) * 0.3 base = b.add_link(xform=tf((0.0, y, 0.5))) b.add_shape_box(base, xform=tf((0.2, 0, 0)), hx=0.2, hy=0.02, hz=0.02, cfg=cfg(density=500), color=[BLUE, TEAL, GOLD][i]) b.add_shape_sphere(base, xform=tf((0.4, 0, 0)), radius=0.05, cfg=cfg(density=3000), color=RED) j = b.add_joint_revolute(-1, base, parent_xform=tf((0.0, y, 0.5)), axis=(0, -1, 0), target_pos=1.2, target_ke=2000.0, target_kd=60.0, effort_limit=effort, velocity_limit=2.0) b.add_articulation([j]) joints.append(j) return b, {}, "Drive rows: arms driven to 1.2 rad with effort limits 3, 10 and 60 N m and a 2 rad/s velocity limit (drive_mode rows)."
def check(self): """The 60 N m arm holds the 1.2 rad target; the 3 N m arm cannot lift its load and hangs below horizontal.""" q = self.state_0.joint_q.numpy() assert abs(q[2] - 1.2) < 0.02, f"the 60 N m arm is at {q[2]:.3f} rad, not at its 1.2 rad target" assert q[0] < 0.0, f"the 3 N m arm is at {q[0]:.3f} rad: its effort limit should not lift the load"
if __name__ == "__main__": parser = Example.create_parser() viewer, args = newton.examples.init(parser) newton.examples.run(Example(viewer, args), args)example = "drives"source = "steel-webgpu tools/scenes.py drives() @ ad03e49"default = "steel"
[check]# Arguments `python -m shelf check` passes in test mode.args = []
[gallery]short = "Three arms driven to the same angle with different torque limits."title = "Joint motors"frame = 90
[xpbd]status = "untested"
[vbd]status = "untested"
[mujoco]status = "untested"
[featherstone]status = "untested"
[semi_implicit]status = "untested"
[feather_pgs]status = "untested"
[steel]status = "works"# 1 substep x 1 iteration, immediate response, drive_mode rows: the arms follow a 16 x 32 run within 0.018 rad# (7 mm at the 0.4 m arm) over 6 s; the 10 and 60 N m arms reach 1.2 rad at the 2 rad/s cap, the 3 N m arm cannot# lift its 1.9 kg load and swings below horizontal. More iterations change nothing (one DOF per arm); no joint has# position limits, so they are off; immediate costs less than propagation_colored (0.22 vs 0.32 ms; port's 4 x 12:# 2.65 ms).sim = { fps = 60, substeps = 1 }solver = { solve_mode = "matrix_free", iterations = 1, articulated_contact_response = "immediate", enable_joint_velocity_limits = true, enable_joint_limits = false, drive_mode = "rows" }checked = "2026-11-10, newton f6fc82a8b, NVIDIA RTX PRO 6000 Blackwell Server Edition"
[kamino]status = "untested"
[implicit_mpm]status = "untested"
[style3d]status = "untested"
[steel_off]kind = "steel"status = "works"# the "Joint motor constraints" toggle off: drive_mode = "augmented", everything else as [steel]. At these settings the# augmented drives clamp their effort explicitly and the 10 N m arm reaches only 0.23 rad after 0.5 s (rows: 0.85,# 16 x 32 augmented: 0.79), which is the difference the toggle shows.sim = { fps = 60, substeps = 1 }solver = { solve_mode = "matrix_free", iterations = 1, articulated_contact_response = "immediate", enable_joint_velocity_limits = true, enable_joint_limits = false, drive_mode = "augmented" }checked = "2026-11-10, newton f6fc82a8b, NVIDIA RTX PRO 6000 Blackwell Server Edition"Steel docs and tutorials are licensed under Apache-2.0. Third-party notices. "Skild", "Skild AI" and the Skild logo are trademarks of Skild AI and are not licensed under Apache-2.0.