Reset pending keyframes in source model after attaching.
Fixes #2101. PiperOrigin-RevId: 680526395 Change-Id: I3bd06db5231d653b1c5bc1c2ba6b03b52e65f288
This commit is contained in:
committed by
Copybara-Service
parent
58a49bad96
commit
40b2ae92e5
@@ -899,6 +899,11 @@ mjCBody& mjCBody::operator+=(const mjCFrame& other) {
|
||||
// attach referencing elements
|
||||
*model += *other.model;
|
||||
|
||||
// leave the source model in a clean state
|
||||
if (other.model != model) {
|
||||
other.model->key_pending_.clear();
|
||||
}
|
||||
|
||||
// clear namespace and return body
|
||||
other.model->prefix.clear();
|
||||
other.model->suffix.clear();
|
||||
@@ -1785,6 +1790,11 @@ mjCFrame& mjCFrame::operator+=(const mjCBody& other) {
|
||||
// attach referencing elements
|
||||
*model += *other.model;
|
||||
|
||||
// leave the source model in a clean state
|
||||
if (other.model != model) {
|
||||
other.model->key_pending_.clear();
|
||||
}
|
||||
|
||||
// clear suffixes and return
|
||||
other.model->suffix.clear();
|
||||
other.model->prefix.clear();
|
||||
|
||||
@@ -1386,5 +1386,56 @@ TEST_F(MujocoTest, AttachNestedKeyframe) {
|
||||
mj_deleteModel(m_child);
|
||||
}
|
||||
|
||||
TEST_F(MujocoTest, RepeatedAttachKeyframe) {
|
||||
static constexpr char xml_1[] = R"(
|
||||
<mujoco model="MuJoCo Model">
|
||||
<worldbody>
|
||||
<body name="body"/>
|
||||
</worldbody>
|
||||
</mujoco>)";
|
||||
|
||||
static constexpr char xml_2[] = R"(
|
||||
<mujoco model="MuJoCo Model">
|
||||
<worldbody>
|
||||
<body name="b1">
|
||||
<joint/>
|
||||
<geom size="0.1"/>
|
||||
</body>
|
||||
<body name="b2">
|
||||
<joint/>
|
||||
<geom size="0.1"/>
|
||||
</body>
|
||||
</worldbody>
|
||||
<keyframe>
|
||||
<key name="home" qpos="1 2" />
|
||||
</keyframe>
|
||||
</mujoco>)";
|
||||
|
||||
std::array<char, 1000> er;
|
||||
mjSpec* spec_1 = mj_parseXMLString(xml_1, 0, er.data(), er.size());
|
||||
EXPECT_THAT(spec_1, NotNull()) << er.data();
|
||||
mjSpec* spec_2 = mj_parseXMLString(xml_2, 0, er.data(), er.size());
|
||||
EXPECT_THAT(spec_2, NotNull()) << er.data();
|
||||
|
||||
mjsBody* body_1 = mjs_findBody(spec_1, "body");
|
||||
mjsFrame* attachment_frame = mjs_addFrame(body_1, 0);
|
||||
mjs_attachBody(attachment_frame, mjs_findBody(spec_2, "b1"), "b1-", "");
|
||||
mjModel* model_1 = mj_compile(spec_1, 0);
|
||||
EXPECT_THAT(model_1, NotNull());
|
||||
mjs_attachBody(attachment_frame, mjs_findBody(spec_2, "b2"), "b2-", "");
|
||||
mjModel* model_2 = mj_compile(spec_1, 0);
|
||||
EXPECT_THAT(model_2, NotNull());
|
||||
|
||||
EXPECT_EQ(model_1->nkey, 1);
|
||||
EXPECT_EQ(model_2->nkey, 2);
|
||||
EXPECT_STREQ(mj_id2name(model_2, mjOBJ_KEY, 0), "b1-home");
|
||||
EXPECT_STREQ(mj_id2name(model_2, mjOBJ_KEY, 1), "b2-home");
|
||||
|
||||
mj_deleteSpec(spec_1);
|
||||
mj_deleteSpec(spec_2);
|
||||
mj_deleteModel(model_1);
|
||||
mj_deleteModel(model_2);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace mujoco
|
||||
|
||||
Reference in New Issue
Block a user