|
| 1 | +<p align="center"> |
| 2 | + <img src="./img/Logo.svg" alt="MuJoCo Tutorial Logo" width="125"/> |
| 3 | +</p> |
| 4 | + |
| 5 | +<h1 align="center">MuJoCo Tutorial 🤖</h1> |
| 6 | + |
| 7 | +<p align="center"> |
| 8 | +A modern tutorial for getting started with <a href="https://mujoco.org/">MuJoCo</a> — a fast, accurate physics engine for robotics, biomechanics, and reinforcement learning. |
| 9 | +</p> |
| 10 | + |
| 11 | +> MuJoCo is open-source (Apache 2.0) and maintained by Google DeepMind. Since v3.0, it includes GPU-accelerated simulation via MJX. |
| 12 | +
|
| 13 | +[](https://colab.research.google.com/github/tayalmanan28/MuJoCo-Tutorial/blob/main/tutorial/quickstart.ipynb) |
| 14 | + |
| 15 | +--- |
| 16 | + |
| 17 | +## Installation 🚀 |
| 18 | + |
| 19 | +MuJoCo is a pure Python package — no license keys, no system dependencies: |
| 20 | + |
| 21 | +```bash |
| 22 | +pip install mujoco gymnasium[mujoco] mediapy |
| 23 | +``` |
| 24 | + |
| 25 | +That's it. For interactive visualization you also need a display (or use offscreen rendering in notebooks). |
| 26 | + |
| 27 | +### Optional: Conda environment |
| 28 | + |
| 29 | +```bash |
| 30 | +conda create -n mujoco-tut python=3.11 |
| 31 | +conda activate mujoco-tut |
| 32 | +pip install -r requirements.txt |
| 33 | +``` |
| 34 | + |
| 35 | +--- |
| 36 | + |
| 37 | +## Quickstart |
| 38 | + |
| 39 | +```python |
| 40 | +import mujoco |
| 41 | +import mujoco.viewer |
| 42 | + |
| 43 | +model = mujoco.MjModel.from_xml_string(""" |
| 44 | +<mujoco> |
| 45 | + <worldbody> |
| 46 | + <light pos="0 0 3" dir="0 0 -1"/> |
| 47 | + <geom type="plane" size="5 5 0.1"/> |
| 48 | + <body pos="0 0 2"> |
| 49 | + <joint type="free"/> |
| 50 | + <geom type="sphere" size="0.2" rgba="1 0 0 1"/> |
| 51 | + </body> |
| 52 | + </worldbody> |
| 53 | +</mujoco> |
| 54 | +""") |
| 55 | +data = mujoco.MjData(model) |
| 56 | + |
| 57 | +# Launch interactive viewer |
| 58 | +mujoco.viewer.launch(model, data) |
| 59 | +``` |
| 60 | + |
| 61 | +For headless/notebook rendering, see [`examples/offscreen_rendering.py`](examples/offscreen_rendering.py). |
| 62 | + |
| 63 | +--- |
| 64 | + |
| 65 | +## Preview |
| 66 | + |
| 67 | +<p align="center"> |
| 68 | +<img src="img/previews/trajectory_tracking.gif" width="45%" alt="Trajectory Tracking"/> |
| 69 | +<img src="img/previews/lqr_control.gif" width="45%" alt="LQR Cart-Pole"/> |
| 70 | +</p> |
| 71 | +<p align="center"> |
| 72 | +<img src="img/previews/impedance_control.gif" width="45%" alt="Impedance Control"/> |
| 73 | +<img src="img/previews/pick_and_place.gif" width="45%" alt="Pick and Place"/> |
| 74 | +</p> |
| 75 | + |
| 76 | +<p align="center"><em>Left to right: trajectory tracking, LQR balancing, impedance control, pick-and-place</em></p> |
| 77 | + |
| 78 | +--- |
| 79 | + |
| 80 | +## Contents |
| 81 | + |
| 82 | +| Example | Description | |
| 83 | +|---------|-------------| |
| 84 | +| [`examples/projectile.py`](examples/projectile.py) | Projectile with drag force | |
| 85 | +| [`examples/pendulum_control.py`](examples/pendulum_control.py) | PD control of a pendulum | |
| 86 | +| [`examples/double_pendulum.py`](examples/double_pendulum.py) | Double pendulum swing-up control | |
| 87 | +| [`examples/hopper.py`](examples/hopper.py) | 2D hopper with open-loop jumping | |
| 88 | +| [`examples/inverse_kinematics.py`](examples/inverse_kinematics.py) | Damped least-squares IK with Jacobians | |
| 89 | +| [`examples/contact_forces.py`](examples/contact_forces.py) | Reading contact info & forces | |
| 90 | +| [`examples/domain_randomization.py`](examples/domain_randomization.py) | Varying physics params across episodes | |
| 91 | +| [`examples/menagerie_robot.py`](examples/menagerie_robot.py) | Loading robots from MuJoCo Menagerie | |
| 92 | +| [`examples/mjx_parallel.py`](examples/mjx_parallel.py) | GPU-parallel sim with MJX (JAX) | |
| 93 | +| [`examples/gymnasium_env.py`](examples/gymnasium_env.py) | Using Gymnasium's MuJoCo envs | |
| 94 | +| [`examples/offscreen_rendering.py`](examples/offscreen_rendering.py) | Headless rendering & video export | |
| 95 | +| [`examples/trajectory_tracking.py`](examples/trajectory_tracking.py) | Arm follows circular path (task-space PD) | |
| 96 | +| [`examples/operational_space_control.py`](examples/operational_space_control.py) | Full dynamics compensation in task space | |
| 97 | +| [`examples/lqr_control.py`](examples/lqr_control.py) | LQR cart-pole balancing (linearization + Riccati) | |
| 98 | +| [`examples/impedance_control.py`](examples/impedance_control.py) | Compliant end-effector (spring-damper behavior) | |
| 99 | +| [`examples/locomotion_controller.py`](examples/locomotion_controller.py) | Hopper FSM locomotion (finite state machine) | |
| 100 | +| [`examples/pick_and_place.py`](examples/pick_and_place.py) | Gripper pick-and-place with waypoint sequencing | |
| 101 | +| [`examples/record_playback.py`](examples/record_playback.py) | Save/load trajectories (record & replay) | |
| 102 | + |
| 103 | +### Base class |
| 104 | + |
| 105 | +[`mujoco_base.py`](mujoco_base.py) provides a minimal base class for building custom simulations: |
| 106 | + |
| 107 | +```python |
| 108 | +from mujoco_base import MuJoCoBase |
| 109 | + |
| 110 | +class MySim(MuJoCoBase): |
| 111 | + def reset(self): |
| 112 | + pass # set initial conditions |
| 113 | + |
| 114 | + def controller(self, model, data): |
| 115 | + data.ctrl[0] = ... # your control logic |
| 116 | + |
| 117 | +sim = MySim("my_model.xml") |
| 118 | +sim.run() # interactive viewer |
| 119 | +# or |
| 120 | +frames = sim.run_headless(duration=5.0) # offscreen |
| 121 | +``` |
| 122 | + |
| 123 | +--- |
| 124 | + |
| 125 | +## Tutorial Notebooks |
| 126 | + |
| 127 | +Step-by-step Jupyter notebooks (run in Colab or locally): |
| 128 | + |
| 129 | +| Notebook | Topic | |
| 130 | +|----------|-------| |
| 131 | +| [`tutorial/00_what_is_mujoco.ipynb`](tutorial/00_what_is_mujoco.ipynb) | **Start here!** What MuJoCo is, mental model, first simulation | |
| 132 | +| [`tutorial/quickstart.ipynb`](tutorial/quickstart.ipynb) | Zero-install quickstart (Colab-ready) | |
| 133 | +| [`tutorial/01_basics.ipynb`](tutorial/01_basics.ipynb) | MjModel, MjData, named access | |
| 134 | +| [`tutorial/02_rendering.ipynb`](tutorial/02_rendering.ipynb) | Rendering, cameras, scenes | |
| 135 | +| [`tutorial/03_simulation.ipynb`](tutorial/03_simulation.ipynb) | Time stepping, mj_step, mj_forward | |
| 136 | +| [`tutorial/04_control.ipynb`](tutorial/04_control.ipynb) | Actuators, PD control, callbacks | |
| 137 | +| [`tutorial/05_contact.ipynb`](tutorial/05_contact.ipynb) | Collision, contacts, force sensing | |
| 138 | +| [`tutorial/06_xml_modeling.ipynb`](tutorial/06_xml_modeling.ipynb) | MJCF modeling guide | |
| 139 | +| [`tutorial/07_mjx.ipynb`](tutorial/07_mjx.ipynb) | MJX: GPU-parallel simulation with JAX | |
| 140 | +| [`tutorial/08_gymnasium.ipynb`](tutorial/08_gymnasium.ipynb) | MuJoCo + Gymnasium for RL | |
| 141 | +| [`tutorial/09_sensors_and_estimation.ipynb`](tutorial/09_sensors_and_estimation.ipynb) | Sensors, IMU, noise, state estimation | |
| 142 | +| [`tutorial/10_troubleshooting.ipynb`](tutorial/10_troubleshooting.ipynb) | Common errors & how to fix them | |
| 143 | +| [`tutorial/interactive_control.ipynb`](tutorial/interactive_control.ipynb) | 🎮 Interactive PD tuning with sliders | |
| 144 | + |
| 145 | +--- |
| 146 | + |
| 147 | +## Key Concepts |
| 148 | + |
| 149 | +| Concept | Description | |
| 150 | +|---------|-------------| |
| 151 | +| **MJCF** | MuJoCo's XML format for defining models ([docs](https://mujoco.readthedocs.io/en/stable/XMLreference.html)) | |
| 152 | +| **`MjModel`** | Compiled model (static) — physics parameters, geometry | |
| 153 | +| **`MjData`** | Simulation state (dynamic) — positions, velocities, forces | |
| 154 | +| **`mujoco.viewer`** | Built-in interactive 3D viewer | |
| 155 | +| **`mujoco.Renderer`** | Offscreen rendering for headless environments | |
| 156 | +| **MJX** | JAX backend for GPU-parallel simulation ([docs](https://mujoco.readthedocs.io/en/stable/mjx.html)) | |
| 157 | + |
| 158 | +--- |
| 159 | + |
| 160 | +## Resources |
| 161 | + |
| 162 | +- [Official MuJoCo Documentation](https://mujoco.readthedocs.io/) |
| 163 | +- [MuJoCo GitHub](https://github.com/google-deepmind/mujoco) |
| 164 | +- [Gymnasium MuJoCo Environments](https://gymnasium.farama.org/environments/mujoco/) |
| 165 | +- [MuJoCo Menagerie](https://github.com/google-deepmind/mujoco_menagerie) — collection of robot models |
| 166 | +- [MJX Tutorial](https://mujoco.readthedocs.io/en/stable/mjx.html) — GPU-accelerated simulation |
| 167 | + |
| 168 | +--- |
| 169 | + |
| 170 | +## What's Next? 🚀 |
| 171 | + |
| 172 | +Once you've completed these tutorials, explore: |
| 173 | + |
| 174 | +| Resource | What you'll learn | |
| 175 | +|----------|-------------------| |
| 176 | +| [MuJoCo Menagerie](https://github.com/google-deepmind/mujoco_menagerie) | Production-quality robot models (Franka, UR5e, Unitree, etc.) | |
| 177 | +| [dm_control](https://github.com/google-deepmind/dm_control) | DeepMind's control suite — benchmarks for continuous control | |
| 178 | +| [Gymnasium Leaderboard](https://gymnasium.farama.org/environments/mujoco/) | Standard RL benchmarks (HalfCheetah, Humanoid, Ant) | |
| 179 | +| [Brax](https://github.com/google/brax) | Differentiable physics in JAX (alternative to MJX) | |
| 180 | +| [MuJoCo XLA (MJX) Paper](https://arxiv.org/abs/2307.00282) | Technical details of GPU-parallel MuJoCo | |
| 181 | +| [Robosuite](https://robosuite.ai/) | Manipulation benchmarks built on MuJoCo | |
| 182 | +| [IsaacLab](https://github.com/isaac-sim/IsaacLab) | NVIDIA's sim framework (comparison point) | |
| 183 | + |
| 184 | +--- |
| 185 | + |
| 186 | +## Contributing 🤝 |
| 187 | + |
| 188 | +1. Fork this repository |
| 189 | +2. Create a new example in `examples/` with inline MJCF or an XML in `xml/` |
| 190 | +3. Submit a pull request |
| 191 | + |
| 192 | +See [CONTRIBUTING.md](CONTRIBUTING.md) for details. |
| 193 | + |
| 194 | +--- |
| 195 | + |
| 196 | +## License 📃 |
| 197 | + |
| 198 | +MIT — free to use without restrictions. |
0 commit comments