Skip to content

Commit 315bcfb

Browse files
yuvaltassacopybara-github
authored andcommitted
Remove mjData.qM
PiperOrigin-RevId: 942520660 Change-Id: I422358e299ca0fcfe4c49cd0ee90c014a4c319d7
1 parent 7c6f519 commit 315bcfb

16 files changed

Lines changed: 14 additions & 76 deletions

File tree

doc/changelog.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ General
2525
- Switched :ref:`mjd_inverseFD` to use the CSR-format ``mjData.M`` representation instead of the legacy ``mjData.qM``
2626
for the mass matrix derivative. This changes the shape of the ``DmDq`` parameter from ``(nv x nM)`` to
2727
``(nv x nC)``.
28+
- Removed the legacy sparse ancestor-walk inertia matrix ``mjData.qM``. The joint-space inertia matrix is now stored
29+
exclusively in the compressed sparse row (CSR) format ``mjData.M``.
2830

2931
Version 3.10.0 (June 22, 2026)
3032
------------------------------

doc/includes/references.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -223,8 +223,7 @@ typedef struct mjData_ {
223223

224224
// computed by mj_fwdPosition/mj_makeM
225225
mjtNum* crb; // com-based composite inertia and mass (nbody x 10)
226-
mjtNum* qM; // inertia (sparse) (nM x 1)
227-
mjtNum* M; // reduced inertia (compressed sparse row) (nC x 1)
226+
mjtNum* M; // inertia (sparse) (nC x 1)
228227

229228
// computed by mj_fwdPosition/mj_factorM
230229
mjtNum* qLD; // L'*D*L factorization of M (sparse) (nC x 1)
@@ -273,7 +272,7 @@ typedef struct mjData_ {
273272
mjtNum* qDeriv; // d (passive + actuator - bias) / d qvel (nD x 1)
274273

275274
// computed by mj_implicit/mju_factorLUSparse
276-
mjtNum* qLU; // sparse LU of (qM - dt*qDeriv) (nD x 1)
275+
mjtNum* qLU; // sparse LU of (M - dt*qDeriv) (nD x 1)
277276

278277
//-------------------- POSITION, VELOCITY, CONTROL/ACCELERATION dependent
279278

include/mujoco/mjdata.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -247,8 +247,7 @@ typedef struct mjData_ {
247247

248248
// computed by mj_fwdPosition/mj_makeM
249249
mjtNum* crb; // com-based composite inertia and mass (nbody x 10)
250-
mjtNum* qM; // inertia (sparse) (nM x 1)
251-
mjtNum* M; // reduced inertia (compressed sparse row) (nC x 1)
250+
mjtNum* M; // inertia (sparse) (nC x 1)
252251

253252
// computed by mj_fwdPosition/mj_factorM
254253
mjtNum* qLD; // L'*D*L factorization of M (sparse) (nC x 1)
@@ -297,7 +296,7 @@ typedef struct mjData_ {
297296
mjtNum* qDeriv; // d (passive + actuator - bias) / d qvel (nD x 1)
298297

299298
// computed by mj_implicit/mju_factorLUSparse
300-
mjtNum* qLU; // sparse LU of (qM - dt*qDeriv) (nD x 1)
299+
mjtNum* qLU; // sparse LU of (M - dt*qDeriv) (nD x 1)
301300

302301
//-------------------- POSITION, VELOCITY, CONTROL/ACCELERATION dependent
303302

include/mujoco/mjxmacro.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -875,7 +875,6 @@
875875
X ( int, moment_colind, nJmom, 1 ) \
876876
X ( mjtNum, actuator_moment, nJmom, 1 ) \
877877
XNV ( mjtNum, crb, nbody, 10 ) \
878-
XNV ( mjtNum, qM, nM, 1 ) \
879878
XNV ( mjtNum, M, nC, 1 ) \
880879
XNV ( mjtNum, qLD, nC, 1 ) \
881880
X ( mjtNum, qLDiagInv, nv, 1 ) \

mjx/mujoco/mjx/_src/io.py

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1297,12 +1297,11 @@ def _get_data_into_warp(
12971297
value = value.reshape((-1, 9))
12981298
# elif field.name == 'efc_J': # TODO(btaba): add this back
12991299
# elif field.name.startswith('efc_'): # TODO(btaba): add this back
1300-
# TODO(btaba): qM, qLD, qLDiagInv
1300+
# TODO(btaba): qLD, qLDiagInv
13011301

13021302
if field.name in (
13031303
'actuator_moment',
13041304
'contact',
1305-
'qM',
13061305
'qLD',
13071306
'qLU',
13081307
'qLDiagInv',
@@ -1472,10 +1471,6 @@ def _get_data_into(
14721471
else:
14731472
setattr(result_i, field.name, value)
14741473

1475-
if hasattr(result_i, 'qM'):
1476-
result_i.qM.fill(0.0)
1477-
result_i.qM[m.mapM2M] = result_i.M
1478-
14791474
# recalculate qLD and qLDiagInv as MJX and MuJoCo have different
14801475
# representations of the Cholesky decomposition.
14811476
mujoco.mj_factorM(m, result_i)

mjx/mujoco/mjx/_src/io_test.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -671,7 +671,6 @@ def test_get_data(self, impl: str, sparse: bool):
671671
np.testing.assert_allclose(d_2.xpos, d.xpos)
672672
np.testing.assert_allclose(d_2.cvel, d.cvel)
673673
np.testing.assert_allclose(d_2.cdof_dot, d.cdof_dot)
674-
np.testing.assert_allclose(d_2.qM, d.qM)
675674
np.testing.assert_allclose(d_2.qLD, d.qLD, atol=1e-6)
676675
np.testing.assert_allclose(d_2.qLDiagInv, d.qLDiagInv, atol=1e-6)
677676

@@ -782,7 +781,6 @@ def test_get_data_into(self, impl):
782781
# check a few fields
783782
np.testing.assert_allclose(d_2.qpos, d.qpos)
784783
np.testing.assert_allclose(d_2.xpos, d.xpos)
785-
np.testing.assert_allclose(d_2.qM, d.qM)
786784

787785
# only 1 contact active
788786
self.assertEqual(d_2.contact.dist.shape, (1,))

python/mujoco/introspect/structs.py

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6115,20 +6115,12 @@
61156115
doc='com-based composite inertia and mass',
61166116
array_extent=('nbody', 10),
61176117
),
6118-
StructFieldDecl(
6119-
name='qM',
6120-
type=PointerType(
6121-
inner_type=ValueType(name='mjtNum'),
6122-
),
6123-
doc='inertia (sparse)',
6124-
array_extent=('nM',),
6125-
),
61266118
StructFieldDecl(
61276119
name='M',
61286120
type=PointerType(
61296121
inner_type=ValueType(name='mjtNum'),
61306122
),
6131-
doc='reduced inertia (compressed sparse row)',
6123+
doc='inertia (sparse)',
61326124
array_extent=('nC',),
61336125
),
61346126
StructFieldDecl(
@@ -6328,7 +6320,7 @@
63286320
type=PointerType(
63296321
inner_type=ValueType(name='mjtNum'),
63306322
),
6331-
doc='sparse LU of (qM - dt*qDeriv)',
6323+
doc='sparse LU of (M - dt*qDeriv)',
63326324
array_extent=('nD',),
63336325
),
63346326
StructFieldDecl(

src/engine/engine_core_smooth.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1871,7 +1871,6 @@ void mj_makeM(const mjModel* m, mjData* d) {
18711871
TM_START;
18721872
mj_crb(m, d);
18731873
mj_tendonArmature(m, d);
1874-
mju_scatter(d->qM, d->M, m->mapM2M, m->nC); // TODO(tassa): scatter only awake dofs
18751874
TM_END(mjTIMER_POS_INERTIA);
18761875
}
18771876

src/engine/engine_inverse.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,10 +132,10 @@ static void mj_discreteAcc(const mjModel* m, mjData* d) {
132132
// compute qDeriv
133133
mjd_smooth_vel(m, d, /* flg_bias = */ 1);
134134

135-
// gather qLU <- qM (lower to full)
135+
// gather qLU <- M (lower to full)
136136
mju_gatherMasked(d->qLU, d->M, m->mapM2D, nD);
137137

138-
// set qLU = qM - dt*qDeriv
138+
// set qLU = M - dt*qDeriv
139139
mju_addToScl(d->qLU, d->qDeriv, -m->opt.timestep, m->nD);
140140

141141
// set qfrc = qLU * qacc

src/engine/engine_io.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1446,9 +1446,6 @@ static void _resetData(const mjModel* m, mjData* d, unsigned char debug_value) {
14461446
}
14471447
}
14481448

1449-
// zero out qM, special case because scattering from M skips simple body off-diagonals
1450-
mju_zero(d->qM, m->nM);
1451-
14521449
// copy qpos0 from model
14531450
if (m->qpos0) {
14541451
mju_copy(d->qpos, m->qpos0, m->nq);

0 commit comments

Comments
 (0)