diff --git a/src/user/user_model.cc b/src/user/user_model.cc index 7e95353a..2af21381 100644 --- a/src/user/user_model.cc +++ b/src/user/user_model.cc @@ -3538,6 +3538,12 @@ void mjCModel::CopyObjects(mjModel* m) { } } + if (!pfl->rigid && m->flex_edgeequality[i] == 0 && + !pfl->edgestiffness && !pfl->edgedamping && !pfl->damping) { + mju_warning("flex '%s' is not rigid and has no equality constraints " + "or passive forces", pfl->name.c_str()); + } + // copy bvh data (flex aabb computed dynamically in mjData) if (pfl->tree.Nbvh()) { memcpy(m->bvh_child + 2*bvh_adr, pfl->tree.Child().data(), 2*pfl->tree.Nbvh()*sizeof(int)); diff --git a/test/user/user_flex_test.cc b/test/user/user_flex_test.cc index 457ea0af..017bb320 100644 --- a/test/user/user_flex_test.cc +++ b/test/user/user_flex_test.cc @@ -991,5 +991,22 @@ TEST_F(UserFlexTest, FlexAttachConstraintPreserved) { mj_deleteVFS(vfs.get()); } +TEST_F(UserFlexTest, FlexNoConstraintsWarning) { + static constexpr char xml[] = R"( + + + + + + )"; + std::array error; + mjModel* m = LoadModelFromString(xml, error.data(), error.size()); + ASSERT_THAT(m, NotNull()) << error.data(); + EXPECT_THAT(error.data(), + HasSubstr("no equality constraints or passive forces")); + mj_deleteModel(m); +} + } // namespace } // namespace mujoco