{
"cells": [
{
"cell_type": "markdown",
"id": "9ad05586",
"metadata": {},
"source": [
"# MuJoCo Quickstart 🤖\n",
"\n",
"This notebook gets you running MuJoCo simulations in Google Colab with zero setup."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e98d4497",
"metadata": {},
"outputs": [],
"source": [
"!pip install -q mujoco mediapy"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "eb91cdc1",
"metadata": {},
"outputs": [],
"source": [
"import mujoco\n",
"import numpy as np\n",
"import mediapy\n",
"\n",
"print(f\"MuJoCo version: {mujoco.__version__}\")"
]
},
{
"cell_type": "markdown",
"id": "748cc7fd",
"metadata": {},
"source": [
"## 1. Define a model in MJCF (XML)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a0400644",
"metadata": {},
"outputs": [],
"source": [
"XML = \"\"\"\n",
"\n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
"\n",
"\"\"\"\n",
"\n",
"model = mujoco.MjModel.from_xml_string(XML)\n",
"data = mujoco.MjData(model)\n",
"print(f\"Model has {model.nq} DOFs, timestep = {model.opt.timestep}s\")"
]
},
{
"cell_type": "markdown",
"id": "628ad5c8",
"metadata": {},
"source": [
"## 2. Simulate and render"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e0d7df1c",
"metadata": {},
"outputs": [],
"source": [
"renderer = mujoco.Renderer(model, height=480, width=640)\n",
"frames = []\n",
"fps = 30\n",
"duration = 2.0\n",
"\n",
"mujoco.mj_resetData(model, data)\n",
"data.qvel[0] = 3.0 # initial x velocity\n",
"\n",
"while data.time < duration:\n",
" mujoco.mj_step(model, data)\n",
" if len(frames) < data.time * fps:\n",
" renderer.update_scene(data)\n",
" frames.append(renderer.render().copy())\n",
"\n",
"renderer.close()\n",
"mediapy.show_video(frames, fps=fps)"
]
},
{
"cell_type": "markdown",
"id": "3643a3c8",
"metadata": {},
"source": [
"## 3. Add a controller\n",
"\n",
"Let's control a pendulum with a PD controller."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "383e9e5e",
"metadata": {},
"outputs": [],
"source": [
"PENDULUM_XML = \"\"\"\n",
"\n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
"\n",
"\"\"\"\n",
"\n",
"model = mujoco.MjModel.from_xml_string(PENDULUM_XML)\n",
"data = mujoco.MjData(model)\n",
"renderer = mujoco.Renderer(model, height=480, width=640)\n",
"\n",
"target = np.pi / 4 # 45 degrees\n",
"kp, kd = 50.0, 10.0\n",
"frames = []\n",
"\n",
"while data.time < 5.0:\n",
" # PD control\n",
" data.ctrl[0] = kp * (target - data.qpos[0]) - kd * data.qvel[0]\n",
" mujoco.mj_step(model, data)\n",
" if len(frames) < data.time * fps:\n",
" renderer.update_scene(data)\n",
" frames.append(renderer.render().copy())\n",
"\n",
"renderer.close()\n",
"mediapy.show_video(frames, fps=fps)"
]
},
{
"cell_type": "markdown",
"id": "03802786",
"metadata": {},
"source": [
"## Next Steps\n",
"\n",
"- [MJCF Reference](https://mujoco.readthedocs.io/en/stable/XMLreference.html) — build your own models\n",
"- [Gymnasium MuJoCo envs](https://gymnasium.farama.org/environments/mujoco/) — RL-ready environments\n",
"- [MJX](https://mujoco.readthedocs.io/en/stable/mjx.html) — GPU-parallel simulation with JAX\n",
"- [MuJoCo Menagerie](https://github.com/google-deepmind/mujoco_menagerie) — robot model zoo"
]
}
],
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}