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
+12
-2
@@ -471,7 +471,7 @@ mjsKey* mjs_addKey(mjSpec* s) {
|
||||
mjsPlugin* mjs_addPlugin(mjSpec* s) {
|
||||
mjCModel* modelC = static_cast<mjCModel*>(s->element);
|
||||
mjCPlugin* plugin = modelC->AddPlugin();
|
||||
plugin->spec.instance = static_cast<mjsElement*>(plugin);
|
||||
plugin->spec.element = static_cast<mjsElement*>(plugin);
|
||||
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
|
||||
void mjs_setBuffer(mjByteVec* dest, const void* array, int size) {
|
||||
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
|
||||
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 =
|
||||
reinterpret_cast<std::map<std::string, std::string, std::less<>>*>(attributes);
|
||||
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.
|
||||
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 ---------------------------------------------
|
||||
|
||||
|
||||
@@ -315,7 +315,7 @@ bool mjCComposite::Make(mjSpec* spec, mjsBody* body, char* error, int error_sz)
|
||||
// overwrite plugin name
|
||||
if (plugin_instance_name.empty() && plugin.active) {
|
||||
plugin_instance_name = "composite" + prefix;
|
||||
(static_cast<mjCPlugin*>(plugin.instance))->name = plugin_instance_name;
|
||||
(static_cast<mjCPlugin*>(plugin.element))->name = plugin_instance_name;
|
||||
}
|
||||
|
||||
// dispatch
|
||||
@@ -714,7 +714,7 @@ mjsBody* mjCComposite::AddCableBody(mjCModel* model, mjsBody* body, int ix,
|
||||
if (plugin.active) {
|
||||
mjsPlugin* pplugin = &body->plugin;
|
||||
pplugin->active = true;
|
||||
pplugin->instance = plugin.instance;
|
||||
pplugin->element = plugin.element;
|
||||
mjs_setString(pplugin->name, mjs_getString(plugin.name));
|
||||
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
|
||||
if (plugin.active && plugin_instance_name.empty()) {
|
||||
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
|
||||
@@ -440,7 +440,7 @@ bool mjCFlexcomp::Make(mjSpec* spec, mjsBody* body, char* error, int error_sz) {
|
||||
if (plugin.active) {
|
||||
mjsPlugin* pplugin = &body->plugin;
|
||||
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->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) {
|
||||
mjsPlugin* pplugin = &pb->plugin;
|
||||
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->instance_name, plugin_instance_name.c_str());
|
||||
}
|
||||
|
||||
@@ -246,7 +246,7 @@ void mjCMesh::CopyFromSpec() {
|
||||
facetexcoord_ = spec_facetexcoord_;
|
||||
maxhullvert_ = spec.maxhullvert;
|
||||
plugin.active = spec.plugin.active;
|
||||
plugin.instance = spec.plugin.instance;
|
||||
plugin.element = spec.plugin.element;
|
||||
plugin.name = spec.plugin.name;
|
||||
plugin.instance_name = spec.plugin.instance_name;
|
||||
|
||||
@@ -270,7 +270,7 @@ mjCMesh::~mjCMesh() {
|
||||
if (center_) mju_free(center_);
|
||||
if (graph_) mju_free(graph_);
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
plugin.instance = plugin_instance;
|
||||
plugin.element = plugin_instance;
|
||||
const mjpPlugin* pplugin = mjp_getPluginAtSlot(plugin_instance->spec.plugin_slot);
|
||||
if (!(pplugin->capabilityflags & mjPLUGIN_SDF)) {
|
||||
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_);
|
||||
|
||||
for (const auto& vbodyid : vertbodyid) {
|
||||
if (model->Bodies()[vbodyid]->plugin.instance) {
|
||||
if (model->Bodies()[vbodyid]->plugin.element) {
|
||||
mjCPlugin* plugin_instance =
|
||||
static_cast<mjCPlugin*>(model->Bodies()[vbodyid]->plugin.instance);
|
||||
static_cast<mjCPlugin*>(model->Bodies()[vbodyid]->plugin.element);
|
||||
if (damping > 0) {
|
||||
plugin_instance->config_attribs["damping"] = std::to_string(damping);
|
||||
}
|
||||
|
||||
@@ -938,6 +938,8 @@ mjsElement* mjCModel::NextObject(mjsElement* object, mjtObj type) {
|
||||
return GetNext(textures_, object);
|
||||
case mjOBJ_MATERIAL:
|
||||
return GetNext(materials_, object);
|
||||
case mjOBJ_PLUGIN:
|
||||
return GetNext(plugins_, object);
|
||||
default:
|
||||
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);
|
||||
for (int i = 0; i < nu; ++i) {
|
||||
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;
|
||||
plugin_to_actuators[actuator_plugin].push_back(i);
|
||||
} else {
|
||||
@@ -3942,7 +3944,7 @@ void mjCModel::TryCompile(mjModel*& m, mjData*& d, const mjVFS* vfs) {
|
||||
|
||||
for (int i = 0; i < nbody; ++i) {
|
||||
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 {
|
||||
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) {
|
||||
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 {
|
||||
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);
|
||||
for (int i = 0; i < nsensor; ++i) {
|
||||
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;
|
||||
plugin_to_sensors[sensor_plugin].push_back(i);
|
||||
} else {
|
||||
|
||||
+16
-16
@@ -959,7 +959,7 @@ void mjCBody::CopyFromSpec() {
|
||||
*static_cast<mjsBody*>(this) = spec;
|
||||
userdata_ = spec_userdata_;
|
||||
plugin.active = spec.plugin.active;
|
||||
plugin.instance = spec.plugin.instance;
|
||||
plugin.element = spec.plugin.element;
|
||||
plugin.name = spec.plugin.name;
|
||||
plugin.instance_name = spec.plugin.instance_name;
|
||||
}
|
||||
@@ -986,7 +986,7 @@ mjCBody::~mjCBody() {
|
||||
lights.clear();
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
plugin.instance = plugin_instance;
|
||||
plugin.element = plugin_instance;
|
||||
const mjpPlugin* pplugin = mjp_getPluginAtSlot(plugin_instance->spec.plugin_slot);
|
||||
if (!(pplugin->capabilityflags & mjPLUGIN_PASSIVE)) {
|
||||
throw mjCError(this, "plugin '%s' does not support passive forces", pplugin->name);
|
||||
@@ -2132,7 +2132,7 @@ mjCGeom::mjCGeom(const mjCGeom& other) {
|
||||
|
||||
mjCGeom::~mjCGeom() {
|
||||
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_;
|
||||
material_ = spec_material_;
|
||||
plugin.active = spec.plugin.active;
|
||||
plugin.instance = spec.plugin.instance;
|
||||
plugin.element = spec.plugin.element;
|
||||
plugin.name = spec.plugin.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");
|
||||
}
|
||||
|
||||
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);
|
||||
plugin.instance = plugin_instance;
|
||||
plugin.element = plugin_instance;
|
||||
const mjpPlugin* pplugin = mjp_getPluginAtSlot(plugin_instance->spec.plugin_slot);
|
||||
if (!(pplugin->capabilityflags & mjPLUGIN_SDF)) {
|
||||
throw mjCError(this, "plugin '%s' does not support sign distance fields", pplugin->name);
|
||||
@@ -5554,7 +5554,7 @@ mjCActuator::mjCActuator(const mjCActuator& other) {
|
||||
|
||||
mjCActuator::~mjCActuator() {
|
||||
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_;
|
||||
slidersite_ = spec_slidersite_;
|
||||
plugin.active = spec.plugin.active;
|
||||
plugin.instance = spec.plugin.instance;
|
||||
plugin.element = spec.plugin.element;
|
||||
plugin.name = spec.plugin.name;
|
||||
plugin.instance_name = spec.plugin.instance_name;
|
||||
}
|
||||
@@ -5869,9 +5869,9 @@ void mjCActuator::Compile(void) {
|
||||
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);
|
||||
plugin.instance = plugin_instance;
|
||||
plugin.element = plugin_instance;
|
||||
const mjpPlugin* pplugin = mjp_getPluginAtSlot(plugin_instance->spec.plugin_slot);
|
||||
if (!(pplugin->capabilityflags & mjPLUGIN_ACTUATOR)) {
|
||||
throw mjCError(this, "plugin '%s' does not support actuators", pplugin->name);
|
||||
@@ -5916,7 +5916,7 @@ mjCSensor::mjCSensor(const mjCSensor& other) {
|
||||
|
||||
mjCSensor::~mjCSensor() {
|
||||
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_;
|
||||
refname_ = spec_refname_;
|
||||
plugin.active = spec.plugin.active;
|
||||
plugin.instance = spec.plugin.instance;
|
||||
plugin.element = spec.plugin.element;
|
||||
plugin.name = spec.plugin.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
|
||||
{
|
||||
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);
|
||||
plugin.instance = plugin_instance;
|
||||
plugin.element = plugin_instance;
|
||||
const mjpPlugin* pplugin = mjp_getPluginAtSlot(plugin_instance->spec.plugin_slot);
|
||||
if (!(pplugin->capabilityflags & mjPLUGIN_SENSOR)) {
|
||||
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->instance_name, instance_name.c_str());
|
||||
if (instance_name.empty()) {
|
||||
plugin->instance = mjs_addPlugin(spec)->instance;
|
||||
plugin->element = mjs_addPlugin(spec)->element;
|
||||
ReadPluginConfigs(elem, plugin);
|
||||
} else {
|
||||
spec->hasImplicitPluginElem = true;
|
||||
|
||||
@@ -827,8 +827,8 @@ void mjXWriter::OnePlugin(XMLElement* elem, const mjsPlugin* plugin) {
|
||||
} else {
|
||||
WriteAttrTxt(elem, "plugin", plugin_name);
|
||||
const mjpPlugin* pplugin = mjp_getPluginAtSlot(
|
||||
static_cast<mjCPlugin*>(plugin->instance)->spec.plugin_slot);
|
||||
const char* c = &(static_cast<mjCPlugin*>(plugin->instance)->flattened_attributes[0]);
|
||||
static_cast<mjCPlugin*>(plugin->element)->spec.plugin_slot);
|
||||
const char* c = &(static_cast<mjCPlugin*>(plugin->element)->flattened_attributes[0]);
|
||||
for (int i = 0; i < pplugin->nattribute; ++i) {
|
||||
string value(c);
|
||||
if (!value.empty()) {
|
||||
|
||||
Reference in New Issue
Block a user