Skip to content

Sleeping dominos (mujoco.org)

Many contacts

One tilted domino starts a wave through 96 sleeping dominoes; each row wakes as it arrives.

0.00 s
The steel preset (the default), recordedon an NVIDIA RTX PRO 6000 Blackwell, sped up 2× (the readout shows sim time).

Run it

Terminal window
cd examples
# the default preset (steel), then the others
uv run shelf play mjorg_sleeping_dominos
# change solver settings live
uv run shelf tune mjorg_sleeping_dominos

Source: examples/shelf/02_many_contacts/mjorg_sleeping_dominos/ · ported from google-deepmind/mujoco model/sleep/dominos.xml (MuJoCo 4.0 tour on mujoco.org)

Presets

PresetSolverStatusChecked

Solvers with no row are untested on this example. The full settings are inpresets.toml.

Code

examples/shelf/02_many_contacts/mjorg_sleeping_dominos/example.py
# SPDX-FileCopyrightText: Copyright (c) 2026 Skild AI and the Steel contributors
# SPDX-License-Identifier: Apache-2.0
###########################################################################
# Example mujoco.org sleeping dominos
#
# 96 dominoes in five rows joined by U-turns. One tilted domino starts the wave; the rest
# sleep until it reaches them, and fall back asleep once they have toppled.
#
# Replicates the "Island Sleeping" scene of the MuJoCo 4.0 tour on mujoco.org from its
# MJCF (scene.xml, flattened from google-deepmind/mujoco model/sleep/dominos.xml), with
# Steel's island sleeping. See README.md for the gaps.
#
# Command: python -m shelf run mjorg_sleeping_dominos
#
###########################################################################
from pathlib import Path
import numpy as np
import newton
import newton.examples
from common.steel_scenes import SceneExample
# A domino has toppled when its long axis leans this far from vertical [deg].
TOPPLED_TILT_DEG = 45.0
class Example(SceneExample):
file = __file__
# MuJoCo's free camera for the scene: azimuth 60, elevation -25 around the statistic centre
camera = {"eye": (-0.34, -2.66, 1.43), "target": (1.2, 0.0, 0.0)}
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):
"""Every domino has toppled."""
self.solver.check_constraint_capacity() # dropped contact rows invalidate the run
q = self.state_0.body_q.numpy()
x, y = q[:, 3], q[:, 4]
tilt = np.degrees(np.arccos(np.clip(1.0 - 2.0 * (x * x + y * y), -1.0, 1.0)))
standing = np.flatnonzero(tilt < TOPPLED_TILT_DEG)
assert len(standing) == 0, f"{len(standing)} of {len(q)} dominoes still stand: bodies {standing.tolist()}"
if __name__ == "__main__":
parser = Example.create_parser()
viewer, args = newton.examples.init(parser)
newton.examples.run(Example(viewer, args), args)

README

Steel replica of “Island Sleeping” from the MuJoCo 4.0 tour on mujoco.org. 96 dominoes stand in five rows joined by U-turns. One tilted domino starts a wave; the dominoes ahead of it sleep until it reaches them, and the fallen ones go back to sleep.

  • Source: google-deepmind/mujoco model/sleep/dominos.xml, Apache-2.0 (text in LICENSE). scene.xml is that file compiled with MuJoCo 3.17 and re-emitted flat (its replicate blocks expanded), without the 4.0 sleep flag and sleep_tolerance. Steel’s enable_sleeping replaces them.
  • Check: after 15 s every domino leans more than 45 degrees from vertical. In Steel the wave reaches all 96 by 8 s, as it does in MuJoCo 3.17 on the same file, and 96 of 96 are asleep by 9.5 s.

Known gaps:

  • Steel’s sleep thresholds (body speed 0.05 m/s, 0.15 rad/s for 0.5 s) differ from MuJoCo’s sleep_tolerance.
  • The shelf viewer does not mark sleeping bodies; the tour colours them.
  • Rendering uses the shelf viewer, not MuJoCo’s Filament renderer.