Skip to content

Commit 96b7f38

Browse files
committed
Add MuJoCo Playground environments
1 parent f34b34f commit 96b7f38

71 files changed

Lines changed: 20642 additions & 5 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
- [x] [MyoSuite](https://envpool.readthedocs.io/en/latest/env/myosuite.html)
2424
- [x] [PGX](https://envpool.readthedocs.io/en/latest/env/pgx.html)
2525
- [x] [Jumanji](https://envpool.readthedocs.io/en/latest/env/jumanji.html)
26+
- [x] [MuJoCo Playground](https://envpool.readthedocs.io/en/latest/env/mujoco_playground.html)
2627

2728
Here are EnvPool's several highlights:
2829

573 KB
Loading

docs/env/mujoco_playground.rst

Lines changed: 267 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,267 @@
1+
MuJoCo Playground
2+
=================
3+
4+
EnvPool provides native C++ implementations for the non-DM-Control tasks from
5+
``google-deepmind/mujoco_playground`` tag ``v0.2.0``. This covers all 19
6+
Playground locomotion tasks and all 10 Playground manipulation tasks in that
7+
release. The implementation uses the pinned Playground XMLs together with
8+
``google-deepmind/mujoco_menagerie`` commit
9+
``1b86ece576591213e2b666ebf59508454200ca97`` for robot assets.
10+
11+
MuJoCo Playground also vendors DM Control Suite tasks, but EnvPool already
12+
ships those through the existing :doc:`dm_control` family. They are not
13+
registered again here.
14+
15+
Each task has both the direct task ID and a ``MuJoCoPlayground/`` alias, for
16+
example ``Go1Getup-v1`` and ``MuJoCoPlayground/Go1Getup-v1``.
17+
18+
19+
Task Coverage
20+
-------------
21+
22+
All action spaces are ``Box(-1, 1, dtype=float64)``. All tasks support
23+
``render_mode="rgb_array"`` and pixel-only observations through
24+
``from_pixels=True``.
25+
26+
.. list-table::
27+
:header-rows: 1
28+
:widths: 30 18 23 10 9
29+
30+
* - EnvPool task ID
31+
- Upstream task
32+
- Observation
33+
- Action
34+
- Render
35+
* - ``AlohaHandOver-v1``
36+
- ``AlohaHandOver``
37+
- ``obs`` shape ``(83,)``
38+
- ``(14,)``
39+
- yes
40+
* - ``AlohaSinglePegInsertion-v1``
41+
- ``AlohaSinglePegInsertion``
42+
- ``obs`` shape ``(82,)``
43+
- ``(14,)``
44+
- yes
45+
* - ``ApolloJoystickFlatTerrain-v1``
46+
- ``ApolloJoystickFlatTerrain``
47+
- ``state`` ``(112,)``; ``privileged_state`` ``(224,)``
48+
- ``(32,)``
49+
- yes
50+
* - ``BarkourJoystick-v1``
51+
- ``BarkourJoystick``
52+
- ``obs`` shape ``(465,)``
53+
- ``(12,)``
54+
- yes
55+
* - ``BerkeleyHumanoidJoystickFlatTerrain-v1``
56+
- ``BerkeleyHumanoidJoystickFlatTerrain``
57+
- ``state`` ``(52,)``; ``privileged_state`` ``(114,)``
58+
- ``(12,)``
59+
- yes
60+
* - ``BerkeleyHumanoidJoystickRoughTerrain-v1``
61+
- ``BerkeleyHumanoidJoystickRoughTerrain``
62+
- ``state`` ``(52,)``; ``privileged_state`` ``(114,)``
63+
- ``(12,)``
64+
- yes
65+
* - ``G1JoystickFlatTerrain-v1``
66+
- ``G1JoystickFlatTerrain``
67+
- ``state`` ``(103,)``; ``privileged_state`` ``(216,)``
68+
- ``(29,)``
69+
- yes
70+
* - ``G1JoystickRoughTerrain-v1``
71+
- ``G1JoystickRoughTerrain``
72+
- ``state`` ``(103,)``; ``privileged_state`` ``(216,)``
73+
- ``(29,)``
74+
- yes
75+
* - ``Go1JoystickFlatTerrain-v1``
76+
- ``Go1JoystickFlatTerrain``
77+
- ``state`` ``(48,)``; ``privileged_state`` ``(123,)``
78+
- ``(12,)``
79+
- yes
80+
* - ``Go1JoystickRoughTerrain-v1``
81+
- ``Go1JoystickRoughTerrain``
82+
- ``state`` ``(48,)``; ``privileged_state`` ``(123,)``
83+
- ``(12,)``
84+
- yes
85+
* - ``Go1Getup-v1``
86+
- ``Go1Getup``
87+
- ``state`` ``(42,)``; ``privileged_state`` ``(91,)``
88+
- ``(12,)``
89+
- yes
90+
* - ``Go1Handstand-v1``
91+
- ``Go1Handstand``
92+
- ``state`` ``(45,)``; ``privileged_state`` ``(94,)``
93+
- ``(12,)``
94+
- yes
95+
* - ``Go1Footstand-v1``
96+
- ``Go1Footstand``
97+
- ``state`` ``(45,)``; ``privileged_state`` ``(94,)``
98+
- ``(12,)``
99+
- yes
100+
* - ``H1InplaceGaitTracking-v1``
101+
- ``H1InplaceGaitTracking``
102+
- ``obs`` shape ``(186,)``
103+
- ``(19,)``
104+
- yes
105+
* - ``H1JoystickGaitTracking-v1``
106+
- ``H1JoystickGaitTracking``
107+
- ``obs`` shape ``(113,)``
108+
- ``(19,)``
109+
- yes
110+
* - ``LeapCubeReorient-v1``
111+
- ``LeapCubeReorient``
112+
- ``state`` ``(57,)``; ``privileged_state`` ``(128,)``
113+
- ``(16,)``
114+
- yes
115+
* - ``LeapCubeRotateZAxis-v1``
116+
- ``LeapCubeRotateZAxis``
117+
- ``state`` ``(32,)``; ``privileged_state`` ``(105,)``
118+
- ``(16,)``
119+
- yes
120+
* - ``Op3Joystick-v1``
121+
- ``Op3Joystick``
122+
- ``obs`` shape ``(147,)``
123+
- ``(20,)``
124+
- yes
125+
* - ``PandaPickCube-v1``
126+
- ``PandaPickCube``
127+
- ``obs`` shape ``(66,)``
128+
- ``(8,)``
129+
- yes
130+
* - ``PandaPickCubeCartesian-v1``
131+
- ``PandaPickCubeCartesian``
132+
- ``obs`` shape ``(70,)``
133+
- ``(3,)``
134+
- yes
135+
* - ``PandaPickCubeOrientation-v1``
136+
- ``PandaPickCubeOrientation``
137+
- ``obs`` shape ``(66,)``
138+
- ``(8,)``
139+
- yes
140+
* - ``PandaOpenCabinet-v1``
141+
- ``PandaOpenCabinet``
142+
- ``obs`` shape ``(55,)``
143+
- ``(8,)``
144+
- yes
145+
* - ``PandaRobotiqPushCube-v1``
146+
- ``PandaRobotiqPushCube``
147+
- ``obs`` shape ``(48,)``
148+
- ``(7,)``
149+
- yes
150+
* - ``AeroCubeRotateZAxis-v1``
151+
- ``AeroCubeRotateZAxis``
152+
- ``state`` ``(14,)``; ``privileged_state`` ``(81,)``
153+
- ``(7,)``
154+
- yes
155+
* - ``SpotFlatTerrainJoystick-v1``
156+
- ``SpotFlatTerrainJoystick``
157+
- ``state`` ``(81,)``; ``privileged_state`` ``(167,)``
158+
- ``(12,)``
159+
- yes
160+
* - ``SpotGetup-v1``
161+
- ``SpotGetup``
162+
- ``obs`` shape ``(30,)``
163+
- ``(12,)``
164+
- yes
165+
* - ``SpotJoystickGaitTracking-v1``
166+
- ``SpotJoystickGaitTracking``
167+
- ``obs`` shape ``(69,)``
168+
- ``(12,)``
169+
- yes
170+
* - ``T1JoystickFlatTerrain-v1``
171+
- ``T1JoystickFlatTerrain``
172+
- ``state`` ``(85,)``; ``privileged_state`` ``(180,)``
173+
- ``(23,)``
174+
- yes
175+
* - ``T1JoystickRoughTerrain-v1``
176+
- ``T1JoystickRoughTerrain``
177+
- ``state`` ``(85,)``; ``privileged_state`` ``(180,)``
178+
- ``(23,)``
179+
- yes
180+
181+
182+
Render
183+
------
184+
185+
Rendering is implemented in C++ through EnvPool's MuJoCo
186+
``OffscreenRenderer``. The Playground env owns the same ``mjModel`` and
187+
``mjData`` used by stepping; ``env.render()`` draws directly from that native
188+
state. Pixel-observation variants render once per reset or step, update the
189+
frame stack, and cache that same frame so a same-step ``env.render()`` call
190+
returns the identical image.
191+
192+
The render API supports ``render_mode="rgb_array"``, ``render_width``,
193+
``render_height``, and ``render_camera_id``. If no explicit render size is
194+
requested, ``env.render()`` uses 480 by 480 pixels. Pixel observations default
195+
to 84 by 84 pixels.
196+
197+
Like other native MuJoCo environments in EnvPool, MuJoCo Playground also
198+
supports pixel-only observations through ``from_pixels=True``. In that mode the
199+
public observation is ``obs["pixels"]`` with channel-first shape
200+
``(3 * frame_stack, render_height, render_width)`` and dtype ``uint8``; the
201+
state and privileged-state vectors are not returned as observations.
202+
203+
.. code-block:: python
204+
205+
import envpool
206+
207+
env = envpool.make_gymnasium(
208+
"Go1JoystickFlatTerrain-v1",
209+
num_envs=8,
210+
from_pixels=True,
211+
frame_stack=3,
212+
render_width=84,
213+
render_height=84,
214+
render_mode="rgb_array",
215+
)
216+
obs, info = env.reset()
217+
218+
The reset-frame comparison below places EnvPool on the left and the official
219+
MuJoCo Playground renderer on the right. The documentation image is generated
220+
by syncing the official renderer from EnvPool's reset ``qpos`` and ``qvel``
221+
debug fields, so both sides render the same MuJoCo state. The comparison
222+
ignores RGB channel deltas up to 3/255 when counting mismatched pixels, while
223+
still enforcing a bounded raw mean absolute difference.
224+
225+
For ``Op3Joystick-v1`` the official render-side model is loaded from the
226+
filesystem XML/assets instead of MuJoCo Playground's in-memory asset dict.
227+
OP3's visual meshes and simplified collision meshes share STL basenames, and
228+
MuJoCo's asset dict cannot represent both at once without collapsing the visual
229+
model to the simplified collision mesh. The filesystem path keeps the same
230+
pinned XML and menagerie assets while preserving the intended visual meshes.
231+
232+
.. image:: ../_static/render_samples/mujoco_playground_official_compare.png
233+
:width: 900px
234+
:align: center
235+
236+
Regenerate the image with:
237+
238+
.. code-block:: bash
239+
240+
bazel run --config=debug //scripts:render_compare -- \
241+
--family=mujoco_playground \
242+
--columns=4 \
243+
--source-width=480 \
244+
--source-height=360 \
245+
--tile-width=144 \
246+
--tile-height=108 \
247+
--max-mean-abs-diff=4.2 \
248+
--max-mismatch-ratio=0.15 \
249+
--max-ignored-abs-diff=3
250+
251+
252+
Validation
253+
----------
254+
255+
The native implementation is checked against the official MuJoCo Playground
256+
Python oracle. The coverage test compares EnvPool's Playground registry against
257+
the pinned upstream ``locomotion.ALL_ENVS`` and ``manipulation.ALL_ENVS`` lists;
258+
the vendored DM Control Suite registry is intentionally excluded.
259+
260+
The alignment test reset-syncs MuJoCo state once, then drives both
261+
implementations with the same external actions and compares observations,
262+
rewards, termination flags, truncation flags, and exposed info fields.
263+
264+
Rendering is checked separately on reset and for the first three control steps
265+
against the official MuJoCo renderer using the same synchronized state. The
266+
test keeps per-task pixel budgets narrow because OpenGL rasterization can leave
267+
small backend-dependent edge differences even when the MuJoCo state is aligned.

docs/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ stable version through `envpool.readthedocs.io/en/stable/
103103
env/procgen
104104
env/toy_text
105105
env/vizdoom
106+
env/mujoco_playground
106107

107108

108109
Indices and tables

docs/spelling_wordlist.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,3 +106,6 @@ deleter
106106
gfootball
107107
minimap
108108
rollouts
109+
filesystem
110+
basenames
111+
vendored

envpool/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ py_library(
4444
"//envpool/mujoco:mujoco_dmc_registration",
4545
"//envpool/mujoco:mujoco_gym_registration",
4646
"//envpool/mujoco:myosuite_registration",
47+
"//envpool/mujoco:playground_registration",
4748
"//envpool/mujoco:robotics_registration",
4849
"//envpool/pgx:pgx_registration",
4950
"//envpool/procgen:procgen_registration",

envpool/entry.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import envpool.mujoco.gym.registration # noqa: F401
2525
import envpool.mujoco.metaworld.registration # noqa: F401
2626
import envpool.mujoco.myosuite.registration # noqa: F401
27+
import envpool.mujoco.playground.registration # noqa: F401
2728
import envpool.mujoco.robotics.registration # noqa: F401
2829
import envpool.pgx.registration # noqa: F401
2930
import envpool.procgen.registration # noqa: F401

0 commit comments

Comments
 (0)