|
| 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. |
0 commit comments