| Name | Modified | Size | Downloads / Week |
|---|---|---|---|
| Parent folder | |||
| mujoco-3.17.0-macos-universal2.dmg.sha256 | 2026-10-22 | 101 Bytes | |
| mujoco-3.17.0-macos-universal2.dmg | 2026-10-22 | 55.2 MB | |
| mujoco-3.17.0-windows-x86_64.zip.sha256 | 2026-10-22 | 99 Bytes | |
| mujoco-3.17.0-linux-aarch64.tar.gz.sha256 | 2026-10-22 | 101 Bytes | |
| mujoco-3.17.0-windows-x86_64.zip | 2026-10-22 | 22.5 MB | |
| mujoco-3.17.0-linux-aarch64.tar.gz | 2026-10-22 | 34.6 MB | |
| mujoco-3.17.0-linux-x86_64.tar.gz.sha256 | 2026-10-22 | 100 Bytes | |
| mujoco-3.17.0-linux-x86_64.tar.gz | 2026-10-22 | 35.1 MB | |
| 3.17.0 source code.tar.gz | 2026-10-22 | 77.0 MB | |
| 3.17.0 source code.zip | 2026-10-22 | 78.3 MB | |
| README.md | 2026-10-22 | 20.5 kB | |
| Totals: 11 Items | 302.7 MB | 2 | |
Version 3.17.0 (October 22, 2026)
Significant new features
c00ed8153Added a batch API inmujoco/mjbatch.h(in Python as mujoco.batch (mujoco.readthedocs.io)): many simulations of one model stepped on a thread pool of its own, each held as its integration state and loaded into anmjDatafor each call, so memory scales with threads and results are bit-identical to a plain loop at any thread count. It supports per-simulation model and option fields or models of the caller's, observations of the state after a step, recorded trajectories, persistent simulations (required for sleep), and arbitrary per-simulation functions. Follows the design of mjbatch by @kevinzakka.
Engine
-
Flex improvements:
-
94483e166Added bending elasticity for 1D flexes, using a twist-free isotropic discrete elastic rod model. The cross-section is selected with the new section attribute: a circle of the flex radius, or a box with half-sizes sectionsize that uses the stiffness of its weak axis. It is enabled by a positive young modulus, requires a straight reference configuration (curved initial poses can be set withqposor keyframes), is compatible with edge equality constraints, and is integrated implicitly by the discrete integrator. Previouslyyoungwas ignored for 1D flexes: existing models that set it now bend, and fail to compile if the cross-section is degenerate (zero radius with the default circle section), if a vertex joins a zero-length edge, or if the rod is not straight. -
36d0df9a5,897e3fcb1Interpolated flexes (trilinear or quadratic dofs) now support self-collision, excluding elements in the same or neighboring cells. -
39dd10f2dThe default arena memory for flex models is now much smaller, sized from the flex mesh topology instead ofnv^2. If the Newton solver runs out of arena memory it falls back to CG with a warning. -
mj_setConstnow computes only quantities derived from other fields ofmjModel, while the compiler alone resolves spec-level conventions: -
55c1b585a,d6d41f324The damping of position actuators from dampratio, the spring length of tendons from(-1, -1), and model statistics are now resolved only at compile time, not bymj_setConst. Set the model fields directly when editing a compiled model (mj_copyBacknow copies tendon spring lengths back to the spec). -
c8362756dConstraint solvers now scale their termination criteria by the trace of the current inertia matrix (of the model or island) instead ofmjModel.stat.meaninertia. Models solved with PGS, noslip or islands disabled can stop at slightly different iterations. The meaninertia attribute is deprecated and now emits a compile warning; remove it to migrate. -
abddec5b9For body-based weld constraints without a specified relpose, the relative pose inqpos0is now recomputed bymj_setConstwhen the model is modified after compilation (matching the second body's anchor in body-basedconnectconstraints). The compiler marks such welds with a nonzeroeq_data[11], and mjNEQDATA increased from 11 to 12.
[!WARNING] Breaking ABI changes
body-based welds that had no
relposeat compile time. Zeroeq_data[11]before callingmj_setConstto set the relative pose of such a weld directly.
-
865316f19AddedMJSETCONST_ARRAYSandMJSETCONST_SCALARSinmjxmacro.h, listing themjModelarrays and scalars read and written by each phase ofmj_setConst. -
e15ecd842Added single-shot multicontact for geoms with positive contact margins. -
7394a8672mju_boxQPnow updates its Cholesky factor incrementally withmju_cholUpdate, making cold-started solves 1.4-1.6x faster and warm-started solves 1.9-2.9x faster. -
aa0f88e77Trees marked sleep="init" which cannot be put to sleep now cause a warning rather than an error, and start awake. See Sleeping for details.
Compiler
[!WARNING] Breaking API changes
aad2e2982mjs_fuseStaticandmjs_discardVisualnow return the number of bodies fused or elements discarded, and -1 on error. Previously they returned 0 on success, so a caller could not tell whether the spec changed. In Python,MjSpec.fuse_staticandMjSpec.discard_visualreturn the same number instead ofNone.Migration: Test for an error with
< 0rather than!= 0.
084828896mjs_addTexturenow takes a default class, likemjs_addMeshandmjs_addMaterial.Migration:
mjs_addTexture(spec)→mjs_addTexture(spec, NULL).MjSpec.add_textureis unchanged.
-
3576818f5,b0f206d04Textures can be left by reference instead of being decoded intomjModel. With compiler/passthrough set to "textures", or texture/embed set to "false", a single-file texture is not read at compile time; the model holds its path instead of its pixels, so a scene that attaches many textured sub-models loads in a fraction of the memory and time. In addition, a compiledmjSpecno longer keeps the decoded pixels of its textures between compilations. -
3576818f5What the model holds:tex_adris -1,tex_widthandtex_heightare 0,ntexdataexcludes the texture, the resolved path is attex_pathadr, and any authored content_type is at the newtex_contenttypeadr. Flipped, composite, six-file, procedural, buffer and in-memory textures stay embedded, as does any texture withembed"true". -
1be762d0cGetting the pixels:mj_loadTexturedecodes a texture of either kind, andmj_embedAssetsreturns a copy of the model with every by-reference texture loaded (which followed bymj_saveModelgives a hermetic MJB). Both are in Python asmujoco.mj_loadTextureandmujoco.mj_embedAssets. -
fd92ba1dbRendering: the built-in and Filament renderers load by-reference textures on demand, and Filament uploads each file once for all textures that share it. A file that fails to resolve produces a warning and an untextured material. -
084828896Textures can have default classes:mjsDefaulthas atexturemember and texture takes a class. -
4e9a2de2dAddedmjs_dedupAssets(MjSpec.dedup_assets), which merges the textures and meshes of anmjSpecthat would compile to the same asset, as those of a sub-model attached several times do: the first of each group is kept and every reference to the others is rewritten to it. Likemjs_fuseStatic, it returns the number of assets merged. -
027cb3dd8The asset paths inmjModel(pathsatmesh_pathadr,hfield_pathadr,skin_pathadrandtex_pathadr) now store the resolved path or URI from which the compiler read the asset (combining the model file's directory andmeshdirortexturedirwithfile, unlessfileis an absolute path or URI), somju_openResourcecan open them directly even after attaching models with different asset directories. Code that prefixed these paths with its own directory should pass them tomju_openResourceas is. -
9f035384dMesh polygon normals (mjModel.mesh_polynormal) are now computed from the whole polygon outline using Newell's method rather than the first three vertices (#3691).
Python bindings
-
08330629bAdded a mujoco.batch (mujoco.readthedocs.io) module over the batch API:Batch(model, nsim)with live(nsim, ...)arrays frombind()and named views such asjoint(name), per-simulation model fields fromexpand(),step,forward,reset,set_constandrolloutwith the GIL released, andjacandrayqueries. -
1313ef78eAdded support for building the Python bindings with Bazel (initially covers the core bindings, without rendering or the viewer). -
39b7193e8Fixed several bugs in named access (data.actuator('a'),model.joint('j'),data.bind(...)), and the corresponding generated accessors in the JavaScript bindings:-
Multi-control or multi-output actuators (such as orientation) now follow
actuator_ctrladrandactuator_outadrwith leading dimensionctrlnumoroutnum, instead of reading a single row at the actuator index. -
data.actuator('a').momentis now a read-only dense copy of the actuator's moment arm of shape(nv,)or(outnum, nv), instead of reading the sparseactuator_momentarray as if it were dense. -
Views of multi-column per-dof fields (
cdof,cdof_dot,dof_dampingpoly) on joints after the first now index the right rows.
-
-
7cdc8857eUnallocated arena arrays ofMjData(such asefm_*when thediscreteintegrator is not used, or island arrays when no islands are formed) are now filled with zeros, or -1 for index fields, instead of returning uninitialized memory.
Bug fixes
-
Fixed several bugs in interpolated flexcomp elasticity:
-
4bbc96957Volume (solid) interpolated flexes whose first cell is empty (e.g. a trilinear flexcomp from a mesh that does not fill the corner of its bounding box) now retain their elasticity; previously elasticity was gated on the first cell's stiffness. -
b0b20166dEditing a flex to remove a strain equality (e.g. frombody.make_flex) and recompiling now recomputes stiffness instead of keeping the strain constraint eigenmodes. -
08bf94b18Shell-mode interpolated flexes with elastic2d set to"stretch"or"both"now apply membrane stretch forces and implicit stiffness, and"bend"shells without strain constraints no longer allocateflex_stiffness.
-
-
Fixed several bugs in the Filament renderer:
-
5c7c1e3aeTextures now allocate mipmap levels (including sRGB textures), fixing minification aliasing. -
e81c8aed4Skins that share vertices across faces no longer fail with an index count mismatch (#3719). -
001aa3203Material colors now apply only when an object has the default color, instead of overwriting custom object colors. -
6cfc76e32Textures with an unsupported number of channels are now skipped with a warning, matching the classic renderer, instead of callingmju_error.
-
-
Fixed several bugs on error paths which called
mju_errorwhile C++ objects or locks were held (an error handler that does not return, as in the Python bindings and the model compiler, skips C++ destructors):-
4cc38db84,8c1e45559,526583e5bInvalid configurations of the touch grid, cable and SDF plugins leaked more than 10 MB per failed compilation (they now fail plugin initialization with a warning);mju_getXMLDependenciesand unknown material layer roles also leaked memory on invalid XML, and unsupported equality types in the XML writer are now reported as write errors instead of callingmju_error. -
4cc38db84An error while compiling meshes or textures on the compiler's worker threads crashed the process, and a failed library load inmj_loadAllPluginLibrariesleft its mutex locked. -
ae15ab978mj_recompilefreed the givenmjDataand calledmju_errorif a plugin failed to initialize, and did not delete the model and data on some other failures, contrary to its documentation.
-
Models
94483e166The elastic mechanism example models now use 1D flex rods: the cantilever comparison of quadratic flexes adds a rod, and the elastic slider-crank and the tendon-loaded dipper arm are built from rods.