Commit Graph

260 Commits

Author SHA1 Message Date
Michael Moss bbdda5dda5 Update MuJoCo version to 3.12.0 in preparation for breaking changes release.
PiperOrigin-RevId: 965899864
Change-Id: I4fb90e357bed3d7f2f8d86e500aed53646c4b1ea
2026-08-17 05:01:33 -07:00
Yuval Tassa 2f1843f4a7 Redesign the dcmotor controller: setpoint inputs, torque-space gains.
The dcmotor input block is any subset of the canonical list [pos, vel,
ff, voltage], selected with input="pos vel ff voltage" and recorded as
mjtCtrlInput bits in actuator_ctrlspec like pid. Tokens are required in
canonical order: the attribute denotes a set, the block always packs
canonically, and accepting permutations invites reading the string as a
layout choice. The mode flag in gainprm[8] is retired (reserved,
written 0).

Controller gains are now in torque space, as for pid: the controller
commands tau = kp*(q*-l) + kd*(v*-ldot) + ki*x_I + tau_ff over the
present inputs (absent setpoints frozen at zero) and converts to drive
voltage V = R/K * tau + K*ldot. The second term compensates back-EMF,
as the current loop of a real torque-mode driver does (torque commands
are current commands): commanded torque is delivered exactly until a
limit binds, and the torque-speed envelope emerges from the Vmax clamp.
The map uses the nameplate R: thermal resistance growth is not
compensated, so a hot motor under-delivers by R/R(T). A stateless
setpoint dcmotor now matches <pid> exactly, for any K and R; the old
back-EMF droop remains available as the physical behavior of the raw
voltage path. Voltage-space datasheet gains convert by K/R. Controller
inputs require a positive motor constant (the map divides by K), and
controller gains require a controller input.

ff and voltage are distinct inputs, different in kind: ff is a torque
feedforward added to the controller output, uniform with pid's ff
(feedforward in the actuator's output space), while voltage is the raw
terminal voltage of the physical device, injected downstream of the
controller and its Vmax clamp, unclamped (ctrlrange bounds it if
desired). input="voltage" is the default: the plain voltage-commanded
motor, whose behavior is unchanged by this commit. The integrator
always accumulates position error; the old velocity mode's integral
term, ki*(int(u)dt - theta), which tracked the integral of the velocity
command, is retired without replacement, keeping ki mode-independent --
commanded integrated velocity belongs to an integrator activation
state, not to controller gains. slewmax rate-limits the first controller
input -- position setpoint (rad/s), velocity setpoint (rad/s^2) or torque
feedforward (N*m/s), each a real driver feature (reference ramping,
ramped-velocity and ramped-torque input modes); the raw voltage input
is never rate-limited and slewmax requires a controller input.

input="none" selects the empty signature: the actuator owns no controls
at all (nu = 0 is now legal with actuators present) and is purely
passive -- LuGre friction, cogging and back-EMF braking as passive
joint forces. This exists because auxiliary dynamic states (the LuGre
bristle) attach to actuators, not joints. The terminal voltage is
identically zero, i.e. a shorted motor (dynamic braking); motorconst=0
decouples the electrical branch. mjINPUT_NONE is a distinct enum value
because ctrlspec = 0 means "unset, use the type default". History and
delay require an input; the controller voltage override and input read
in mj_fwdActuation are gated on a nonempty block.

The analytic velocity derivative of the controller becomes
dV/dw = -kd*R/K + K, whose second term cancels the back-EMF bias
exactly: the net damping of an unclipped torque-mode motor is -kd, and
of a voltage-mode or passive motor -K^2/R. Viewers label inputs via
mj_actuatorInputName: pos, vel, ff, voltage.

The dcmotor LaTeX design doc is updated accordingly: torque-space
units, the tau->V map and its saturation-generated envelope, the
input-block pipeline figure, and a Passive Operation section.

PiperOrigin-RevId: 965795351
Change-Id: Ibc308ca21bd6bad014e77f950ee08feaad449b73
2026-08-17 00:43:48 -07:00
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
Michael Moss 1db801460b Update MuJoCo version to 3.11.1 following the 3.11.0 release
PiperOrigin-RevId: 954833728
Change-Id: I1c006cdd72072c6821d7b3c28d8ac320de19b8c5
2026-07-27 14:35:26 -07:00
Yuval Tassa 259e6c4dc6 Fix MSVC ASan compilation by avoiding GCC/Clang specific stack instrumentation
PiperOrigin-RevId: 951656966
Change-Id: I51294e6a95c39f4037e8feb2aee45e69cb51beb0
2026-07-21 13:09:23 -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
Michael Moss b942c9f922 Update MuJoCo version to 3.11.0 in preparation for breaking changes release.
PiperOrigin-RevId: 950824721
Change-Id: Icc06b10ea69f5dd84e100eb75233f1598c2cbf88
2026-07-20 07:26:25 -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
Michael Moss 5700829122 Update MuJoCo version to 3.10.1 following the 3.10.0 release
PiperOrigin-RevId: 936044969
Change-Id: If0ebcc192419302da01741ebabb2b7dd3d7f7baf
2026-06-22 07:25:02 -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
Michael Moss 79aeceeaa3 Update MuJoCo version to 3.10.0 following the 3.9.0 release
PiperOrigin-RevId: 922027849
Change-Id: I52dd7fb5eeb962c2670ab5dbbe7ce192ac9332c5
2026-05-27 03:50:22 -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 15d27b363f Compile-time size assertions for MuJoCo basic types
PiperOrigin-RevId: 919107499
Change-Id: I07fcba4f33c77a2a1e68528dba6d399af94d0220
2026-05-21 09:55:04 -07:00
Yuval Tassa 2810edd27a Rename mjtnum.h to mjtype.h, move enum types to mjtype.h
PiperOrigin-RevId: 919020039
Change-Id: I441295c0baa0b7456f78239fbd5478d32ffc07c1
2026-05-21 06:43:29 -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
Michael Moss 28548ce51c Update MuJoCo version to 3.9.0 following the 3.8.1 release
PiperOrigin-RevId: 913596257
Change-Id: Ib8b27fd2224e38560a209054c1d508a9bba21bbf
2026-05-11 02:58:56 -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
Michael Moss 2b7cc28afa Update MuJoCo version to 3.8.1 following the 3.8.0 release
PiperOrigin-RevId: 905108575
Change-Id: Ief1f9c6f34559e7a5ccc60dcceec589316bcdf9e
2026-04-24 10:37:50 -07:00
Michael Moss 15f61679bf Update next MuJoCo version to 3.8.0 for pending breaking changes.
PiperOrigin-RevId: 904496070
Change-Id: I0b8b01cbcf27f28ac80dbc283bc63090f745f403
2026-04-23 09:33:15 -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
Michael Moss 4a98cc8bff Update MuJoCo version to 3.7.1 following the 3.7.0 release
PiperOrigin-RevId: 899835826
Change-Id: Ibe247b921e7dad7184acef69ee3199fec79c6e24
2026-04-14 16:49:03 -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
Yuval Tassa 5107c31c06 Add missing API documentation entries.
PiperOrigin-RevId: 891658745
Change-Id: I7fa4f0535e72eaaf8964ce3f1bcf4bf87486580a
2026-03-30 05:13:31 -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
Michael Moss 6d70e66810 Update MuJoCo version from 3.6.0 to 3.7.0 following the 3.6.0 release
PiperOrigin-RevId: 881995135
Change-Id: I0c1a3b4a22c4c7cfada580b49a2cacde64cc84f3
2026-03-11 07:09:24 -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
Michael Moss 955d6c0b02 Update MuJoCo version from 3.5.1 to 3.6.0 prior to next release.
The next release will include breaking changes, so this bumps the major
version to reflect that.

PiperOrigin-RevId: 881351265
Change-Id: I970c68a0211651c07fcb8109ebd0b138196cf50a
2026-03-10 04:30:07 -07:00
Michael Moss 42958aab81 Update MuJoCo version from 3.5.0 to 3.5.1 following the 3.5.0 release
PiperOrigin-RevId: 869654894
Change-Id: I9cacaf4cbb70ad17faa24c3c30ec38ffe91b5deb
2026-02-13 03:54:25 -08:00
Yuval Tassa c54f1fe380 Use semantic versioning.
PiperOrigin-RevId: 869102767
Change-Id: I8b01b9343289d4ad7d15bcc3634a28e661308a90
2026-02-12 02:11:20 -08: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 4fa062c7e5 Update unreleased MuJoCo version from 3.4.1 to 3.5.0.
PiperOrigin-RevId: 868169291
Change-Id: I8041842811f5f664c80116993315f50d549b5575
2026-02-10 08:52:04 -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