Load-dependent friction
Basics
A hinge whose friction grows with load holds a heavy pendulum.
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 load_friction# change solver settings liveuv run shelf tune load_frictionSource: examples/shelf/00_basics/load_friction/ · ported from steel-webgpu tools/scenes.py load_friction() @ ad03e49
Presets
| Preset | Solver | Status | Checked |
|---|---|---|---|
steeldefault | steel | works | 2026-11-10, newton f6fc82a8b, NVIDIA RTX PRO 6000 Blackwell Server Edition |
xpbd | xpbd | unsupported | the hinges use Steel's steel:joint_friction_load_coefficient joint attribute |
vbd | vbd | unsupported | the hinges use Steel's steel:joint_friction_load_coefficient joint attribute |
mujoco | mujoco | unsupported | the hinges use Steel's steel:joint_friction_load_coefficient joint attribute |
featherstone | featherstone | unsupported | the hinges use Steel's steel:joint_friction_load_coefficient joint attribute |
semi_implicit | semi_implicit | unsupported | the hinges use Steel's steel:joint_friction_load_coefficient joint attribute |
feather_pgs | feather_pgs | unsupported | the hinges use Steel's steel:joint_friction_load_coefficient joint attribute |
kamino | kamino | unsupported | the hinges use Steel's steel:joint_friction_load_coefficient joint attribute |
implicit_mpm | implicit_mpm | unsupported | the hinges use Steel's steel:joint_friction_load_coefficient joint attribute |
style3d | style3d | unsupported | the hinges use Steel's steel:joint_friction_load_coefficient joint attribute |
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 Load-dependent friction## Load-dependent joint friction: two loaded pendulums, the gold hinge with joint_friction_load_coefficient 0.4.## Ported from steel-webgpu's tools/scenes.py (load_friction); the scene builds# as it does there and the shelf's preset drives the solver.## Command: python -m shelf run load_friction############################################################################
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.4, -1.3, 0.8), 'target': (0.1, 0.0, 0.5)}
def build(self): """Load-dependent joint friction: two loaded pendulums, the gold hinge with joint_friction_load_coefficient 0.4.""" b = newton.ModelBuilder() newton.solvers.SolverSteel.register_custom_attributes(b) b.add_ground_plane() joints = [] for y, coef, color in ((0.2, 0.0, GREY), (-0.2, 0.4, GOLD)): arm = b.add_link(xform=tf((0.0, y, 0.6))) b.add_shape_capsule(arm, xform=tf((0.15, 0, 0), wp.quat_rpy(0.0, math.pi / 2, 0.0)), radius=0.012, half_height=0.15, cfg=cfg(density=300), color=GREY) b.add_shape_sphere(arm, xform=tf((0.3, 0, 0)), radius=0.05, cfg=cfg(density=4000), color=color) j = b.add_joint_revolute(-1, arm, parent_xform=tf((0.0, y, 0.6)), axis=(0, 1, 0), custom_attributes={"steel:joint_friction_load_coefficient": coef}) b.add_articulation([j]) joints.append(j) start = {"grey": (joints[0], (-0.8,)), "gold": (joints[1], (-0.8,))} return b, {}, "Load-dependent joint friction: two loaded pendulums released at 45 deg; the gold hinge's friction grows with the load it carries and holds it.", start
def step(self): super().step() if self.test_mode: # the grey pendulum's widest swing so far, for check() self.grey_swing = max(getattr(self, "grey_swing", 0.0), abs(float(self.state_0.joint_q.numpy()[0]) + 0.8))
def check(self): """The gold hinge's load-dependent friction holds its pendulum at the release angle; the grey one swings.""" q = self.state_0.joint_q.numpy() assert abs(q[1] + 0.8) < 0.01, f"the gold pendulum moved to {q[1]:.3f} rad from its -0.8 rad release" assert self.grey_swing > 1.0, f"the grey pendulum swung only {self.grey_swing:.3f} rad: it should swing freely"
if __name__ == "__main__": parser = Example.create_parser() viewer, args = newton.examples.init(parser) newton.examples.run(Example(viewer, args), args)example = "load_friction"source = "steel-webgpu tools/scenes.py load_friction() @ ad03e49"default = "steel"
[check]# Arguments `python -m shelf check` passes in test mode.args = []
[gallery]short = "A hinge whose friction grows with load holds a heavy pendulum."title = "Load-dependent friction"frame = 90
[xpbd]status = "unsupported"reason = "the hinges use Steel's steel:joint_friction_load_coefficient joint attribute"
[vbd]status = "unsupported"reason = "the hinges use Steel's steel:joint_friction_load_coefficient joint attribute"
[mujoco]status = "unsupported"reason = "the hinges use Steel's steel:joint_friction_load_coefficient joint attribute"
[featherstone]status = "unsupported"reason = "the hinges use Steel's steel:joint_friction_load_coefficient joint attribute"
[semi_implicit]status = "unsupported"reason = "the hinges use Steel's steel:joint_friction_load_coefficient joint attribute"
[feather_pgs]status = "unsupported"reason = "the hinges use Steel's steel:joint_friction_load_coefficient joint attribute"
[steel]status = "works"# 4 substeps x 1 iteration, immediate response: the gold hinge holds its pendulum at the -0.8 rad release (no drift);# the grey one swings to 3.94 rad and back as in a 16 x 32 run, within 0.016 rad (5 mm at the bob) over 6 s# (2 substeps: 0.038 rad, 1: 0.081 rad). Iterations change nothing; no joint has limits, so they are off; no contacts,# so the immediate response (0.50 ms; 2 substeps 0.25 ms). The port's 4 x 12 colored: 1.62 ms.sim = { fps = 60, substeps = 4 }solver = { solve_mode = "matrix_free", iterations = 1, articulated_contact_response = "immediate", enable_joint_friction = true, enable_joint_limits = false }checked = "2026-11-10, newton f6fc82a8b, NVIDIA RTX PRO 6000 Blackwell Server Edition"
[kamino]status = "unsupported"reason = "the hinges use Steel's steel:joint_friction_load_coefficient joint attribute"
[implicit_mpm]status = "unsupported"reason = "the hinges use Steel's steel:joint_friction_load_coefficient joint attribute"
[style3d]status = "unsupported"reason = "the hinges use Steel's steel:joint_friction_load_coefficient joint attribute"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.