Skip to content

Simulation: MuJoCo, Isaac Lab, Newton and PhysX

Stage 4 · Model and simulation · ~35 min · Before this: 02 Balance, 13 The robot description · numbers from the repository as of 2026-11-02

Marvin Bot exists today only in simulation. Every policy it has learned was trained in one physics engine and checked in another. This page opens the box: what a simulator computes every few milliseconds, how it fakes the contact between a foot and the floor, and why two simulators can disagree about the same robot.

A simulator is a video game engine with honest physics: you give it the robot (the description from page 13) and the motor torques, and it tells you where every part of the robot will be a moment later, and the moment after that. A humanoid needs one because learning to walk takes millions of falls. Falling in a computer costs nothing; falling in real life can break a robot whose parts cost about $17,600 (page 21). The catch is that a simulator is only an approximation, so the robot can learn habits that only work in the game.

A physics engine moves a model forward in time in small fixed steps. Each step it (1) finds which shapes touch, (2) works out the forces that stop them passing through each other and that resist sliding, and (3) uses Newton’s laws to update every velocity and position by one timestep. Marvin Bot’s MuJoCo checks step every 2 ms; its Isaac Lab training steps every 5 ms. Everything a policy (the trained neural-network controller, page 16) learns, it learns from the numbers this loop produces, including its mistakes.

The hard part is contact. A real foot and floor deform by fractions of a millimetre in a few milliseconds; resolving that exactly would need microsecond steps. Every simulator approximates it differently, and a policy trained against one approximation can learn to rely on it. The two playgrounds show both halves of that problem.

One body falls onto the ground. Choose how contact is modelled and how time is stepped, then watch the penetration, the bounce and the energy. With no damping, total energy should stay at 100% until contact; anything above 100% is energy the numerics invented (a bug in the maths, not physics).

Start here: press the presets from left to right and watch the three plots. How to read them: blue (top) is how high the body is; red (middle) is how far it sinks into the floor, which a real floor would not allow (a few millimetres is fine, centimetres is bad); green (bottom) is the total energy, which should never rise above 100%. In the readouts, contact ω·dt compares how fast the contact “springs” with the timestep: below about 2 is stable, above 2 the simulation blows up. Steps per contact is how many timesteps the bounce lasts; more is more accurate.

Presets

Contact model

How hard the floor's spring pushes back per metre of sinking (log scale). Stiffer = less sinking, but needs smaller timesteps.
How much the floor soaks up the impact, like a shock absorber. 0 = perfectly bouncy.
Roughly how long the floor takes to push the body back out. Shorter = harder floor.
1 = settles without bouncing; below 1 bounces, above 1 is sluggish.
Defaults 0.02 s and 1; impedance from solimp 0.9 → 0.95 over 1 mm (linear here).
Fraction of the impact speed kept in the bounce: 0 = lands dead, 1 = bounces back to full height.

Time stepping

How far time jumps each step (log scale). Smaller = more accurate but more steps to compute.
The hard constraint always uses semi-implicit Euler with an impulse.

Body

Max penetration
–
Resting penetration
–
Contact ω·dt
–
Steps per contact
–
First bounce e (sim / theory)
–
Peak energy / start
–
height of the body's undersidepenetrationtotal energy / initial

A computer cannot let time flow smoothly; it can only jump forward by a small amount Δt (the timestep, “delta t”) and recompute. Like a flip-book, the smaller the jumps, the closer it looks to real motion. For a body of mass m at height z with velocity v, Newton’s second law gives the acceleration a = F/m. A simulator cannot solve this exactly, so it steps: given the state now, estimate the state Δt later. Three common ways:

  • Explicit Euler: z ← z + Δt·v, v ← v + Δt·a(z, v), both from the old state. Simple, but it adds energy to anything that oscillates, at any step size.
  • Semi-implicit (symplectic) Euler: update the velocity first, then move with the new velocity. Same cost, no systematic energy drift, stable for a spring of natural frequency ω while ω·Δt < 2. MuJoCo’s default integrator, called “Euler”, is of this kind (with implicit joint damping); its recommended implicitfast integrator also treats velocity-dependent forces implicitly.[1]
  • Runge-Kutta 4: four evaluations per step, blended. Much more accurate per step for smooth motion, but four times the cost, and a contact switching on mid-step spoils its accuracy. MuJoCo offers it for nearly energy-conserving systems.[1]

Contact: three ways to stop a foot passing through the floor

Section titled “Contact: three ways to stop a foot passing through the floor”

Penalty springs. Let the bodies overlap by a depth p and push back with F = k p − c v (only while pushing). Easy and explicit, but a spring stiff enough to keep penetration small has a high natural frequency ω = √(k/m), which needs a small timestep. A 41 kg robot on k = 10⁵ N/m rests 41 × 9.81 / 10⁵ = 4 mm deep, with ω = 49 rad/s.

Soft constraints (MuJoCo). Instead of a spring with a stiffness, MuJoCo says “get the foot back out of the floor in about this much time, with this much bounce”. Because those settings are a time and a ratio, not a stiffness, a 4 kg arm and a 41 kg robot sink about equally. The price: bodies always sink in a little, and objects can creep under a steady sideways push.

Go deeper: how MuJoCo’s soft contact is defined

MuJoCo treats contact as a constraint solved together with all others each step, but deliberately softened: it asks the constraint violation r to follow a reference acceleration aref = −b v − k r, where b and k come from solref = (time constant, damping ratio), default (0.02 s, 1), and an impedance d between 0 and 1 from solimp (default 0.9 rising to 0.95 over 1 mm) blends that reference with the unconstrained motion.[1][2] Because the parameters are a time and a ratio, not a stiffness, the contact behaves the same for any mass, and softness makes the problem convex and smooth, which helps both the solver and gradient-based tools. The price: bodies always sink in a little, and objects can creep under steady sideways load. MuJoCo recommends the time constant be at least twice the timestep (and clamps it there unless told otherwise).[2]

Hard constraints with impulses. Forbid penetration outright: when a contact would close, apply an instantaneous impulse that sets the approaching velocity to −e times itself (e the coefficient of restitution) and project the position back. This is closest to a rigid floor, but it is harder to compute: the solver has to juggle many contacts at once and only gets an approximate answer in a fixed number of rounds.

Go deeper: LCP, PGS and TGS

Many contacts at once form a linear complementarity problem (LCP), solved iteratively. PhysX, the engine inside Isaac Sim, works this way, with a projected Gauss-Seidel (PGS) or a temporal Gauss-Seidel (TGS) solver; TGS sub-steps the iterations and converges better for stiff articulated robots, and is Isaac Lab’s default for PhysX.[3][4]

Coulomb friction says the sideways force Ft at a contact can be anything up to μ times the normal force Fn: |Ft| ≤ μ Fn. In 3-D the allowed forces form a cone around the contact normal, the friction cone. Solvers either use the exact (elliptic) cone or approximate it with a pyramid of a few planes; MuJoCo supports both, pyramidal by default.[1] With μ = 1 (Marvin Bot’s floor in MuJoCo) a foot can push sideways with up to its own normal load before slipping.

Reinforcement learning (learning by trial and error, page 16) needs billions of steps of experience. A GPU (graphics processing unit, the chip that draws video-game graphics) can do thousands of small, identical sums at the same time, which is exactly what simulating thousands of identical robots needs. Rudin et al. showed in 2021 that running thousands of robots in one GPU simulation, each a separate environment, trains a quadruped to walk on flat ground in minutes and on rough terrain in about twenty.[5] The GPU computes the same physics for every robot in parallel; the policy network also runs on the GPU, so no data crosses to the CPU. Marvin Bot’s walking runs use 4,096 robots at once, its motion tracker 16,384.

A policy only ever sees its training simulator. It will exploit any quirk there, a contact that is a little too sticky, a joint with no friction, if that earns reward. A second simulator with a different contact model, solver and integrator has different quirks. A policy that still walks there has probably learned to walk, not to exploit; one that falls has found something to fix before any hardware is at risk. This “sim-to-sim” transfer is not proof of sim-to-real transfer, but it is free and catches a large class of failures.[6] Playground B shows how much a contact model alone can change.

Playground B: the same robot, two contact models

Section titled “Playground B: the same robot, two contact models”

Same robot, two different floors: does the outcome change? A sagittal (side-view) model of a standing robot: a foot 0.24 m long touching the floor at heel and toe, and a body (39 kg, centre of mass 0.75 m above the ankle) on an ankle joint held upright by a PD controller (a spring-and-damper pull towards upright, explained on page 15; torque limited to 238 N·m, two RS03 pairs through the linkage). After one second, a push acts on the body for 0.15 s. The same robot runs twice, under model A and model B.

Start here: press 150 N: one model falls, then compare the blue and orange lines. How to read the plots: solid lines are how far the body leans (degrees), dashed lines how far the heel lifts off the floor (mm), dotted lines how far the foot slides (mm). Blue and orange lines that stay together mean the two simulators agree; lines that split mean a policy could be fooled.

Presets

Scenario

A shove on the body for 0.15 s, after 1 s of standing. 60 N is a firm nudge.
Stiffness: ankle torque per radian of lean. Must exceed m·g·h = 39 × 9.81 × 0.75 = 287 N·m/rad to stand (otherwise gravity wins).
Damping: resists the ankle moving fast, so the body does not wobble.

Model A (MuJoCo-like: soft, smooth friction)

Model B (PhysX-like: stiff, stick-slip)

Extra lean from the push A / B
–
Max heel lift A / B
–
Foot slide A / B
–
Outcome A / B
–
Largest difference in that lean
–
model Amodel Bsolid: body lean (°) · dashed: heel lift (mm) · dotted: foot slide (mm)
Engine / framework Licence Runs on Contact model Role for Marvin Bot
MuJoCo[1] Apache-2.0 (open source) CPU; GPU through MJX (JAX) and MuJoCo Warp Soft constraints, convex optimisation (Newton solver by default; CG, PGS); pyramidal or elliptic cones Every cross-check: standing, step-up, symmetry, policies
Newton[7][8] Apache-2.0, a Linux Foundation project (NVIDIA, Google DeepMind, Disney Research) NVIDIA GPU, built on Warp Several solvers: MuJoCo Warp (MuJoCo’s soft contacts on the GPU; its own package, versioned with MuJoCo, is still labelled alpha[11]), Featherstone, XPBD, VBD and others; Kamino experimental Isaac Lab’s backend for Marvin Bot’s training (MuJoCo Warp solver)
PhysX 5[3][9] BSD-3-Clause; GPU source opened in April 2025 CPU and NVIDIA GPU Rigid constraints, PGS or TGS iterative solver, contact offsets Isaac Lab’s second backend; check_robot.py compares it with Newton
Isaac Sim[12] Source on GitHub under Apache-2.0; a build downloads the Omniverse Kit SDK under NVIDIA’s Omniverse licence NVIDIA RTX GPU PhysX Optional since Isaac Lab 3.0; needed for PhysX through Isaac Sim (Isaac Lab can also run PhysX standalone as OVPhysX) and for the URDF importer
Isaac Lab 3.0[4] BSD-3-Clause framework NVIDIA GPU Whatever the backend uses: Newton or PhysX Training framework (tasks, rewards, motor models, thousands of robots)
Drake[10] BSD-3-Clause CPU Point contact or hydroelastic (pressure-field) contact Not used; an accurate, slower alternative for analysis
  • Train in MuJoCo (CPU) instead of on a GPU: simpler, the reference contact model, but thousands of times fewer steps per second for the same hardware; MuJoCo Warp, used through Newton, brings the same contact model to the GPU.
  • Train on PhysX instead of Newton: mature and fast; Isaac Lab 3.0’s quick-start uses Newton with the MuJoCo Warp solver, and Newton runs without Isaac Sim. Marvin Bot keeps PhysX working as a second backend so a policy can be trained or checked on either.[4]
  • Cross-check in PhysX instead of MuJoCo: MuJoCo is free, runs on any CPU (including CI), and its contact model differs from the training contacts in solver and implementation even with MuJoCo Warp in training: the CPU and GPU versions use different collision code paths and settings. A cross-check engine with a different family of contact model (PhysX, Drake) would be a stronger test; that has not been done.
  • Smaller timestep: more accurate contacts, proportionally slower training. 5 ms with a soft, implicit solver is a common choice for legged robots of this size.
  • Which backend to train on (Newton MuJoCo Warp or PhysX), and whether to cross-check in a simulator with a different contact family. The trade: adding a PhysX or Drake cross-check is a stronger test, but it is another setup to maintain and run on every policy.
  • Physics timestep and contact softness (solref, solimp) for training, and whether to randomise them as part of domain randomisation (varying the simulator’s settings so the policy cannot rely on any one of them). Halving the timestep roughly doubles training time; randomising contact makes the policy sturdier but can make training slower to converge.
  • Which checks a policy must pass in the second simulator before it goes near hardware: noise level, pushes, stairs, seeds. Stricter checks reject more policies (rough v10 failed and was dropped) but each rejection is a fall that did not happen on hardware.
Your decision note

Built from your settings above. Paste it into an issue, a design discussion or an AI assistant session.

  1. MuJoCo documentation, Computation — used for: soft contact, solvers (Newton default), integrators (Euler as semi-implicit, implicitfast recommended, RK4), friction cones and condim.
  2. MuJoCo documentation, Modeling (solver parameters) — used for: solref and solimp meaning and defaults, the time-constant ≥ 2 × timestep recommendation.
  3. NVIDIA PhysX 5 SDK documentation, Rigid Body Dynamics — used for: PGS and TGS solvers, contact offsets.
  4. Isaac Lab v3.0.0 release notes (2026-10-20) — used for: Newton and PhysX backends, MuJoCo Warp, Kamino experimental, Isaac Sim optional.
  5. N. Rudin, D. Hoeller, P. Reist, M. Hutter, Learning to Walk in Minutes Using Massively Parallel Deep Reinforcement Learning, CoRL 2021 — used for: thousands of parallel robots on one GPU, minutes of training.
  6. X. Gu, Y.-J. Wang, J. Chen, Humanoid-Gym: Reinforcement Learning for Humanoid Robot with Zero-Shot Sim2Real Transfer, arXiv 2404.05695, 2024 — used for: sim-to-sim validation (training in Isaac Gym, checking in MuJoCo) before hardware.
  7. Newton physics engine, GitHub (releases to v1.7.0, 2026-10-14) — used for: licence, Warp, solvers, release status.
  8. Linux Foundation, contribution of Newton (2025) — used for: governance and co-developers.
  9. NVIDIA PhysX SDK on GitHub — used for: BSD-3-Clause licence, GPU source in 5.6.
  10. Drake — used for: hydroelastic contact, licence.
  11. mujoco-warp on PyPI (3.17.0, 2026-10-22) — used for: MuJoCo Warp’s release status (development status “3 - Alpha”), Apache-2.0.
  12. Isaac Sim on GitHub — used for: Isaac Sim source licence (Apache-2.0) and the Omniverse Kit SDK it downloads.