Expose mj_copyData in Python bindings.

This allows calling `mujoco.mj_copyData(dest, model, src)` to copy data between existing `mjData` instances.

PiperOrigin-RevId: 855150139
Change-Id: If122cb7acf590846e25ee15f9770c3c087147169
This commit is contained in:
Yuval Tassa
2026-01-12 03:20:08 -08:00
committed by Copybara-Service
parent 1d482047d1
commit d7e4038be8
2 changed files with 14 additions and 1 deletions
+9
View File
@@ -495,6 +495,15 @@ class MuJoCoBindingsTest(parameterized.TestCase):
mujoco.mj_forward(self.model, data_copy)
self.assertEqual(data_copy.ncon, 4)
# Test copying into existing data.
data_copy.qpos[1] = 1.234
data_copy.geom_xpos[2] = 5.678
self.assertFalse(np.array_equal(self.data.qpos, data_copy.qpos))
self.assertFalse(np.array_equal(self.data.geom_xpos, data_copy.geom_xpos))
mujoco.mj_copyData(self.data, self.model, data_copy)
np.testing.assert_array_equal(self.data.qpos, data_copy.qpos)
np.testing.assert_array_equal(self.data.geom_xpos, data_copy.geom_xpos)
def test_mjdata_can_read_warning_array(self):
warnings = self.data.warning
self.assertLen(warnings, mujoco.mjtWarning.mjNWARNING)
+5 -1
View File
@@ -159,7 +159,11 @@ PYBIND11_MODULE(_functions, pymodule) {
// Skipped: mj_deleteModel (have MjModel.__del__)
Def<traits::mj_sizeModel>(pymodule);
// Skipped: mj_makeData (have MjData.__init__)
// Skipped: mj_copyData (have MjData.__copy__, memory managed by MjData)
DEF_WITH_OMITTED_PY_ARGS(traits::mj_copyData)(
pymodule,
[](raw::MjData* dest, const raw::MjModel* m, const raw::MjData* src) {
InterceptMjErrors(::mj_copyData)(dest, m, src);
});
Def<traits::mj_resetData>(pymodule);
Def<traits::mj_resetDataDebug>(pymodule);
Def<traits::mj_resetDataKeyframe>(pymodule);