Add bindings generation for mjOption, mjVisual, and mjStatistic.
Fixes #2076. PiperOrigin-RevId: 677789263 Change-Id: Ie1bda40af62c5ac9bbba541668a50adfc59d3f7c
This commit is contained in:
committed by
Copybara-Service
parent
41ea95f077
commit
b5bcc91a03
@@ -43,6 +43,13 @@ def _value_binding_code(
|
||||
fulltype = fulltype + '&' # plugin and orientation are not pointers
|
||||
else:
|
||||
fulltype = fulltype + '*'
|
||||
# non-mjs structs
|
||||
rawclassname = rawclassname.replace('mjOption', 'raw::MjOption')
|
||||
rawclassname = rawclassname.replace('mjVisual', 'raw::MjVisual')
|
||||
rawclassname = rawclassname.replace('mjStatistic', 'raw::MjStatistic')
|
||||
fulltype = fulltype.replace('mjOption', 'raw::MjOption')
|
||||
fulltype = fulltype.replace('mjVisual', 'raw::MjVisual')
|
||||
fulltype = fulltype.replace('mjStatistic', 'raw::MjStatistic')
|
||||
|
||||
def_property_args = (
|
||||
f'"{varname}"',
|
||||
@@ -68,6 +75,9 @@ def _array_binding_code(
|
||||
raise NotImplementedError()
|
||||
innertype = field.inner_type.decl()
|
||||
rawclassname = classname.replace('mjs', 'raw::Mjs')
|
||||
rawclassname = rawclassname.replace('mjOption', 'raw::MjOption')
|
||||
rawclassname = rawclassname.replace('mjVisual', 'raw::MjVisual')
|
||||
rawclassname = rawclassname.replace('mjStatistic', 'raw::MjStatistic')
|
||||
fullvarname = varname
|
||||
if classname == 'mjSpec': # raw mjSpec has a wrapper
|
||||
rawclassname = classname.replace('mjS', 'MjS')
|
||||
@@ -209,12 +219,17 @@ def _ptr_binding_code(
|
||||
}}
|
||||
}}, py::return_value_policy::reference_internal);"""
|
||||
|
||||
raise NotImplementedError()
|
||||
raise NotImplementedError(
|
||||
'Unsupported array type: ' + vartype + ' in ' + classname
|
||||
)
|
||||
|
||||
|
||||
def _binding_code(field: ast_nodes.StructFieldDecl, key: str) -> str:
|
||||
if isinstance(field.type, ast_nodes.ValueType):
|
||||
return _value_binding_code(field.type, key, field.name)
|
||||
elif isinstance(field.type, ast_nodes.AnonymousStructDecl):
|
||||
field.type = ast_nodes.ValueType(name='mjVisual'+field.name.title())
|
||||
return _value_binding_code(field.type, key, field.name)
|
||||
elif isinstance(field.type, ast_nodes.PointerType):
|
||||
return _ptr_binding_code(field.type, key, field.name)
|
||||
elif isinstance(field.type, ast_nodes.ArrayType):
|
||||
@@ -224,7 +239,10 @@ def _binding_code(field: ast_nodes.StructFieldDecl, key: str) -> str:
|
||||
|
||||
def generate() -> None:
|
||||
for key in structs.STRUCTS.keys():
|
||||
if (key.startswith('mjs') or key == 'mjSpec') and key != 'mjsElement':
|
||||
if (
|
||||
key.startswith('mjs')
|
||||
or key in ['mjSpec', 'mjOption', 'mjVisual', 'mjStatistic']
|
||||
) and key != 'mjsElement':
|
||||
print('\n // ' + key)
|
||||
for field in structs.STRUCTS[key].fields:
|
||||
code = _binding_code(field, key)
|
||||
|
||||
@@ -109,6 +109,9 @@ PYBIND11_MODULE(_specs, m) {
|
||||
py::class_<raw::MjsPlugin> mjsPlugin(m, "MjsPlugin");
|
||||
py::class_<raw::MjsOrientation> mjsOrientation(m, "MjsOrientation");
|
||||
py::class_<raw::MjsWrap> mjsWrap(m, "MjsWrap");
|
||||
py::class_<raw::MjOption> mjOption(m, "MjOption");
|
||||
py::class_<raw::MjStatistic> mjStatistic(m, "MjStatistic");
|
||||
py::class_<raw::MjVisual> mjVisual(m, "MjVisual");
|
||||
|
||||
// ============================= MJSPEC =====================================
|
||||
mjSpec.def(py::init<>());
|
||||
|
||||
@@ -717,5 +717,30 @@ class SpecsTest(absltest.TestCase):
|
||||
self.assertIsNotNone(model)
|
||||
self.assertEqual(model.nplugin, 0)
|
||||
|
||||
def test_access_option_stat_visual(self):
|
||||
spec = mujoco.MjSpec()
|
||||
spec.from_string(textwrap.dedent("""
|
||||
<mujoco model="MuJoCo Model">
|
||||
<option timestep="0.001"/>
|
||||
<statistic meansize="0.05"/>
|
||||
<visual>
|
||||
<quality shadowsize="4096"/>
|
||||
</visual>
|
||||
</mujoco>
|
||||
"""))
|
||||
self.assertEqual(spec.option.timestep, 0.001)
|
||||
self.assertEqual(spec.stat.meansize, 0.05)
|
||||
self.assertEqual(spec.visual.quality.shadowsize, 4096)
|
||||
|
||||
spec.option.timestep = 0.002
|
||||
spec.stat.meansize = 0.06
|
||||
spec.visual.quality.shadowsize = 8192
|
||||
|
||||
model = spec.compile()
|
||||
|
||||
self.assertEqual(model.opt.timestep, 0.002)
|
||||
self.assertEqual(model.stat.meansize, 0.06)
|
||||
self.assertEqual(model.vis.quality.shadowsize, 8192)
|
||||
|
||||
if __name__ == '__main__':
|
||||
absltest.main()
|
||||
|
||||
Reference in New Issue
Block a user