Update list ids immediately during body detach.

Fixes #2499.

PiperOrigin-RevId: 736449320
Change-Id: Ieeae52bdbbbb896d886221ab088229c8287a32a3
This commit is contained in:
Alessio Quaglino
2025-03-13 03:55:06 -07:00
committed by Copybara-Service
parent 8f4c5c4b16
commit 8e300eb628
2 changed files with 69 additions and 1 deletions
+4
View File
@@ -494,6 +494,10 @@ void mjCModel::RemoveFromList(std::vector<T*>& list, const mjCModel& other) {
removed++;
}
}
if (removed > 0 && !list.empty()) {
// if any elements were removed, update ids using processlist
processlist(ids, list, list[0]->elemtype, /*checkrepeat=*/false);
}
}
+65 -1
View File
@@ -1441,7 +1441,7 @@ TEST_F(XMLReaderTest, ParseReplicateRepeatedName) {
EXPECT_THAT(error.data(), HasSubstr("Element 'replicate'"));
}
TEST_F(XMLReaderTest, ParseReplicateTendon) {
TEST_F(XMLReaderTest, ParseReplicateExcludeTendon) {
static constexpr char xml[] = R"(
<mujoco>
<worldbody>
@@ -1505,6 +1505,70 @@ TEST_F(XMLReaderTest, ParseReplicateTendon) {
mj_deleteSpec(spec);
}
TEST_F(XMLReaderTest, ParseReplicateWithTendon) {
static constexpr char xml[] = R"(
<mujoco>
<worldbody>
<replicate count="2" offset=".025 0 0">
<replicate count="2" offset="0 .025 0">
<replicate count="2" offset="0 0 .025">
<body name="winch" pos="-.01 0 .35">
<joint name="winch" damping="1"/>
<geom type="cylinder" size=".015 .01"/>
<site name="anchor" pos=".1 0 .04"/>
</body>
<site name="pulley" pos=".1 0 .32"/>
<site name="hook_left" pos=".08 0 .3"/>
<site name="hook_right" pos=".12 0 .3"/>
<body name="sphere" pos=".1 0 .2">
<freejoint/>
<geom type="sphere" size=".03"/>
<site name="pin_left" pos="-.025 0 .025"/>
<site name="pin_right" pos=".025 0 .025"/>
</body>
<body pos=".06 -.04 .05">
<geom type="sphere" size=".012"/>
</body>
</replicate>
</replicate>
</replicate>
</worldbody>
<tendon>
<spatial range="0 .19" limited="true" name="tendon">
<site site="anchor"/>
<site site="pulley"/>
<pulley divisor="3"/>
<site site="pulley"/>
<site site="hook_left"/>
<site site="pin_left"/>
<pulley divisor="3"/>
<site site="pulley"/>
<site site="hook_right"/>
<site site="pin_right"/>
</spatial>
</tendon>
<actuator>
<position name="winch" joint="winch" ctrlrange="-.7 .5" ctrllimited="true" kp="10"/>
<position name="tendon" tendon="tendon" ctrlrange="0 1" kp="100" dampratio="1"/>
</actuator>
</mujoco>
)";
std::array<char, 1024> error;
mjSpec* spec = mj_parseXMLString(xml, 0, error.data(), error.size());
EXPECT_THAT(spec, NotNull()) << error.data();
mjModel* m = mj_compile(spec, 0);
EXPECT_THAT(m, NotNull()) << mjs_getError(spec);
EXPECT_THAT(m->nbody, 25);
EXPECT_THAT(m->ngeom, 24);
EXPECT_THAT(m->nsite, 48);
EXPECT_THAT(m->nu, 16);
EXPECT_THAT(m->ntendon, 8);
mj_deleteModel(m);
mj_deleteSpec(spec);
}
// ---------------------- test spec assets parsing -----------------------------
TEST_F(XMLReaderTest, ParseSpecAssets) {