Simulation: MuJoCo, Isaac Lab, Newton and PhysX
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.
The idea in one picture
Section titled “The idea in one picture”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.
Playground A: a mass hitting the floor
Section titled “Playground A: a mass hitting the floor”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.
From first principles
Section titled “From first principles”Integration: turning forces into motion
Section titled “Integration: turning forces into motion”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
implicitfastintegrator 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]
Friction cones
Section titled “Friction cones”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.
Massively parallel simulation
Section titled “Massively parallel simulation”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.
Sim-to-sim: a cheap stand-in for reality
Section titled “Sim-to-sim: a cheap stand-in for reality”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.
The simulators
Section titled “The simulators”| 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 |
How Marvin Bot does it
Section titled “How Marvin Bot does it”Trade-offs and alternatives
Section titled “Trade-offs and alternatives”- 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.
Decisions you can make here
Section titled “Decisions you can make here”- 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.
Built from your settings above. Paste it into an issue, a design discussion or an AI assistant session.
Further reading
Section titled “Further reading”- MuJoCo documentation: Computation: the clearest public explanation of soft contact, solver choices and integrators.
- Rudin et al., Learning to Walk in Minutes: the paper behind the “thousands of robots on one GPU” recipe that Isaac Lab’s locomotion tasks follow.
- Newton on GitHub: solvers, examples and release notes.
- Isaac Lab documentation: physics backends, actuators and the locomotion tasks.
- R. Tedrake, Underactuated Robotics: simulation and contact from a control point of view.
Sources
Section titled “Sources”- MuJoCo documentation, Computation — used for: soft contact, solvers (Newton default), integrators (Euler as semi-implicit, implicitfast recommended, RK4), friction cones and condim.
- MuJoCo documentation, Modeling (solver parameters) — used for: solref and solimp meaning and defaults, the time-constant ≥ 2 × timestep recommendation.
- NVIDIA PhysX 5 SDK documentation, Rigid Body Dynamics — used for: PGS and TGS solvers, contact offsets.
- Isaac Lab v3.0.0 release notes (2026-10-20) — used for: Newton and PhysX backends, MuJoCo Warp, Kamino experimental, Isaac Sim optional.
- 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.
- 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.
- Newton physics engine, GitHub (releases to v1.7.0, 2026-10-14) — used for: licence, Warp, solvers, release status.
- Linux Foundation, contribution of Newton (2025) — used for: governance and co-developers.
- NVIDIA PhysX SDK on GitHub — used for: BSD-3-Clause licence, GPU source in 5.6.
- Drake — used for: hydroelastic contact, licence.
- mujoco-warp on PyPI (3.17.0, 2026-10-22) — used for: MuJoCo Warp’s release status (development status “3 - Alpha”), Apache-2.0.
- Isaac Sim on GitHub — used for: Isaac Sim source licence (Apache-2.0) and the Omniverse Kit SDK it downloads.