Allow detaching from a compiled model.
PiperOrigin-RevId: 638299270 Change-Id: I944d2a24578b63463eddfa55d89f39fcfbafd2b4
This commit is contained in:
committed by
Copybara-Service
parent
195bd32aa6
commit
dec55b59fa
+37
-12
@@ -132,6 +132,7 @@ mjCModel::mjCModel() {
|
|||||||
|
|
||||||
|
|
||||||
mjCModel::mjCModel(const mjCModel& other) {
|
mjCModel::mjCModel(const mjCModel& other) {
|
||||||
|
CreateObjectLists();
|
||||||
*this = other;
|
*this = other;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,8 +207,19 @@ static void resetlist(std::vector<T*>& list) {
|
|||||||
|
|
||||||
mjCModel& mjCModel::operator+=(const mjCModel& other) {
|
mjCModel& mjCModel::operator+=(const mjCModel& other) {
|
||||||
// create global lists
|
// create global lists
|
||||||
MakeLists(bodies_[0]);
|
mjCBody *world = bodies_[0];
|
||||||
CreateObjectLists();
|
if (compiled) {
|
||||||
|
resetlist(bodies_);
|
||||||
|
resetlist(joints_);
|
||||||
|
resetlist(geoms_);
|
||||||
|
resetlist(sites_);
|
||||||
|
resetlist(cameras_);
|
||||||
|
resetlist(lights_);
|
||||||
|
resetlist(frames_);
|
||||||
|
world->id = 0;
|
||||||
|
bodies_.push_back(world);
|
||||||
|
}
|
||||||
|
MakeLists(world);
|
||||||
ProcessLists(/*checkrepeat=*/false);
|
ProcessLists(/*checkrepeat=*/false);
|
||||||
|
|
||||||
// copy all elements not in the tree
|
// copy all elements not in the tree
|
||||||
@@ -264,9 +276,8 @@ mjCModel& mjCModel::operator+=(const mjCModel& other) {
|
|||||||
lights_[i]->def= defaults_[def_map[other.lights_[i]->def]];
|
lights_[i]->def= defaults_[def_map[other.lights_[i]->def]];
|
||||||
}
|
}
|
||||||
|
|
||||||
// restore to the same state as other
|
// restore to the original state
|
||||||
if (!compiled) {
|
if (!compiled) {
|
||||||
mjCBody *world = bodies_[0];
|
|
||||||
resetlist(bodies_);
|
resetlist(bodies_);
|
||||||
resetlist(joints_);
|
resetlist(joints_);
|
||||||
resetlist(geoms_);
|
resetlist(geoms_);
|
||||||
@@ -317,16 +328,30 @@ void mjCModel::RemoveFromList(std::vector<T*>& list, const mjCModel& other) {
|
|||||||
|
|
||||||
mjCModel& mjCModel::operator-=(const mjCBody& subtree) {
|
mjCModel& mjCModel::operator-=(const mjCBody& subtree) {
|
||||||
mjCModel oldmodel(*this);
|
mjCModel oldmodel(*this);
|
||||||
oldmodel.MakeLists(oldmodel.bodies_[0]);
|
|
||||||
oldmodel.CreateObjectLists();
|
// create global lists in the old model if not compiled
|
||||||
oldmodel.ProcessLists(/*checkrepeat=*/false);
|
if (!oldmodel.IsCompiled()) {
|
||||||
|
oldmodel.MakeLists(oldmodel.bodies_[0]);
|
||||||
|
oldmodel.ProcessLists(/*checkrepeat=*/false);
|
||||||
|
}
|
||||||
|
|
||||||
// remove body from tree
|
// remove body from tree
|
||||||
*bodies_[0] -= subtree;
|
mjCBody* world = bodies_[0];
|
||||||
|
*world -= subtree;
|
||||||
|
|
||||||
// create global lists
|
// create global lists
|
||||||
MakeLists(bodies_[0]);
|
if (compiled) {
|
||||||
CreateObjectLists();
|
resetlist(bodies_);
|
||||||
|
resetlist(joints_);
|
||||||
|
resetlist(geoms_);
|
||||||
|
resetlist(sites_);
|
||||||
|
resetlist(cameras_);
|
||||||
|
resetlist(lights_);
|
||||||
|
resetlist(frames_);
|
||||||
|
world->id = 0;
|
||||||
|
bodies_.push_back(world);
|
||||||
|
}
|
||||||
|
MakeLists(world);
|
||||||
ProcessLists(/*checkrepeat=*/false);
|
ProcessLists(/*checkrepeat=*/false);
|
||||||
|
|
||||||
// check if we have to remove anything else
|
// check if we have to remove anything else
|
||||||
@@ -337,9 +362,8 @@ mjCModel& mjCModel::operator-=(const mjCBody& subtree) {
|
|||||||
RemoveFromList(actuators_, oldmodel);
|
RemoveFromList(actuators_, oldmodel);
|
||||||
RemoveFromList(sensors_, oldmodel);
|
RemoveFromList(sensors_, oldmodel);
|
||||||
|
|
||||||
// restore to the same state as before call
|
// restore to the original state
|
||||||
if (!compiled) {
|
if (!compiled) {
|
||||||
mjCBody* world = bodies_[0];
|
|
||||||
resetlist(bodies_);
|
resetlist(bodies_);
|
||||||
resetlist(joints_);
|
resetlist(joints_);
|
||||||
resetlist(geoms_);
|
resetlist(geoms_);
|
||||||
@@ -527,6 +551,7 @@ void mjCModel::Clear() {
|
|||||||
sites_.clear();
|
sites_.clear();
|
||||||
cameras_.clear();
|
cameras_.clear();
|
||||||
lights_.clear();
|
lights_.clear();
|
||||||
|
frames_.clear();
|
||||||
|
|
||||||
// internal variables
|
// internal variables
|
||||||
hasImplicitPluginElem = false;
|
hasImplicitPluginElem = false;
|
||||||
|
|||||||
@@ -650,7 +650,7 @@ TEST_F(MujocoTest, AttachFrame) {
|
|||||||
mj_deleteModel(m_expected);
|
mj_deleteModel(m_expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(MujocoTest, DetachBody) {
|
void TestDetachBody(bool compile) {
|
||||||
std::array<char, 1000> er;
|
std::array<char, 1000> er;
|
||||||
mjtNum tol = 0;
|
mjtNum tol = 0;
|
||||||
std::string field = "";
|
std::string field = "";
|
||||||
@@ -679,6 +679,9 @@ TEST_F(MujocoTest, DetachBody) {
|
|||||||
mjSpec* child = ParseSpecFromString(xml_child, er.data(), er.size());
|
mjSpec* child = ParseSpecFromString(xml_child, er.data(), er.size());
|
||||||
EXPECT_THAT(child, NotNull()) << er.data();
|
EXPECT_THAT(child, NotNull()) << er.data();
|
||||||
|
|
||||||
|
// compile model (for testing double compilation)
|
||||||
|
mjModel* m_child = compile ? mjs_compile(child, 0) : nullptr;
|
||||||
|
|
||||||
// get subtree
|
// get subtree
|
||||||
mjsBody* body = mjs_findBody(child, "body");
|
mjsBody* body = mjs_findBody(child, "body");
|
||||||
EXPECT_THAT(body, NotNull());
|
EXPECT_THAT(body, NotNull());
|
||||||
@@ -701,6 +704,12 @@ TEST_F(MujocoTest, DetachBody) {
|
|||||||
mjs_deleteSpec(child);
|
mjs_deleteSpec(child);
|
||||||
mj_deleteModel(m_detached);
|
mj_deleteModel(m_detached);
|
||||||
mj_deleteModel(m_expected);
|
mj_deleteModel(m_expected);
|
||||||
|
if (m_child) mj_deleteModel(m_child);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(MujocoTest, DetachBody) {
|
||||||
|
TestDetachBody(/*compile=*/false);
|
||||||
|
TestDetachBody(/*compile=*/true);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
Reference in New Issue
Block a user