Commit Graph

1060 Commits

Author SHA1 Message Date
Yuval Tassa f712eed4ce Allow flex sleeping
PiperOrigin-RevId: 917817500
Change-Id: Ia3bd5e52e7c2eaa3f70c81352d82c130b1d357f6
2026-05-19 07:15:27 -07:00
Copybara-Service a1056676a0 Merge pull request #3276 from dparikh79:fix/3275-boxqp-symmetric-lower-matvec
PiperOrigin-RevId: 917279467
Change-Id: If4117b1e2147679336becb558e0f87621555dfc7
2026-05-18 09:36:01 -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
Yuval Tassa 04042d8bf3 Move square root of Delassus matrix from stack to arena
PiperOrigin-RevId: 916852244
Change-Id: I4379553f808d0b238a1421606f806ea2d0a33d7c
2026-05-17 11:21:55 -07:00
Dhruvil 71072c025d Honor lower-triangle contract for H in mju_boxQP.
mju_boxQP documents that only the lower triangle of the Hessian H is
read, but the gradient and search-direction updates inside
mju_boxQPoption still called the dense mju_mulMatVec, which reads the
upper triangle as well. This violated the documented contract and
prevented callers from safely leaving the upper triangle uninitialized.

Add a file-local mulMatVecSym helper that computes res = H*vec while
reading only the lower triangle of H (mirroring the convention of the
existing mulVecMatVecSym quadratic-form helper), and use it in place of
mju_mulMatVec in both call sites. Extend the BoxQP test suite with
UpperTrianglePoisoned, which fills the strict upper triangle of H with
NaN and verifies that the solver produces the same result as on the
clean symmetric input.

Reported by @lshdlut.

Fixes #3275
2026-05-17 13:56:53 -04:00
Alessio Quaglino 71ddeb3efc Add fast path for flex derivative computation in centered flexes.
Introduce a fast path in mj_addFlexDerivatives for centered flexes where all nodes are attached to bodies with only 3 translational DOFs and no DOF-contributing ancestors. This allows for a direct scatter of K*vec, avoiding the overhead of sparse Jacobian construction and multiplication.

PiperOrigin-RevId: 916063477
Change-Id: I824728a5bdc3b975b04b46ecf22994922e307a8c
2026-05-15 10:13:22 -07:00
Alessio Quaglino 093b92acc1 Add bounds check for cached node indices in passive mesh.
The global node indices stored in face_gidx are now checked to ensure they are within the valid range of node numbers, raising an error if any index is out of bounds.

PiperOrigin-RevId: 916025763
Change-Id: I1d2dcb11603137c337493541066b62b2ed2854c0
2026-05-15 08:50:49 -07:00
Alessio Quaglino 9fb548cadb Optimize flex bending edge computation by caching face states.
In `mj_flexPassive`, precompute and cache face positions, global indices, and corotational quaternions for all faces. This avoids redundant calls to `mju_flexGatherFaceState` for each bending edge, as each face can be part of multiple bending edges. This gives a 3-4x speedup in mj_passive.

PiperOrigin-RevId: 915912918
Change-Id: I3e1c00cf2d989f85398a0750a0faf359249cfe01
2026-05-15 03:32:01 -07:00
Alessio Quaglino 0ad77f1ddf Optimize flexedge velocity computation.
Skip flexedge velocity calculation for rigid and interpolated flexes, as they are not used in those cases. The computation is now done per-flex, only for the edges within each non-rigid, non-interpolated flex.

PiperOrigin-RevId: 915907396
Change-Id: I0beb1f98f0115c83da13fed184e89101f57563ab
2026-05-15 03:16:09 -07:00
Alessio Quaglino 7ca1bc6a56 Precompute rotated stiffness matrix before CG in implicit flex integrator.
This gives a 3x speedup in implicitfast.

Also cleanup old code that was used in the dense factorization of the stiffness matrix before we switched to CG.

PiperOrigin-RevId: 915900315
Change-Id: Id6973c4bfd7d371a43ec6db982703969b23a3550
2026-05-15 02:58:06 -07:00
Taylor Howell e1f5534b5f Fix tactile sensor body validation.
PiperOrigin-RevId: 914870657
Change-Id: I57565b4975e0cd7eb1b1ffa199e451a5c5bc0a6e
2026-05-13 08:11:36 -07:00
Alessio Quaglino 955ae3f3c0 Fix sign error in flex interp implicit integration.
The flex interp stiffness matrix is Negative Semi-Definite (NSD). When forming the RHS for implicit integration, the term involving the velocity and stiffness should be added, not subtracted. A new test is added to ensure energy stability for flex interp stretch stiffness with the implicitfast integrator.

PiperOrigin-RevId: 914845245
Change-Id: Iaaf0914909128e64e195f17cc5f2f344a8a43bc2
2026-05-13 07:15:20 -07:00
Alessio Quaglino 35cdc779e6 Add implicit bending stiffness for standard flex.
Standard flex (flex_interp=0) with thin-plate bending treated bending forces purely explicitly. This caused contact-induced vertex vibrations and non-physical energy injection for flat resting sheets, because the solver treated each vertex as an independent mass during contact and contact normals are orthogonal to stretch constraints.

Fix: extend the existing preconditioned CG solver to include the constant bending stiffness K_bend in the implicit operator via matrix-free mat-vec.
PiperOrigin-RevId: 914774020
Change-Id: I45e0d6749abb6f873566203bccae956514b2576b
2026-05-13 03:58:16 -07:00
Yuval Tassa 7bfdbad80b Make PGS solver constraint visitation order time-independent.
PiperOrigin-RevId: 914741347
Change-Id: I7889a42543e9a9f3ff883e25ee9eafaceedc29e1
2026-05-13 02:34:30 -07:00
Yuval Tassa a4e49f2dff Margin and gap redesign (breaking change)
PiperOrigin-RevId: 914329812
Change-Id: I905665e4c1965bdb8b90587e5b1277cfbfe5cce0
2026-05-12 09:43:43 -07:00
Alessio Quaglino f9f1db1e0a Replace the banded Cholesky solver for implicit flex interpolation
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
2026-05-11 10:11:51 -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
Alessio Quaglino df59e7d0f1 Fix mj_makeConstraint error for flex trilinear vs trilinear contacts.
The coordinates for flex interpolation are now computed using the absolute values of the vertex weights. The sign of the first vertex weight is then applied to the resulting barycentric weights. This correctly handles cases where the flex is both the first and the second entity in the contact pair.

PiperOrigin-RevId: 913590928
Change-Id: I970b35fba3d209e13b5b33bb5f945e3c6a43d487
2026-05-11 02:45:27 -07:00
Alessio Quaglino 5ee8bd7b9c Rotate undeformed normals before using them in the bending passive forces.
The normal jump residual in flex elasticity calculations now rotates the rest-frame normal jump into the current frame using the face's corotational quaternion before subtracting the jump from the current normal difference.

PiperOrigin-RevId: 913242127
Change-Id: Ia62b28ecccd59e79225737d8225ef4131b333c96
2026-05-10 03:00:11 -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
Alessio Quaglino 0c05215e18 Reduce flex stiffness and bending memory size to the exact amount needed.
PiperOrigin-RevId: 911774147
Change-Id: I3b18eba23e75ec91ece8342945f25e0cd7c63a1a
2026-05-06 23:53:19 -07:00
Yuval Tassa 6376e67070 Extract AVX code from engine_util_blas.c into engine_util_blas_avx.h
PiperOrigin-RevId: 911274884
Change-Id: Iaac2789f9538f669c49b497d1e60947a783368d3
2026-05-06 05:25:53 -07:00
Alessio Quaglino d249c882d5 Fix gcc errors due to restrict.
PiperOrigin-RevId: 910814591
Change-Id: I6858b1a36e21c6d47df803f49ceaed62c8e56248
2026-05-05 11:38:55 -07:00
Yuval Tassa 5c156ebf15 Refactor sparse constraint Jacobian supernode computation.
- Compute efc_J_rowsuper incrementally in mj_addConstraint instead of post-hoc via mju_superSparse.
- Better exploitation of supernodes in A matrix pipeline: precount and fill skip redundant chain traversals for supernode rows.
- Redundant B_rowsuper computation via mju_superSparse is eliminated (indentical to efc_J_rowsuper).

PiperOrigin-RevId: 910787825
Change-Id: I6eda9996659602b7051ee1090aeedb862603c84e
2026-05-05 10:57:31 -07:00
Alessio Quaglino d933b195ee Implement bending forces for interpolated flex shells.
This change adds a new passive force computation for flexes with elastic2d="bend" and dof="trilinear". The bending energy is based on the squared difference of normals between adjacent face elements at their shared edge midpoint. The edge data is precomputed during model compilation and stored in flex_bending.

PiperOrigin-RevId: 910772638
Change-Id: I3b12c7b7f1ba6ac1875df495d89e8cfec921ca80
2026-05-05 10:33:18 -07:00
Yuval Tassa 4ed69b5ce7 Randomize PGS constraint visitation order.
Total testspeed runtime for `2humanoids100.xml` reduced by 19.6% (49.5 -> 39.8s).

PiperOrigin-RevId: 910608140
Change-Id: Ided0ae5bdb8e4e8196f84e08354a9ae8cfa5b626
2026-05-05 05:10:26 -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
Yuval Tassa 25751a7b98 Add dense LU factorization and solve functions.
PiperOrigin-RevId: 909290647
Change-Id: I77ae2352b20abf96ef7b48ae32b03a1f4098604e
2026-05-02 13:27:04 -07:00
Alessio Quaglino dbd451138c Add flex_bendingadr to mjModel.
PiperOrigin-RevId: 909088123
Change-Id: If062335d0aa3702c1e0b082dd9e29c3be0e76ea6
2026-05-02 00:13:39 -07:00
Alessio Quaglino b2feed63e4 Skip implicit solver if there are strain constraints.
PiperOrigin-RevId: 908890994
Change-Id: Ieb05a162142edac14269ec6a509fc507c9146ac5
2026-05-01 14:10:00 -07:00
Yuval Tassa 910b3336ed Restrict midpoint integration to unconstrained free bodies in implicitfast
PiperOrigin-RevId: 908750768
Change-Id: I9a45a160ac757cc82bfe54871609956769988369
2026-05-01 08:41:47 -07:00
Alessio Quaglino 8287d9d152 Fix insidesite sensor for massless flex parent bodies.
mjSENS_INSIDESITE uses xipos to test containment, but for massless flex
parent bodies xipos equals the static body frame origin and does not
track the actual flex position.

Fix: in the INSIDESITE sensor case, when the object is a massless body
with positive subtree mass (i.e., a flex parent), use subtree_com
instead of xipos. This correctly reflects the mass-weighted centroid of
the flex child bodies without changing the global semantics of xipos.
PiperOrigin-RevId: 908745144
Change-Id: I527f0efb7b419345188411c9da883505156ebeea
2026-05-01 08:27:04 -07:00
Yuval Tassa f7d31e06f0 Refactor utility functions for block extraction.
PiperOrigin-RevId: 908744392
Change-Id: I8d1323946870c90d5e37b1853697fb35d5291e11
2026-05-01 08:24:38 -07:00
Alessio Quaglino e71bd3db8e Refactor flex passive forces into dedicated functions.
The code for computing passive forces for flex elements is moved into new static functions `mj_flexPassiveInterp`, `mj_flexPassiveBend`, and `mj_flexPassiveStretch`. This improves the structure of `mj_springdamper`.

PiperOrigin-RevId: 907671516
Change-Id: I6d1e781bbd370331ae645a954b78092ecb1925b9
2026-04-29 10:50:54 -07:00
Alessio Quaglino 9c6a4f76eb Add 2D membrane elasticity for interpolated flex shell mode
When elastic2d="stretch" is set on an interpolated flexcomp, treat the bounding box boundary as membrane elements rather than volumetric cells. This computes plane-stress stiffness over the boundary faces and updates the runtime force/derivative kernels accordingly.

Interior vertex tracking (moving vertices that follow the deforming shell) is not yet implemented so all mesh vertices need to be on the bounding box surface or the background grid should have no interior nodes (i.e. cellcount should be 1 on at least one axis).

PiperOrigin-RevId: 907654080
Change-Id: I51b90e2f6a1d1b036f9604e42de20e377dc5d3f9
2026-04-29 10:17:21 -07:00
Yuval Tassa 647af382c1 Add per-island PGS solver dispatch.
Total testspeed runtime for `2humanoids100.xml` reduced by 27.6% (63.4 -> 49.5s) due to early termination on small islands

PiperOrigin-RevId: 906910915
Change-Id: If55ad468c3680ef44eda7000455a77f8003b3122
2026-04-28 05:13:54 -07:00
Yuval Tassa 25a9114705 No-op refactor of PGS and NoSlip solvers in preparation for island support.
PiperOrigin-RevId: 906826882
Change-Id: I2003097e1bb81ebabda3a7075f1f8200d4d5ff95
2026-04-28 02:11:30 -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
Alessio Quaglino a891782553 Clean-up flex assumptions.
Do not allow a mix of `elastic2d != none` with `dof = trilinear` since the latter assumes 3d elasticity.

Also, do not assume that `flex_interp > 0` in the engine. This will enable to use, e.g., `flex_interp = -1` to mean a linear surface finite element instead of a 3d finite element which is currently identified with `flex_interp = 1`.

PiperOrigin-RevId: 903852035
Change-Id: Ia6290b4a05e9e510ffb7f36d141cd525b40d3110
2026-04-22 08:01:34 -07:00
Kyle Bayes 3325971840 Add mj_maxContact API function.
PiperOrigin-RevId: 903135055
Change-Id: I5f103c7d51f97e327c923bc567002ace835f5517
2026-04-21 04:03:22 -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 508e581ba9 Optimize flex by pinning nodes in empty cells.
This change introduces an optimization for flexcomp objects defined by a mesh. It identifies grid cells that do not contain any mesh vertices and marks them as empty. Nodes that are exclusively part of empty cells are pinned, preventing them from moving. Stiffness computations are skipped for empty cells, reducing computational cost. The total mass is now distributed only among the non-pinned nodes.

PiperOrigin-RevId: 902565735
Change-Id: Id0a9a685536d5e18a3e42124a25ab08ff3a918f2
2026-04-20 04:41:17 -07:00
Yuval Tassa e6d77650f7 Refactor mju_combineSparse to eliminate temporary buffers.
Combine sparse vectors in-place by first counting total `nnz` and then working backwards from the end. This removes the need for temporary buffers in `mju_combineSparse` and its callers and speeds up the function by ~10%.

PiperOrigin-RevId: 902530210
Change-Id: I4f48c327103552ab968d3915399c6067367bec9f
2026-04-20 03:10:18 -07:00
Alessio Quaglino 3230cf99f9 Change flex constraints to eigenmodes of the stiffness matrix.
This provides a reduction from 26 to 18 constraints for trilinear and from 162 to 75 for quadratic. The assembly of the constraints becomes trivial. In total the speedup for a trilinear 3x3x3 grid is about 3x.

PiperOrigin-RevId: 902502398
Change-Id: I764772c7adef78da5a644f64701f842d36e4b543
2026-04-20 02:02:44 -07:00
Yuval Tassa a04c2b1b4a Consolidate stack allocation calls in primal solvers down from 30 to 2 (dense) or 6 (sparse). Preparation for atomic allocation calls in threaded mode.
PiperOrigin-RevId: 902496039
Change-Id: I39df011951713505c4743c7475d74856ddbdf4f9
2026-04-20 01:47:30 -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 b16383dfaf Use banded solver for implicit flex integration.
The flex interpolation stiffness matrix within the implicit/implicitfast solvers is now built and factorized in a banded format instead of a dense one. This involves:
-   Calculating the bandwidth based on the sparsity of the mass/damping matrix and the connectivity within flex cells.
-   Allocating and populating a banded matrix `H`.
-   Using `mju_cholFactorBand` and `mju_cholSolveBand` for factorization and solving.
This change improves performance for flexes with many DOFs but local coupling.

PiperOrigin-RevId: 901297952
Change-Id: I3efe06353d1903ea65ab30dc49685cede228bb68
2026-04-17 08:00:07 -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
Kyle Bayes 56e98cc16c Improve AABB bounds in makeAAMM.
MODEL           BEFORE(ns)   AFTER(ns)
boxmesh.xml     874645       744822
box.xml         808226       786226
ellipsoid.xml   1477609      1436058
mixed.xml       1492063      1404848

PiperOrigin-RevId: 900626282
Change-Id: I3df5a6cd8a4cb2e3b9ded1b40a5310a4c14ec624
2026-04-16 03:25:18 -07:00