diff --git a/doc/APIreference/functions.rst b/doc/APIreference/functions.rst index 029fac76..9606e94d 100644 --- a/doc/APIreference/functions.rst +++ b/doc/APIreference/functions.rst @@ -4401,6 +4401,15 @@ Get string contents. Get double array contents and optionally its size. +.. _mjs_getPluginAttributes: + +`mjs_getPluginAttributes <#mjs_getPluginAttributes>`__ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_getPluginAttributes + +Get plugin attributes. + .. _SpecUtilities: Spec utilities diff --git a/doc/includes/references.h b/doc/includes/references.h index 89890efc..ce9bd670 100644 --- a/doc/includes/references.h +++ b/doc/includes/references.h @@ -3686,6 +3686,7 @@ void mjs_setDouble(mjDoubleVec* dest, const double* array, int size); void mjs_setPluginAttributes(mjsPlugin* plugin, void* attributes); const char* mjs_getString(const mjString* source); const double* mjs_getDouble(const mjDoubleVec* source, int* size); +const void* mjs_getPluginAttributes(const mjsPlugin* plugin); void mjs_setDefault(mjsElement* element, const mjsDefault* def); int mjs_setFrame(mjsElement* dest, mjsFrame* frame); const char* mjs_resolveOrientation(double quat[4], mjtByte degree, const char* sequence, diff --git a/include/mujoco/mujoco.h b/include/mujoco/mujoco.h index 94f89a4a..63bfafcc 100644 --- a/include/mujoco/mujoco.h +++ b/include/mujoco/mujoco.h @@ -1622,6 +1622,9 @@ MJAPI const char* mjs_getString(const mjString* source); // Get double array contents and optionally its size. MJAPI const double* mjs_getDouble(const mjDoubleVec* source, int* size); +// Get plugin attributes. +MJAPI const void* mjs_getPluginAttributes(const mjsPlugin* plugin); + //---------------------------------- Spec utilities ------------------------------------------------ diff --git a/python/mujoco/introspect/functions.py b/python/mujoco/introspect/functions.py index 9e61b828..b74e222f 100644 --- a/python/mujoco/introspect/functions.py +++ b/python/mujoco/introspect/functions.py @@ -10298,6 +10298,22 @@ FUNCTIONS: Mapping[str, FunctionDecl] = dict([ ), doc='Get double array contents and optionally its size.', )), + ('mjs_getPluginAttributes', + FunctionDecl( + name='mjs_getPluginAttributes', + return_type=PointerType( + inner_type=ValueType(name='void', is_const=True), + ), + parameters=( + FunctionParameterDecl( + name='plugin', + type=PointerType( + inner_type=ValueType(name='mjsPlugin', is_const=True), + ), + ), + ), + doc='Get plugin attributes.', + )), ('mjs_setDefault', FunctionDecl( name='mjs_setDefault', diff --git a/python/mujoco/specs.cc b/python/mujoco/specs.cc index 3adc549b..c1bbc3eb 100644 --- a/python/mujoco/specs.cc +++ b/python/mujoco/specs.cc @@ -1034,8 +1034,15 @@ PYBIND11_MODULE(_specs, m) { [](raw::MjsPlugin& self) { mjs_delete(self.element); }); mjsPlugin.def_property( "config", - [](raw::MjsPlugin& self) -> void { - throw pybind11::value_error("Reading plugin config is not supported."); + [](raw::MjsPlugin& self) -> py::dict { + const std::map>* config_attribs = + static_cast>*>( + mjs_getPluginAttributes(&self)); + py::dict config; + for (const auto& [key, value] : *config_attribs) { + config[py::str(key)] = value; + } + return config; }, [](raw::MjsPlugin& self, py::dict& config) { std::map> config_attribs; @@ -1047,7 +1054,8 @@ PYBIND11_MODULE(_specs, m) { config_attribs[key_str] = value.cast(); } mjs_setPluginAttributes(&self, &config_attribs); - }); + }, + py::return_value_policy::reference_internal); // ============================= MJVISUAL ==================================== mjVisual.def_property( "global_", diff --git a/python/mujoco/specs_test.py b/python/mujoco/specs_test.py index e8aafa23..ac702876 100644 --- a/python/mujoco/specs_test.py +++ b/python/mujoco/specs_test.py @@ -844,6 +844,7 @@ class SpecsTest(absltest.TestCase): info='info' ) plugin.config = {'twist': '10', 'bend': '1'} + self.assertEqual(plugin.config, {'twist': '10', 'bend': '1'}) body = spec.worldbody.add_body() body.plugin = plugin diff --git a/src/user/user_api.cc b/src/user/user_api.cc index e21181dd..e103aa8e 100644 --- a/src/user/user_api.cc +++ b/src/user/user_api.cc @@ -1302,6 +1302,14 @@ void mjs_setPluginAttributes(mjsPlugin* plugin, void* attributes) { +// get plugin attributes +const void* mjs_getPluginAttributes(const mjsPlugin* plugin) { + mjCPlugin* pluginC = static_cast(plugin->element); + return &pluginC->config_attribs; +} + + + // -------------------------- GLOBAL ASSET CACHE ------------------------------- void mj_setCacheSize(mjCache cache, std::size_t size) { diff --git a/src/user/user_api.h b/src/user/user_api.h index d01b5172..e1b73d86 100644 --- a/src/user/user_api.h +++ b/src/user/user_api.h @@ -352,6 +352,9 @@ MJAPI const char* mjs_getString(const mjString* source); // Get double array contents and optionally its size. MJAPI const double* mjs_getDouble(const mjDoubleVec* source, int* size); +// Get plugin attributes. +MJAPI const void* mjs_getPluginAttributes(const mjsPlugin* plugin); + //---------------------------------- Other utilities -----------------------------------------------