Commit Graph

197 Commits

Author SHA1 Message Date
Yuval Tassa 9553926158 Save flex node coordinates in the new nodecoord attribute.
Interpolated flexes with pinned nodes could not be reloaded after saving:
pinned nodes share their parent body, and their positions within it lived
only in mjsFlex.node, which had no MJCF attribute. On reload the pinned
nodes collapsed onto the parent body origin, degenerating the trilinear
interpolation grid ("flex grid rotation R0 is not orthonormal"). This
made model/flex/strain.xml and gripper_trilinear.xml fail to round-trip.

Add flex/nodecoord, real(3*nnode), the node analog of flex/vertex: local
node coordinates within the corresponding body frames. The reader picks
it up from the regenerated schema tables; the writer emits it with the
precision-aware WriteVector, since VectorToString ignores the XML
precision setting and truncating node coordinates to 6 digits while body
positions carry 17 fails the R0 orthonormality check at full precision.

Add a WritesPinnedFlexNodes round-trip regression test, and remove the
two write-read sweep exclusions documenting this bug. The removed
substring filter "strain" was also matching core_constraint, silently
excluding that entire testdata directory from the sweep; its ~40 models
are now covered and pass.

PiperOrigin-RevId: 959025281
Change-Id: I2fed28c01491c5a8431e813102a423d12b659911
2026-08-04 08:04:27 -07:00
Yuval Tassa 574b6bd6bf More schema-related cleanup.
- Declare every nonzero default; make the defaults cross-check total.
- Skip default-valued attributes in the hand-written writer paths.
- Fix type facts on hand-read elements, found by the dm_control diff.

PiperOrigin-RevId: 958999733
Change-Id: I3064ccc6ae1f049c20f273abc234cd02990a8b7e
2026-08-04 07:05:41 -07:00
Yuval Tassa b475bb6f36 Move schema related generated files into their own directory
PiperOrigin-RevId: 958296165
Change-Id: I48cacc72c7df5994f5f816489ba069a5813845a1
2026-08-03 04:23:56 -07:00
Yuval Tassa 5e99ca6cb8 Table-driven attribute writing: rebase the writer on the shared rows.
The writer consumes the same generated rows as the reader.
mjXWriter::WriteAttrTable drives the mechanical attributes of an
element from its mjXAttr rows: each bound field is compared against
the class default at the same offset -- the default object is the same
struct type, so the rows carry no comparison values -- and attributes
equal to their default are skipped. A null default object means the
element has no defaults, and every defined value is written.
Ranged-arity rows write with trailing-default trimming, which the
reader makes round-trip exact by refilling from the same default.
Call sites upcast to the private mjs base (the friend declarations
permit it; mjCMesh gains the friendship its siblings had); the
comparison object is def->X().spec, a freshly-defaulted struct for
the sections, or zero-initialized for size, whose spec defaults (-1,
auto) are resolved by compilation.

Converted: pair, geom, site, joint, camera, light, material, the
equality family, both tendon types (the fixed rows are the spatial
rows without appearance attributes -- exactly the tag difference), the
actuator, flex with its three sub-elements, mesh, skin, option, the
six visual sub-sections, statistic and size. The remnants keep names,
files, resolved reference strings (the mjC classes null their private
base's string pointers; resolved names live behind accessors), and the
writing=custom policies the schema declares: compile directives never
saved (fromto, springdamper, fitscale), type-dependent lengths and
attributes (sizes, joint pos/axis/limited, shellinertia), and
alternatives (mass/density, fovy-versus-intrinsics, the plugin-gated
gain/bias family). Compiler keeps its write-if-nonzero policy;
keyframe keeps its model-sized vectors.

Saved files are canonical: attributes follow schema declaration order
with remnants trailing, and sections follow the schema's dependency
order (statistic before visual, deformable before the contact and
equality sections that name flexes, tendon before the equality
constraints that name tendons, custom demoted to the data tail).
Uniform behavior fixes fall out: default-equal positionals are
dropped, dynprm is trimmed like every other ranged vector, and mesh
material -- read into the spec but never written -- now survives
save/load round trips. Changelog entries ride along.

Verified: full suite, doc_test, and the two-tier A/B harness --
saved XML reorders attributes, and every corpus model reloads to a
byte-identical binary.
PiperOrigin-RevId: 958255003
Change-Id: I5fe7346014450db88b2f3f8680a8f616f7d31266
2026-08-03 02:27:22 -07:00
Yuval Tassa 4278c7b0cd Table-driven attribute reading: rebase the reader on generated rows.
Every mechanical attribute read in MJCF now derives from mjcf.schema.
generate_read_table.py emits typed mjXAttr rows (mjcf_read_table.inc,
doc_test-gated) binding each attribute to its spec struct field; field
offsets are offsetof() expressions, so binding mistakes are compile
errors, and the field's C type -- parsed from the headers -- selects the
row kind, so mjtNum-versus-double is decided by the struct, not the
schema. mjXReader::ReadAttrTable is the generic loop; its static core
also serves the section parsers and records XML-authored fields via
mjs_setAuthored for attach conflict resolution. Row kinds cover
strings, string lists, numeric scalars and vectors (exact and ranged),
enums (int- and byte-width), bitwise flag sets, bools, unbounded typed
vectors, fixed char arrays, and identity constants declared by 'set'.
The rows are inline variables, and carry the writing=custom flag,
because the writer will share them.

The keyword maps the rows reference are generated too: the ~48
hand-written mjMap tables become mjcf_map.h, one map and size constant
per enum as C++17 inline variables, retiring the hand-maintained
extern block in xml_base.h. Map names follow the schema enum names
(fluid->fluidshape, TFAuto->FalseTrueAuto, FAuto->FalseAuto,
joint->jointtype, geom->geomtype, jac->jacobian); all maps are
key-order- and value-identical to the hand tables they replace, and
bool_map is hand-emitted (the bool type is built in, not a schema
enum).

The OneX() parsers reduce to genuine irregulars, schema-marked as
reading=custom: orientation alternatives, file attributes (VFS and
asset-dir context), the actuator shorthand remappings and per-type
input maps, springlength's one-value copy, mesh builtin construction,
hfield elevation, texture cube files, flexcomp seeding, the memory
suffix parse, and the flag bit families. All 41 sensors that are pure
identity-plus-references -- including the frame family and insidesite
-- dispatch through a generated tag table; frame-sensor
objtype/reftype vocabulary tightens from the full mju_str2Type
namespace to the documented body/xbody/geom/site/camera subset, so an
invalid keyword now fails at parse time instead of compile time. The
equality family and both tendon types read shared group rows; the
twelve actuator shorthands share the general rows, with per-tag
legality enforced by the schema check. Sections bind non-mjs structs,
the visual sub-sections reaching their anonymous sub-structs through
member paths declared by an element-level field= facet.

Latent irregularities surfaced by the migration and preserved via
schema declarations or remnants: key's name is set even when absent,
eulerseq and gridlayout are fixed char arrays (chars[n], arity in
characters), gridlayout's length-must-match-gridsize stays a
value-conditional remnant, and constructor-style elements (tendon
wraps, asset model, replicate, attach) are annotated as such -- their
attributes are arguments, not field writes.

Two coherence tests guard the schema against the C sources: every
schema enum constant must be a member of the C enum it claims, and
every C member must be a keyword, a count sentinel, or a documented
exemption; and generate_default_table.py emits one row per defaulted
attribute (mjcf_default_table.inc), compared by SchemaDefaultsTest
against a freshly-constructed spec -- the schema cannot disagree with
the C default-constructors without failing the suite.

Verified: doc_test regenerates and diffs every artifact; the full
suite; and an A/B harness compiling the model corpus against the
pre-migration reader -- saved XML and binary models are byte-identical.
PiperOrigin-RevId: 958075724
Change-Id: I9715fe4deeb438eec988fd5084d74ba8b466b10b
2026-08-02 17:24:45 -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
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
Yuval Tassa a264d0bc8b Add geom adhesion: contacts that pull, via translated friction cones.
https://youtu.be/GioWwB36XHI

The new geom attribute adhesion (units of force, signed; pair-level
override) translates the contact friction cone along its normal so
that the force origin lies strictly inside it. Consequences: each
contact can pull with up to the given force before breaking, and the
tangential friction budget becomes mu*(f_N + adhesion) -- the
Mohr-Coulomb yield condition with cohesion c = mu*adhesion -- so
lightly-squeezed grasps retain a guaranteed friction floor.

A translated cone factors exactly into {constant attractive force}
+ {original cone}, so no solver kernels change. The implementation is
this factorization: a constant attraction along contact normals
accumulated into the new mjData.qfrc_adhesion (summed into
qfrc_passive), plus a bias of adhesive contact rows' reference
acceleration (aref += R*adhesion), which makes resting penetration
exactly independent of adhesion. Contacts of adhesive pairs remain
active throughout the gap zone, producing rows with positive violation
whose reference acceleration pulls: a tether that resists pull-off
smoothly, captures objects released within the band into steady
contact, and detaches at the specified force. Adhesion values of the
two geoms combine by sum; explicit pairs override.

mj_contactForce reports the net interface force (cone force minus the
adhesive pull), whose normal component can now be negative. Negative
adhesion is allowed and produces a repulsive offset (air hockey).

PiperOrigin-RevId: 950858148
Change-Id: I879c08eba7ae501e5c0f8c2f807167344da4c2bc
2026-07-20 08:35:45 -07:00
Yuval Tassa 4787c8094c Add geom surfacevel: zero-dof conveyors, treadmills and turntables.
https://www.youtube.com/watch?v=PdSdrqhSiZA

The new geom attribute surfacevel (6 numbers: linear and angular velocity in the geom's local frame, angular about the geom frame origin) specifies the velocity of the geom's surface material relative to the geom frame. The relative surface velocity of the two geoms is added to the tangential contact rows of efc_vel in mj_referenceConstraint, so friction drives touching bodies toward the motion of the surface: objects on a conveyor are transported at belt speed, turntables impart omega x r with torsional spin-up for condim >= 4, and surface velocities compose with each other and with body motion. The component along the contact normal is projected out: probe experiments showed that velocity-space emission chatters mass-independently and ingestion merely deepens penetration; normal-direction effects belong to force-space features.

surfacevel is interpreted in the geom frame as authored: for mesh geoms, whose compiled frame absorbs the mesh centering and principal-axes transform, the compiler re-expresses the authored value in the compiled frame.

No special interaction with sleeping: objects being transported do not fall asleep because they are moving; objects at rest on an active surface may sleep like any other resting object.

Includes showcase models (model/surfacevel/): a luggage carousel whose ring is a spinning square-profile supertorus fed by a cascade of belts with matched spinning end rollers, bags dropping in and circulating indefinitely; and a treadmill with a passive humanoid.

PiperOrigin-RevId: 948647785
Change-Id: I0c6559a91cc7ece1237eb8ac2e51986e7342d962
2026-07-15 17:58:17 -07:00
Yuval Tassa 5618666a7d Add body/simple attribute to control simple body optimization.
PiperOrigin-RevId: 942164766
Change-Id: I1e83bb99b6a1955917eb9b2e9bed0dc7b8e6a161
2026-07-03 09:09:30 -07:00
Yuval Tassa 410c73168c Add policies for global attribute conflict resolution upon attach
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
2026-06-17 03:36:10 -07:00
Kevin Zakka 1aaced190a Copybara import of the project:
--
3439d8a5cd745dfd2776593916eead65cb456afc by Kevin Zakka <kevinarmandzakka@gmail.com>:

Respect an explicit CMAKE_INTERPROCEDURAL_OPTIMIZATION=OFF

The default-LTO guard checked the value rather than whether it was DEFINED, so an
explicit -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=OFF (used in CI to cut build time)
was silently flipped back ON. Check DEFINED instead; default-on for Release is
preserved when the caller makes no choice.

--
bd15d1b264e5ab9594669b58fa1e0388d0a16f6b by Kevin Zakka <kevinarmandzakka@gmail.com>:

Speed up CI

~10x faster on the POSIX jobs (~45m -> ~4-5m) and ~2x overall wall-clock.

- Build Studio/Filament and WASM only in their dedicated canary jobs, not in
  every matrix job (WASM uses emcc, which ignores the host compiler).
- Compiler matrix -> build_matrix.json with core/extended tiers: PRs build the
  core set, pushes to main run the full sweep.
- ccache across build jobs (studio cache keyed on the Filament pin); fix the
  Python-bindings build so ccache hits (CCACHE_BASEDIR).
- Disable IPO/LTO on POSIX (it was silently on); keep it on Windows where /GL-off
  exposes a latent test bug and build time is not the bottleneck.
- Run ctest in parallel on POSIX (~2x); uv for Python installs (~29s -> ~8s).
- Move MJX (compiler-independent) to a single dedicated job.
- Restrict GITHUB_TOKEN to contents: read; bump actions off deprecated Node20.

--
c0618ab7aef524b238e0a30f2f23c50c4ce0c9b1 by Kevin Zakka <kevinarmandzakka@gmail.com>:

Build the gcc jobs with LTO off too

Restores LTO-off for gcc (recovering the build-time win). That surfaces known
gcc-12 -Wrestrict false positives in libstdc++ <char_traits> at -O3; two clean,
behavior-preserving rewrites in the XML writer avoid them. Confirmed gcc-12 and
gcc-14 build clean with LTO off (PR #3325).

--
2c38da0f48f77635e58e4b7931b86d60f3c253c7 by Kevin Zakka <kevinarmandzakka@gmail.com>:

Respect explicit IPO=OFF in the Simulate and Sample options too

Apply the same DEFINED check as cmake/MujocoOptions.cmake to the simulate/ and
sample/ subprojects (which carry identical copies of the guard) to keep the three
in sync, as the internal import requires. Since the guard now honors =OFF, stop
forcing IPO=OFF on the tiny samples/simulate CI builds so they keep their default
LTO and don't expose the gcc -Werror false positives that -O3-without-LTO triggers.

COPYBARA_INTEGRATE_REVIEW=https://github.com/google-deepmind/mujoco/pull/3315 from google-deepmind:speed-up-ci 2c38da0f48f77635e58e4b7931b86d60f3c253c7
PiperOrigin-RevId: 930008698
Change-Id: Ic41dc87881833c95f2ebfc0602de1ed438db3d4f
2026-06-10 12:27:14 -07:00
Yuval Tassa 71d1014e70 Add mjENBL_DIAGEXACT for exact constraint diagonal. Fixes #2472
PiperOrigin-RevId: 916932908
Change-Id: Id23ac39b5cd996afc52990719a4e07c0cc7de600
2026-05-17 16:47:54 -07:00
Alessio Quaglino fa912dffa0 Add flex arrays to CompareModel check.
Due to a bug, all flex mjModel fields were previously ignored.

PiperOrigin-RevId: 912546202
Change-Id: Ica95ecfcbbe366fd81de6e8f7d83ed57a7d23033
2026-05-08 08:47:51 -07:00
Kyle Bayes 6cb6e5a93f Enable multiccd by default.
PiperOrigin-RevId: 902752921
Change-Id: I8e2085ff17db0ac0db1641b8837415c458e5eca4
2026-04-20 12:00:10 -07:00
Alessio Quaglino 3d45a33190 Refactor flex strain constraints to be per-cell.
Each mjEQ_FLEXSTRAIN equality now represents a single cell within a flex. This allows for more efficient sparse Jacobian computation by only considering the degrees of freedom of the nodes within each specific cell. This change gives a speedup of about 10x on a 3x3x3 model.

PiperOrigin-RevId: 902164069
Change-Id: I78eedf1d5cf39b8989fe9863c22d164922fc0efb
2026-04-19 07:21:18 -07:00
Alessio Quaglino 6c7ed66781 Implement multi-cell finite element method for interpolated flexes.
This change introduces a `flex_cellcount` field to `mjModel` to specify the number of cells in each dimension for interpolated flexes. The stiffness computation, passive force calculation, and Jacobian derivatives are updated to operate on a per-cell basis, significantly improving performance by localizing computations to the nodes within each cell.

PiperOrigin-RevId: 901216393
Change-Id: Ic23132e609de11e71bb7fef8d1f139daad2ec264
2026-04-17 04:13:19 -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 510d75f4cf Allow actuators to add damping and armature to joint and tendon transmissions.
PiperOrigin-RevId: 886899849
Change-Id: I02200ee0d4f7c96096d8188b95f823b566562a30
2026-03-20 11:41:15 -07:00
Yuval Tassa efae9157a7 Polynomial stiffness and damping https://youtu.be/aKa3ZlEF9_Y
PiperOrigin-RevId: 884607673
Change-Id: If8088dbf37fed1055304778a7eb84dec52cba920
2026-03-16 13:25:25 -07:00
Alessio Quaglino 713b5524bc Introduces a new "strain" equality mode (flex_edgeequality = 3) for flexcomps with trilinear interpolation. This mode enforces constraints on the three invariants of the Green-Lagrange strain tensor at 8 Gauss quadrature points within each flex element, resulting in 24 equality constraints per flexcomp.
Also fixes a bug when attaching a flex with constraints.

PiperOrigin-RevId: 881349765
Change-Id: I8e6df8239488bfdc87d7e5b473568975e38c737e
2026-03-10 04:26:07 -07: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
Alessio Quaglino 7da271c687 Add vertex equality option.
PiperOrigin-RevId: 860299454
Change-Id: I7befd8e5f4c8bac6d74684a96a9cc3cee9ae1e29
2026-01-23 16:30:05 -08:00
Yuval Tassa 608115ab95 Add output attribute to camera elements.
This attribute allows specifying the intended output types (e.g., RGB, depth, normal) for each camera in the XML. The output types are stored as bit flags in `mjModel`.

PiperOrigin-RevId: 853316261
Change-Id: I1ad2e94102593cf402756f8f4c80509371ca86d2
2026-01-07 10:22:27 -08:00
Yuval Tassa 70bc7be4bc Add additional data fields that can be reported by rangefinder sensors.
PiperOrigin-RevId: 848316991
Change-Id: Idbf7ba81b4da711a22c23302c8782ab2b0b98d82
2025-12-23 15:33:00 -08:00
Yuval Tassa 9d646e6548 Extend rangefinder sensor to support cameras.
PiperOrigin-RevId: 848255889
Change-Id: I6e1a9ed13d29d2242558625a47e24e47ad6e87db
2025-12-23 12:04:49 -08:00
Yuval Tassa b8a4ac5d48 Refactor camera orthographic attribute to projection enum.
PiperOrigin-RevId: 847069028
Change-Id: I7f686fe654e9b56519cab8bd2f37c9cc40091d3f
2025-12-20 03:28:29 -08:00
Yuval Tassa c064abc3da Change row-flipping logic for heightfields.
Move row-flipping logic from `mjCModel::CopyBack` to `mjXWriter`.

PiperOrigin-RevId: 842220322
Change-Id: I6fb09db6c9e8689f6e435f82f58dd3e7c4314478
2025-12-09 07:02:21 -08:00
Yuval Tassa 252a0d73df Add sleep related data structures
PiperOrigin-RevId: 829055431
Change-Id: I1ccbd77a57044a754ae7db611b4c2c0010fbda53
2025-11-06 12:10:55 -08:00
Sam Haves 59f14485e0 Move mjCWrap type to mjsWrap.
PiperOrigin-RevId: 821851540
Change-Id: I53382a8a21312a96aea46eec130f43e7cad70f92
2025-10-20 16:28:41 -07:00
Yuval Tassa 431f96572e Remove unused mjOption.apirate.
PiperOrigin-RevId: 815633571
Change-Id: Ib98f3eb2df47f96fa1fe6e987a3a0cd23a9479f6
2025-10-06 02:51:17 -07:00
Yuval Tassa b092563cab Remove mjDSBL_PASSIVE, split it into mjDSBL_SPRING and mjDSBL_DAMPING.
PiperOrigin-RevId: 800870384
Change-Id: I273e0ceec090901e2620febb67e57914928e94bb
2025-08-29 06:06:28 -07:00
Yuval Tassa ec94bb49aa Make constraint island discovery on by default.
Also fix latent bug in mjData serialization.

PiperOrigin-RevId: 799505349
Change-Id: I299e7cc8133fa2ec0b339a7ff3d02543e06778b1
2025-08-26 04:27:24 -07:00
Alessio Quaglino 51babec9c5 Move tactile sensor to the engine.
PiperOrigin-RevId: 788863133
Change-Id: I3172ebb7641fa8146469da25cba7db794760e7b1
2025-07-30 05:27:44 -07:00
Yuval Tassa d0e4771c8c Add contact sensor.
PiperOrigin-RevId: 783011982
Change-Id: Ica56fe9d520fa1d1ee7338e09148b1a55a049912
2025-07-14 13:03:35 -07:00
Yuval Tassa e6c5715903 Add insidesite sensor for detecting when an object is inside the volume of a site.
PiperOrigin-RevId: 780993257
Change-Id: I2dcfc840d222680adc3b934344a0819f4d78b6eb
2025-07-09 04:56:42 -07:00
Yuval Tassa c945247e7c Don't write limited and actuatorfrclimited attributes when "true" is not a valid value.
Saved XMLs are filled with
```
<joint type="free" limited="false" actuatorforcelimited="false"/>
```

but since these are hardcoded to "false" at compile time, there is no point in saving them to XML.

PiperOrigin-RevId: 776606516
Change-Id: Iac61c5126231f776077a8c265be732f9215fbfbb
2025-06-27 09:07:30 -07:00
Yuval Tassa 14dc7c2a60 Add "cameraid" attribute to visual/global specifying the default camera to use at model load.
PiperOrigin-RevId: 773783069
Change-Id: I2fff2abdceedc982d89cee8d14b95abceea1c113
2025-06-20 11:41:27 -07:00
Alessio Quaglino 5f42078dc1 Do not write nameless frames whose class is "main".
PiperOrigin-RevId: 769685151
Change-Id: I3d993d7521db2b2adbf611c3e4eb5b4b293bdc30
2025-06-10 10:15:43 -07:00
Alessio Quaglino 84ad22a590 Add mj_copyBack for copying real-valued arrays from mjModel back to mjSpec.
Also add `SaveAndReadXML` function to test fixture using `mjSpec` as input.

PiperOrigin-RevId: 765393821
Change-Id: Ic257addd2fc89678fc11b226c168c077626cc51e
2025-05-30 17:17:14 -07:00
Google DeepMind 568620dd2f Add texture attribute to lights.
PiperOrigin-RevId: 763739805
Change-Id: I333ed2ac68f30f79f688ca01d7b5fd6bf2d836c9
2025-05-27 05:04:01 -07:00
Google DeepMind 74cc904edc Convert light directional boolean into a type enum.
PiperOrigin-RevId: 761983728
Change-Id: Id5bf93c103e5358d9c5cd9f1176532a978e0b3a8
2025-05-22 08:51:18 -07:00
Google DeepMind 3e9bc79b54 Adds color space to textures.
PiperOrigin-RevId: 761907261
Change-Id: Iec546d1d5907a15e57ef809ec31850640fc52915
2025-05-22 04:33:40 -07:00
Alessio Quaglino 7edbdd0ad6 Remove the Shell plugin and integrate it into the engine.
PiperOrigin-RevId: 760688502
Change-Id: Ia70988d42b7edf571d7cb4a4f48f8fc50b51667d
2025-05-19 10:51:25 -07:00
Alessio Quaglino 71bdd915f7 Move bending stiffness from plugin to the compiler.
PiperOrigin-RevId: 758677644
Change-Id: I7d5c5140ba6948002bfa4ae9d6b4bf0f6de0e39b
2025-05-14 07:39:24 -07:00
Google DeepMind fa95fe0c59 Add intensity and range parameters to lights.
PiperOrigin-RevId: 758603199
Change-Id: I74e88bdfeedd9224e84d953f237d68eca79e6cb7
2025-05-14 03:28:03 -07:00
Alessio Quaglino 449de73430 Do not skip cow and touch_grid during WriteReadCompare.
PiperOrigin-RevId: 755370618
Change-Id: I90dfe66b20c316b19c943eab8d031f5aef187fa7
2025-05-06 07:54:39 -07:00
Taylor Howell 96dda6ea75 Add tendon actuator force limits and tendon actuator force sensor.
PiperOrigin-RevId: 745096883
Change-Id: Ib9acb727fbbfc6b0b0323ee6a889053a7a878056
2025-04-08 05:16:35 -07:00
Yuval Tassa e1f5ceb65a Add mjModel.tendon_armature (in preparation, not yet implemented)
PiperOrigin-RevId: 743649968
Change-Id: I1d893e3e06afc48b652575bc7837750ab3573670
2025-04-03 12:06:27 -07:00
Yuval Tassa f96f3e1c22 Add XML compiler/saveinertial flag. Fixes #2405
PiperOrigin-RevId: 743607654
Change-Id: I1f2e61be89b79c1995e079f36aa285096f9fb441
2025-04-03 10:12:42 -07:00