Change mjSpec and mjModel signature mechanism.
The signature now contains the necessary information to safely perform `bind`. The private UIDs are now removed. Fixes an issue of changing signature when compiling a copy of an mjSpec. PiperOrigin-RevId: 744670626 Change-Id: Id3c66419cf2afbe78e91bc4b37d2299f5ec00ab1
This commit is contained in:
committed by
Copybara-Service
parent
93251f07d9
commit
cc2f57d820
+76
-20
@@ -201,7 +201,6 @@ 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";
|
||||
@@ -297,7 +296,6 @@ void mjCModel::CopyList(std::vector<T*>& dest,
|
||||
// copy the element from the other model to this model
|
||||
if (deepcopy_) {
|
||||
source[i]->ForgetKeyframes();
|
||||
candidate->uid = source[i]->uid;
|
||||
} else {
|
||||
candidate->AddRef();
|
||||
}
|
||||
@@ -1038,7 +1036,6 @@ 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;
|
||||
@@ -1051,7 +1048,6 @@ 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;
|
||||
@@ -3615,7 +3611,7 @@ void mjCModel::SaveState(const std::string& state_name, const T* qpos, const T*
|
||||
}
|
||||
|
||||
for (auto body : bodies_) {
|
||||
if (!body->spec.mocap) {
|
||||
if (!body->spec.mocap || body->mocapid == -1) {
|
||||
continue;
|
||||
}
|
||||
if (mpos) {
|
||||
@@ -4388,6 +4384,9 @@ void mjCModel::TryCompile(mjModel*& m, mjData*& d, const mjVFS* vfs) {
|
||||
bodies_[i]->subtreedofs = 0;
|
||||
}
|
||||
|
||||
// initialize spec signature (needed if the user changed sensor or joint types)
|
||||
spec.element->signature = Signature();
|
||||
|
||||
// fill missing names and check that they are all filled
|
||||
for (const auto& asset : meshes_) asset->CopyFromSpec();
|
||||
for (const auto& asset : skins_) asset->CopyFromSpec();
|
||||
@@ -4651,7 +4650,7 @@ void mjCModel::TryCompile(mjModel*& m, mjData*& d, const mjVFS* vfs) {
|
||||
|
||||
// special cases that are not caused by user edits
|
||||
if (compiler.fusestatic || compiler.discardvisual ||
|
||||
!spec.element->signature || !pairs_.empty() || !excludes_.empty()) {
|
||||
!pairs_.empty() || !excludes_.empty()) {
|
||||
spec.element->signature = m->signature;
|
||||
}
|
||||
|
||||
@@ -4663,21 +4662,78 @@ void mjCModel::TryCompile(mjModel*& m, mjData*& d, const mjVFS* vfs) {
|
||||
|
||||
|
||||
|
||||
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) + " ";
|
||||
}
|
||||
std::string mjCModel::PrintTree(const mjCBody* body, std::string indent) {
|
||||
std::string tree;
|
||||
tree += indent + "<body>\n";
|
||||
indent += " ";
|
||||
for (const auto& joint : body->joints) {
|
||||
tree += indent + "<joint>" + std::to_string(joint->nq()) + "</joint>\n";
|
||||
}
|
||||
return mj_hashString(uid_str.c_str(), UINT64_MAX);
|
||||
for (uint64_t i = 0; i < body->geoms.size(); ++i) {
|
||||
tree += indent + "<geom/>\n";
|
||||
}
|
||||
for (uint64_t i = 0; i < body->sites.size(); ++i) {
|
||||
tree += indent + "<site/>\n";
|
||||
}
|
||||
for (uint64_t i = 0; i < body->cameras.size(); ++i) {
|
||||
tree += indent + "<camera/>\n";
|
||||
}
|
||||
for (uint64_t i = 0; i < body->lights.size(); ++i) {
|
||||
tree += indent + "<light/>\n";
|
||||
}
|
||||
for (uint64_t i = 0; i < body->bodies.size(); ++i) {
|
||||
tree += PrintTree(body->bodies[i], indent);
|
||||
}
|
||||
indent.pop_back();
|
||||
indent.pop_back();
|
||||
tree += indent + "</body>\n";
|
||||
return tree;
|
||||
}
|
||||
|
||||
|
||||
|
||||
uint64_t mjCModel::Signature() {
|
||||
std::string tree = "\n" + PrintTree(bodies_[0]);
|
||||
for (unsigned int i = 0; i < flexes_.size(); ++i) {
|
||||
tree += "<flex/>\n";
|
||||
}
|
||||
for (unsigned int i = 0; i < meshes_.size(); ++i) {
|
||||
tree += "<mesh/>\n";
|
||||
}
|
||||
for (unsigned int i = 0; i < skins_.size(); ++i) {
|
||||
tree += "<skin/>\n";
|
||||
}
|
||||
for (unsigned int i = 0; i < hfields_.size(); ++i) {
|
||||
tree += "<heightfield/>\n";
|
||||
}
|
||||
for (unsigned int i = 0; i < textures_.size(); ++i) {
|
||||
tree += "<texture/>\n";
|
||||
}
|
||||
for (unsigned int i = 0; i < materials_.size(); ++i) {
|
||||
tree += "<material/>\n";
|
||||
}
|
||||
for (unsigned int i = 0; i < pairs_.size(); ++i) {
|
||||
tree += "<pair/>\n";
|
||||
}
|
||||
for (unsigned int i = 0; i < excludes_.size(); ++i) {
|
||||
tree += "<exclude/>\n";
|
||||
}
|
||||
for (unsigned int i = 1; i < equalities_.size(); ++i) {
|
||||
tree += "<equality/>\n";
|
||||
}
|
||||
for (unsigned int i = 0; i < tendons_.size(); ++i) {
|
||||
tree += "<tendon/>\n";
|
||||
}
|
||||
for (unsigned int i = 0; i < actuators_.size(); ++i) {
|
||||
tree += "<actuator/>\n";
|
||||
}
|
||||
for (unsigned int i = 0; i < sensors_.size(); ++i) {
|
||||
tree += "<sensor>" + std::to_string(sensors_[i]->spec.type) + "<sensor/>\n";
|
||||
}
|
||||
for (unsigned int i = 0; i < keys_.size(); ++i) {
|
||||
tree += "<key/>\n";
|
||||
}
|
||||
return mj_hashString(tree.c_str(), UINT64_MAX);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user