From d7e4038be844a10e612859b9aa15f4a84413e250 Mon Sep 17 00:00:00 2001 From: Yuval Tassa Date: Mon, 12 Jan 2026 03:20:08 -0800 Subject: [PATCH] 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 --- python/mujoco/bindings_test.py | 9 +++++++++ python/mujoco/functions.cc | 6 +++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/python/mujoco/bindings_test.py b/python/mujoco/bindings_test.py index b15dc261..42e758cf 100644 --- a/python/mujoco/bindings_test.py +++ b/python/mujoco/bindings_test.py @@ -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) diff --git a/python/mujoco/functions.cc b/python/mujoco/functions.cc index 5e5bb2c5..3ddb86fd 100644 --- a/python/mujoco/functions.cc +++ b/python/mujoco/functions.cc @@ -159,7 +159,11 @@ PYBIND11_MODULE(_functions, pymodule) { // Skipped: mj_deleteModel (have MjModel.__del__) Def(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(pymodule); Def(pymodule); Def(pymodule);