Make constraint island discovery on by default.
Also fix latent bug in mjData serialization. PiperOrigin-RevId: 799505349 Change-Id: I299e7cc8133fa2ec0b339a7ff3d02543e06778b1
This commit is contained in:
committed by
Copybara-Service
parent
4cf5c37211
commit
ec94bb49aa
@@ -587,6 +587,14 @@ from its default.
|
||||
This flag enables the native convex collision detection pipeline instead of using the
|
||||
`libccd library <https://github.com/danfis/libccd>`__, see :ref:`convex collisions<coCCD>` for more details.
|
||||
|
||||
.. _option-flag-island:
|
||||
|
||||
:at:`island`: :at-val:`[disable, enable], "enable"`
|
||||
This flag enables discovery and construction of constraint islands: disjoint sets of constraints and
|
||||
degrees-of-freedom that do not interact and can be solved independently. Islanding is not yet supported by the PGS
|
||||
solver. See :ref:`soIsland` for more details. The :ref:`mjVIS_ISLAND <mjtVisFlag>` enables
|
||||
`island visualization <https://youtu.be/Vc1tq0fFvQA>`__.
|
||||
|
||||
.. _option-flag-eulerdamp:
|
||||
|
||||
:at:`eulerdamp`: :at-val:`[disable, enable], "enable"`
|
||||
@@ -647,14 +655,6 @@ from its default.
|
||||
to instabilities that typically manifest as sliding or wobbling. The implementation of this feature depends on the
|
||||
selected convex collision pipeline, see :ref:`convex collisions<coCCD>` for more details.
|
||||
|
||||
.. _option-flag-island:
|
||||
|
||||
:at:`island`: :at-val:`[disable, enable], "disable"`
|
||||
This flag enables discovery of constraint islands: disjoint sets of constraints and
|
||||
degrees-of-freedom that do not interact. The flag currently has no effect on the physics pipeline, but enabling it
|
||||
allows for `island visualization <https://youtu.be/Vc1tq0fFvQA>`__.
|
||||
In a future release, the constraint solver will exploit the disjoint nature of constraint islands.
|
||||
|
||||
.. _compiler:
|
||||
|
||||
**compiler** (*)
|
||||
|
||||
+2
-2
@@ -37,9 +37,9 @@
|
||||
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||
| | | | :ref:`sensor<option-flag-sensor>` | :ref:`midphase<option-flag-midphase>` | :ref:`eulerdamp<option-flag-eulerdamp>` | :ref:`autoreset<option-flag-autoreset>` | |
|
||||
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||
| | | | :ref:`override<option-flag-override>` | :ref:`energy<option-flag-energy>` | :ref:`fwdinv<option-flag-fwdinv>` | :ref:`invdiscrete<option-flag-invdiscrete>` | |
|
||||
| | | | :ref:`nativeccd<option-flag-nativeccd>` | :ref:`island<option-flag-island>` | :ref:`override<option-flag-override>` | :ref:`energy<option-flag-energy>` | |
|
||||
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||
| | | | :ref:`multiccd<option-flag-multiccd>` | :ref:`island<option-flag-island>` | :ref:`nativeccd<option-flag-nativeccd>` | | |
|
||||
| | | | :ref:`fwdinv<option-flag-fwdinv>` | :ref:`invdiscrete<option-flag-invdiscrete>` | :ref:`multiccd<option-flag-multiccd>` | | |
|
||||
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| mujoco |br| |L| | | .. table:: |
|
||||
|
||||
@@ -7,9 +7,16 @@ Upcoming version (not yet released)
|
||||
|
||||
General
|
||||
^^^^^^^
|
||||
- Constraint island discovery and construction, previously an experimental feature, is now :ref:`documented<soIsland>`
|
||||
and promoted to default; disable it with :ref:`option/flag/island <option-flag-island>`. We expect islanding to be
|
||||
a strict improvement over the monolithic constraint solver, please let us know if you experience any issues.
|
||||
|
||||
.. admonition:: Breaking API changes
|
||||
:class: attention
|
||||
|
||||
- The promotion of islanding to default involved removing the enable flag ``mjENBL_ISLAND`` and
|
||||
converting it to a disable flag :ref:`mjDSBL_ISLAND <mjtDisableBit>`.
|
||||
|
||||
- The update of ``mjData.qacc_warmstart`` was moved from the end of the solver call (:ref:`mj_fwdConstraint`) to the
|
||||
end of :ref:`mj_step`, and is now updated with all other state variables. This change makes :ref:`mj_forward`
|
||||
fully idempotent.
|
||||
@@ -43,6 +50,11 @@ MJX
|
||||
|
||||
- ``ten_length`` was moved from ``mjx.Data._impl.ten_length`` to a public field ``mjx.Data.ten_length``.
|
||||
|
||||
Bug fixes
|
||||
^^^^^^^^^
|
||||
- Fixed a latent bug where MjData objects were not serialized correctly by the Python bindings when islanding was
|
||||
enabled.
|
||||
|
||||
|
||||
Version 3.3.5 (August 8, 2025)
|
||||
------------------------------
|
||||
|
||||
@@ -1362,15 +1362,45 @@ representations of the constraint Jacobian and related matrices.
|
||||
axes. The right panel illustrates our solution to this problem. We still update one contact at a time, but within a
|
||||
contact we update along non-orthogonal axes adapted to the constraint surface, as follows. First, we optimize the
|
||||
quadratic cost along the ray from the tip of the cone through the current solution. Then we slice the cone with a
|
||||
hyperplane passing through the current solution and orthogonal to the contact normal. This yields an ellipsoid -which
|
||||
can be up to 5-dimensional given our contact model. Now we optimize the quadratic cost within this ellipsoid. This is
|
||||
an instance of quadratically constrained quadratic programming (QCQP). Since there is only one scalar constraint
|
||||
hyperplane passing through the current solution and orthogonal to the contact normal. This yields an ellipsoid which
|
||||
can be up to 5-dimensional, given our contact model. Now we optimize the quadratic cost within this ellipsoid. This
|
||||
is an instance of quadratically constrained quadratic programming (QCQP). Since there is only one scalar constraint
|
||||
(however nonlinear it may be), the dual is a scalar optimization problem over the unknown Lagrange multiplier. We
|
||||
solve this problem with Newton's method applied until convergence -- which in practice takes less than 10 iterations,
|
||||
and involves small matrices. Overall this algorithm has similar behavior to PGS for pyramidal cones, but it can
|
||||
handle elliptic cones without approximating them. It does more work per contact, however the contact dimensionality
|
||||
is smaller, and these two factors roughly balance each other.
|
||||
|
||||
.. _soIsland:
|
||||
|
||||
Constraint islands
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. image:: ../images/computation/island.svg
|
||||
:width: 58%
|
||||
:align: right
|
||||
|
||||
Consider the abstract graph defined by degrees of freedom (dofs) and constraints. A vertex is all the dofs in a single
|
||||
kinematic subtree; an edge is a constraint (a contact or equality) between two bodies belonging to different subtrees. A
|
||||
*constraint island* is a disjoint sub-graph which can be solved for independently, because constraint forces cannot
|
||||
propagate between islands. Constraint island discovery and construction ("islanding") invloves finding the disjoint
|
||||
subgraphs and reordering both the dofs and constraints to make them memory-contiguous. This amounts to a
|
||||
block-diagonalization of the constraint Jacobian :math:`J`, as illustrated in the figure. On the left is the monolithic
|
||||
Jacobian of size :math:`\nc \times \nv`, where we use the :ref:`corresponding <Framework>` size names from MuJoCo's data
|
||||
structures ``mjData.nefc`` and ``mjModel.nv``. On the right is the block-diagonalized Jacobian with 3 islands that can
|
||||
be solved indepenently. Note that islanding also identifies unconstrained dofs, so ``mjData.nidof``, the total number of
|
||||
dofs in all islands, might be smaller than ``mjModel.nv``. While islanding is not free (see implementation in
|
||||
`engine_island.c <https://github.com/google-deepmind/mujoco/blob/main/src/engine/engine_island.c>`__), it is worth the
|
||||
effort:
|
||||
|
||||
- Different islands require different numbers of iterations to converge, and a monolithic solve would run for the
|
||||
number required by the slowest island.
|
||||
- Unconstrained dofs are completely untouched by the solver, which otherwise needs to discover that they are unaffected.
|
||||
- Solving separate islands can be multi-threaded.
|
||||
|
||||
Islanding is not yet supported by the PGS solver.
|
||||
|
||||
|
||||
.. _soParameters:
|
||||
|
||||
Parameters
|
||||
@@ -1694,7 +1724,8 @@ The stages below compute quantities that depend on the generalized positions ``m
|
||||
7. Compute the sparse factorization of the joint-space inertia matrix: :ref:`mj_factorM`
|
||||
8. Construct the list of active contacts. This includes both broad-phase and near-phase collision detection:
|
||||
:ref:`mj_collision`
|
||||
9. Construct the constraint Jacobian and compute the constraint residuals: :ref:`mj_makeConstraint`
|
||||
9. Construct the constraint Jacobian, compute the constraint residuals, construct islands: :ref:`mj_makeConstraint`,
|
||||
``mj_island`` (not yet exposed in the API)
|
||||
10. Compute the actuator lengths and moment arms: :ref:`mj_transmission`
|
||||
11. Compute the matrices and vectors needed by the constraint solvers: :ref:`mj_projectConstraint`
|
||||
12. Compute sensor data that only depends on position, and the potential energy if enabled: :ref:`mj_sensorPos`,
|
||||
|
||||
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 6.7 KiB |
@@ -464,8 +464,9 @@ typedef enum mjtDisableBit_ { // disable default feature bitflags
|
||||
mjDSBL_EULERDAMP = 1<<14, // implicit integration of joint damping in Euler integrator
|
||||
mjDSBL_AUTORESET = 1<<15, // automatic reset when numerical issues are detected
|
||||
mjDSBL_NATIVECCD = 1<<16, // native convex collision detection
|
||||
mjDSBL_ISLAND = 1<<17, // constraint island discovery
|
||||
|
||||
mjNDISABLE = 17 // number of disable flags
|
||||
mjNDISABLE = 18 // number of disable flags
|
||||
} mjtDisableBit;
|
||||
typedef enum mjtEnableBit_ { // enable optional feature bitflags
|
||||
mjENBL_OVERRIDE = 1<<0, // override contact parameters
|
||||
@@ -474,9 +475,8 @@ typedef enum mjtEnableBit_ { // enable optional feature bitflags
|
||||
mjENBL_INVDISCRETE = 1<<3, // discrete-time inverse dynamics
|
||||
// experimental features:
|
||||
mjENBL_MULTICCD = 1<<4, // multi-point convex collision detection
|
||||
mjENBL_ISLAND = 1<<5, // constraint island discovery
|
||||
|
||||
mjNENABLE = 6 // number of enable flags
|
||||
mjNENABLE = 5 // number of enable flags
|
||||
} mjtEnableBit;
|
||||
typedef enum mjtJoint_ { // type of degree of freedom
|
||||
mjJNT_FREE = 0, // global position and orientation (quat) (7)
|
||||
|
||||
Reference in New Issue
Block a user