Falling chain (mujoco.org)
Basic contacts
Four interlocked thin chain links drop onto a catch bar and hang from it.
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 mjorg_falling_chain# change solver settings liveuv run shelf tune mjorg_falling_chainSource: examples/shelf/01_basic_contacts/mjorg_falling_chain/ · ported from google-deepmind/mujoco model/speculative/chain.xml (MuJoCo 4.0 tour on mujoco.org)
Presets
| Preset | Solver | Status | Checked |
|---|---|---|---|
steeldefault | steel | 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
############################################################################ Example mujoco.org falling chain## Four interlocked chain links of 6 mm capsules drop onto a thin catch bar at a coarse# time step and hang there without passing through each other.## Replicates the "Speculative Contacts: Falling Chain" scene of the MuJoCo 4.0 tour on# mujoco.org from its MJCF (scene.xml, flattened from google-deepmind/mujoco# model/speculative/chain.xml). See README.md for the gaps.## Command: python -m shelf run mjorg_falling_chain############################################################################
from pathlib import Path
import numpy as np
import newtonimport newton.examplesfrom common.steel_scenes import SceneExample
class Example(SceneExample): file = __file__ # MuJoCo's free camera for the scene: azimuth 135, elevation -14 around the statistic centre camera = {"eye": (1.48, -1.48, 1.77), "target": (0.0, 0.0, 1.25)}
def build(self): builder = newton.ModelBuilder() self.preset.apply_model(builder) builder.add_mjcf(str(Path(__file__).with_name("scene.xml"))) return builder, {}
def check(self): """The chain dropped onto the bar and hangs from it, each link stretched below the one above.""" self.solver.check_constraint_capacity() # dropped contact rows invalidate the run q = self.state_0.body_q.numpy() assert 1.6 < q[0, 2] < 1.76, f"link1 is not hanging from the catch bar (z={q[0, 2]:.3f})" # links start 18 cm apart; hanging interlocked they are about 31 cm apart, and more once one slips out gaps = np.linalg.norm(np.diff(q[:, :3], axis=0), axis=1) assert (gaps > 0.25).all() and (gaps < 0.34).all(), f"links not hanging interlocked: gaps {np.round(gaps, 3)}"
if __name__ == "__main__": parser = Example.create_parser() viewer, args = newton.examples.init(parser) newton.examples.run(Example(viewer, args), args)example = "mjorg_falling_chain"source = "google-deepmind/mujoco model/speculative/chain.xml (MuJoCo 4.0 tour on mujoco.org)"license = "Apache-2.0"default = "steel"
[check]# Arguments `python -m shelf check` passes in test mode.args = ["--num-frames", "500"]
[gallery]short = "Four interlocked thin chain links drop onto a catch bar and hang from it."title = "Falling chain (mujoco.org)"frame = 60
[xpbd]status = "untested"
[vbd]status = "untested"
[mujoco]status = "untested"
[featherstone]status = "untested"
[semi_implicit]status = "untested"
[feather_pgs]status = "untested"
[steel]status = "works"# MuJoCo's 6 ms step, coarsened to 6.7 ms. A zero authored gap matches MuJoCo's zero margin: without the# velocity-sized speculative gap, links 3 and 4 fall through link 2 here as they do in MuJoCo 3.17.sim = { fps = 50, substeps = 3 }model = { rigid_gap = 0.0 }collision = { speculative_contact_gap_max = 0.2 }solver = { solve_mode = "colored", iterations = 12, articulated_contact_response = "propagation" }checked = "2026-11-10, newton f6fc82a8b, NVIDIA RTX PRO 6000 Blackwell Server Edition"
[kamino]status = "untested"
[implicit_mpm]status = "untested"
[style3d]status = "untested"README
Steel replica of “Speculative Contacts: Falling Chain” from the MuJoCo 4.0 tour on mujoco.org. Four interlocked chain links built from 6 mm capsules drop 8 cm onto a catch bar at a coarse time step. With speculative contacts the links stay interlocked and the chain hangs from the bar.
- Source:
google-deepmind/mujocomodel/speculative/chain.xml, Apache-2.0 (text inLICENSE).scene.xmlis that file compiled with MuJoCo 3.17 and re-emitted flat, without the 4.0speculativeflag (Newton’s collision pipeline enables speculative contacts instead, from the preset’scollisiontable). - Check: after 10 s link 1 hangs on the bar and each link hangs 25-34 cm below the one above (they start 18 cm apart). Without speculative contacts links 3 and 4 fall through, as they do in MuJoCo 3.17.
Known gaps:
- Newton sizes the speculative gap from each body’s velocity at the start of the step, capped by
speculative_contact_gap_max. MuJoCo 4.0’s speculative contacts are its own scheme. - The step is 6.7 ms (3 substeps at 50 fps); the tour uses 6 ms.
- Rendering uses the shelf viewer, not MuJoCo’s Filament renderer, image-based light or skybox.
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.