From dc98ae978d8337e014f411eb36acb2ca709a572f Mon Sep 17 00:00:00 2001 From: Yuval Tassa Date: Tue, 25 Feb 2025 05:19:46 -0800 Subject: [PATCH] Publicize the rollout notebook, small improvements to plotting. PiperOrigin-RevId: 730841667 Change-Id: Id365f21cee078f28cb3fa797701c3c5a409607cd --- README.md | 2 ++ doc/images/python/rollout.png | Bin 0 -> 46402 bytes doc/python.rst | 17 +++++++--- python/rollout.ipynb | 60 ++++++++++++++++++---------------- 4 files changed, 46 insertions(+), 33 deletions(-) create mode 100644 doc/images/python/rollout.png diff --git a/README.md b/README.md index d5f5a27f..db022581 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,8 @@ running on Google Colab: - The **introductory** tutorial teaches MuJoCo basics: [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/google-deepmind/mujoco/blob/main/python/tutorial.ipynb) + - The **rollout** tutorial shows how to use the multithreaded `rollout` module: + [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/google-deepmind/mujoco/blob/main/python/rollout.ipynb) - The **LQR** tutorial synthesizes a linear-quadratic controller, balancing a humanoid on one leg: [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/google-deepmind/mujoco/blob/main/python/LQR.ipynb) - The **least-squares** tutorial explains how to use the Python-based nonlinear least-squares solver: diff --git a/doc/images/python/rollout.png b/doc/images/python/rollout.png new file mode 100644 index 0000000000000000000000000000000000000000..9901e6870b845a664daec4c03c0c74ade7f878af GIT binary patch literal 46402 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 A`v3p{ literal 0 HcmV?d00001 diff --git a/doc/python.rst b/doc/python.rst index e2fb7dbc..163d7896 100644 --- a/doc/python.rst +++ b/doc/python.rst @@ -736,15 +736,24 @@ The ``mujoco`` package contains two sub-modules: ``mujoco.rollout`` and ``mujoco rollout ------- - ``mujoco.rollout`` and ``mujoco.rollout.Rollout`` shows how to add additional C/C++ functionality, exposed as a Python module via pybind11. It is implemented in `rollout.cc `__ and wrapped in `rollout.py -`__. The module performs a common -functionality where tight loops implemented outside of Python are beneficial: rolling out a trajectory (i.e., calling +`__. The module addresses a common +use-case where tight loops implemented outside of Python are beneficial: rolling out a trajectory (i.e., calling :ref:`mj_step` in a loop), given an initial state and sequence of controls, and returning subsequent states and sensor values. The rollouts are run in parallel with an internally managed thread pool if multiple MjData instances (one per -thread) are passed as an argument. The basic usage form is +thread) are passed as an argument. This notebook shows how to use ``rollout`` |rollout_colab|, along with some +benchmarks e.g., the figure below. + +.. |rollout_colab| image:: https://colab.research.google.com/assets/colab-badge.svg + :target: https://colab.research.google.com/github/google-deepmind/mujoco/blob/main/python/rollout.ipynb + +.. image:: images/python/rollout.png + :align: right + :width: 97% + +The basic usage form is .. code-block:: python diff --git a/python/rollout.ipynb b/python/rollout.ipynb index fb559c3d..61b21ffc 100644 --- a/python/rollout.ipynb +++ b/python/rollout.ipynb @@ -51,7 +51,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 0, "id": "0f9fbad1-59d0-40ac-b2b6-99f37313670f", "metadata": { "editable": true, @@ -166,7 +166,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 0, "id": "082482c7", "metadata": { "editable": true, @@ -288,7 +288,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 0, "id": "849b93e5", "metadata": { "id": "849b93e5" @@ -392,7 +392,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 0, "id": "9cd2f94a-11df-4247-986c-5a56af69a1f5", "metadata": { "id": "9cd2f94a-11df-4247-986c-5a56af69a1f5" @@ -418,7 +418,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 0, "id": "849af5f2-9de1-4cb9-bc3a-c9b7acf0e3fe", "metadata": { "id": "849af5f2-9de1-4cb9-bc3a-c9b7acf0e3fe" @@ -463,7 +463,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 0, "id": "957b8566-da31-410b-b385-e78241c5247a", "metadata": { "id": "957b8566-da31-410b-b385-e78241c5247a" @@ -497,7 +497,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 0, "id": "7c39e79e-8942-4fea-b306-ea0cb3c826e2", "metadata": { "id": "7c39e79e-8942-4fea-b306-ea0cb3c826e2" @@ -578,7 +578,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 0, "id": "b8a5d3d4-24e7-41a1-b3bd-7b63c1812b03", "metadata": { "id": "b8a5d3d4-24e7-41a1-b3bd-7b63c1812b03" @@ -610,7 +610,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 0, "id": "2a184873-8d24-45da-b444-8d21f5dcd733", "metadata": { "id": "2a184873-8d24-45da-b444-8d21f5dcd733" @@ -676,7 +676,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 0, "id": "4b02bb61-912d-47de-a956-aadfcd4c5cd5", "metadata": { "id": "4b02bb61-912d-47de-a956-aadfcd4c5cd5" @@ -747,7 +747,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 0, "id": "d02cc8e8-63cd-4852-ab3c-364a18025a95", "metadata": { "id": "d02cc8e8-63cd-4852-ab3c-364a18025a95" @@ -820,7 +820,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 0, "id": "dd05bbdf-f389-4e4e-b389-d47fe976cb49", "metadata": { "id": "dd05bbdf-f389-4e4e-b389-d47fe976cb49" @@ -875,7 +875,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 0, "id": "b6aa6801", "metadata": { "id": "b6aa6801" @@ -908,7 +908,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 0, "id": "7f46a6d8", "metadata": { "id": "7f46a6d8" @@ -941,7 +941,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 0, "id": "a1be8f93", "metadata": { "id": "a1be8f93" @@ -1004,7 +1004,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 0, "id": "d4d9f660-f83c-432e-a579-124a7ecab4fb", "metadata": { "id": "d4d9f660-f83c-432e-a579-124a7ecab4fb" @@ -1098,7 +1098,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 0, "id": "cb6355dd", "metadata": { "id": "cb6355dd" @@ -1128,7 +1128,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 0, "id": "74f143e2", "metadata": { "id": "74f143e2" @@ -1155,7 +1155,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 0, "id": "0301e3ee", "metadata": { "cellView": "form", @@ -1253,6 +1253,7 @@ " ax1.set_xticks(x + width, nbatch)\n", " ax1.yaxis.set_major_formatter(ticker)\n", " ax1.grid()\n", + " ax1.set_axisbelow(True)\n", " ax1.set_xlabel('nbatch')\n", " ax1.set_ylabel('steps per second')\n", " ax1.set_title(f'nbatch varied, nstep = {nominal_nstep}')\n", @@ -1268,11 +1269,12 @@ " ax2.set_xticks(x + width, nstep)\n", " ax2.yaxis.set_major_formatter(ticker)\n", " ax2.grid()\n", + " ax2.set_axisbelow(True)\n", " ax2.set_xlabel('nstep')\n", " ax2.set_title(f'nstep varied, nbatch = {nominal_nbatch}')\n", "\n", - " ax2.legend(loc=(1.04, 0.0))\n", - " fig.set_size_inches(10, 4)\n", + " ax1.legend(loc=(0.03, 0.8))\n", + " fig.set_size_inches(10, 5)\n", " plt.suptitle(title)\n", " plt.tight_layout()" ] @@ -1289,7 +1291,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 0, "id": "f7e54830", "metadata": { "id": "f7e54830" @@ -1321,7 +1323,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 0, "id": "c9e58c6c", "metadata": { "id": "c9e58c6c" @@ -1353,7 +1355,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 0, "id": "83d775d4", "metadata": { "id": "83d775d4" @@ -1404,7 +1406,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 0, "id": "7c86d157", "metadata": { "cellView": "form", @@ -1538,7 +1540,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 0, "id": "98c580b0", "metadata": { "id": "98c580b0" @@ -1567,7 +1569,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 0, "id": "53166ae1", "metadata": { "id": "53166ae1" @@ -1602,7 +1604,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 0, "id": "3d6be608", "metadata": { "id": "3d6be608" @@ -1654,7 +1656,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 0, "id": "b6c5fc2e", "metadata": { "id": "b6c5fc2e"