Add mjs_getCompiler C API and compiler property to Python spec elements.
PiperOrigin-RevId: 881488083 Change-Id: I3aa1c0562bf2fd27057b8056048e3156fc1b067c
This commit is contained in:
committed by
Copybara-Service
parent
d6aac2041e
commit
6890e133c0
@@ -4580,6 +4580,15 @@ Find and get utilities
|
|||||||
|
|
||||||
Get spec from body.
|
Get spec from body.
|
||||||
|
|
||||||
|
.. _mjs_getCompiler:
|
||||||
|
|
||||||
|
`mjs_getCompiler <#mjs_getCompiler>`__
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. mujoco-include:: mjs_getCompiler
|
||||||
|
|
||||||
|
Get compiler associated with element's origin spec.
|
||||||
|
|
||||||
.. _mjs_findSpec:
|
.. _mjs_findSpec:
|
||||||
|
|
||||||
`mjs_findSpec <#mjs_findSpec>`__
|
`mjs_findSpec <#mjs_findSpec>`__
|
||||||
|
|||||||
@@ -15,6 +15,9 @@ General
|
|||||||
``ten_J_colind`` have been moved from :ref:`mjData` to :ref:`mjModel` and are no longer computed at run time by
|
``ten_J_colind`` have been moved from :ref:`mjData` to :ref:`mjModel` and are no longer computed at run time by
|
||||||
``mj_tendon`` but at compile time.
|
``mj_tendon`` but at compile time.
|
||||||
|
|
||||||
|
- Added :ref:`mjs_getCompiler` C API function and a ``compiler`` read-only property to all Python spec element types.
|
||||||
|
This allows querying the compiler settings (e.g., ``meshdir``) from any element, with the correct originating spec's
|
||||||
|
compiler preserved after attachment.
|
||||||
- Added a new ``strain`` :ref:`equality constraint<flexcomp-edge-equality>` type for trilinear and quadratic
|
- Added a new ``strain`` :ref:`equality constraint<flexcomp-edge-equality>` type for trilinear and quadratic
|
||||||
:ref:`dofs<body-flexcomp-dof>`.
|
:ref:`dofs<body-flexcomp-dof>`.
|
||||||
- Flexes now support collisions with SDF geoms.
|
- Flexes now support collisions with SDF geoms.
|
||||||
|
|||||||
@@ -3643,6 +3643,7 @@ mjsTexture* mjs_addTexture(mjSpec* s);
|
|||||||
mjsMaterial* mjs_addMaterial(mjSpec* s, const mjsDefault* def);
|
mjsMaterial* mjs_addMaterial(mjSpec* s, const mjsDefault* def);
|
||||||
int mjs_makeMesh(mjsMesh* mesh, mjtMeshBuiltin builtin, double* params, int nparams);
|
int mjs_makeMesh(mjsMesh* mesh, mjtMeshBuiltin builtin, double* params, int nparams);
|
||||||
mjSpec* mjs_getSpec(mjsElement* element);
|
mjSpec* mjs_getSpec(mjsElement* element);
|
||||||
|
mjsCompiler* mjs_getCompiler(mjsElement* element);
|
||||||
mjSpec* mjs_findSpec(mjSpec* spec, const char* name);
|
mjSpec* mjs_findSpec(mjSpec* spec, const char* name);
|
||||||
mjsBody* mjs_findBody(mjSpec* s, const char* name);
|
mjsBody* mjs_findBody(mjSpec* s, const char* name);
|
||||||
mjsElement* mjs_findElement(mjSpec* s, mjtObj type, const char* name);
|
mjsElement* mjs_findElement(mjSpec* s, mjtObj type, const char* name);
|
||||||
|
|||||||
@@ -1734,6 +1734,9 @@ MJAPI int mjs_makeMesh(mjsMesh* mesh, mjtMeshBuiltin builtin, double* params, in
|
|||||||
// Get spec from body.
|
// Get spec from body.
|
||||||
MJAPI mjSpec* mjs_getSpec(mjsElement* element);
|
MJAPI mjSpec* mjs_getSpec(mjsElement* element);
|
||||||
|
|
||||||
|
// Get compiler associated with element's origin spec.
|
||||||
|
MJAPI mjsCompiler* mjs_getCompiler(mjsElement* element);
|
||||||
|
|
||||||
// Find spec (model asset) by name.
|
// Find spec (model asset) by name.
|
||||||
MJAPI mjSpec* mjs_findSpec(mjSpec* spec, const char* name);
|
MJAPI mjSpec* mjs_findSpec(mjSpec* spec, const char* name);
|
||||||
|
|
||||||
|
|||||||
@@ -947,6 +947,24 @@ def generate_name() -> None:
|
|||||||
print(code)
|
print(code)
|
||||||
|
|
||||||
|
|
||||||
|
def generate_compiler() -> None:
|
||||||
|
"""Generate compiler property for all spec element types."""
|
||||||
|
for key, _, _, _, _ in SPECS:
|
||||||
|
elem = key.removeprefix('mjs')
|
||||||
|
titlecase = 'Mjs' + elem
|
||||||
|
code = f"""\n
|
||||||
|
{key}.def_property_readonly("compiler",
|
||||||
|
[](raw::{titlecase}& self) -> raw::MjsCompiler& {{
|
||||||
|
::mjsCompiler* compiler = mjs_getCompiler(self.element);
|
||||||
|
if (!compiler) {{
|
||||||
|
throw pybind11::value_error("Element is not attached to a spec.");
|
||||||
|
}}
|
||||||
|
return *compiler;
|
||||||
|
}}, py::return_value_policy::reference_internal);
|
||||||
|
"""
|
||||||
|
print(code)
|
||||||
|
|
||||||
|
|
||||||
def main(argv: Sequence[str]) -> None:
|
def main(argv: Sequence[str]) -> None:
|
||||||
if len(argv) > 1:
|
if len(argv) > 1:
|
||||||
raise app.UsageError('Too many command-line arguments.')
|
raise app.UsageError('Too many command-line arguments.')
|
||||||
@@ -956,6 +974,7 @@ def main(argv: Sequence[str]) -> None:
|
|||||||
generate_signature()
|
generate_signature()
|
||||||
generate_id()
|
generate_id()
|
||||||
generate_name()
|
generate_name()
|
||||||
|
generate_compiler()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|||||||
@@ -10823,6 +10823,22 @@ FUNCTIONS: Mapping[str, FunctionDecl] = dict([
|
|||||||
),
|
),
|
||||||
doc='Get spec from body.',
|
doc='Get spec from body.',
|
||||||
)),
|
)),
|
||||||
|
('mjs_getCompiler',
|
||||||
|
FunctionDecl(
|
||||||
|
name='mjs_getCompiler',
|
||||||
|
return_type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjsCompiler'),
|
||||||
|
),
|
||||||
|
parameters=(
|
||||||
|
FunctionParameterDecl(
|
||||||
|
name='element',
|
||||||
|
type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjsElement'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
doc="Get compiler associated with element's origin spec.",
|
||||||
|
)),
|
||||||
('mjs_findSpec',
|
('mjs_findSpec',
|
||||||
FunctionDecl(
|
FunctionDecl(
|
||||||
name='mjs_findSpec',
|
name='mjs_findSpec',
|
||||||
|
|||||||
@@ -1188,6 +1188,36 @@ class SpecsTest(absltest.TestCase):
|
|||||||
model = parent.compile()
|
model = parent.compile()
|
||||||
np.testing.assert_almost_equal(model.body_quat[1], [1, 0, 0, 0])
|
np.testing.assert_almost_equal(model.body_quat[1], [1, 0, 0, 0])
|
||||||
|
|
||||||
|
def test_compiler_from_element(self):
|
||||||
|
child = mujoco.MjSpec()
|
||||||
|
child.meshdir = '/child/meshes'
|
||||||
|
child.texturedir = '/child/textures'
|
||||||
|
child_body = child.worldbody.add_body()
|
||||||
|
child_geom = child_body.add_geom()
|
||||||
|
child_geom.size[0] = 1
|
||||||
|
child_site = child_body.add_site()
|
||||||
|
|
||||||
|
parent = mujoco.MjSpec()
|
||||||
|
parent.meshdir = '/parent/meshes'
|
||||||
|
parent.texturedir = '/parent/textures'
|
||||||
|
parent_geom = parent.worldbody.add_geom()
|
||||||
|
parent_geom.size[0] = 1
|
||||||
|
parent_site = parent.worldbody.add_site()
|
||||||
|
|
||||||
|
self.assertEqual(parent_geom.compiler.meshdir, '/parent/meshes')
|
||||||
|
self.assertEqual(parent_geom.compiler.texturedir, '/parent/textures')
|
||||||
|
self.assertEqual(child_geom.compiler.meshdir, '/child/meshes')
|
||||||
|
self.assertEqual(child_site.compiler.meshdir, '/child/meshes')
|
||||||
|
|
||||||
|
frame = parent.worldbody.add_frame()
|
||||||
|
frame.attach_body(child_body, prefix='child-')
|
||||||
|
|
||||||
|
self.assertEqual(parent_geom.compiler.meshdir, '/parent/meshes')
|
||||||
|
self.assertEqual(parent_site.compiler.meshdir, '/parent/meshes')
|
||||||
|
self.assertEqual(child_geom.compiler.meshdir, '/child/meshes')
|
||||||
|
self.assertEqual(child_geom.compiler.texturedir, '/child/textures')
|
||||||
|
self.assertEqual(child_site.compiler.meshdir, '/child/meshes')
|
||||||
|
|
||||||
def test_attach_to_site(self):
|
def test_attach_to_site(self):
|
||||||
parent = mujoco.MjSpec()
|
parent = mujoco.MjSpec()
|
||||||
parent.assets = {'path/cube.obj': 'cube_content'}
|
parent.assets = {'path/cube.obj': 'cube_content'}
|
||||||
|
|||||||
@@ -1074,6 +1074,12 @@ mjSpec* mjs_getSpec(mjsElement* element) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
mjsCompiler* mjs_getCompiler(mjsElement* element) {
|
||||||
|
return static_cast<mjCBase*>(element)->compiler;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// find spec (model asset) by name
|
// find spec (model asset) by name
|
||||||
mjSpec* mjs_findSpec(mjSpec* s, const char* name) {
|
mjSpec* mjs_findSpec(mjSpec* s, const char* name) {
|
||||||
mjCModel* model = static_cast<mjCModel*>(s->element);
|
mjCModel* model = static_cast<mjCModel*>(s->element);
|
||||||
|
|||||||
@@ -9668,6 +9668,14 @@ std::optional<MjsElement> mjs_firstElement_wrapper(MjSpec& s, mjtObj type) {
|
|||||||
return MjsElement(result);
|
return MjsElement(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::optional<MjsCompiler> mjs_getCompiler_wrapper(MjsElement& element) {
|
||||||
|
mjsCompiler* result = mjs_getCompiler(element.get());
|
||||||
|
if (result == nullptr) {
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
return MjsCompiler(result);
|
||||||
|
}
|
||||||
|
|
||||||
std::optional<MjsDefault> mjs_getDefault_wrapper(MjsElement& element) {
|
std::optional<MjsDefault> mjs_getDefault_wrapper(MjsElement& element) {
|
||||||
mjsDefault* result = mjs_getDefault(element.get());
|
mjsDefault* result = mjs_getDefault(element.get());
|
||||||
if (result == nullptr) {
|
if (result == nullptr) {
|
||||||
@@ -13191,6 +13199,7 @@ EMSCRIPTEN_BINDINGS(mujoco_bindings) {
|
|||||||
function("mjs_findSpec", &mjs_findSpec_wrapper);
|
function("mjs_findSpec", &mjs_findSpec_wrapper);
|
||||||
function("mjs_firstChild", &mjs_firstChild_wrapper);
|
function("mjs_firstChild", &mjs_firstChild_wrapper);
|
||||||
function("mjs_firstElement", &mjs_firstElement_wrapper);
|
function("mjs_firstElement", &mjs_firstElement_wrapper);
|
||||||
|
function("mjs_getCompiler", &mjs_getCompiler_wrapper);
|
||||||
function("mjs_getDefault", &mjs_getDefault_wrapper);
|
function("mjs_getDefault", &mjs_getDefault_wrapper);
|
||||||
function("mjs_getError", &mjs_getError_wrapper);
|
function("mjs_getError", &mjs_getError_wrapper);
|
||||||
function("mjs_getFrame", &mjs_getFrame_wrapper);
|
function("mjs_getFrame", &mjs_getFrame_wrapper);
|
||||||
|
|||||||
Reference in New Issue
Block a user