Add plugins list to mjSpec Python API.
Fixes #2061. PiperOrigin-RevId: 677762985 Change-Id: I8e407373e7b505d9b0f1c023e97c5ea92169bbf6
This commit is contained in:
committed by
Copybara-Service
parent
91cedfd65c
commit
0ba11b9623
@@ -4432,6 +4432,15 @@ mjs_asMaterial
|
|||||||
|
|
||||||
Safely cast an element as mjsMaterial, or return NULL if the element is not an mjsMaterial.
|
Safely cast an element as mjsMaterial, or return NULL if the element is not an mjsMaterial.
|
||||||
|
|
||||||
|
.. _mjs_asPlugin:
|
||||||
|
|
||||||
|
mjs_asPlugin
|
||||||
|
~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. mujoco-include:: mjs_asPlugin
|
||||||
|
|
||||||
|
Safely cast an element as mjsPlugin, or return NULL if the element is not an mjsPlugin.
|
||||||
|
|
||||||
.. _AttributeSetters:
|
.. _AttributeSetters:
|
||||||
|
|
||||||
Attribute setters
|
Attribute setters
|
||||||
|
|||||||
@@ -1738,7 +1738,7 @@ typedef struct mjsOrientation_ { // alternative orientation specifiers
|
|||||||
double euler[3]; // Euler angles
|
double euler[3]; // Euler angles
|
||||||
} mjsOrientation;
|
} mjsOrientation;
|
||||||
typedef struct mjsPlugin_ { // plugin specification
|
typedef struct mjsPlugin_ { // plugin specification
|
||||||
mjsElement* instance; // element type
|
mjsElement* element; // element type
|
||||||
mjString* name; // name
|
mjString* name; // name
|
||||||
mjString* instance_name; // instance name
|
mjString* instance_name; // instance name
|
||||||
int plugin_slot; // global registered slot number of the plugin
|
int plugin_slot; // global registered slot number of the plugin
|
||||||
@@ -3622,6 +3622,7 @@ mjsHField* mjs_asHField(mjsElement* element);
|
|||||||
mjsSkin* mjs_asSkin(mjsElement* element);
|
mjsSkin* mjs_asSkin(mjsElement* element);
|
||||||
mjsTexture* mjs_asTexture(mjsElement* element);
|
mjsTexture* mjs_asTexture(mjsElement* element);
|
||||||
mjsMaterial* mjs_asMaterial(mjsElement* element);
|
mjsMaterial* mjs_asMaterial(mjsElement* element);
|
||||||
|
mjsPlugin* mjs_asPlugin(mjsElement* element);
|
||||||
void mjs_setBuffer(mjByteVec* dest, const void* array, int size);
|
void mjs_setBuffer(mjByteVec* dest, const void* array, int size);
|
||||||
void mjs_setString(mjString* dest, const char* text);
|
void mjs_setString(mjString* dest, const char* text);
|
||||||
void mjs_setStringVec(mjStringVec* dest, const char* text);
|
void mjs_setStringVec(mjStringVec* dest, const char* text);
|
||||||
|
|||||||
@@ -181,7 +181,7 @@ typedef struct mjsOrientation_ { // alternative orientation specifiers
|
|||||||
|
|
||||||
|
|
||||||
typedef struct mjsPlugin_ { // plugin specification
|
typedef struct mjsPlugin_ { // plugin specification
|
||||||
mjsElement* instance; // element type
|
mjsElement* element; // element type
|
||||||
mjString* name; // name
|
mjString* name; // name
|
||||||
mjString* instance_name; // instance name
|
mjString* instance_name; // instance name
|
||||||
int plugin_slot; // global registered slot number of the plugin
|
int plugin_slot; // global registered slot number of the plugin
|
||||||
|
|||||||
@@ -1628,6 +1628,9 @@ MJAPI mjsTexture* mjs_asTexture(mjsElement* element);
|
|||||||
// Safely cast an element as mjsMaterial, or return NULL if the element is not an mjsMaterial.
|
// Safely cast an element as mjsMaterial, or return NULL if the element is not an mjsMaterial.
|
||||||
MJAPI mjsMaterial* mjs_asMaterial(mjsElement* element);
|
MJAPI mjsMaterial* mjs_asMaterial(mjsElement* element);
|
||||||
|
|
||||||
|
// Safely cast an element as mjsPlugin, or return NULL if the element is not an mjsPlugin.
|
||||||
|
MJAPI mjsPlugin* mjs_asPlugin(mjsElement* element);
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------- Attribute setters ---------------------------------------------
|
//---------------------------------- Attribute setters ---------------------------------------------
|
||||||
|
|
||||||
|
|||||||
@@ -10270,6 +10270,22 @@ FUNCTIONS: Mapping[str, FunctionDecl] = dict([
|
|||||||
),
|
),
|
||||||
doc='Safely cast an element as mjsMaterial, or return NULL if the element is not an mjsMaterial.', # pylint: disable=line-too-long
|
doc='Safely cast an element as mjsMaterial, or return NULL if the element is not an mjsMaterial.', # pylint: disable=line-too-long
|
||||||
)),
|
)),
|
||||||
|
('mjs_asPlugin',
|
||||||
|
FunctionDecl(
|
||||||
|
name='mjs_asPlugin',
|
||||||
|
return_type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjsPlugin'),
|
||||||
|
),
|
||||||
|
parameters=(
|
||||||
|
FunctionParameterDecl(
|
||||||
|
name='element',
|
||||||
|
type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjsElement'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
doc='Safely cast an element as mjsPlugin, or return NULL if the element is not an mjsPlugin.', # pylint: disable=line-too-long
|
||||||
|
)),
|
||||||
('mjs_setBuffer',
|
('mjs_setBuffer',
|
||||||
FunctionDecl(
|
FunctionDecl(
|
||||||
name='mjs_setBuffer',
|
name='mjs_setBuffer',
|
||||||
|
|||||||
@@ -8565,7 +8565,7 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
|||||||
declname='struct mjsPlugin_',
|
declname='struct mjsPlugin_',
|
||||||
fields=(
|
fields=(
|
||||||
StructFieldDecl(
|
StructFieldDecl(
|
||||||
name='instance',
|
name='element',
|
||||||
type=PointerType(
|
type=PointerType(
|
||||||
inner_type=ValueType(name='mjsElement'),
|
inner_type=ValueType(name='mjsElement'),
|
||||||
),
|
),
|
||||||
|
|||||||
+15
-3
@@ -274,6 +274,18 @@ PYBIND11_MODULE(_specs, m) {
|
|||||||
mjSpec.def("detach_body", [](MjSpec& self, raw::MjsBody& body) {
|
mjSpec.def("detach_body", [](MjSpec& self, raw::MjsBody& body) {
|
||||||
mjs_detachBody(self.ptr, &body);
|
mjs_detachBody(self.ptr, &body);
|
||||||
});
|
});
|
||||||
|
mjSpec.def_property_readonly(
|
||||||
|
"plugins",
|
||||||
|
[](MjSpec& self) -> py::list {
|
||||||
|
py::list list;
|
||||||
|
raw::MjsElement* el = mjs_firstElement(self.ptr, mjOBJ_PLUGIN);
|
||||||
|
while (el) {
|
||||||
|
list.append(mjs_asPlugin(el));
|
||||||
|
el = mjs_nextElement(self.ptr, el);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
},
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
mjSpec.def_property_readonly(
|
mjSpec.def_property_readonly(
|
||||||
"actuators",
|
"actuators",
|
||||||
[](MjSpec& self) -> py::list {
|
[](MjSpec& self) -> py::list {
|
||||||
@@ -900,12 +912,12 @@ PYBIND11_MODULE(_specs, m) {
|
|||||||
// ============================= MJSPLUGIN ===================================
|
// ============================= MJSPLUGIN ===================================
|
||||||
mjsPlugin.def_property(
|
mjsPlugin.def_property(
|
||||||
"id",
|
"id",
|
||||||
[](raw::MjsPlugin& self) -> int { return mjs_getId(self.instance); },
|
[](raw::MjsPlugin& self) -> int { return mjs_getId(self.element); },
|
||||||
[](raw::MjsPlugin& self, raw::MjsPlugin* other) {
|
[](raw::MjsPlugin& self, raw::MjsPlugin* other) {
|
||||||
self.instance = other->instance;
|
self.element = other->element;
|
||||||
});
|
});
|
||||||
mjsPlugin.def("delete",
|
mjsPlugin.def("delete",
|
||||||
[](raw::MjsPlugin& self) { mjs_delete(self.instance); });
|
[](raw::MjsPlugin& self) { mjs_delete(self.element); });
|
||||||
|
|
||||||
#include "specs.cc.inc"
|
#include "specs.cc.inc"
|
||||||
} // PYBIND11_MODULE // NOLINT
|
} // PYBIND11_MODULE // NOLINT
|
||||||
|
|||||||
@@ -690,5 +690,32 @@ class SpecsTest(absltest.TestCase):
|
|||||||
):
|
):
|
||||||
spec.recompile(model, data)
|
spec.recompile(model, data)
|
||||||
|
|
||||||
|
def test_delete_unused_plugin(self):
|
||||||
|
spec = mujoco.MjSpec()
|
||||||
|
spec.from_string(textwrap.dedent("""
|
||||||
|
<mujoco model="MuJoCo Model">
|
||||||
|
<extension>
|
||||||
|
<plugin plugin="mujoco.pid">
|
||||||
|
<instance name="pid1">
|
||||||
|
<config key="kp" value="4.0"/>
|
||||||
|
</instance>
|
||||||
|
</plugin>
|
||||||
|
</extension>
|
||||||
|
|
||||||
|
<worldbody>
|
||||||
|
<body>
|
||||||
|
<geom size="1"/>
|
||||||
|
</body>
|
||||||
|
</worldbody>
|
||||||
|
</mujoco>
|
||||||
|
"""))
|
||||||
|
plugin = spec.plugins[0]
|
||||||
|
self.assertIsNotNone(plugin)
|
||||||
|
plugin.delete()
|
||||||
|
|
||||||
|
model = spec.compile()
|
||||||
|
self.assertIsNotNone(model)
|
||||||
|
self.assertEqual(model.nplugin, 0)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
absltest.main()
|
absltest.main()
|
||||||
|
|||||||
+12
-2
@@ -471,7 +471,7 @@ mjsKey* mjs_addKey(mjSpec* s) {
|
|||||||
mjsPlugin* mjs_addPlugin(mjSpec* s) {
|
mjsPlugin* mjs_addPlugin(mjSpec* s) {
|
||||||
mjCModel* modelC = static_cast<mjCModel*>(s->element);
|
mjCModel* modelC = static_cast<mjCModel*>(s->element);
|
||||||
mjCPlugin* plugin = modelC->AddPlugin();
|
mjCPlugin* plugin = modelC->AddPlugin();
|
||||||
plugin->spec.instance = static_cast<mjsElement*>(plugin);
|
plugin->spec.element = static_cast<mjsElement*>(plugin);
|
||||||
return &plugin->spec;
|
return &plugin->spec;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -887,6 +887,16 @@ mjsMaterial* mjs_asMaterial(mjsElement* element) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// return plugin given mjsElement
|
||||||
|
mjsPlugin* mjs_asPlugin(mjsElement* element) {
|
||||||
|
if (element && element->elemtype == mjOBJ_PLUGIN) {
|
||||||
|
return &(static_cast<mjCPlugin*>(element)->spec);
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// copy buffer to destination buffer
|
// copy buffer to destination buffer
|
||||||
void mjs_setBuffer(mjByteVec* dest, const void* array, int size) {
|
void mjs_setBuffer(mjByteVec* dest, const void* array, int size) {
|
||||||
const std::byte* buffer = static_cast<const std::byte*>(array);
|
const std::byte* buffer = static_cast<const std::byte*>(array);
|
||||||
@@ -995,7 +1005,7 @@ const double* mjs_getDouble(const mjDoubleVec* source, int* size) {
|
|||||||
|
|
||||||
// set plugin attributes
|
// set plugin attributes
|
||||||
void mjs_setPluginAttributes(mjsPlugin* plugin, void* attributes) {
|
void mjs_setPluginAttributes(mjsPlugin* plugin, void* attributes) {
|
||||||
mjCPlugin* pluginC = static_cast<mjCPlugin*>(plugin->instance);
|
mjCPlugin* pluginC = static_cast<mjCPlugin*>(plugin->element);
|
||||||
std::map<std::string, std::string, std::less<>>* config_attribs =
|
std::map<std::string, std::string, std::less<>>* config_attribs =
|
||||||
reinterpret_cast<std::map<std::string, std::string, std::less<>>*>(attributes);
|
reinterpret_cast<std::map<std::string, std::string, std::less<>>*>(attributes);
|
||||||
pluginC->config_attribs = std::move(*config_attribs);
|
pluginC->config_attribs = std::move(*config_attribs);
|
||||||
|
|||||||
@@ -296,6 +296,9 @@ MJAPI mjsTexture* mjs_asTexture(mjsElement* element);
|
|||||||
// Safely cast an element as mjsMaterial, or return NULL if the element is not an mjsMaterial.
|
// Safely cast an element as mjsMaterial, or return NULL if the element is not an mjsMaterial.
|
||||||
MJAPI mjsMaterial* mjs_asMaterial(mjsElement* element);
|
MJAPI mjsMaterial* mjs_asMaterial(mjsElement* element);
|
||||||
|
|
||||||
|
// Safely cast an element as mjsPlugin, or return NULL if the element is not an mjsPlugin.
|
||||||
|
MJAPI mjsPlugin* mjs_asPlugin(mjsElement* element);
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------- Attribute setters ---------------------------------------------
|
//---------------------------------- Attribute setters ---------------------------------------------
|
||||||
|
|
||||||
|
|||||||
@@ -315,7 +315,7 @@ bool mjCComposite::Make(mjSpec* spec, mjsBody* body, char* error, int error_sz)
|
|||||||
// overwrite plugin name
|
// overwrite plugin name
|
||||||
if (plugin_instance_name.empty() && plugin.active) {
|
if (plugin_instance_name.empty() && plugin.active) {
|
||||||
plugin_instance_name = "composite" + prefix;
|
plugin_instance_name = "composite" + prefix;
|
||||||
(static_cast<mjCPlugin*>(plugin.instance))->name = plugin_instance_name;
|
(static_cast<mjCPlugin*>(plugin.element))->name = plugin_instance_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
// dispatch
|
// dispatch
|
||||||
@@ -714,7 +714,7 @@ mjsBody* mjCComposite::AddCableBody(mjCModel* model, mjsBody* body, int ix,
|
|||||||
if (plugin.active) {
|
if (plugin.active) {
|
||||||
mjsPlugin* pplugin = &body->plugin;
|
mjsPlugin* pplugin = &body->plugin;
|
||||||
pplugin->active = true;
|
pplugin->active = true;
|
||||||
pplugin->instance = plugin.instance;
|
pplugin->element = plugin.element;
|
||||||
mjs_setString(pplugin->name, mjs_getString(plugin.name));
|
mjs_setString(pplugin->name, mjs_getString(plugin.name));
|
||||||
mjs_setString(pplugin->instance_name, plugin_instance_name.c_str());
|
mjs_setString(pplugin->instance_name, plugin_instance_name.c_str());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -422,7 +422,7 @@ bool mjCFlexcomp::Make(mjSpec* spec, mjsBody* body, char* error, int error_sz) {
|
|||||||
// overwrite plugin name
|
// overwrite plugin name
|
||||||
if (plugin.active && plugin_instance_name.empty()) {
|
if (plugin.active && plugin_instance_name.empty()) {
|
||||||
plugin_instance_name = "flexcomp_" + name;
|
plugin_instance_name = "flexcomp_" + name;
|
||||||
static_cast<mjCPlugin*>(plugin.instance)->name = plugin_instance_name;
|
static_cast<mjCPlugin*>(plugin.element)->name = plugin_instance_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
// create bodies, construct flex vert and vertbody
|
// create bodies, construct flex vert and vertbody
|
||||||
@@ -440,7 +440,7 @@ bool mjCFlexcomp::Make(mjSpec* spec, mjsBody* body, char* error, int error_sz) {
|
|||||||
if (plugin.active) {
|
if (plugin.active) {
|
||||||
mjsPlugin* pplugin = &body->plugin;
|
mjsPlugin* pplugin = &body->plugin;
|
||||||
pplugin->active = true;
|
pplugin->active = true;
|
||||||
pplugin->instance = static_cast<mjsElement*>(plugin.instance);
|
pplugin->element = static_cast<mjsElement*>(plugin.element);
|
||||||
mjs_setString(pplugin->name, mjs_getString(plugin.name));
|
mjs_setString(pplugin->name, mjs_getString(plugin.name));
|
||||||
mjs_setString(pplugin->instance_name, plugin_instance_name.c_str());
|
mjs_setString(pplugin->instance_name, plugin_instance_name.c_str());
|
||||||
}
|
}
|
||||||
@@ -504,7 +504,7 @@ bool mjCFlexcomp::Make(mjSpec* spec, mjsBody* body, char* error, int error_sz) {
|
|||||||
if (plugin.active) {
|
if (plugin.active) {
|
||||||
mjsPlugin* pplugin = &pb->plugin;
|
mjsPlugin* pplugin = &pb->plugin;
|
||||||
pplugin->active = true;
|
pplugin->active = true;
|
||||||
pplugin->instance = static_cast<mjsElement*>(plugin.instance);
|
pplugin->element = static_cast<mjsElement*>(plugin.element);
|
||||||
mjs_setString(pplugin->name, mjs_getString(plugin.name));
|
mjs_setString(pplugin->name, mjs_getString(plugin.name));
|
||||||
mjs_setString(pplugin->instance_name, plugin_instance_name.c_str());
|
mjs_setString(pplugin->instance_name, plugin_instance_name.c_str());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -246,7 +246,7 @@ void mjCMesh::CopyFromSpec() {
|
|||||||
facetexcoord_ = spec_facetexcoord_;
|
facetexcoord_ = spec_facetexcoord_;
|
||||||
maxhullvert_ = spec.maxhullvert;
|
maxhullvert_ = spec.maxhullvert;
|
||||||
plugin.active = spec.plugin.active;
|
plugin.active = spec.plugin.active;
|
||||||
plugin.instance = spec.plugin.instance;
|
plugin.element = spec.plugin.element;
|
||||||
plugin.name = spec.plugin.name;
|
plugin.name = spec.plugin.name;
|
||||||
plugin.instance_name = spec.plugin.instance_name;
|
plugin.instance_name = spec.plugin.instance_name;
|
||||||
|
|
||||||
@@ -270,7 +270,7 @@ mjCMesh::~mjCMesh() {
|
|||||||
if (center_) mju_free(center_);
|
if (center_) mju_free(center_);
|
||||||
if (graph_) mju_free(graph_);
|
if (graph_) mju_free(graph_);
|
||||||
if (spec.plugin.active && spec.plugin.instance_name->empty()) {
|
if (spec.plugin.active && spec.plugin.instance_name->empty()) {
|
||||||
model->DeleteElement(spec.plugin.instance);
|
model->DeleteElement(spec.plugin.element);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -289,9 +289,9 @@ void mjCMesh::LoadSDF() {
|
|||||||
name.c_str(), id);
|
name.c_str(), id);
|
||||||
}
|
}
|
||||||
|
|
||||||
mjCPlugin* plugin_instance = static_cast<mjCPlugin*>(plugin.instance);
|
mjCPlugin* plugin_instance = static_cast<mjCPlugin*>(plugin.element);
|
||||||
model->ResolvePlugin(this, plugin_name, plugin_instance_name, &plugin_instance);
|
model->ResolvePlugin(this, plugin_name, plugin_instance_name, &plugin_instance);
|
||||||
plugin.instance = plugin_instance;
|
plugin.element = plugin_instance;
|
||||||
const mjpPlugin* pplugin = mjp_getPluginAtSlot(plugin_instance->spec.plugin_slot);
|
const mjpPlugin* pplugin = mjp_getPluginAtSlot(plugin_instance->spec.plugin_slot);
|
||||||
if (!(pplugin->capabilityflags & mjPLUGIN_SDF)) {
|
if (!(pplugin->capabilityflags & mjPLUGIN_SDF)) {
|
||||||
throw mjCError(this, "plugin '%s' does not support signed distance fields", pplugin->name);
|
throw mjCError(this, "plugin '%s' does not support signed distance fields", pplugin->name);
|
||||||
@@ -2919,9 +2919,9 @@ void mjCFlex::Compile(const mjVFS* vfs) {
|
|||||||
useredge = VectorToString(edgeidx_);
|
useredge = VectorToString(edgeidx_);
|
||||||
|
|
||||||
for (const auto& vbodyid : vertbodyid) {
|
for (const auto& vbodyid : vertbodyid) {
|
||||||
if (model->Bodies()[vbodyid]->plugin.instance) {
|
if (model->Bodies()[vbodyid]->plugin.element) {
|
||||||
mjCPlugin* plugin_instance =
|
mjCPlugin* plugin_instance =
|
||||||
static_cast<mjCPlugin*>(model->Bodies()[vbodyid]->plugin.instance);
|
static_cast<mjCPlugin*>(model->Bodies()[vbodyid]->plugin.element);
|
||||||
if (damping > 0) {
|
if (damping > 0) {
|
||||||
plugin_instance->config_attribs["damping"] = std::to_string(damping);
|
plugin_instance->config_attribs["damping"] = std::to_string(damping);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -938,6 +938,8 @@ mjsElement* mjCModel::NextObject(mjsElement* object, mjtObj type) {
|
|||||||
return GetNext(textures_, object);
|
return GetNext(textures_, object);
|
||||||
case mjOBJ_MATERIAL:
|
case mjOBJ_MATERIAL:
|
||||||
return GetNext(materials_, object);
|
return GetNext(materials_, object);
|
||||||
|
case mjOBJ_PLUGIN:
|
||||||
|
return GetNext(plugins_, object);
|
||||||
default:
|
default:
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -3932,7 +3934,7 @@ void mjCModel::TryCompile(mjModel*& m, mjData*& d, const mjVFS* vfs) {
|
|||||||
std::vector<std::vector<int>> plugin_to_actuators(nplugin);
|
std::vector<std::vector<int>> plugin_to_actuators(nplugin);
|
||||||
for (int i = 0; i < nu; ++i) {
|
for (int i = 0; i < nu; ++i) {
|
||||||
if (actuators_[i]->plugin.active) {
|
if (actuators_[i]->plugin.active) {
|
||||||
int actuator_plugin = static_cast<mjCPlugin*>(actuators_[i]->plugin.instance)->id;
|
int actuator_plugin = static_cast<mjCPlugin*>(actuators_[i]->plugin.element)->id;
|
||||||
m->actuator_plugin[i] = actuator_plugin;
|
m->actuator_plugin[i] = actuator_plugin;
|
||||||
plugin_to_actuators[actuator_plugin].push_back(i);
|
plugin_to_actuators[actuator_plugin].push_back(i);
|
||||||
} else {
|
} else {
|
||||||
@@ -3942,7 +3944,7 @@ void mjCModel::TryCompile(mjModel*& m, mjData*& d, const mjVFS* vfs) {
|
|||||||
|
|
||||||
for (int i = 0; i < nbody; ++i) {
|
for (int i = 0; i < nbody; ++i) {
|
||||||
if (bodies_[i]->plugin.active) {
|
if (bodies_[i]->plugin.active) {
|
||||||
m->body_plugin[i] = static_cast<mjCPlugin*>(bodies_[i]->plugin.instance)->id;
|
m->body_plugin[i] = static_cast<mjCPlugin*>(bodies_[i]->plugin.element)->id;
|
||||||
} else {
|
} else {
|
||||||
m->body_plugin[i] = -1;
|
m->body_plugin[i] = -1;
|
||||||
}
|
}
|
||||||
@@ -3950,7 +3952,7 @@ void mjCModel::TryCompile(mjModel*& m, mjData*& d, const mjVFS* vfs) {
|
|||||||
|
|
||||||
for (int i = 0; i < ngeom; ++i) {
|
for (int i = 0; i < ngeom; ++i) {
|
||||||
if (geoms_[i]->plugin.active) {
|
if (geoms_[i]->plugin.active) {
|
||||||
m->geom_plugin[i] = static_cast<mjCPlugin*>(geoms_[i]->plugin.instance)->id;
|
m->geom_plugin[i] = static_cast<mjCPlugin*>(geoms_[i]->plugin.element)->id;
|
||||||
} else {
|
} else {
|
||||||
m->geom_plugin[i] = -1;
|
m->geom_plugin[i] = -1;
|
||||||
}
|
}
|
||||||
@@ -3959,7 +3961,7 @@ void mjCModel::TryCompile(mjModel*& m, mjData*& d, const mjVFS* vfs) {
|
|||||||
std::vector<std::vector<int>> plugin_to_sensors(nplugin);
|
std::vector<std::vector<int>> plugin_to_sensors(nplugin);
|
||||||
for (int i = 0; i < nsensor; ++i) {
|
for (int i = 0; i < nsensor; ++i) {
|
||||||
if (sensors_[i]->type == mjSENS_PLUGIN) {
|
if (sensors_[i]->type == mjSENS_PLUGIN) {
|
||||||
int sensor_plugin = static_cast<mjCPlugin*>(sensors_[i]->plugin.instance)->id;
|
int sensor_plugin = static_cast<mjCPlugin*>(sensors_[i]->plugin.element)->id;
|
||||||
m->sensor_plugin[i] = sensor_plugin;
|
m->sensor_plugin[i] = sensor_plugin;
|
||||||
plugin_to_sensors[sensor_plugin].push_back(i);
|
plugin_to_sensors[sensor_plugin].push_back(i);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
+16
-16
@@ -959,7 +959,7 @@ void mjCBody::CopyFromSpec() {
|
|||||||
*static_cast<mjsBody*>(this) = spec;
|
*static_cast<mjsBody*>(this) = spec;
|
||||||
userdata_ = spec_userdata_;
|
userdata_ = spec_userdata_;
|
||||||
plugin.active = spec.plugin.active;
|
plugin.active = spec.plugin.active;
|
||||||
plugin.instance = spec.plugin.instance;
|
plugin.element = spec.plugin.element;
|
||||||
plugin.name = spec.plugin.name;
|
plugin.name = spec.plugin.name;
|
||||||
plugin.instance_name = spec.plugin.instance_name;
|
plugin.instance_name = spec.plugin.instance_name;
|
||||||
}
|
}
|
||||||
@@ -986,7 +986,7 @@ mjCBody::~mjCBody() {
|
|||||||
lights.clear();
|
lights.clear();
|
||||||
|
|
||||||
if (spec.plugin.active && spec.plugin.instance_name->empty()) {
|
if (spec.plugin.active && spec.plugin.instance_name->empty()) {
|
||||||
model->DeleteElement(spec.plugin.instance);
|
model->DeleteElement(spec.plugin.element);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1669,9 +1669,9 @@ void mjCBody::Compile(void) {
|
|||||||
name.c_str(), id);
|
name.c_str(), id);
|
||||||
}
|
}
|
||||||
|
|
||||||
mjCPlugin* plugin_instance = static_cast<mjCPlugin*>(plugin.instance);
|
mjCPlugin* plugin_instance = static_cast<mjCPlugin*>(plugin.element);
|
||||||
model->ResolvePlugin(this, plugin_name, plugin_instance_name, &plugin_instance);
|
model->ResolvePlugin(this, plugin_name, plugin_instance_name, &plugin_instance);
|
||||||
plugin.instance = plugin_instance;
|
plugin.element = plugin_instance;
|
||||||
const mjpPlugin* pplugin = mjp_getPluginAtSlot(plugin_instance->spec.plugin_slot);
|
const mjpPlugin* pplugin = mjp_getPluginAtSlot(plugin_instance->spec.plugin_slot);
|
||||||
if (!(pplugin->capabilityflags & mjPLUGIN_PASSIVE)) {
|
if (!(pplugin->capabilityflags & mjPLUGIN_PASSIVE)) {
|
||||||
throw mjCError(this, "plugin '%s' does not support passive forces", pplugin->name);
|
throw mjCError(this, "plugin '%s' does not support passive forces", pplugin->name);
|
||||||
@@ -2132,7 +2132,7 @@ mjCGeom::mjCGeom(const mjCGeom& other) {
|
|||||||
|
|
||||||
mjCGeom::~mjCGeom() {
|
mjCGeom::~mjCGeom() {
|
||||||
if (spec.plugin.active && spec.plugin.instance_name->empty()) {
|
if (spec.plugin.active && spec.plugin.instance_name->empty()) {
|
||||||
model->DeleteElement(spec.plugin.instance);
|
model->DeleteElement(spec.plugin.element);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2176,7 +2176,7 @@ void mjCGeom::CopyFromSpec() {
|
|||||||
meshname_ = spec_meshname_;
|
meshname_ = spec_meshname_;
|
||||||
material_ = spec_material_;
|
material_ = spec_material_;
|
||||||
plugin.active = spec.plugin.active;
|
plugin.active = spec.plugin.active;
|
||||||
plugin.instance = spec.plugin.instance;
|
plugin.element = spec.plugin.element;
|
||||||
plugin.name = spec.plugin.name;
|
plugin.name = spec.plugin.name;
|
||||||
plugin.instance_name = spec.plugin.instance_name;
|
plugin.instance_name = spec.plugin.instance_name;
|
||||||
}
|
}
|
||||||
@@ -2913,9 +2913,9 @@ void mjCGeom::Compile(void) {
|
|||||||
this, "neither 'plugin' nor 'instance' is specified for geom");
|
this, "neither 'plugin' nor 'instance' is specified for geom");
|
||||||
}
|
}
|
||||||
|
|
||||||
mjCPlugin* plugin_instance = static_cast<mjCPlugin*>(plugin.instance);
|
mjCPlugin* plugin_instance = static_cast<mjCPlugin*>(plugin.element);
|
||||||
model->ResolvePlugin(this, plugin_name, plugin_instance_name, &plugin_instance);
|
model->ResolvePlugin(this, plugin_name, plugin_instance_name, &plugin_instance);
|
||||||
plugin.instance = plugin_instance;
|
plugin.element = plugin_instance;
|
||||||
const mjpPlugin* pplugin = mjp_getPluginAtSlot(plugin_instance->spec.plugin_slot);
|
const mjpPlugin* pplugin = mjp_getPluginAtSlot(plugin_instance->spec.plugin_slot);
|
||||||
if (!(pplugin->capabilityflags & mjPLUGIN_SDF)) {
|
if (!(pplugin->capabilityflags & mjPLUGIN_SDF)) {
|
||||||
throw mjCError(this, "plugin '%s' does not support sign distance fields", pplugin->name);
|
throw mjCError(this, "plugin '%s' does not support sign distance fields", pplugin->name);
|
||||||
@@ -5554,7 +5554,7 @@ mjCActuator::mjCActuator(const mjCActuator& other) {
|
|||||||
|
|
||||||
mjCActuator::~mjCActuator() {
|
mjCActuator::~mjCActuator() {
|
||||||
if (spec.plugin.active && spec.plugin.instance_name->empty()) {
|
if (spec.plugin.active && spec.plugin.instance_name->empty()) {
|
||||||
model->DeleteElement(spec.plugin.instance);
|
model->DeleteElement(spec.plugin.element);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5640,7 +5640,7 @@ void mjCActuator::CopyFromSpec() {
|
|||||||
refsite_ = spec_refsite_;
|
refsite_ = spec_refsite_;
|
||||||
slidersite_ = spec_slidersite_;
|
slidersite_ = spec_slidersite_;
|
||||||
plugin.active = spec.plugin.active;
|
plugin.active = spec.plugin.active;
|
||||||
plugin.instance = spec.plugin.instance;
|
plugin.element = spec.plugin.element;
|
||||||
plugin.name = spec.plugin.name;
|
plugin.name = spec.plugin.name;
|
||||||
plugin.instance_name = spec.plugin.instance_name;
|
plugin.instance_name = spec.plugin.instance_name;
|
||||||
}
|
}
|
||||||
@@ -5869,9 +5869,9 @@ void mjCActuator::Compile(void) {
|
|||||||
name.c_str(), id);
|
name.c_str(), id);
|
||||||
}
|
}
|
||||||
|
|
||||||
mjCPlugin* plugin_instance = static_cast<mjCPlugin*>(plugin.instance);
|
mjCPlugin* plugin_instance = static_cast<mjCPlugin*>(plugin.element);
|
||||||
model->ResolvePlugin(this, plugin_name, plugin_instance_name, &plugin_instance);
|
model->ResolvePlugin(this, plugin_name, plugin_instance_name, &plugin_instance);
|
||||||
plugin.instance = plugin_instance;
|
plugin.element = plugin_instance;
|
||||||
const mjpPlugin* pplugin = mjp_getPluginAtSlot(plugin_instance->spec.plugin_slot);
|
const mjpPlugin* pplugin = mjp_getPluginAtSlot(plugin_instance->spec.plugin_slot);
|
||||||
if (!(pplugin->capabilityflags & mjPLUGIN_ACTUATOR)) {
|
if (!(pplugin->capabilityflags & mjPLUGIN_ACTUATOR)) {
|
||||||
throw mjCError(this, "plugin '%s' does not support actuators", pplugin->name);
|
throw mjCError(this, "plugin '%s' does not support actuators", pplugin->name);
|
||||||
@@ -5916,7 +5916,7 @@ mjCSensor::mjCSensor(const mjCSensor& other) {
|
|||||||
|
|
||||||
mjCSensor::~mjCSensor() {
|
mjCSensor::~mjCSensor() {
|
||||||
if (spec.plugin.active && spec.plugin.instance_name->empty()) {
|
if (spec.plugin.active && spec.plugin.instance_name->empty()) {
|
||||||
model->DeleteElement(spec.plugin.instance);
|
model->DeleteElement(spec.plugin.element);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5968,7 +5968,7 @@ void mjCSensor::CopyFromSpec() {
|
|||||||
objname_ = spec_objname_;
|
objname_ = spec_objname_;
|
||||||
refname_ = spec_refname_;
|
refname_ = spec_refname_;
|
||||||
plugin.active = spec.plugin.active;
|
plugin.active = spec.plugin.active;
|
||||||
plugin.instance = spec.plugin.instance;
|
plugin.element = spec.plugin.element;
|
||||||
plugin.name = spec.plugin.name;
|
plugin.name = spec.plugin.name;
|
||||||
plugin.instance_name = spec.plugin.instance_name;
|
plugin.instance_name = spec.plugin.instance_name;
|
||||||
}
|
}
|
||||||
@@ -6373,9 +6373,9 @@ void mjCSensor::Compile(void) {
|
|||||||
|
|
||||||
// resolve plugin instance, or create one if using the "plugin" attribute shortcut
|
// resolve plugin instance, or create one if using the "plugin" attribute shortcut
|
||||||
{
|
{
|
||||||
mjCPlugin* plugin_instance = static_cast<mjCPlugin*>(plugin.instance);
|
mjCPlugin* plugin_instance = static_cast<mjCPlugin*>(plugin.element);
|
||||||
model->ResolvePlugin(this, plugin_name, plugin_instance_name, &plugin_instance);
|
model->ResolvePlugin(this, plugin_name, plugin_instance_name, &plugin_instance);
|
||||||
plugin.instance = plugin_instance;
|
plugin.element = plugin_instance;
|
||||||
const mjpPlugin* pplugin = mjp_getPluginAtSlot(plugin_instance->spec.plugin_slot);
|
const mjpPlugin* pplugin = mjp_getPluginAtSlot(plugin_instance->spec.plugin_slot);
|
||||||
if (!(pplugin->capabilityflags & mjPLUGIN_SENSOR)) {
|
if (!(pplugin->capabilityflags & mjPLUGIN_SENSOR)) {
|
||||||
throw mjCError(this, "plugin '%s' does not support sensors", pplugin->name);
|
throw mjCError(this, "plugin '%s' does not support sensors", pplugin->name);
|
||||||
|
|||||||
@@ -2767,7 +2767,7 @@ void mjXReader::OnePlugin(XMLElement* elem, mjsPlugin* plugin) {
|
|||||||
mjs_setString(plugin->name, name.c_str());
|
mjs_setString(plugin->name, name.c_str());
|
||||||
mjs_setString(plugin->instance_name, instance_name.c_str());
|
mjs_setString(plugin->instance_name, instance_name.c_str());
|
||||||
if (instance_name.empty()) {
|
if (instance_name.empty()) {
|
||||||
plugin->instance = mjs_addPlugin(spec)->instance;
|
plugin->element = mjs_addPlugin(spec)->element;
|
||||||
ReadPluginConfigs(elem, plugin);
|
ReadPluginConfigs(elem, plugin);
|
||||||
} else {
|
} else {
|
||||||
spec->hasImplicitPluginElem = true;
|
spec->hasImplicitPluginElem = true;
|
||||||
|
|||||||
@@ -827,8 +827,8 @@ void mjXWriter::OnePlugin(XMLElement* elem, const mjsPlugin* plugin) {
|
|||||||
} else {
|
} else {
|
||||||
WriteAttrTxt(elem, "plugin", plugin_name);
|
WriteAttrTxt(elem, "plugin", plugin_name);
|
||||||
const mjpPlugin* pplugin = mjp_getPluginAtSlot(
|
const mjpPlugin* pplugin = mjp_getPluginAtSlot(
|
||||||
static_cast<mjCPlugin*>(plugin->instance)->spec.plugin_slot);
|
static_cast<mjCPlugin*>(plugin->element)->spec.plugin_slot);
|
||||||
const char* c = &(static_cast<mjCPlugin*>(plugin->instance)->flattened_attributes[0]);
|
const char* c = &(static_cast<mjCPlugin*>(plugin->element)->flattened_attributes[0]);
|
||||||
for (int i = 0; i < pplugin->nattribute; ++i) {
|
for (int i = 0; i < pplugin->nattribute; ++i) {
|
||||||
string value(c);
|
string value(c);
|
||||||
if (!value.empty()) {
|
if (!value.empty()) {
|
||||||
|
|||||||
@@ -147,7 +147,7 @@ TEST_F(PluginTest, ActivatePlugin) {
|
|||||||
// associate plugin to body
|
// associate plugin to body
|
||||||
mjsBody* body = mjs_addBody(mjs_findBody(spec, "world"), 0);
|
mjsBody* body = mjs_addBody(mjs_findBody(spec, "world"), 0);
|
||||||
mjs_setString(body->plugin.name, plugin_name.c_str());
|
mjs_setString(body->plugin.name, plugin_name.c_str());
|
||||||
body->plugin.instance = mjs_addPlugin(spec)->instance;
|
body->plugin.element = mjs_addPlugin(spec)->element;
|
||||||
body->plugin.active = true;
|
body->plugin.active = true;
|
||||||
mjsGeom* geom = mjs_addGeom(body, 0);
|
mjsGeom* geom = mjs_addGeom(body, 0);
|
||||||
geom->type = mjGEOM_BOX;
|
geom->type = mjGEOM_BOX;
|
||||||
@@ -191,7 +191,7 @@ TEST_F(PluginTest, DeletePlugin) {
|
|||||||
mjsActuator* actuator = mjs_addActuator(spec, 0);
|
mjsActuator* actuator = mjs_addActuator(spec, 0);
|
||||||
mjs_setString(actuator->target, "j1");
|
mjs_setString(actuator->target, "j1");
|
||||||
mjs_setString(actuator->plugin.name, plugin_name.c_str());
|
mjs_setString(actuator->plugin.name, plugin_name.c_str());
|
||||||
actuator->plugin.instance = mjs_addPlugin(spec)->instance;
|
actuator->plugin.element = mjs_addPlugin(spec)->element;
|
||||||
actuator->plugin.active = true;
|
actuator->plugin.active = true;
|
||||||
actuator->trntype = mjTRN_JOINT;
|
actuator->trntype = mjTRN_JOINT;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user