Add map from objects names to their index.

Also some minor cleanup of repeated code in user_model.

PiperOrigin-RevId: 589135294
Change-Id: I16f22c4dbdde961cedc042af3bdc9d3577d33459
This commit is contained in:
Alessio Quaglino
2023-12-08 08:13:17 -08:00
committed by Copybara-Service
parent 623201ec76
commit a006b15958
2 changed files with 88 additions and 69 deletions
+79 -69
View File
@@ -21,6 +21,7 @@
#include <cstring> #include <cstring>
#include <map> #include <map>
#include <string> #include <string>
#include <string_view>
#include <vector> #include <vector>
#include <mujoco/mjdata.h> #include <mujoco/mjdata.h>
@@ -136,6 +137,7 @@ mjCModel::mjCModel() {
nuser_sensor = -1; nuser_sensor = -1;
//------------------------ private variables //------------------------ private variables
ids.clear();
cameras.clear(); cameras.clear();
lights.clear(); lights.clear();
flexes.clear(); flexes.clear();
@@ -201,6 +203,7 @@ mjCModel::~mjCModel() {
for (int i=0; i<defaults.size(); i++) delete defaults[i]; for (int i=0; i<defaults.size(); i++) delete defaults[i];
// clear pointer lists created in model construction // clear pointer lists created in model construction
ids.clear();
flexes.clear(); flexes.clear();
meshes.clear(); meshes.clear();
skins.clear(); skins.clear();
@@ -632,14 +635,23 @@ mjCDef* mjCModel::AddDef(string name, int parentid) {
// find object by name in given list // find object by name in given list
template <class T> template <class T>
static T* findobject(string name, vector<T*>& list) { static T* findobject(std::string_view name, const vector<T*>& list, const mjKeyMap& ids) {
for (unsigned int i=0; i<list.size(); i++) { // this can occur in the URDF parser
if (list[i]->name == name) { if (ids.empty()) {
return list[i]; for (unsigned int i=0; i<list.size(); i++) {
if (list[i]->name == name) {
return list[i];
}
} }
return nullptr;
} }
return 0; // during model compilation
auto id = ids.find(name);
if (id == ids.end()) {
return nullptr;
}
return list[id->second];
} }
// find object in global lists given string type and name // find object in global lists given string type and name
@@ -647,49 +659,49 @@ mjCBase* mjCModel::FindObject(mjtObj type, string name) {
switch (type) { switch (type) {
case mjOBJ_BODY: case mjOBJ_BODY:
case mjOBJ_XBODY: case mjOBJ_XBODY:
return findobject(name, bodies); return findobject(name, bodies, ids["body"]);
case mjOBJ_JOINT: case mjOBJ_JOINT:
return findobject(name, joints); return findobject(name, joints, ids["joint"]);
case mjOBJ_GEOM: case mjOBJ_GEOM:
return findobject(name, geoms); return findobject(name, geoms, ids["geom"]);
case mjOBJ_SITE: case mjOBJ_SITE:
return findobject(name, sites); return findobject(name, sites, ids["site"]);
case mjOBJ_CAMERA: case mjOBJ_CAMERA:
return findobject(name, cameras); return findobject(name, cameras, ids["camera"]);
case mjOBJ_LIGHT: case mjOBJ_LIGHT:
return findobject(name, lights); return findobject(name, lights, ids["light"]);
case mjOBJ_FLEX: case mjOBJ_FLEX:
return findobject(name, flexes); return findobject(name, flexes, ids["flex"]);
case mjOBJ_MESH: case mjOBJ_MESH:
return findobject(name, meshes); return findobject(name, meshes, ids["mesh"]);
case mjOBJ_SKIN: case mjOBJ_SKIN:
return findobject(name, skins); return findobject(name, skins, ids["skin"]);
case mjOBJ_HFIELD: case mjOBJ_HFIELD:
return findobject(name, hfields); return findobject(name, hfields, ids["hfield"]);
case mjOBJ_TEXTURE: case mjOBJ_TEXTURE:
return findobject(name, textures); return findobject(name, textures, ids["texture"]);
case mjOBJ_MATERIAL: case mjOBJ_MATERIAL:
return findobject(name, materials); return findobject(name, materials, ids["material"]);
case mjOBJ_PAIR: case mjOBJ_PAIR:
return findobject(name, pairs); return findobject(name, pairs, ids["pair"]);
case mjOBJ_EXCLUDE: case mjOBJ_EXCLUDE:
return findobject(name, excludes); return findobject(name, excludes, ids["exclude"]);
case mjOBJ_EQUALITY: case mjOBJ_EQUALITY:
return findobject(name, equalities); return findobject(name, equalities, ids["equality"]);
case mjOBJ_TENDON: case mjOBJ_TENDON:
return findobject(name, tendons); return findobject(name, tendons, ids["tendon"]);
case mjOBJ_ACTUATOR: case mjOBJ_ACTUATOR:
return findobject(name, actuators); return findobject(name, actuators, ids["actuator"]);
case mjOBJ_SENSOR: case mjOBJ_SENSOR:
return findobject(name, sensors); return findobject(name, sensors, ids["sensor"]);
case mjOBJ_NUMERIC: case mjOBJ_NUMERIC:
return findobject(name, numerics); return findobject(name, numerics, ids["numeric"]);
case mjOBJ_TEXT: case mjOBJ_TEXT:
return findobject(name, texts); return findobject(name, texts, ids["text"]);
case mjOBJ_TUPLE: case mjOBJ_TUPLE:
return findobject(name, tuples); return findobject(name, tuples, ids["tuple"]);
case mjOBJ_PLUGIN: case mjOBJ_PLUGIN:
return findobject(name, plugins); return findobject(name, plugins, ids["plugin"]);
default: default:
return 0; return 0;
} }
@@ -2357,6 +2369,14 @@ void mjCModel::CopyObjects(mjModel* m) {
//------------------------------- FUSE STATIC ------------------------------------------------------ //------------------------------- FUSE STATIC ------------------------------------------------------
template <class T>
static void makelistid(std::vector<T*>& dest, std::vector<T*>& source) {
for (int i=0; i<source.size(); i++) {
source[i]->id = (int)dest.size();
dest.push_back(source[i]);
}
}
// change frame to parent body // change frame to parent body
static void changeframe(double childpos[3], double childquat[4], static void changeframe(double childpos[3], double childquat[4],
const double bodypos[3], const double bodyquat[4]) { const double bodypos[3], const double bodyquat[4]) {
@@ -2379,23 +2399,9 @@ void mjCModel::FuseReindex(mjCBody* body) {
body->bodies[i]->id : body->weldid); body->bodies[i]->id : body->weldid);
} }
// joints makelistid(joints, body->joints);
for (int i=0; i<body->joints.size(); i++) { makelistid(geoms, body->geoms);
body->joints[i]->id = (int)joints.size(); makelistid(sites, body->sites);
joints.push_back(body->joints[i]);
}
// geoms
for (int i=0; i<body->geoms.size(); i++) {
body->geoms[i]->id = (int)geoms.size();
geoms.push_back(body->geoms[i]);
}
// sites
for (int i=0; i<body->sites.size(); i++) {
body->sites[i]->id = (int)sites.size();
sites.push_back(body->sites[i]);
}
// process children recursively // process children recursively
for (int i=0; i<body->bodies.size(); i++) { for (int i=0; i<body->bodies.size(); i++) {
@@ -2632,7 +2638,8 @@ static void reassignid(vector<T*>& list) {
// set ids, check for repeated names // set ids, check for repeated names
template <class T> template <class T>
static void processlist(vector<T*>& list, string defname, bool checkrepeat=true) { static void processlist(mjListKeyMap& ids, vector<T*>& list,
string defname, bool checkrepeat = true) {
// loop over list elements // loop over list elements
for (int i=0; i<(int)list.size(); i++) { for (int i=0; i<(int)list.size(); i++) {
// check for incompatible id setting; SHOULD NOT OCCUR // check for incompatible id setting; SHOULD NOT OCCUR
@@ -2642,6 +2649,9 @@ static void processlist(vector<T*>& list, string defname, bool checkrepeat=true)
// id equals position in array // id equals position in array
list[i]->id = i; list[i]->id = i;
// add to ids map
ids[defname][list[i]->name] = i;
} }
// check for repeated names // check for repeated names
@@ -2792,30 +2802,30 @@ void mjCModel::TryCompile(mjModel*& m, mjData*& d, const mjVFS* vfs) {
SetDefaultNames(textures); SetDefaultNames(textures);
CheckEmptyNames(); CheckEmptyNames();
// set object ids and default names, check for repeated names // set object ids, check for repeated names
processlist(bodies, "body"); processlist(ids, bodies, "body");
processlist(joints, "joint"); processlist(ids, joints, "joint");
processlist(geoms, "geom"); processlist(ids, geoms, "geom");
processlist(sites, "site"); processlist(ids, sites, "site");
processlist(cameras, "camera"); processlist(ids, cameras, "camera");
processlist(lights, "light"); processlist(ids, lights, "light");
processlist(flexes, "flex"); processlist(ids, flexes, "flex");
processlist(meshes, "mesh"); processlist(ids, meshes, "mesh");
processlist(skins, "skin"); processlist(ids, skins, "skin");
processlist(hfields, "hfield"); processlist(ids, hfields, "hfield");
processlist(textures, "texture"); processlist(ids, textures, "texture");
processlist(materials, "material"); processlist(ids, materials, "material");
processlist(pairs, "pair"); processlist(ids, pairs, "pair");
processlist(excludes, "exclude"); processlist(ids, excludes, "exclude");
processlist(equalities, "equality"); processlist(ids, equalities, "equality");
processlist(tendons, "tendon"); processlist(ids, tendons, "tendon");
processlist(actuators, "actuator"); processlist(ids, actuators, "actuator");
processlist(sensors, "sensor"); processlist(ids, sensors, "sensor");
processlist(numerics, "numeric"); processlist(ids, numerics, "numeric");
processlist(texts, "text"); processlist(ids, texts, "text");
processlist(tuples, "tuple"); processlist(ids, tuples, "tuple");
processlist(keys, "key"); processlist(ids, keys, "key");
processlist(plugins, "plugin"); processlist(ids, plugins, "plugin");
// convert names into indices // convert names into indices
IndexAssets(); IndexAssets();
+9
View File
@@ -15,6 +15,8 @@
#ifndef MUJOCO_SRC_USER_USER_MODEL_H_ #ifndef MUJOCO_SRC_USER_USER_MODEL_H_
#define MUJOCO_SRC_USER_USER_MODEL_H_ #define MUJOCO_SRC_USER_USER_MODEL_H_
#include <functional>
#include <map>
#include <string> #include <string>
#include <utility> #include <utility>
#include <vector> #include <vector>
@@ -30,6 +32,10 @@ typedef enum _mjtInertiaFromGeom {
mjINERTIAFROMGEOM_AUTO // use only if inertial element is missing mjINERTIAFROMGEOM_AUTO // use only if inertial element is missing
} mjtInertiaFromGeom; } mjtInertiaFromGeom;
// TODO: convert mjListKeyMap to mjKeyMap[mjNOBJECT] by adding mjNOBJECT to mjtObj
typedef std::map<std::string, int, std::less<> > mjKeyMap;
typedef std::map<std::string, mjKeyMap, std::less<> > mjListKeyMap;
//---------------------------------- class mjCModel ------------------------------------------------ //---------------------------------- class mjCModel ------------------------------------------------
@@ -286,6 +292,9 @@ class mjCModel {
std::vector<mjCCamera*> cameras; // list of cameras std::vector<mjCCamera*> cameras; // list of cameras
std::vector<mjCLight*> lights; // list of lights std::vector<mjCLight*> lights; // list of lights
// map from object names to ids
mjListKeyMap ids;
//------------------------ internal variables //------------------------ internal variables
bool hasImplicitPluginElem; // already encountered an implicit plugin sensor/actuator bool hasImplicitPluginElem; // already encountered an implicit plugin sensor/actuator
bool compiled; // already compiled flag (cannot be compiled again) bool compiled; // already compiled flag (cannot be compiled again)