{
"cells": [
{
"cell_type": "markdown",
"id": "b92d071c",
"metadata": {},
"source": [
"[](https://colab.research.google.com/github/tayalmanan28/MuJoCo-Tutorial/blob/main/tutorial/01_basics.ipynb)\n",
"\n",
"# Tutorial 1: MuJoCo Basics\n",
"\n",
"Learn the fundamentals: loading models, `MjModel`, `MjData`, and named access.\n",
"\n",
"**Prerequisites:** [Tutorial 00: What is MuJoCo?](00_what_is_mujoco.ipynb) — you should already understand:\n",
"- The Describe → Simulate → Observe pattern\n",
"- `MjModel` = blueprint (constant), `MjData` = state (changes)\n",
"- `qpos`/`qvel` = positions/velocities of all joints\n",
"\n",
"This tutorial goes deeper into **inspecting** models and accessing data by name."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "228e3d53",
"metadata": {},
"outputs": [],
"source": [
"!pip install -q mujoco mediapy"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "740c860e",
"metadata": {},
"outputs": [],
"source": [
"import mujoco\n",
"import numpy as np\n",
"import mediapy as media\n",
"\n",
"print(f\"MuJoCo version: {mujoco.__version__}\")"
]
},
{
"cell_type": "markdown",
"id": "8b6c46a6",
"metadata": {},
"source": [
"## Loading a Model\n",
"\n",
"MuJoCo models are defined in [MJCF](https://mujoco.readthedocs.io/en/stable/XMLreference.html) (XML format).\n",
"The smallest valid model is ``. Let's define a simple scene:"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "7edcd2d6",
"metadata": {},
"outputs": [],
"source": [
"xml = \"\"\"\n",
"\n",
" \n",
" \n",
" \n",
" \n",
"\n",
"\"\"\"\n",
"model = mujoco.MjModel.from_xml_string(xml)\n",
"print(f\"Number of geoms: {model.ngeom}\")"
]
},
{
"cell_type": "markdown",
"id": "05459851",
"metadata": {},
"source": [
"## MjModel — The Static Description\n",
"\n",
"`MjModel` contains everything that **doesn't change** during simulation:\n",
"geometry sizes, masses, joint types, colors, etc."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b036caeb",
"metadata": {},
"outputs": [],
"source": [
"# Number of geoms and their RGBA colors\n",
"print(f\"ngeom: {model.ngeom}\")\n",
"print(f\"geom_rgba:\\n{model.geom_rgba}\")"
]
},
{
"cell_type": "markdown",
"id": "39d41b27",
"metadata": {},
"source": [
"## Named Access\n",
"\n",
"The Python bindings provide convenient named accessors:"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "da7aa51d",
"metadata": {},
"outputs": [],
"source": [
"# Access by name\n",
"print(\"green_sphere rgba:\", model.geom('green_sphere').rgba)\n",
"print(\"green_sphere id:\", model.geom('green_sphere').id)\n",
"print(\"geom 0 name:\", model.geom(0).name)\n",
"\n",
"# List all geom names\n",
"print(\"All geoms:\", [model.geom(i).name for i in range(model.ngeom)])"
]
},
{
"cell_type": "markdown",
"id": "38892698",
"metadata": {},
"source": [
"## MjData — The Dynamic State\n",
"\n",
"`MjData` contains the simulation **state** (time, positions, velocities)\n",
"and derived quantities (Cartesian positions, forces, etc.)."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "42c69688",
"metadata": {},
"outputs": [],
"source": [
"data = mujoco.MjData(model)\n",
"\n",
"# Derived quantities need explicit computation\n",
"print(\"Before mj_kinematics:\", data.geom_xpos)\n",
"\n",
"mujoco.mj_kinematics(model, data)\n",
"print(\"After mj_kinematics:\", data.geom_xpos)\n",
"print(\"green_sphere pos:\", data.geom('green_sphere').xpos)"
]
},
{
"cell_type": "markdown",
"id": "16ef6897",
"metadata": {},
"source": [
"## Key Takeaways\n",
"\n",
"- `MjModel` = static description (compiled from XML)\n",
"- `MjData` = dynamic state + derived quantities\n",
"- Use `mj_forward()` or `mj_kinematics()` to propagate state before reading derived quantities\n",
"- Named access: `model.geom('name')`, `data.body('name')`, etc."
]
}
],
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}