Commit Graph

80 Commits

Author SHA1 Message Date
Yuval Tassa 279df98cd0 Add the pid actuator: setpoint inputs, integral action, slew rate limiting.
<pid kp kv|dampratio [ki imax] [slewmax]> is a PID controller with real position and velocity setpoint inputs on a single force output, plus an optional feedforward input. With a zero velocity setpoint it reproduces <position> bit-exactly; the input signature is any subset of [pos, vel, ff], selected with input="..." and recorded as mjtCtrlInput bits in
actuator_ctrlspec; absent setpoint inputs are fixed at zero, so the control vector contains no inert entries.

kp and kv are single-sourced in the affine bias parameters (biasprm[1,2]) with no gainprm mirror: every consumer of the position-servo shape
(dampratio conversion, inheritrange, qDeriv) reads one location, which is what makes the bit-exact <position> parity possible. Controller state uses dyntype 'pid' with slot-gated activations in the order [slew, integral], following the dcmotor slot idiom: slewmax (dynprm[1]) rate limits the effective position setpoint through an activation holding it;
ki (gainprm[0]) integrates the position error -- wrapped on rotational transmissions -- with anti-windup clamping of the integrand at imax (dynprm[0]). Both features require the pos input. Servo input unpacking is shared with the dcmotor controller (unpackServoInputs); per-input ranges are exposed as posrange/velrange/ffrange.

This subsumes the functionality of the mujoco.pid plugin with proper activation state: correct under all integrators, visible to keyframes, act sensors and reset. Migration: kp/ki/kd map to kp/ki/kv, plugin imax is in force units (divide by ki), slewmax carries over; the single ctrl becomes input="pos".

PiperOrigin-RevId: 957588898
Change-Id: Id2786836ca6e76f58e5b5cc8323fc23be0a53784
2026-08-01 04:28:43 -07:00
Haroon Qureshi 8b78378868 Add mjv_camera2GLCamera to mujoco.h.
PiperOrigin-RevId: 956698065
Change-Id: I36856d7142bb5e798c5a90c19609288ddd7c4aac
2026-07-30 13:16:37 -07:00
Yuval Tassa 072e963fa0 Add SO3 transmission and native orientation actuator.
https://youtu.be/17XpwnqyCXs

New transmission type mjTRN_SO3: a relative orientation, targeting a ball
joint or a site+refsite pair. It is the first transmission with more than
one force output: its length is the norm of the expmap vector of the
relative rotation and its moment axes are the 3 rows of the
relative rotational Jacobian, without projecting onto per-actuator gears.

New force law mjGAIN_SO3/mjBIAS_SO3: a geodesic PD servo, force =
kp * log(q_current^-1 * q_target) - kv * velocity, exact for arbitrary axis
combinations with a unique equilibrium at every commanded orientation.
Error, moment rows and velocity all live in the child frame (joint or
site): the right-difference error is the gradient of the geodesic
potential in that frame. The parent-frame (left) error is not: driving
child-frame torques with it pumps energy at large angles, settling into
steady-spinning limit cycles (the SO3LargeAngleConvergence test). The
integrator variant stores the 3D orientation setpoint in act (actnum = 3,
re-anchored to a bounded representative at integration time). Exposed in
MJCF as <orientation joint=|site=+refsite= kp kv|dampratio>, or via
<general gaintype="so3" biastype="so3">.

The setpoint input has two charts: an expmap target (3 controls, default)
or a quaternion target (4 controls) -- <orientation input="quat">, the
first actuator with different input and output widths. The signature is
recorded in a new per-actuator field actuator_ctrlspec (mjtCtrlChart),
whose meaning is scoped by the gain type the way gain/bias parameters are;
ctrlnum is derived from it at compile time and remains the layout
authority. An explicit field rather than width inference or a prm slot:
width-as-chart cannot express same-width signatures (upcoming servo input
subsets), and prm slots are the input_mode pattern this stack retires.
The force law normalizes the commanded quaternion, making it scale- and
antipodally-invariant. The all-zero ctrl still maps to the identity via
mju_normalize4, but it is a degenerate point (a nudge of any component
commands a half-turn), so quat inputs reset to the identity quaternion:
new mj_resetCtrl sets neutral ctrl values (zero, except qw = 1), called
by mj_resetData and the viewers' Clear All. The quat chart is
restricted to dyntype 'none': integrating a quaternion setpoint linearly
is not meaningful on the manifold. New mjsActuator.ctrlspec field carries
the signature through the spec and XML round-trip.

Actuator sensors (actuatorpos/vel/frc) now report one value per force
output; dim = 3 on an SO3 actuator.

As the first actuator with nu != nactuator, this commit also makes the
viewers multi-input aware: the control sliders in simulate and studio,
which indexed per-actuator arrays by control index (out of bounds on
this model class), are generated per control and labeled with the
actuator name plus an input suffix ("orient/qw"), via the new
introspection helper mj_actuatorInputName -- the single source of truth
for input names, extended by each new multi-input type (quaternion
components are w-first: qw, qx, qy, qz). Slider ranges now honor a
defined ctrlrange even when ctrllimited is false: range is the UI hint,
limited is the clamp -- wrapped and expmap setpoints are unbounded but
still want finite sliders, while quat components are truly bounded.

The rotational demo model is orientation.xml under
test/engine/testdata/actuation/, upgraded to a three-way contrast:
per-axis wrapped servos vs an expmap-commanded vs a quat-commanded
orientation actuator, on identical checker-textured boxes. It is loaded
by the mixed-axis contrast and input-name tests, and doubles as the
viewer test model (slider groups of 3 independent, 3 grouped, 4 grouped).

PiperOrigin-RevId: 951607063
Change-Id: If235dba8e2f2ca72672e7c62531a27e967c6a373
2026-07-21 11:36:13 -07:00
Haroon Qureshi fa36015bae Remove unneeded mjvScene argument from mjv_moveCamera.
PiperOrigin-RevId: 948204736
Change-Id: Ic9b116ce439b3153764af67c449a824aec1994dc
2026-07-15 02:26:04 -07:00
Copybara-Service 6c78c8664e Merge pull request #3340 from devshahofficial:devshahofficial/mjr-renderer-info
PiperOrigin-RevId: 948183711
Change-Id: I28b256eca22e86ec0ba05a4fa26458d678aca130
2026-07-15 01:37:11 -07:00
Sam Haves dc7581acfa Add pluggable resource writing to MuJoCo
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
2026-07-09 10:47:48 -07:00
devshahofficial d23ff84c59 Add renderer info query API 2026-07-07 11:44:46 -07:00
Yuval Tassa 7e9ac58ff9 Migrate mjd_inverseFD mass Jacobian from qM to M
PiperOrigin-RevId: 942268237
Change-Id: I0ecfe161867ce9930cd6366d778077df2cd3197f
2026-07-03 15:35:52 -07:00
Sam Haves d83ef0b6b9 Change mj_encode return type to 64-bit (mjtSize)
This supports encoding files larger than 2GB.

PiperOrigin-RevId: 939828697
Change-Id: If60d36c61475ced20b4eb58408ffb37e25bf3db7
2026-06-29 07:41:52 -07:00
Yuval Tassa 6f8bb5ef55 Refactor compiler warning handling.
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
2026-06-16 16:28:33 -07:00
Yuval Tassa 58f6d52491 Introduce new logging API, fixes #858
PiperOrigin-RevId: 930744288
Change-Id: I6ec1203b55c031390f3eef23192e2337508ce886
2026-06-11 14:36:57 -07:00
Yuval Tassa 7b9b88060e Refactor mj_fullM. This change is part of the deprecation of mjData.qM.
PiperOrigin-RevId: 925669464
Change-Id: I4889c66591bc1df4c31135a13776052aad491f7a
2026-06-02 17:22:55 -07:00
Yuval Tassa 062b0f1ea6 Remove deprecated mju_{error,warning}_{i,s} functions.
PiperOrigin-RevId: 925204136
Change-Id: Ia877d08a135092db8037d04e6a237e81325a1d7c
2026-06-02 01:59:05 -07:00
Kyle Bayes b935d4153c Add new mju_threadpool API function, and delete old threading API.
PiperOrigin-RevId: 922838541
Change-Id: Id9f7e0fb298ffde61fcc49a802dc78971858ce51
2026-05-28 10:11:44 -07:00
Alessio Quaglino 4c381635e1 Add mjs_makeFlex to the MuJoCo C and Python APIs.
- Add mjs_makeFlex C API that wraps mjCFlexcomp::Make(), creating
  a flex with auto-generated bodies, joints, and equality constraints
  from parameters (type, dim, dof, count, cellcount, spacing, scale,
  radius, mass, inertiabox, equality, rigid, flatskin, elastic2d,
  pos, quat, origin, file, vfs).
- Add Python binding body.make_flex() in specs.cc with keyword args.
- Refactor flex_spec_provision.py to use make_flex() instead of XML
  string templating + separate spec + attach. Eliminates textwrap
  dependency.
- Merge user_flexcomp into user_model BUILD target to resolve
  circular dependency.

PiperOrigin-RevId: 922725304
Change-Id: Ice13787c45f3173407fec659f9590a6453bc65dd
2026-05-28 05:59:20 -07:00
Yuval Tassa 393c1e4217 Migrate mjtByte to mjtBool for boolean-valued fields.
PiperOrigin-RevId: 921408093
Change-Id: Icb00457836359779f0f72fc02d6a7c0dc9f6bd23
2026-05-26 05:35:49 -07:00
Yuval Tassa bdf00966f9 Add compiler timing diagnostics to mjsCompiler, printed by compile.cc
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
2026-05-19 08:28:47 -07:00
Sam Haves ec50260e26 Add mjs_getOriginSpec to retrieve the original spec of an element.
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
2026-05-07 06:33:28 -07:00
Sam Haves 579a27e9d2 Make mjSpec related getter/find utilities take const parameters.
PiperOrigin-RevId: 910848529
Change-Id: I1c966a6299fe47317cbf0bfb8f8b835cbcd4ed65
2026-05-05 12:35:56 -07:00
Yuval Tassa 767c607f58 Add mju_sym2dense, document future breakage of mj_fullM
PiperOrigin-RevId: 910242375
Change-Id: Ibfbdef9cfb66088723499ea257da09aee0d80938
2026-05-04 14:25:53 -07:00
Sam Haves 4cfebcc32b Add mj_containsFileVFS and mj_containsBufferVFS functions.
PiperOrigin-RevId: 903785790
Change-Id: I013b37a177284f8440179c4ae5c6221e0f572b49
2026-04-22 05:27:15 -07:00
Kyle Bayes 3325971840 Add mj_maxContact API function.
PiperOrigin-RevId: 903135055
Change-Id: I5f103c7d51f97e327c923bc567002ace835f5517
2026-04-21 04:03:22 -07:00
Yuval Tassa 81720071b8 Changes to dcmotor:
- Remove `lugre:viscous`, should now be added directly to actuator `damping`. Trying to do this for the user was incompatible with default inheritance (compounding instead of overriding).
- Move voltage limiting from the `saturation` to the `controller` attribute.
- Fix indexing issues in default inheritance.

PiperOrigin-RevId: 897087642
Change-Id: I5388c2633e15c7e223992e7eb5d6a28db75a6438
2026-04-09 06:52:45 -07:00
Yuval Tassa 382474bb9d Minor improvements to dcmotor
PiperOrigin-RevId: 895907301
Change-Id: Ia50a6d06c1ede9894cc71f375db837d104f0211e
2026-04-07 08:11:13 -07:00
Yuval Tassa 70a7647ad9 Add <dcmotor> actuator and related docs and tests.
PiperOrigin-RevId: 892927987
Change-Id: I38ed6412801341ba03ddf5fe7b93a6081df24d37
2026-04-01 07:50:23 -07:00
Sam Haves f5d3ce3451 Introduce mjpEncoder plugin architecture
Add a new mjpEncoder plugin type mirroring the existing mjpDecoder pattern.
Encoders serialize an mjSpec + mjModel to an mjResource for a given format.

New API functions:
- mjp_registerEncoder: globally register an encoder
- mjp_defaultEncoder: zero-initialize an encoder struct
- mjp_findEncoder: look up an encoder by filename extension or content type

The mjfEncode callback takes (mjSpec*, mjModel*, mjVFS*, mjResource*) and
returns 0 on success. Writing to mjResource keeps symmetry with the decoder
reading from mjResource and leaves the door open for writable resource providers.

PiperOrigin-RevId: 889187898
Change-Id: I180771b2255b91dea188ac5e2cdc3a8f0fb85364
2026-03-25 05:35:39 -07:00
Kyle Bayes acf7f030a6 Remove const qualifier from mjData in mj_geomDistance. The function mj_geomDistance will require data stack space as nativeccd memory is determined from opt.ccd_iterations.
PiperOrigin-RevId: 881946592
Change-Id: I524b9fa41018a581e58647d44de6ca3db4c6608b
2026-03-11 04:55:44 -07:00
Sam Haves 6890e133c0 Add mjs_getCompiler C API and compiler property to Python spec elements.
PiperOrigin-RevId: 881488083
Change-Id: I3aa1c0562bf2fd27057b8056048e3156fc1b067c
2026-03-10 09:57:36 -07:00
Sam Haves 6715a0ceaa Expose mju resource functions to public header.
Many of these functions are useful when writing a custom decoder.

PiperOrigin-RevId: 868321921
Change-Id: I7e0dd285e0559b6f486acf8cbf4376ff8d91943d
2026-02-10 14:31:41 -08:00
Yuval Tassa 6419534bad Add actuator and sensor delays. Fixes #1004
PiperOrigin-RevId: 866478839
Change-Id: Id21a6da0f98454c8fa39ea5af8a5e213d6eae497
2026-02-06 08:47:36 -08:00
Haroon Qureshi 0ddbb46fa1 Refactor mjVFS and resource management.
Resource operations (e.g. mju_openResource, mju_readResource, and
mju_closeResource, etc.) are now all handled by a VFS instance. It
is now up to the VFS to determine which provider to use in order to
handle those operations.

This allows us to dynamically add/remove (aka "mount") providers to
a VFS to handle special requests. mj_addFileVFS and mj_addBufferVFS
have been reimplemented as two such use-cases. Moreover, we expose
the mounting behaviour with two new functions: mj_mountVFS and
mj_unmountVFS.

PiperOrigin-RevId: 861550939
Change-Id: I070eb4bcc2982466c8f368f7918005538baa5185
2026-01-26 23:53:29 -08:00
Google DeepMind cbc1136502 Roll back VFS refactor due internal breakages
PiperOrigin-RevId: 856273160
Change-Id: I4097e05ed4e48ebee05b4347d0f227d4f39c1b09
2026-01-14 10:38:29 -08:00
Haroon Qureshi d387578783 Refactor mjVFS and resource management.
Resource operations (e.g. mju_openResource, mju_readResource, and
mju_closeResource, etc.) are now all handled by a VFS instance. It
is now up to the VFS to determine which provider to use in order to
handle those operations.

This allows us to dynamically add/remove (aka "mount") providers to
a VFS to handle special requests. mj_addFileVFS and mj_addBufferVFS
have been reimplemented as two such use-cases. Moreover, we expose
the mounting behaviour with two new functions: mj_mountVFS and
mj_unmountVFS.

PiperOrigin-RevId: 856166919
Change-Id: Id723d612ffc0bff020705cf19ef95fbf24676840
2026-01-14 05:19:57 -08:00
Yuval Tassa 218226fc95 Breaking change: Add surface normal output to MuJoCo raycast functions.
PiperOrigin-RevId: 855781592
Change-Id: Id96b1ca7eaf722e260cc69d7706c28dc51f52d92
2026-01-13 10:22:21 -08:00
Yuval Tassa a26f09accf Standardize function docstring style in MuJoCo API.
Updates function comments to consistently use a semicolon (`;`) before describing the return value and to use the imperative form "return" instead of "returns".

Also fix error in docstring of `mjp_registerResourceProvider`

PiperOrigin-RevId: 854888532
Change-Id: I311239a2770ded5febece9958ae4e94c1e522600
2026-01-11 09:00:35 -08:00
Yuval Tassa 7fddeeaff6 Minor fixes to mj_multiRay
PiperOrigin-RevId: 847780959
Change-Id: I3588415f215bd5f1592bec6678a5bae45d5f0980
2025-12-22 08:52:36 -08:00
Yuval Tassa 1ff74ba810 Change the type of state signature arguments from unsigned int to int
PiperOrigin-RevId: 843162492
Change-Id: I51d3324f088e8055898e115bdd32267c5950a412
2025-12-11 04:34:36 -08:00
Haroon Qureshi caec236b2f Make mj_loadModelBuffer a public API.
PiperOrigin-RevId: 843105390
Change-Id: I4058471b4cf64995dd5ab43e9c8c24e322004b62
2025-12-11 01:24:17 -08:00
Yuval Tassa 19e2d0ae2f Add mj_fwdKinematics and a table improving documentation of the MuJoCo computation pipeline structure.
PiperOrigin-RevId: 838768130
Change-Id: I1a22d5cdca7db704ba4cea1667fcbecb16b87005
2025-12-01 07:39:00 -08:00
Yuval Tassa 888d3a7b07 Add mj_copyState
PiperOrigin-RevId: 836588419
Change-Id: I7609e121dc0ac697d4d015d4244bdd5962650def
2025-11-25 03:10:30 -08:00
Yuval Tassa a66cf303f8 Clean up ray functions
PiperOrigin-RevId: 833299985
Change-Id: I30aabe889ccc5900ff0e50a578e98e176d3effa4
2025-11-17 05:47:44 -08:00
Haroon Qureshi 6c15c711ee Make mjv_cameraFrame and mjv_cameraFrustum public.
PiperOrigin-RevId: 832187804
Change-Id: I74d05d7fe03bc81bd05a823c7c9791bca12e3079
2025-11-14 00:03:18 -08:00
Yuval Tassa 042c5223a6 Change mj_sizeModel return type to mjtSize.
PiperOrigin-RevId: 831768095
Change-Id: I079fbadc403b32a3ce8a73fe21b2cd66391401c3
2025-11-13 02:32:18 -08:00
Sam Haves 57f7145806 Create mjpDecoder, mj_parse, and mju_decodeResource
- plugin system similar to mjpResourceProvider, but instead of loading a resource it converts an existing mjResource into an mjSpec.
  - The returned spec is then composed into the referencing spec.
  - This enables different file types to generate arbitrary specs, and allows us to separate format parsing from compilation code.

Follow up CLs will move some of the logic in src/engine for PNG, USD, KTX, OBJ loading into decoders.

The mj_parse function MjSpec from a given file, it's a more generic version of mj_parseXML.

In it's implementation, mj_parse as opposed to mj_parseXML will look for any registered decoder and
not assume we are striclty dealing with MJCF.

PiperOrigin-RevId: 826149497
Change-Id: I0ece26904280cb94bd5ded6dd5a565c539d60254
2025-10-30 12:54:40 -07:00
Sam Haves ac2cd5dfd6 Add support for querying of MjsTendon path from Python.
Fixes #2670

PiperOrigin-RevId: 822215254
Change-Id: Ice5a264e54f963776093511c6e4ac830aae6d4f8
2025-10-21 11:51:24 -07:00
Saran Tunyasuvunakool 2f65e23779 Add mj_extractState as a public API function.
This function allows the caller to extract a subset of components of a state previously obtained via `mj_getState` without having to first write it back into `mjData`.

PiperOrigin-RevId: 822165077
Change-Id: I6433261f4f5ec2e8d024bb7dee8f7dbf1e62666c
2025-10-21 10:01:22 -07:00
Sam Haves e4704cd28b Create list_dependencies sample to list all dependencies for an MCJF file.
PiperOrigin-RevId: 814816067
Change-Id: Idc6232e5d1ef1ff0318aeacd0e3d4b4a5a303485
2025-10-03 13:47:28 -07:00
Sam Haves 6320b95957 Add mju_getXMLDependencies that given an MJCF file returns filepaths to all of it's dependencies.
PiperOrigin-RevId: 814203235
Change-Id: Ib5c2e2f4dd42224a768c88d76473544190c72bc0
2025-10-02 06:14:48 -07:00
Haroon Qureshi 6a7566872a Functions for printing the contents of mjvScene.
PiperOrigin-RevId: 812699642
Change-Id: Iafff53c952c952624129ff01a8c1b0aa5d38eec5
2025-09-29 02:47:17 -07:00
Yuval Tassa d71d42a374 Add private function mju_isZeroByte to check for byte-wise zero.
PiperOrigin-RevId: 810456282
Change-Id: I877d0f9225e7a783ed7ff12ce54f4ed0a7889793
2025-09-23 08:49:43 -07:00