Remove mjData.qM

PiperOrigin-RevId: 942520660
Change-Id: I422358e299ca0fcfe4c49cd0ee90c014a4c319d7
This commit is contained in:
Yuval Tassa
2026-07-04 09:38:07 -07:00
committed by Copybara-Service
parent 7c6f519879
commit 315bcfbf3a
16 changed files with 14 additions and 76 deletions
+2
View File
@@ -25,6 +25,8 @@ General
- Switched :ref:`mjd_inverseFD` to use the CSR-format ``mjData.M`` representation instead of the legacy ``mjData.qM``
for the mass matrix derivative. This changes the shape of the ``DmDq`` parameter from ``(nv x nM)`` to
``(nv x nC)``.
- Removed the legacy sparse ancestor-walk inertia matrix ``mjData.qM``. The joint-space inertia matrix is now stored
exclusively in the compressed sparse row (CSR) format ``mjData.M``.
Version 3.10.0 (June 22, 2026)
------------------------------
+2 -3
View File
@@ -223,8 +223,7 @@ typedef struct mjData_ {
// computed by mj_fwdPosition/mj_makeM
mjtNum* crb; // com-based composite inertia and mass (nbody x 10)
mjtNum* qM; // inertia (sparse) (nM x 1)
mjtNum* M; // reduced inertia (compressed sparse row) (nC x 1)
mjtNum* M; // inertia (sparse) (nC x 1)
// computed by mj_fwdPosition/mj_factorM
mjtNum* qLD; // L'*D*L factorization of M (sparse) (nC x 1)
@@ -273,7 +272,7 @@ typedef struct mjData_ {
mjtNum* qDeriv; // d (passive + actuator - bias) / d qvel (nD x 1)
// computed by mj_implicit/mju_factorLUSparse
mjtNum* qLU; // sparse LU of (qM - dt*qDeriv) (nD x 1)
mjtNum* qLU; // sparse LU of (M - dt*qDeriv) (nD x 1)
//-------------------- POSITION, VELOCITY, CONTROL/ACCELERATION dependent
+2 -3
View File
@@ -247,8 +247,7 @@ typedef struct mjData_ {
// computed by mj_fwdPosition/mj_makeM
mjtNum* crb; // com-based composite inertia and mass (nbody x 10)
mjtNum* qM; // inertia (sparse) (nM x 1)
mjtNum* M; // reduced inertia (compressed sparse row) (nC x 1)
mjtNum* M; // inertia (sparse) (nC x 1)
// computed by mj_fwdPosition/mj_factorM
mjtNum* qLD; // L'*D*L factorization of M (sparse) (nC x 1)
@@ -297,7 +296,7 @@ typedef struct mjData_ {
mjtNum* qDeriv; // d (passive + actuator - bias) / d qvel (nD x 1)
// computed by mj_implicit/mju_factorLUSparse
mjtNum* qLU; // sparse LU of (qM - dt*qDeriv) (nD x 1)
mjtNum* qLU; // sparse LU of (M - dt*qDeriv) (nD x 1)
//-------------------- POSITION, VELOCITY, CONTROL/ACCELERATION dependent
-1
View File
@@ -875,7 +875,6 @@
X ( int, moment_colind, nJmom, 1 ) \
X ( mjtNum, actuator_moment, nJmom, 1 ) \
XNV ( mjtNum, crb, nbody, 10 ) \
XNV ( mjtNum, qM, nM, 1 ) \
XNV ( mjtNum, M, nC, 1 ) \
XNV ( mjtNum, qLD, nC, 1 ) \
X ( mjtNum, qLDiagInv, nv, 1 ) \
+1 -6
View File
@@ -1297,12 +1297,11 @@ def _get_data_into_warp(
value = value.reshape((-1, 9))
# elif field.name == 'efc_J': # TODO(btaba): add this back
# elif field.name.startswith('efc_'): # TODO(btaba): add this back
# TODO(btaba): qM, qLD, qLDiagInv
# TODO(btaba): qLD, qLDiagInv
if field.name in (
'actuator_moment',
'contact',
'qM',
'qLD',
'qLU',
'qLDiagInv',
@@ -1472,10 +1471,6 @@ def _get_data_into(
else:
setattr(result_i, field.name, value)
if hasattr(result_i, 'qM'):
result_i.qM.fill(0.0)
result_i.qM[m.mapM2M] = result_i.M
# recalculate qLD and qLDiagInv as MJX and MuJoCo have different
# representations of the Cholesky decomposition.
mujoco.mj_factorM(m, result_i)
-2
View File
@@ -671,7 +671,6 @@ class DataIOTest(parameterized.TestCase):
np.testing.assert_allclose(d_2.xpos, d.xpos)
np.testing.assert_allclose(d_2.cvel, d.cvel)
np.testing.assert_allclose(d_2.cdof_dot, d.cdof_dot)
np.testing.assert_allclose(d_2.qM, d.qM)
np.testing.assert_allclose(d_2.qLD, d.qLD, atol=1e-6)
np.testing.assert_allclose(d_2.qLDiagInv, d.qLDiagInv, atol=1e-6)
@@ -782,7 +781,6 @@ class DataIOTest(parameterized.TestCase):
# check a few fields
np.testing.assert_allclose(d_2.qpos, d.qpos)
np.testing.assert_allclose(d_2.xpos, d.xpos)
np.testing.assert_allclose(d_2.qM, d.qM)
# only 1 contact active
self.assertEqual(d_2.contact.dist.shape, (1,))
+2 -10
View File
@@ -6115,20 +6115,12 @@ STRUCTS: Mapping[str, StructDecl] = dict([
doc='com-based composite inertia and mass',
array_extent=('nbody', 10),
),
StructFieldDecl(
name='qM',
type=PointerType(
inner_type=ValueType(name='mjtNum'),
),
doc='inertia (sparse)',
array_extent=('nM',),
),
StructFieldDecl(
name='M',
type=PointerType(
inner_type=ValueType(name='mjtNum'),
),
doc='reduced inertia (compressed sparse row)',
doc='inertia (sparse)',
array_extent=('nC',),
),
StructFieldDecl(
@@ -6328,7 +6320,7 @@ STRUCTS: Mapping[str, StructDecl] = dict([
type=PointerType(
inner_type=ValueType(name='mjtNum'),
),
doc='sparse LU of (qM - dt*qDeriv)',
doc='sparse LU of (M - dt*qDeriv)',
array_extent=('nD',),
),
StructFieldDecl(
-1
View File
@@ -1871,7 +1871,6 @@ void mj_makeM(const mjModel* m, mjData* d) {
TM_START;
mj_crb(m, d);
mj_tendonArmature(m, d);
mju_scatter(d->qM, d->M, m->mapM2M, m->nC); // TODO(tassa): scatter only awake dofs
TM_END(mjTIMER_POS_INERTIA);
}
+2 -2
View File
@@ -132,10 +132,10 @@ static void mj_discreteAcc(const mjModel* m, mjData* d) {
// compute qDeriv
mjd_smooth_vel(m, d, /* flg_bias = */ 1);
// gather qLU <- qM (lower to full)
// gather qLU <- M (lower to full)
mju_gatherMasked(d->qLU, d->M, m->mapM2D, nD);
// set qLU = qM - dt*qDeriv
// set qLU = M - dt*qDeriv
mju_addToScl(d->qLU, d->qDeriv, -m->opt.timestep, m->nD);
// set qfrc = qLU * qacc
-3
View File
@@ -1446,9 +1446,6 @@ static void _resetData(const mjModel* m, mjData* d, unsigned char debug_value) {
}
}
// zero out qM, special case because scattering from M skips simple body off-diagonals
mju_zero(d->qM, m->nM);
// copy qpos0 from model
if (m->qpos0) {
mju_copy(d->qpos, m->qpos0, m->nq);
-36
View File
@@ -242,41 +242,6 @@ static void printBlockArray(const char* str, const mjtNum* data, int nc,
}
// print sparse inertia-like matrix
static void printInertia(const char* str, const mjtNum* mat, const mjModel* m,
FILE* fp, const char* float_format) {
int nv = m->nv;
// if no data, or too many rows to be visually useful, return
if (!mat || !nv || nv > 300) {
return;
}
// get length of string produced by float_format
char test[100];
int len = snprintf(test, sizeof(test), float_format, 0.0);
fprintf(fp, "%s\n", str);
for (int i=0; i < nv; i++) {
fprintf(fp, " ");
int adr = (i == nv-1) ? m->nM - 1 : m->dof_Madr[i+1] - 1;
for (int k=0; k <= i; k++) {
int j = i;
while (j != k && j >= 0) {
j = m->dof_parentid[j];
}
if (j == k) {
fprintf(fp, " ");
fprintf(fp, float_format, mat[adr--]);
} else {
for (int d=0; d < len+1; d++) fprintf(fp, " ");
}
}
fprintf(fp, "\n");
}
fprintf(fp, "\n");
}
// print sparse matrix structure
void mj_printSparsity(const char* str, int nr, int nc, const int* rowadr, const int* diag,
@@ -1464,7 +1429,6 @@ void mj_printFormattedData(const mjModel* m, const mjData* d, const char* filena
printSparse("ACTUATOR_MOMENT", d->actuator_moment, m->nu, d->moment_rownnz,
d->moment_rowadr, d->moment_colind, fp, float_format);
printArray2d("CRB", m->nbody, 10, d->crb, fp, float_format);
printInertia("QM", d->qM, m, fp, float_format);
printSparse("M", d->M, m->nv, m->M_rownnz,
m->M_rowadr, m->M_colind, fp, float_format);
printSparse("QLD", d->qLD, m->nv, m->M_rownnz,
-1
View File
@@ -227,7 +227,6 @@ TEST_F(CoreSmoothTest, TendonArmature) {
// put only CRB inertia in M2
mj_crb(m, d);
mju_scatter(d->qM, d->M, m->mapM2M, m->nC);
vector<mjtNum> M2(nv * nv);
mj_fullM(m, d, M2.data());
+3 -3
View File
@@ -390,9 +390,9 @@ TEST_F(UserFlexTest, TrilinearInterpolation) {
EXPECT_NEAR(d1->flexvert_xpos[i], d2->flexvert_xpos[i], 1e-7);
}
EXPECT_EQ(m1->nM, m2->nM);
for (int i = 0; i < m1->nM; ++i) {
EXPECT_EQ(d1->qM[i], d2->qM[i]);
EXPECT_EQ(m1->nC, m2->nC);
for (int i = 0; i < m1->nC; ++i) {
EXPECT_EQ(d1->M[i], d2->M[i]);
}
EXPECT_EQ(m1->nbody, m2->nbody);
-1
View File
@@ -5757,7 +5757,6 @@ public unsafe struct mjData_ {
public int* moment_colind;
public double* actuator_moment;
public double* crb;
public double* qM;
public double* M;
public double* qLD;
public double* qLDiagInv;
-1
View File
@@ -4664,7 +4664,6 @@ EMSCRIPTEN_BINDINGS(mujoco_bindings) {
.property("qLD", &MjData::qLD)
.property("qLDiagInv", &MjData::qLDiagInv)
.property("qLU", &MjData::qLU)
.property("qM", &MjData::qM)
.property("qacc", &MjData::qacc)
.property("qacc_smooth", &MjData::qacc_smooth)
.property("qacc_warmstart", &MjData::qacc_warmstart)
-3
View File
@@ -6875,9 +6875,6 @@ struct MjData {
emscripten::val crb() const {
return emscripten::val(emscripten::typed_memory_view(model->nbody * 10, ptr_->crb));
}
emscripten::val qM() const {
return emscripten::val(emscripten::typed_memory_view(model->nM, ptr_->qM));
}
emscripten::val M() const {
return emscripten::val(emscripten::typed_memory_view(model->nC, ptr_->M));
}