Extend mjpResourceProvider with an optional write callback (write)
so that mj_encode, mj_saveXML, and mj_saveModel can write to any
registered provider.
PiperOrigin-RevId: 945202741
Change-Id: I37903425260932e555f4a8c2392c4ff8c2e6cc06
For example when loading parent_merge.xml:
```
WARNING: Attach conflict when attaching 'child' to 'parent_merge', policy is 'merge'
timestep: parent has 0.005, child has 0.002, taking the minimum
iterations: parent has 50, child has 100, taking the maximum
flag 'Damper': added from child
```
When loading parent_error.xml:
```
XML Error: Attach conflict when attaching 'child' to 'parent_error', policy is 'error'
timestep: parent has 0.005, child has 0.002
iterations: parent has 50, child has 100
Element 'attach', line 10
```
PiperOrigin-RevId: 933620810
Change-Id: Ib477863b5ef763474d27fb4be5a4148be1d5d500
Compiler warnings are now accumulated in a vector of strings within the mjSpec object. New API functions `mjs_numWarnings` and `mjs_getWarning` are added to access these warnings. The compiler's log handler now chains warnings to the global log handler, ensuring they are still displayed immediately. Call sites in `mj_loadXML`, `mj_compile`, and the Python and WASM bindings have been updated to use the new warning API.
PiperOrigin-RevId: 933361650
Change-Id: I47cab98a460c57b0898c0a1a43fce2a5b9648eb1
When an mjpResourceProvider's open callback returns 0 (failure), MuJoCo does
not invoke the corresponding close callback. Previously, several resource
provider implementations allocated heap memory or system file handles before
encountering an error, failing to clean them up before returning 0. This change addresses these leaks across the codebase and clarifies the API contract.
PiperOrigin-RevId: 929803942
Change-Id: Ib7344033726895cdf037a8d9356ffc183c78c2d3
The field now stores either an approximate or exact diagonal of the constraint matrix A, so the name is made more general.
PiperOrigin-RevId: 924244954
Change-Id: I62b2f76531fb88b7b3bf96e6769940197596702b
For example, `compile mujoco_menagerie/robotis_op3/scene.xml` now outputs
```
Compile 1 (cold cache):
total: 317.2 ms
assets: 284.8 ms (wall clock)
load: 616.1 ms
hull: 26.4 ms
poly: 137.8 ms
inert: 177.8 ms
bvh: 568.2 ms
octr: 1.6 ms
tex: 25.3 ms
other: 32.4 ms
Compile 2 (warm cache):
total: 79.9 ms
assets: 54.5 ms (wall clock)
load: 888.5 ms
hull: 0.0 ms
poly: 0.0 ms
inert: 0.0 ms
bvh: 0.0 ms
octr: 0.0 ms
tex: 21.4 ms
other: 25.3 ms
```
PiperOrigin-RevId: 917850214
Change-Id: Iaec86230bec0faf2e47820e20cbff61de5b2621e
with a preconditioned Conjugate Gradient (CG) solver that operates
on the full system matrix.
The previous approach extracted flex DOFs into a reduced banded system,
factored it separately, and overwrote the global solve. This required
precomputed bandwidth (makeFlexBandwidth), parent-joint detection,
coupling corrections, and a FlexInterpContext struct — and only worked
for standalone flex trees without parent joints.
The new CG solver uses the already-factored global system (M - h*qDeriv)
as a preconditioner and adds the flex stiffness contribution via
matrix-free products (mjd_flexInterp_mulKD/mulK). This handles any
kinematic configuration — including flexes attached to articulated
chains or with parent joints — without sparsity pattern restrictions.
Before (`bunny_multicell`):
```
Simulation time : 50.80 s
Steps per second : 197
Realtime factor : 0.20 x
Time per step : 5080.3 µs
CG iters / step : 3.16
Contacts / step : 31.04
Constraints / step : 124.15
Degrees of freedom : 178
Dynamic memory usage : 0.4% of 100M
```
After:
```
Simulation time : 9.52 s
Steps per second : 1051
Realtime factor : 1.05 x
Time per step : 951.7 µs
CG iters / step : 3.21
Contacts / step : 30.90
Constraints / step : 123.61
Degrees of freedom : 178
Dynamic memory usage : 0.3% of 100M
```
PiperOrigin-RevId: 913758038
Change-Id: If5aa617b2d535c86aec9bd71c9e0003a2b38bdd7
The maximum depth of the octree used for SDF generation can now be specified in the mesh definition via `mjsMesh::octree_maxdepth`. The default value is 6.
PiperOrigin-RevId: 912494999
Change-Id: I6d828d1d3999b99d1210a6829a05b04fac591e1f
The new function mjs_getOriginSpec returns the mjSpec that was used to define a given mjsElement. Unlike mjs_getSpec, this value remains constant even after the element has been attached to a different model.
PiperOrigin-RevId: 911930951
Change-Id: Ia9cd79d9dfabc513d6121eadcffc5d41075224c9