mujoco 3.2.4 → 3.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/README.md +0 -410
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mujoco",
3
- "version": "3.2.4",
3
+ "version": "3.2.5",
4
4
  "description": "MuJoCo WASM bindings",
5
5
  "repository": {
6
6
  "type": "git",
package/README.md DELETED
@@ -1,410 +0,0 @@
1
- # MuJoCo JavaScript Bindings
2
-
3
- These are the canonical JavaScript and TypeScript bindings for the MuJoCo
4
- physics engine.
5
-
6
- This package provides a high-level API that allows you to interact with the core
7
- MuJoCo engine compiled into a high-performance WebAssembly (WASM) module. These
8
- bindings are developed and maintained by Google DeepMind and are always up to
9
- date with the latest developments in MuJoCo. For brevity, the documentation
10
- below will often refer to “JavaScript” but the concepts apply equally to
11
- TypeScript.
12
-
13
- > [!IMPORTANT]
14
- > _These bindings are still a WIP. For details, see the [Future Work](#future-work)
15
- > section. Also note that development has primarily taken place on Linux using
16
- > Google Chrome. If you're working on a different OS or browser, you may
17
- > encounter some rough edges. We have successfully tested the bindings on MacOS
18
- > in CI but as of November 13th 2025 Windows in untested (the instructions here
19
- > have worked on one Windows 11 machine but have failed on other machines)._
20
-
21
- ## Prerequisites
22
-
23
- > [!NOTE]
24
- > Run all the commands in this README from the top-level directory.
25
-
26
- - To compile the [`bindings.cc`](codegen/generated/bindings.cc) file, which
27
- generates the `.wasm` WebAssembly file, `.js` JavaScript import, and `.d.ts`
28
- TypeScript declaration file, you will need Emscripten SDK version `4.0.10`.
29
- Later versions may work but are untested. To set up the SDK, do the
30
- following, you can run this anywhere but the rest of the commands in this
31
- README only work in the shell where you source the `emsdk_env.sh` script.
32
-
33
- ```sh
34
- git clone https://github.com/emscripten-core/emsdk.git
35
- ./emsdk/emsdk install 4.0.10
36
- ./emsdk/emsdk activate 4.0.10
37
- source ./emsdk/emsdk_env.sh
38
- ```
39
-
40
- - To easily run the JavaScript tests and the demo application, `node` and `npm`
41
- are required. We recommend managing these using
42
- [nvm](https://github.com/nvm-sh/nvm). There are also various JavaScript
43
- dependencies needed for the tests, demo, and bindings build process. These
44
- dependencies are expected to be located in the `wasm` folder. To install
45
- them and ensure they can be found by later commands, run the following:
46
-
47
- ```sh
48
- npm install --prefix ./wasm
49
- export PATH="$(pwd)/wasm/node_modules/.bin:$PATH"
50
- ```
51
-
52
- - To modify the bindings `python3` is required because the [`bindings.cc`](codegen/generated/bindings.cc)
53
- file is generated by a Python script. To run the bindings generator tests,
54
- `absl` is required and `pytest` will be helpful. Set up a Python environment
55
- with these dependencies as follows:
56
-
57
- ```sh
58
- python3 -m venv .venv
59
- source .venv/bin/activate
60
- pip install -r python/build_requirements.txt
61
- ```
62
-
63
- > [!TIP]
64
- > _Emscripten is well-documented. We recommend reading the sections covering the
65
- > [Emscripten Compiler Settings](https://emscripten.org/docs/tools_reference/settings_reference.html),
66
- > the [Emscripten SDK](https://emscripten.org/docs/tools_reference/emsdk.html),
67
- > and the [Embind](https://emscripten.org/docs/porting/connecting_cpp_and_javascript/embind.html)
68
- > library. To understand the limitations and caveats related to using the
69
- > browser as a platform, see the
70
- > [Porting](https://emscripten.org/docs/porting/index.html#porting) section._
71
-
72
- ## User Guide
73
-
74
- ### Bindings Generation
75
-
76
- The [`bindings.cc`](codegen/generated/bindings.cc) file is compiled to generate
77
- to `.wasm` WebAssembly file, `.js` JavaScript import, and `.d.ts` TypeScript
78
- declaration file. These are the files you'll use to call MuJoCo from JavaScript.
79
- To generate them ensure the npm and Emscripten SDK prerequisites are set up and
80
- then run the following:
81
-
82
- ```sh
83
- emcmake cmake -B build && cmake --build build
84
- ```
85
-
86
- This command will generate the following folders under the project root:
87
-
88
- - `build`: contains MuJoCo compiled using Emscripten.
89
- - `wasm/dist`: contains the WebAssembly module, `.js` and `.d.ts` files.
90
-
91
- ### Example Application
92
-
93
- After generating the bindings you will be ready to write web applications using
94
- MuJoCo. We have provided a basic web application that uses Three.js to render a
95
- simple simulation, to try it run this command:
96
-
97
- ```sh
98
- npm run dev:demo --prefix ./wasm
99
- ```
100
-
101
- You may prefer to write your entire app in C++ and compile it using Emscripten.
102
- If you do this, you won’t need to use these bindings, since you’ll be writing
103
- minimal JavaScript, and the granularity of these bindings may be inappropriate
104
- (e.g., you might want to call multiple MuJoCo functions in the C++ callback
105
- invoked by `requestAnimationFrame`).
106
-
107
- We have also found that a hybrid approach can be helpful, as it is often more
108
- convenient to work with browser APIs directly in JavaScript. If you choose to
109
- write your application in C++ and compile it using Emscripten, you may want to
110
- copy a subset of the `EMSCRIPTEN_BINDINGS` from `bindings.cc` into your
111
- application’s source file.
112
-
113
- ### Named Access
114
-
115
- The bindings support named access methods, similar to the Python bindings,
116
- allowing convenient access to model and data elements by name or index. For
117
- example, you can access a geometry by name using `model.geom('mygeom')` or a
118
- joint using `data.jnt('myjoint')`.
119
-
120
- For more details and examples of how to use named access, please refer to the [named access tests](tests/bindings_test.ts#L1876-L2378) and [documentation](https://mujoco.readthedocs.io/en/stable/python.html#named-access).
121
-
122
- ## Usage Guide
123
- When interacting with MuJoCo objects through the WASM bindings, it's important to understand how data is accessed. Properties on objects like `MjModel` and `MjData` can expose data in two ways: by copy or by reference.
124
-
125
- ### Install
126
- ```sh
127
- npm install mujoco
128
- ```
129
-
130
- ```ts
131
- import loadMujoco from 'mujoco';
132
-
133
- const mujoco = await loadMujoco();
134
-
135
- const model = mujoco.MjModel.fromXMLString(`
136
- <mujoco>
137
- <worldbody>
138
- <geom type="sphere" size="0.1"/>
139
- </worldbody>
140
- </mujoco>
141
- `);
142
-
143
- const data = new mujoco.MjData(model);
144
- mujoco.mj_step(model, data);
145
- ```
146
-
147
- ### Copy vs. Reference
148
-
149
- #### 1. By Copy (Value-based access)
150
-
151
- Some properties return a copy of the data at the time of access. This is common for complex data structures that need to be marshalled from C++ to JavaScript.
152
-
153
- A key example is `MjData.contact`. When you access `data.contact`, you get a new array containing the contacts at that specific moment in the simulation. If you step the simulation forward, this array will not be updated. You must access `data.contact` again to get the new contact information.
154
-
155
- Example:
156
- ```typescript
157
- // Gets contacts at the current time.
158
- const contacts = data.contact;
159
-
160
- // Step the simulation
161
- mujoco.mj_step(model, data);
162
-
163
- // `contacts` is now stale. To get the new contacts, you must access the property again:
164
- const newContacts = data.contact;
165
- ```
166
-
167
- #### 2. By Reference (View-based access)
168
- Many properties, especially large numerical arrays, return a live view directly into the WebAssembly memory. This is highly efficient as it avoids copying large amounts of data.
169
-
170
- A key example is `MjData.qpos` (joint positions). When you get a reference to this array, it points directly to the simulation's state data. Any changes in the simulation (e.g., after a call to `mj_step`) will be immediately reflected in this array.
171
-
172
- ```typescript
173
- // `qpos` is a live view into the simulation state.
174
- const qpos = data.qpos;
175
-
176
- console.log(qpos[0]); // Print initial position
177
-
178
- // Step the simulation
179
- mujoco.mj_step(model, data);
180
-
181
- // `qpos` is automatically updated.
182
- console.log(qpos[0]); // Print new position
183
- ```
184
-
185
- ### Data Layout: Row-Major Matrices
186
- When a function from the MuJoCo C API returns a matrix (or needs a matrix as input), these are represented in the JavaScript bindings as flat, one-dimensional `TypedArray`'s. The elements are stored in row-major order.
187
-
188
- For example, a 3x10 matrix will be returned as a flat array with 30 elements. The first 10 elements represent the first row, the next 10 represent the second row, and so on.
189
-
190
- Example: Accessing an element at `(row, col)`
191
- ```typescript
192
- // A 3x10 matrix stored as a flat array.
193
- const matrix: Float64Array = ...;
194
- const nRows = 3;
195
- const nCols = 10;
196
-
197
- // To access the element at row `i` and column `j`:
198
- const element = matrix[i * nCols + j];
199
- ```
200
-
201
- ### Working with Out Parameters
202
- Many functions in the MuJoCo C API use "out parameters" to return data. This means instead of returning a value, they write the result into one of the arguments passed to them by reference (using pointers). In our JavaScript bindings, you'll need to handle these cases specifically.
203
-
204
- There are two main scenarios you'll encounter:
205
-
206
- #### 1. Array-like Out Parameters
207
- When a function expects a pointer to a primitive type (like `mjtNum*` or `int*`) to write an array of values, you need to pre-allocate memory for the result on the JavaScript side. We provide helper classes for this: `mujoco.Uint8Buffer`, `mujoco.DoubleBuffer`, `mujoco.FloatBuffer`, and `mujoco.IntBuffer`.
208
-
209
- Here's how to use them:
210
-
211
- 1. Create a buffer: Instantiate the appropriate buffer class with an initial array of the correct size (e.g., an array of zeros).
212
- 2. Call the function: Pass the buffer instance to the function as the out parameter.
213
- 3. Access the result: Use the `.getView()` method on the buffer to get a `TypedArray` view of the data written by the C++ function.
214
- 4. Free the memory: When you are done with the buffer, you must call the `.delete()` method to free the underlying memory and prevent memory leaks.
215
-
216
- Example: Rotating a vector
217
-
218
- The function `mju_rotVecQuat` rotates a vector `vec` by a quaternion `quat` and stores the result in the `res` out parameter.
219
-
220
- ```typescript
221
- // Create a buffer to hold the 3D vector result.
222
- const res = new mujoco.DoubleBuffer([0, 0, 0]);
223
-
224
- const vec = [1, 0, 0];
225
- const quat = [0.707, 0, 0, 0.707]; // 90-degree rotation around z-axis
226
-
227
- try {
228
- // Call the function with the buffer as the out parameter.
229
- mujoco.mju_rotVecQuat(res, vec, quat);
230
-
231
- // Get the result as a Float64Array.
232
- const resultView = res.getView();
233
- console.log(resultView); // Expected: approximately [0, 1, 0]
234
-
235
- } finally {
236
- // IMPORTANT: Free the memory allocated for the buffer.
237
- res.delete();
238
- }
239
- ```
240
-
241
- #### 2. Struct Out Parameters (e.g., mjvCamera*, mjvScene*)
242
- When a function modifies a struct passed by pointer, you should pass an instance of the corresponding JavaScript wrapper class. The underlying C++ struct will be modified in place.
243
-
244
- Example: Updating a scene
245
-
246
- The function `mjv_updateScene` populates an `mjvScene` object with information from `mjModel` and `mjData`.
247
- ```typescript
248
- // Create instances of the necessary structs.
249
- const model = mujoco.MjModel.loadFromXML(xmlContent);
250
- const data = new mujoco.MjData(model);
251
- const scene = new mujoco.MjvScene(model, 1000);
252
- const option = new mujoco.MjvOption();
253
- const perturb = new mujoco.MjvPerturb();
254
- const camera = new mujoco.MjvCamera();
255
-
256
- // ... (step simulation, etc.)
257
-
258
- // Update the scene. The 'scene' object is modified by the function.
259
- mujoco.mjv_updateScene(
260
- model,
261
- data,
262
- option,
263
- perturb,
264
- camera,
265
- mujoco.mjtCatBit.mjCAT_ALL.value,
266
- scene
267
- );
268
-
269
- console.log('Number of geoms in scene:', scene.ngeom);
270
-
271
- // Remember to delete all created objects when they are no longer needed.
272
- scene.delete();
273
- camera.delete();
274
- perturb.delete();
275
- option.delete();
276
- data.delete();
277
- model.delete();
278
- ```
279
-
280
- As with buffers, you are responsible for managing the memory of these struct instances and must call `.delete()` on them when you are finished.
281
-
282
- ### Enums
283
- Access via `.value`:
284
- ```javascript
285
- mujoco.mjtDisableBit.mjDSBL_CLAMPCTRL.value
286
- ```
287
-
288
- ### Constants
289
- Scalar constants will be accessed the same way they are on python, simply:
290
-
291
- ```javascript
292
- mujoco.mjNEQDATA
293
- ```
294
-
295
- Due to Embind limitations, more complex constants that are not scalar, but are represented in more dimensions are exposed as functions. E.g to use `mujoco.mjFRAMESTRING` you will need to call a function:
296
-
297
- ```javascript
298
- mujoco.get_mjFRAMESTRING()
299
- ```
300
-
301
- This will return a javascript array representation of the values in MuJoCo `mjFRAMESTRING`.
302
-
303
- ### About assets
304
- The package is ESM (`type: module`) and ships TypeScript types.
305
-
306
- Ensure your bundler or dev server serves the `.wasm` asset at runtime.
307
-
308
- ## Development
309
-
310
- In order to change the bindings you will need to change the [`bindings.cc`](codegen/generated/bindings.cc)
311
- file but this should not be done manually. The file is generated using the
312
- Python scripts and template files in the [`codegen`](codegen) folder, to edit
313
- the bindings you will need to change those files and re-generate [`bindings.cc`](codegen/generated/bindings.cc)
314
- using this command:
315
-
316
- ```sh
317
- PYTHONPATH=python/mujoco python3 -m wasm.codegen.update
318
- ```
319
-
320
- The codegen scripts use MuJoCo’s Python introspect library to generate the
321
- Embind `EMSCRIPTEN_BINDINGS` block that binds C++ functions and classes to
322
- JavaScript. The functions and classes that are bound are wrappers around
323
- MuJoCo's C API. These wrappers provide a convenient place to add features like
324
- bounds checking and nice error reporting.
325
-
326
- ### Testing
327
-
328
- 1. **JavaScript API tests.**
329
- These verify that a wide variety of MuJoCo functions and classes work
330
- correctly when called from JavaScript. Run the tests as follows:
331
-
332
- ```sh
333
- npm run test --prefix ./wasm
334
- ```
335
-
336
- 2. **JavaScript API benchmark tests.**
337
- The current benchmark tests check JavaScript/C++ shared memory buffers
338
- performance. We will increase the coverage of the benchmarks overtime. Run
339
- the benchmarks using this command:
340
-
341
- ```sh
342
- npm run benchmark --prefix ./wasm
343
- ```
344
-
345
- 3. **Bindings generator tests.**
346
- These are relevant when developing or extending the bindings. The following
347
- command finds and runs all `test_*.py` or `*_test.py` files in the `wasm`
348
- folder:
349
-
350
- ```sh
351
- PYTHONPATH=python/mujoco python3 -m pytest ./wasm
352
- ```
353
-
354
- ### Debugging
355
-
356
- We provide a “sandbox” app where you can quickly write code to run in your
357
- browser. Write your code in the [`main.ts`](tests/sandbox/main.ts) file and use
358
- the following command to execute it in your browser:
359
-
360
- ```sh
361
- npm run dev:sandbox --prefix ./wasm
362
- ```
363
-
364
- The page will be blank since the script only logs to the console output. You
365
- can add your code at the indicated placeholder and use Chrome DevTools for
366
- debugging. It is possible to set up a debug workflow where stack traces and
367
- stepping through code across language boundaries work correctly. Our current
368
- method to do this only works internally at Google, but it should be possible to
369
- replicate the experience with open-source tooling — community suggestions are
370
- welcome!
371
-
372
- ## Versioning
373
- Package versions follow the official MuJoCo release versions.
374
- For example:
375
-
376
- | npm version | MuJoCo version |
377
- |-------------|----------------|
378
- | 3.5.0 | 3.5.0 |
379
-
380
- ## Future Work
381
-
382
- 1. **Bind all useful APIs.**
383
- These bindings are not yet complete. While the main MuJoCo APIs (`mj_step`,
384
- `mj_loadXML`, etc.) are well tested, other APIs (e.g., functions from
385
- `mjspec.h`) remain untested in real web applications (though test code for
386
- the `mjspec` bindings does exist).
387
-
388
- 2. **Improve the developer experience.**
389
- There is still work to be done to improve the developer experience when
390
- developing the WASM bindings. The most obvious issue is that bindings
391
- generation is not yet fully automated. As a result, it is currently less
392
- convenient than we'd like to identify and apply the changes needed to update
393
- the bindings. The goal is to eventually automate all binding code generation
394
- and clearly communicate what changes are required in the WASM bindings as a
395
- result of C++ updates. This problem should only affect developers working on
396
- the MuJoCo engine in C++, not end users writing JavaScript.
397
-
398
- 3. **Improve the documentation.**
399
- The documentation in this README will eventually be merged into the main
400
- MuJoCo documentation once the bindings are complete and named access is
401
- implemented. We also intend to review the bindings APIs and make adjustments
402
- to minimize differences with the Python bindings (while respecting language
403
- idioms) to reduce the amount of additional documentation required.
404
-
405
- 4. **Improve the [example](#example-application).**
406
- We aim to provide an example application that can be easily modified and
407
- embedded into a paper project page (see [this example](https://kzakka.com/robopianist/)).
408
- This could be achieved by extending the Three.js example or by compiling the
409
- MuJoCo platform C++ code using the Emscripten toolchain. Community
410
- suggestions and contributions are welcome!