Make "id" a property rather than a method of mjsElements in Python bindings.

PiperOrigin-RevId: 649424035
Change-Id: I8226b3040aa2001ae9748399257e36ac263b7c8b
This commit is contained in:
Yuval Tassa
2024-07-04 08:34:35 -07:00
committed by Copybara-Service
parent f8b944bf7f
commit 118b6810b3
2 changed files with 90 additions and 85 deletions
+84 -81
View File
@@ -13,21 +13,21 @@
// limitations under the License. // limitations under the License.
#include <array> #include <array>
#include <cstddef> #include <cstddef> // IWYU pragma: keep
#include <cstdint> #include <cstdint>
#include <memory> #include <memory>
#include <string> #include <string>
#include <string_view> #include <string_view> // IWYU pragma: keep
#include <vector> #include <vector> // IWYU pragma: keep
#include <Eigen/Core> #include <Eigen/Core>
#include <Eigen/Eigen> #include <Eigen/Eigen>
#include <mujoco/mjspec.h> #include <mujoco/mjspec.h> // IWYU pragma: keep
#include <mujoco/mujoco.h> #include <mujoco/mujoco.h>
#include "errors.h" #include "errors.h"
#include "indexers.h" #include "indexers.h" // IWYU pragma: keep
#include "raw.h" #include "raw.h"
#include "structs.h" #include "structs.h" // IWYU pragma: keep
#include <pybind11/cast.h> #include <pybind11/cast.h>
#include <pybind11/eigen.h> #include <pybind11/eigen.h>
#include <pybind11/eigen/matrix.h> #include <pybind11/eigen/matrix.h>
@@ -490,10 +490,10 @@ PYBIND11_MODULE(_specs, m) {
}, },
py::return_value_policy::reference_internal); py::return_value_policy::reference_internal);
// ============================= MJSBODY ==================================== // ============================= MJSBODY =====================================
mjsBody.def("id", [](raw::MjsBody& self) -> int { mjsBody.def_property_readonly(
return mjs_getId(self.element); "id", [](raw::MjsBody& self) -> int { return mjs_getId(self.element); },
}); py::return_value_policy::reference_internal);
mjsBody.def("delete", [](raw::MjsBody& self) { mjs_delete(self.element); }); mjsBody.def("delete", [](raw::MjsBody& self) { mjs_delete(self.element); });
mjsBody.def( mjsBody.def(
"add_body", "add_body",
@@ -665,9 +665,9 @@ PYBIND11_MODULE(_specs, m) {
}); });
// ============================= MJSFRAME ==================================== // ============================= MJSFRAME ====================================
mjsFrame.def("id", [](raw::MjsFrame& self) -> int { mjsFrame.def_property_readonly(
return mjs_getId(self.element); "id", [](raw::MjsFrame& self) -> int { return mjs_getId(self.element); },
}); py::return_value_policy::reference_internal);
mjsFrame.def("delete", [](raw::MjsFrame& self) { mjs_delete(self.element); }); mjsFrame.def("delete", [](raw::MjsFrame& self) { mjs_delete(self.element); });
mjsFrame.def("set_frame", [](raw::MjsFrame& self, raw::MjsFrame& frame) { mjsFrame.def("set_frame", [](raw::MjsFrame& self, raw::MjsFrame& frame) {
mjs_setFrame(self.element, &frame); mjs_setFrame(self.element, &frame);
@@ -677,10 +677,10 @@ PYBIND11_MODULE(_specs, m) {
mjs_attachBody(&self, &body, prefix.c_str(), suffix.c_str()); mjs_attachBody(&self, &body, prefix.c_str(), suffix.c_str());
}); });
// ============================= MJSGEOM ==================================== // ============================= MJSGEOM =====================================
mjsGeom.def("id", [](raw::MjsGeom& self) -> int { mjsGeom.def_property_readonly(
return mjs_getId(self.element); "id", [](raw::MjsGeom& self) -> int { return mjs_getId(self.element); },
}); py::return_value_policy::reference_internal);
mjsGeom.def("delete", [](raw::MjsGeom& self) { mjs_delete(self.element); }); mjsGeom.def("delete", [](raw::MjsGeom& self) { mjs_delete(self.element); });
mjsGeom.def("set_frame", [](raw::MjsGeom& self, raw::MjsFrame& frame) { mjsGeom.def("set_frame", [](raw::MjsGeom& self, raw::MjsFrame& frame) {
mjs_setFrame(self.element, &frame); mjs_setFrame(self.element, &frame);
@@ -696,9 +696,9 @@ PYBIND11_MODULE(_specs, m) {
py::return_value_policy::reference_internal); py::return_value_policy::reference_internal);
// ============================= MJSJOINT ==================================== // ============================= MJSJOINT ====================================
mjsJoint.def("id", [](raw::MjsJoint& self) -> int { mjsJoint.def_property_readonly(
return mjs_getId(self.element); "id", [](raw::MjsJoint& self) -> int { return mjs_getId(self.element); },
}); py::return_value_policy::reference_internal);
mjsJoint.def("delete", [](raw::MjsJoint& self) { mjs_delete(self.element); }); mjsJoint.def("delete", [](raw::MjsJoint& self) { mjs_delete(self.element); });
mjsJoint.def("set_frame", [](raw::MjsJoint& self, raw::MjsFrame& frame) { mjsJoint.def("set_frame", [](raw::MjsJoint& self, raw::MjsFrame& frame) {
mjs_setFrame(self.element, &frame); mjs_setFrame(self.element, &frame);
@@ -713,10 +713,10 @@ PYBIND11_MODULE(_specs, m) {
}, },
py::return_value_policy::reference_internal); py::return_value_policy::reference_internal);
// ============================= MJSSITE ==================================== // ============================= MJSSITE =====================================
mjsSite.def("id", [](raw::MjsSite& self) -> int { mjsSite.def_property_readonly(
return mjs_getId(self.element); "id", [](raw::MjsSite& self) -> int { return mjs_getId(self.element); },
}); py::return_value_policy::reference_internal);
mjsSite.def("delete", [](raw::MjsSite& self) { mjs_delete(self.element); }); mjsSite.def("delete", [](raw::MjsSite& self) { mjs_delete(self.element); });
mjsSite.def("set_frame", [](raw::MjsSite& self, raw::MjsFrame& frame) { mjsSite.def("set_frame", [](raw::MjsSite& self, raw::MjsFrame& frame) {
mjs_setFrame(self.element, &frame); mjs_setFrame(self.element, &frame);
@@ -731,10 +731,10 @@ PYBIND11_MODULE(_specs, m) {
}, },
py::return_value_policy::reference_internal); py::return_value_policy::reference_internal);
// ============================= MJSCAMERA ================================== // ============================= MJSCAMERA ===================================
mjsCamera.def("id", [](raw::MjsCamera& self) -> int { mjsCamera.def_property_readonly(
return mjs_getId(self.element); "id", [](raw::MjsCamera& self) -> int { return mjs_getId(self.element); },
}); py::return_value_policy::reference_internal);
mjsCamera.def("delete", mjsCamera.def("delete",
[](raw::MjsCamera& self) { mjs_delete(self.element); }); [](raw::MjsCamera& self) { mjs_delete(self.element); });
mjsCamera.def("set_frame", [](raw::MjsCamera& self, raw::MjsFrame& frame) { mjsCamera.def("set_frame", [](raw::MjsCamera& self, raw::MjsFrame& frame) {
@@ -751,9 +751,9 @@ PYBIND11_MODULE(_specs, m) {
py::return_value_policy::reference_internal); py::return_value_policy::reference_internal);
// ============================= MJSLIGHT ==================================== // ============================= MJSLIGHT ====================================
mjsLight.def("id", [](raw::MjsLight& self) -> int { mjsLight.def_property_readonly(
return mjs_getId(self.element); "id", [](raw::MjsLight& self) -> int { return mjs_getId(self.element); },
}); py::return_value_policy::reference_internal);
mjsLight.def("delete", [](raw::MjsLight& self) { mjs_delete(self.element); }); mjsLight.def("delete", [](raw::MjsLight& self) { mjs_delete(self.element); });
mjsLight.def("set_frame", [](raw::MjsLight& self, raw::MjsFrame& frame) { mjsLight.def("set_frame", [](raw::MjsLight& self, raw::MjsFrame& frame) {
mjs_setFrame(self.element, &frame); mjs_setFrame(self.element, &frame);
@@ -768,10 +768,11 @@ PYBIND11_MODULE(_specs, m) {
}, },
py::return_value_policy::reference_internal); py::return_value_policy::reference_internal);
// ============================= MJSMATERIAL ================================ // ============================= MJSMATERIAL =================================
mjsMaterial.def("id", [](raw::MjsMaterial& self) -> int { mjsMaterial.def_property_readonly(
return mjs_getId(self.element); "id",
}); [](raw::MjsMaterial& self) -> int { return mjs_getId(self.element); },
py::return_value_policy::reference_internal);
mjsMaterial.def("delete", mjsMaterial.def("delete",
[](raw::MjsMaterial& self) { mjs_delete(self.element); }); [](raw::MjsMaterial& self) { mjs_delete(self.element); });
mjsMaterial.def("set_default", mjsMaterial.def("set_default",
@@ -785,10 +786,10 @@ PYBIND11_MODULE(_specs, m) {
}, },
py::return_value_policy::reference_internal); py::return_value_policy::reference_internal);
// ============================= MJSMESH ==================================== // ============================= MJSMESH =====================================
mjsMesh.def("id", [](raw::MjsMesh& self) -> int { mjsMesh.def_property_readonly(
return mjs_getId(self.element); "id", [](raw::MjsMesh& self) -> int { return mjs_getId(self.element); },
}); py::return_value_policy::reference_internal);
mjsMesh.def("delete", [](raw::MjsMesh& self) { mjs_delete(self.element); }); mjsMesh.def("delete", [](raw::MjsMesh& self) { mjs_delete(self.element); });
mjsMesh.def("set_default", [](raw::MjsMesh& self, raw::MjsDefault& def) { mjsMesh.def("set_default", [](raw::MjsMesh& self, raw::MjsDefault& def) {
mjs_setDefault(self.element, &def); mjs_setDefault(self.element, &def);
@@ -800,10 +801,10 @@ PYBIND11_MODULE(_specs, m) {
}, },
py::return_value_policy::reference_internal); py::return_value_policy::reference_internal);
// ============================= MJSPAIR ==================================== // ============================= MJSPAIR =====================================
mjsPair.def("id", [](raw::MjsPair& self) -> int { mjsPair.def_property_readonly(
return mjs_getId(self.element); "id", [](raw::MjsPair& self) -> int { return mjs_getId(self.element); },
}); py::return_value_policy::reference_internal);
mjsPair.def("delete", [](raw::MjsPair& self) { mjs_delete(self.element); }); mjsPair.def("delete", [](raw::MjsPair& self) { mjs_delete(self.element); });
mjsPair.def("set_default", [](raw::MjsPair& self, raw::MjsDefault& def) { mjsPair.def("set_default", [](raw::MjsPair& self, raw::MjsDefault& def) {
mjs_setDefault(self.element, &def); mjs_setDefault(self.element, &def);
@@ -816,9 +817,10 @@ PYBIND11_MODULE(_specs, m) {
py::return_value_policy::reference_internal); py::return_value_policy::reference_internal);
// ============================= MJSEQUAL ==================================== // ============================= MJSEQUAL ====================================
mjsEquality.def("id", [](raw::MjsEquality& self) -> int { mjsEquality.def_property_readonly(
return mjs_getId(self.element); "id",
}); [](raw::MjsEquality& self) -> int { return mjs_getId(self.element); },
py::return_value_policy::reference_internal);
mjsEquality.def("delete", mjsEquality.def("delete",
[](raw::MjsEquality& self) { mjs_delete(self.element); }); [](raw::MjsEquality& self) { mjs_delete(self.element); });
mjsEquality.def("set_default", mjsEquality.def("set_default",
@@ -832,10 +834,11 @@ PYBIND11_MODULE(_specs, m) {
}, },
py::return_value_policy::reference_internal); py::return_value_policy::reference_internal);
// ============================= MJSACTUATOR ================================ // ============================= MJSACTUATOR =================================
mjsActuator.def("id", [](raw::MjsActuator& self) -> int { mjsActuator.def_property_readonly(
return mjs_getId(self.element); "id",
}); [](raw::MjsActuator& self) -> int { return mjs_getId(self.element); },
py::return_value_policy::reference_internal);
mjsActuator.def("delete", mjsActuator.def("delete",
[](raw::MjsActuator& self) { mjs_delete(self.element); }); [](raw::MjsActuator& self) { mjs_delete(self.element); });
mjsActuator.def("set_default", mjsActuator.def("set_default",
@@ -849,10 +852,10 @@ PYBIND11_MODULE(_specs, m) {
}, },
py::return_value_policy::reference_internal); py::return_value_policy::reference_internal);
// ============================= MJSTENDON ================================== // ============================= MJSTENDON ===================================
mjsTendon.def("id", [](raw::MjsTendon& self) -> int { mjsTendon.def_property_readonly(
return mjs_getId(self.element); "id", [](raw::MjsTendon& self) -> int { return mjs_getId(self.element); },
}); py::return_value_policy::reference_internal);
mjsTendon.def("delete", mjsTendon.def("delete",
[](raw::MjsTendon& self) { mjs_delete(self.element); }); [](raw::MjsTendon& self) { mjs_delete(self.element); });
mjsTendon.def("set_default", [](raw::MjsTendon& self, raw::MjsDefault& def) { mjsTendon.def("set_default", [](raw::MjsTendon& self, raw::MjsDefault& def) {
@@ -889,71 +892,72 @@ PYBIND11_MODULE(_specs, m) {
}, },
py::return_value_policy::reference_internal); py::return_value_policy::reference_internal);
// ============================= MJSSENSOR ================================== // ============================= MJSSENSOR ===================================
mjsSensor.def("id", [](raw::MjsSensor& self) -> int { mjsSensor.def_property_readonly(
return mjs_getId(self.element); "id", [](raw::MjsSensor& self) -> int { return mjs_getId(self.element); },
}); py::return_value_policy::reference_internal);
mjsSensor.def("delete", mjsSensor.def("delete",
[](raw::MjsSensor& self) { mjs_delete(self.element); }); [](raw::MjsSensor& self) { mjs_delete(self.element); });
// ============================= MJSFLEX ==================================== // ============================= MJSFLEX =====================================
mjsFlex.def("id", [](raw::MjsFlex& self) -> int { mjsFlex.def_property_readonly(
return mjs_getId(self.element); "id", [](raw::MjsFlex& self) -> int { return mjs_getId(self.element); },
}); py::return_value_policy::reference_internal);
mjsFlex.def("delete", [](raw::MjsFlex& self) { mjs_delete(self.element); }); mjsFlex.def("delete", [](raw::MjsFlex& self) { mjs_delete(self.element); });
// ============================= MJSHFIELD ================================== // ============================= MJSHFIELD ===================================
mjsHField.def("id", [](raw::MjsHField& self) -> int { mjsHField.def_property_readonly(
return mjs_getId(self.element); "id", [](raw::MjsHField& self) -> int { return mjs_getId(self.element); },
}); py::return_value_policy::reference_internal);
mjsHField.def("delete", mjsHField.def("delete",
[](raw::MjsHField& self) { mjs_delete(self.element); }); [](raw::MjsHField& self) { mjs_delete(self.element); });
// ============================= MJSSKIN ==================================== // ============================= MJSSKIN =====================================
mjsSkin.def("id", [](raw::MjsSkin& self) -> int { mjsSkin.def_property_readonly(
return mjs_getId(self.element); "id", [](raw::MjsSkin& self) -> int { return mjs_getId(self.element); },
}); py::return_value_policy::reference_internal);
mjsSkin.def("delete", [](raw::MjsSkin& self) { mjs_delete(self.element); }); mjsSkin.def("delete", [](raw::MjsSkin& self) { mjs_delete(self.element); });
// ============================= MJSTEXTURE ================================= // ============================= MJSTEXTURE ==================================
mjsTexture.def("id", [](raw::MjsTexture& self) -> int { mjsTexture.def_property_readonly(
return mjs_getId(self.element); "id",
}); [](raw::MjsTexture& self) -> int { return mjs_getId(self.element); },
py::return_value_policy::reference_internal);
mjsTexture.def("delete", mjsTexture.def("delete",
[](raw::MjsTexture& self) { mjs_delete(self.element); }); [](raw::MjsTexture& self) { mjs_delete(self.element); });
// ============================= MJSKEY ===================================== // ============================= MJSKEY ======================================
mjsKey.def("id", mjsKey.def("id",
[](raw::MjsKey& self) -> int { return mjs_getId(self.element); }); [](raw::MjsKey& self) -> int { return mjs_getId(self.element); });
mjsKey.def("delete", [](raw::MjsKey& self) { mjs_delete(self.element); }); mjsKey.def("delete", [](raw::MjsKey& self) { mjs_delete(self.element); });
// ============================= MJSTEXT ==================================== // ============================= MJSTEXT =====================================
mjsText.def("id", [](raw::MjsText& self) -> int { mjsText.def("id", [](raw::MjsText& self) -> int {
return mjs_getId(self.element); return mjs_getId(self.element);
}); });
mjsText.def("delete", [](raw::MjsText& self) { mjs_delete(self.element); }); mjsText.def("delete", [](raw::MjsText& self) { mjs_delete(self.element); });
// ============================= MJSNUMERIC ================================= // ============================= MJSNUMERIC ==================================
mjsNumeric.def("id", [](raw::MjsNumeric& self) -> int { mjsNumeric.def("id", [](raw::MjsNumeric& self) -> int {
return mjs_getId(self.element); return mjs_getId(self.element);
}); });
mjsNumeric.def("delete", mjsNumeric.def("delete",
[](raw::MjsNumeric& self) { mjs_delete(self.element); }); [](raw::MjsNumeric& self) { mjs_delete(self.element); });
// ============================= MJSEXCLUDE ================================ // ============================= MJSEXCLUDE ==================================
mjsExclude.def("id", [](raw::MjsExclude& self) -> int { mjsExclude.def("id", [](raw::MjsExclude& self) -> int {
return mjs_getId(self.element); return mjs_getId(self.element);
}); });
mjsExclude.def("delete", mjsExclude.def("delete",
[](raw::MjsExclude& self) { mjs_delete(self.element); }); [](raw::MjsExclude& self) { mjs_delete(self.element); });
// ============================= MJSTUPLE =================================== // ============================= MJSTUPLE ====================================
mjsTuple.def("id", [](raw::MjsTuple& self) -> int { mjsTuple.def("id", [](raw::MjsTuple& self) -> int {
return mjs_getId(self.element); return mjs_getId(self.element);
}); });
mjsTuple.def("delete", [](raw::MjsTuple& self) { mjs_delete(self.element); }); mjsTuple.def("delete", [](raw::MjsTuple& self) { mjs_delete(self.element); });
// ============================= MJSPLUGIN ================================== // ============================= MJSPLUGIN ===================================
mjsPlugin.def("id", [](raw::MjsPlugin& self) -> int { mjsPlugin.def("id", [](raw::MjsPlugin& self) -> int {
return mjs_getId(self.instance); return mjs_getId(self.instance);
}); });
@@ -961,6 +965,5 @@ PYBIND11_MODULE(_specs, m) {
[](raw::MjsPlugin& self) { mjs_delete(self.instance); }); [](raw::MjsPlugin& self) { mjs_delete(self.instance); });
#include "specs.cc.inc" #include "specs.cc.inc"
} // PYBIND11_MODULE // NOLINT } // PYBIND11_MODULE // NOLINT
} // namespace mujoco::python } // namespace mujoco::python
+6 -4
View File
@@ -66,13 +66,15 @@ class SpecsTest(absltest.TestCase):
self.assertEqual(site.name, 'sitename') self.assertEqual(site.name, 'sitename')
np.testing.assert_array_equal(site.userdata, [1, 2, 3, 4, 5, 6]) np.testing.assert_array_equal(site.userdata, [1, 2, 3, 4, 5, 6])
# Check that the site has no id before compilation. # Check that the site and body have no id before compilation.
self.assertEqual(body.id(), -1) self.assertEqual(body.id, -1)
self.assertEqual(site.id, -1)
# Compile the spec and check for expected values in the model. # Compile the spec and check for expected values in the model.
model = spec.compile() model = spec.compile()
self.assertEqual(spec.worldbody.id(), 0) self.assertEqual(spec.worldbody.id, 0)
self.assertEqual(body.id(), 1) self.assertEqual(body.id, 1)
self.assertEqual(site.id, 0)
self.assertEqual(model.nbody, 2) # 2 bodies, including the world body self.assertEqual(model.nbody, 2) # 2 bodies, including the world body
np.testing.assert_array_equal(model.body_pos[1], [1, 2, 3]) np.testing.assert_array_equal(model.body_pos[1], [1, 2, 3])
np.testing.assert_array_equal(model.body_quat[1], [0, 1, 0, 0]) np.testing.assert_array_equal(model.body_quat[1], [0, 1, 0, 0])