diff --git a/src/user/user_api.cc b/src/user/user_api.cc index 6962493f..e21181dd 100644 --- a/src/user/user_api.cc +++ b/src/user/user_api.cc @@ -73,7 +73,7 @@ mjSpec* mj_copySpec(const mjSpec* s) { try { modelC = new mjCModel(*static_cast(s->element)); } catch (mjCError& e) { - modelC->SetError(e); + static_cast(s->element)->SetError(e); return nullptr; } return &modelC->spec; diff --git a/src/user/user_objects.cc b/src/user/user_objects.cc index b3208662..827b5e48 100644 --- a/src/user/user_objects.cc +++ b/src/user/user_objects.cc @@ -916,7 +916,7 @@ mjCBody& mjCBody::operator+=(const mjCBody& other) { // attach frame to body mjCBody& mjCBody::operator+=(const mjCFrame& other) { // append a copy of the attached spec - if (other.model != model && !model->FindSpec(mjs_getString(other.model->spec.modelname))) { + if (other.model != model && !model->FindSpec(&other.model->spec.compiler)) { model->AppendSpec(mj_copySpec(&other.model->spec), &other.model->spec.compiler); } @@ -2029,7 +2029,7 @@ mjCFrame& mjCFrame::operator=(const mjCFrame& other) { // attach body to frame mjCFrame& mjCFrame::operator+=(const mjCBody& other) { // append a copy of the attached spec - if (other.model != model && !model->FindSpec(mjs_getString(other.model->spec.modelname))) { + if (other.model != model && !model->FindSpec(&other.model->spec.compiler)) { model->AppendSpec(mj_copySpec(&other.model->spec), &other.model->spec.compiler); } diff --git a/test/user/user_api_test.cc b/test/user/user_api_test.cc index 993be5cd..4db9f25b 100644 --- a/test/user/user_api_test.cc +++ b/test/user/user_api_test.cc @@ -2552,31 +2552,46 @@ TEST_F(MujocoTest, DifferentOptionsInAttachedFrame) { // load specs and compile child mjSpec* parent = mj_parseXMLString(xml_parent, 0, nullptr, 0); EXPECT_THAT(parent, NotNull()); - mjSpec* child = mj_parseXMLString(xml_child, 0, nullptr, 0); - EXPECT_THAT(child, NotNull()); - mjModel* m_child = mj_compile(child, 0); - EXPECT_THAT(m_child, NotNull()); + mjSpec* child1 = mj_parseXMLString(xml_child, 0, nullptr, 0); + EXPECT_THAT(child1, NotNull()); + mjModel* m_child1 = mj_compile(child1, 0); + EXPECT_THAT(m_child1, NotNull()); + mjSpec* child2 = mj_parseXMLString(xml_child, 0, nullptr, 0); + EXPECT_THAT(child2, NotNull()); + mjModel* m_child2 = mj_compile(child1, 0); + EXPECT_THAT(m_child2, NotNull()); // attach child frame to parent worldbody mjsBody* world = mjs_findBody(parent, "world"); EXPECT_THAT(world, NotNull()); - mjsFrame* child_frame = mjs_findFrame(child, "child"); - EXPECT_THAT(child_frame, NotNull()); - mjsElement* attached_frame = - mjs_attach(world->element, child_frame->element, "child-", ""); - EXPECT_THAT(attached_frame, NotNull()); + mjsFrame* child1_frame = mjs_findFrame(child1, "child"); + EXPECT_THAT(child1_frame, NotNull()); + mjsFrame* child2_frame = mjs_findFrame(child2, "child"); + EXPECT_THAT(child2_frame, NotNull()); + mjsElement* attached_frame1 = + mjs_attach(world->element, child1_frame->element, "child-", "-1"); + EXPECT_THAT(attached_frame1, NotNull()); + mjsElement* attached_frame2 = + mjs_attach(world->element, child2_frame->element, "child-", "-2"); + EXPECT_THAT(attached_frame2, NotNull()); // wrap the child frame in the parent frame and compile mjModel* m_attached = mj_compile(parent, 0); EXPECT_THAT(m_attached, NotNull()); - EXPECT_NEAR(m_attached->site_quat[0], m_child->site_quat[0], 1e-6); - EXPECT_NEAR(m_attached->site_quat[1], m_child->site_quat[1], 1e-6); - EXPECT_NEAR(m_attached->site_quat[2], m_child->site_quat[2], 1e-6); - EXPECT_NEAR(m_attached->site_quat[3], m_child->site_quat[3], 1e-6); + EXPECT_NEAR(m_attached->site_quat[0], m_child1->site_quat[0], 1e-6); + EXPECT_NEAR(m_attached->site_quat[1], m_child1->site_quat[1], 1e-6); + EXPECT_NEAR(m_attached->site_quat[2], m_child1->site_quat[2], 1e-6); + EXPECT_NEAR(m_attached->site_quat[3], m_child1->site_quat[3], 1e-6); + EXPECT_NEAR(m_attached->site_quat[4], m_child2->site_quat[0], 1e-6); + EXPECT_NEAR(m_attached->site_quat[5], m_child2->site_quat[1], 1e-6); + EXPECT_NEAR(m_attached->site_quat[6], m_child2->site_quat[2], 1e-6); + EXPECT_NEAR(m_attached->site_quat[7], m_child2->site_quat[3], 1e-6); mj_deleteSpec(parent); - mj_deleteSpec(child); - mj_deleteModel(m_child); + mj_deleteSpec(child1); + mj_deleteModel(m_child1); + mj_deleteSpec(child2); + mj_deleteModel(m_child2); mj_deleteModel(m_attached); }