Add signature to mjSpec and mjModel and use it to perform safe bind to mjModel and mjData.
PiperOrigin-RevId: 740378879 Change-Id: If14b326942529494f172e7aedcae30195798b458
This commit is contained in:
committed by
Copybara-Service
parent
c931565fdc
commit
157b074116
@@ -2014,6 +2014,9 @@ static void _resetData(const mjModel* m, mjData* d, unsigned char debug_value) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// copy signature from model
|
||||
d->signature = m->signature;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -403,12 +403,14 @@ bool mjCFlexcomp::Make(mjsBody* body, char* error, int error_sz) {
|
||||
mjCFlex* flex = model->AddFlex();
|
||||
mjsFlex* pf = &flex->spec;
|
||||
int id = flex->id;
|
||||
int uid = flex->uid;
|
||||
|
||||
*flex = def.Flex();
|
||||
flex->PointToLocal();
|
||||
|
||||
flex->model = model;
|
||||
flex->id = id;
|
||||
flex->uid = uid;
|
||||
mjs_setString(pf->name, name.c_str());
|
||||
mjs_setInt(pf->elem, element.data(), element.size());
|
||||
mjs_setFloat(pf->texcoord, texcoord.data(), texcoord.size());
|
||||
|
||||
@@ -201,6 +201,7 @@ mjCModel::mjCModel() {
|
||||
world->mass = 0;
|
||||
mjuu_zerovec(world->inertia, 3);
|
||||
world->id = 0;
|
||||
world->uid = GetUid();
|
||||
world->parent = nullptr;
|
||||
world->weldid = 0;
|
||||
world->name = "world";
|
||||
@@ -213,6 +214,9 @@ mjCModel::mjCModel() {
|
||||
|
||||
// the source spec is the model itself, overwritten in the copy constructor
|
||||
source_spec_ = &spec;
|
||||
|
||||
// set the signature
|
||||
spec.element->signature = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -289,6 +293,7 @@ void mjCModel::CopyList(std::vector<T*>& dest,
|
||||
// copy the element from the other model to this model
|
||||
if (deepcopy_) {
|
||||
source[i]->ForgetKeyframes();
|
||||
candidate->uid = GetUid();
|
||||
} else {
|
||||
candidate->AddRef();
|
||||
}
|
||||
@@ -499,6 +504,9 @@ mjCModel& mjCModel::operator+=(const mjCModel& other) {
|
||||
nq = nv = na = nu = nmocap = 0;
|
||||
}
|
||||
|
||||
// update signature before we reset the tree lists
|
||||
spec.element->signature = Signature();
|
||||
|
||||
PointToLocal();
|
||||
return *this;
|
||||
}
|
||||
@@ -633,6 +641,9 @@ mjCModel& mjCModel::operator-=(const mjCBody& subtree) {
|
||||
RemoveFromList(sensors_, oldmodel);
|
||||
RemovePlugins();
|
||||
|
||||
// update signature before we reset the tree lists
|
||||
spec.element->signature = Signature();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -803,6 +814,9 @@ void mjCModel::DeleteElement(mjsElement* el) {
|
||||
break;
|
||||
}
|
||||
|
||||
// update signature before we reset the tree lists
|
||||
spec.element->signature = Signature();
|
||||
|
||||
ResetTreeLists(); // in case of a nested delete
|
||||
MakeTreeLists();
|
||||
ProcessLists(/*checkrepeat=*/false);
|
||||
@@ -1019,7 +1033,9 @@ template <class T>
|
||||
T* mjCModel::AddObject(vector<T*>& list, string type) {
|
||||
T* obj = new T(this);
|
||||
obj->id = (int)list.size();
|
||||
obj->uid = GetUid();
|
||||
list.push_back(obj);
|
||||
spec.element->signature = Signature();
|
||||
return obj;
|
||||
}
|
||||
|
||||
@@ -1030,7 +1046,9 @@ T* mjCModel::AddObjectDefault(vector<T*>& list, string type, mjCDef* def) {
|
||||
T* obj = new T(this, def ? def : defaults_[0]);
|
||||
obj->id = (int)list.size();
|
||||
obj->classname = def ? def->name : "main";
|
||||
obj->uid = GetUid();
|
||||
list.push_back(obj);
|
||||
spec.element->signature = Signature();
|
||||
return obj;
|
||||
}
|
||||
|
||||
@@ -4572,6 +4590,28 @@ void mjCModel::TryCompile(mjModel*& m, mjData*& d, const mjVFS* vfs) {
|
||||
mju::strcpy_arr(errInfo.message, warningtext);
|
||||
errInfo.warning = true;
|
||||
}
|
||||
|
||||
// save signature
|
||||
m->signature = Signature();
|
||||
}
|
||||
|
||||
|
||||
|
||||
uint64_t mjCModel::Signature() {
|
||||
std::string uid_str;
|
||||
for (int i = 0; i < mjNOBJECT; ++i) {
|
||||
if (i == mjOBJ_XBODY || i == mjOBJ_UNKNOWN || i == mjOBJ_DOF) {
|
||||
continue;
|
||||
}
|
||||
if (object_lists_[i] == nullptr) {
|
||||
throw mjCError(0, "object list %s is null", std::to_string(i).c_str());
|
||||
}
|
||||
uid_str += '|';
|
||||
for (mjCBase* object : *object_lists_[i]) {
|
||||
uid_str += std::to_string(object->uid) + " ";
|
||||
}
|
||||
}
|
||||
return mj_hashString(uid_str.c_str(), UINT64_MAX);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#define MUJOCO_SRC_USER_USER_MODEL_H_
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <string>
|
||||
@@ -324,6 +325,9 @@ class mjCModel : public mjCModel_, private mjSpec {
|
||||
// set attached flag
|
||||
void SetAttached(bool deepcopy) { attached_ |= !deepcopy; }
|
||||
|
||||
// get new uid
|
||||
int GetUid() { return uid_count_++; }
|
||||
|
||||
private:
|
||||
// settings for each defaults class
|
||||
std::vector<mjCDef*> defaults_;
|
||||
@@ -440,11 +444,14 @@ class mjCModel : public mjCModel_, private mjSpec {
|
||||
void MarkPluginInstance(std::unordered_map<std::string, bool>& instances,
|
||||
const std::vector<T*>& list);
|
||||
|
||||
// generate a signature for the model
|
||||
uint64_t Signature();
|
||||
|
||||
mjListKeyMap ids; // map from object names to ids
|
||||
mjCError errInfo; // last error info
|
||||
std::vector<mjKeyInfo> key_pending_; // attached keyframes
|
||||
bool deepcopy_; // copy objects when attaching
|
||||
bool attached_ = false; // true if model is attached to a parent model
|
||||
int uid_count_ = 0; // unique id count for all objects
|
||||
};
|
||||
#endif // MUJOCO_SRC_USER_USER_MODEL_H_
|
||||
|
||||
@@ -837,6 +837,7 @@ mjCBody::mjCBody(mjCModel* _model) {
|
||||
|
||||
mjCBody::mjCBody(const mjCBody& other, mjCModel* _model) {
|
||||
model = _model;
|
||||
uid = model->GetUid();
|
||||
mjSpec* origin = model->FindSpec(other.compiler);
|
||||
compiler = origin ? &origin->compiler : &model->spec.compiler;
|
||||
*this = other;
|
||||
@@ -930,6 +931,7 @@ mjCBody& mjCBody::operator+=(const mjCFrame& other) {
|
||||
frames.back()->frame = other.frame;
|
||||
if (model->deepcopy_) {
|
||||
frames.back()->NameSpace(other_model);
|
||||
frames.back()->uid = model->GetUid();
|
||||
} else {
|
||||
frames.back()->AddRef();
|
||||
}
|
||||
@@ -1022,6 +1024,8 @@ void mjCBody::CopyList(std::vector<T*>& dst, const std::vector<T*>& src,
|
||||
// increment refcount if shallow copy is made
|
||||
if (!model->deepcopy_) {
|
||||
dst.back()->AddRef();
|
||||
} else {
|
||||
dst.back()->uid = model->GetUid();
|
||||
}
|
||||
|
||||
// set namespace
|
||||
@@ -1237,6 +1241,10 @@ mjCBody* mjCBody::AddBody(mjCDef* _def) {
|
||||
model->MakeTreeLists();
|
||||
|
||||
obj->parent = this;
|
||||
|
||||
// update signature
|
||||
obj->uid = model->GetUid();
|
||||
model->spec.element->signature = model->Signature();
|
||||
return obj;
|
||||
}
|
||||
|
||||
@@ -1248,6 +1256,10 @@ mjCFrame* mjCBody::AddFrame(mjCFrame* _frame) {
|
||||
frames.push_back(obj);
|
||||
model->ResetTreeLists();
|
||||
model->MakeTreeLists();
|
||||
|
||||
// update signature
|
||||
obj->uid = model->GetUid();
|
||||
model->spec.element->signature = model->Signature();
|
||||
return obj;
|
||||
}
|
||||
|
||||
@@ -1268,6 +1280,10 @@ mjCJoint* mjCBody::AddFreeJoint() {
|
||||
model->ResetTreeLists();
|
||||
model->MakeTreeLists();
|
||||
|
||||
|
||||
// update signature
|
||||
obj->uid = model->GetUid();
|
||||
model->spec.element->signature = model->Signature();
|
||||
return obj;
|
||||
}
|
||||
|
||||
@@ -1287,6 +1303,10 @@ mjCJoint* mjCBody::AddJoint(mjCDef* _def) {
|
||||
model->ResetTreeLists();
|
||||
model->MakeTreeLists();
|
||||
|
||||
|
||||
// update signature
|
||||
obj->uid = model->GetUid();
|
||||
model->spec.element->signature = model->Signature();
|
||||
return obj;
|
||||
}
|
||||
|
||||
@@ -1306,6 +1326,10 @@ mjCGeom* mjCBody::AddGeom(mjCDef* _def) {
|
||||
model->ResetTreeLists();
|
||||
model->MakeTreeLists();
|
||||
|
||||
|
||||
// update signature
|
||||
obj->uid = model->GetUid();
|
||||
model->spec.element->signature = model->Signature();
|
||||
return obj;
|
||||
}
|
||||
|
||||
@@ -1325,6 +1349,10 @@ mjCSite* mjCBody::AddSite(mjCDef* _def) {
|
||||
model->ResetTreeLists();
|
||||
model->MakeTreeLists();
|
||||
|
||||
|
||||
// update signature
|
||||
obj->uid = model->GetUid();
|
||||
model->spec.element->signature = model->Signature();
|
||||
return obj;
|
||||
}
|
||||
|
||||
@@ -1344,6 +1372,10 @@ mjCCamera* mjCBody::AddCamera(mjCDef* _def) {
|
||||
model->ResetTreeLists();
|
||||
model->MakeTreeLists();
|
||||
|
||||
|
||||
// update signature
|
||||
obj->uid = model->GetUid();
|
||||
model->spec.element->signature = model->Signature();
|
||||
return obj;
|
||||
}
|
||||
|
||||
@@ -1363,6 +1395,10 @@ mjCLight* mjCBody::AddLight(mjCDef* _def) {
|
||||
model->ResetTreeLists();
|
||||
model->MakeTreeLists();
|
||||
|
||||
|
||||
// update signature
|
||||
obj->uid = model->GetUid();
|
||||
model->spec.element->signature = model->Signature();
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
@@ -219,6 +219,7 @@ class mjCBoundingVolumeHierarchy : public mjCBoundingVolumeHierarchy_ {
|
||||
class mjCBase_ : public mjsElement {
|
||||
public:
|
||||
int id; // object id
|
||||
int uid; // unique identifier
|
||||
std::string name; // object name
|
||||
std::string classname; // defaults class name
|
||||
std::string info; // error message info set by the user
|
||||
|
||||
Reference in New Issue
Block a user