A passive cartpole in MuJoCo
5th Jun 2026
A first MuJoCo demo — releasing a cartpole from a small offset and recording the fall as an mp4. Also: the notebook runner now drives more than one CLI tool.
The cartpole is the simplest physics-engine model that still looks like something. A cart slides on a frictionless rail; a thin pole is hinged on top. With no controller, the pole tips over under gravity, and the cart drifts only by the tiny horizontal reaction force the hinge transmits.
The model is defined inline as MJCF in src/clis/mujoco_cli/cli.py:
- one slide joint (
slider) for the cart along the x-axis - one hinge joint (
hinge) for the pole about the y-axis - damping coefficients and for the cart and pole
- timestep , simulation length
- initial pole offset (); everything else starts at rest
The CLI runs mj_step in a loop, samples a frame every with mujoco.Renderer, and pipes the stack of RGB arrays through imageio + libx264 into cartpole.mp4.
The pole crosses from vertical at , ends the run essentially horizontal, and the cart barely moves — only of recoil over the full four seconds, because almost all the angular momentum of the falling pole is absorbed by the rail’s reaction force rather than by translating the cart.
Run parameters
| Parameter | Value |
|---|---|
| theta0 (rad) | 0.15 |
| duration (s) | 4.0 |
| fps | 60 |
| fall_time_s | 0.595 |
| final_angle_deg | 89.5 |
| max_cart_displacement_m | 3.05e-05 |
A second CLI tool
This is also the first notebook that shells out to a CLI other than neuron. src/notebooks/nb002.py declares its commands as (tool, command, deps) triples:
COMMANDS = (
("mujoco_cli", "cartpole", ("mujoco", "imageio[ffmpeg]", "numpy")),
)
so the same runner can drive an arbitrary mix of tools — neuron_cli for the integrate-and-fire work, mujoco_cli for physics, and any future tool that satisfies the same manifest contract. The contract gained one optional field, headline_video, alongside headline_figure; the runner copies whichever is set into the post’s public/ directory.