diff --git a/doc/changelog.rst b/doc/changelog.rst index 52592511..0b89de4b 100644 --- a/doc/changelog.rst +++ b/doc/changelog.rst @@ -7,9 +7,12 @@ Upcoming version (not yet released) MJX ^^^ +1. Added :ref:`dyntype` ``filterexact``. +2. Added :at:`site` transmission. -1. Add :ref:`dyntype` ``filterexact``. -2. Add :at:`site` transmission. +Bug fixes +^^^^^^^^^ +3. Fixed a bug that prevented the use of pins with plugins if flexes are not in the worldbody. Fixes :github:issue:`1270`. Version 3.1.1 (December 18, 2023) diff --git a/plugin/elasticity/elasticity.h b/plugin/elasticity/elasticity.h index 8436777e..00074a6e 100644 --- a/plugin/elasticity/elasticity.h +++ b/plugin/elasticity/elasticity.h @@ -133,6 +133,9 @@ inline void ComputeForce(mjtNum* qfrc_passive, if (vertbodyid) { body_dofnum = m->body_dofnum[vertbodyid[v[i]]]; body_dofadr = m->body_dofadr[vertbodyid[v[i]]]; + if (body_dofnum && m->body_simple[vertbodyid[v[i]]] != 2) { + mju_error("Non-simple or non-static bodies are not yet supported"); + } } for (int x = 0; x < body_dofnum; x++) { qfrc_passive[body_dofadr+x] -= force[3*i+x]; diff --git a/src/user/user_flexcomp.cc b/src/user/user_flexcomp.cc index 033a215b..b6f24b96 100644 --- a/src/user/user_flexcomp.cc +++ b/src/user/user_flexcomp.cc @@ -399,6 +399,14 @@ bool mjCFlexcomp::Make(mjCModel* model, mjCBody* body, char* error, int error_sz // pinned: parent body if (pinned[i]) { pf->vertbody.push_back(body->name); + + // add plugin + if (plugin_instance) { + body->is_plugin = true; + body->plugin_name = plugin_name; + body->plugin_instance = plugin_instance; + body->plugin_instance_name = plugin_instance_name; + } } // not pinned: new body diff --git a/test/plugin/elasticity/elasticity_test.cc b/test/plugin/elasticity/elasticity_test.cc index ae240eba..199f3d0b 100644 --- a/test/plugin/elasticity/elasticity_test.cc +++ b/test/plugin/elasticity/elasticity_test.cc @@ -31,6 +31,38 @@ namespace { using ElasticityTest = PluginTest; +// -------------------------------- flex ------------------------------------ +TEST_F(ElasticityTest, FlexCompatibility) { + static constexpr char flex_xml[] = R"( + + + + + + + + + + + + + + + + + + )"; + + char error[1024] = {0}; + mjModel* m = LoadModelFromString(flex_xml, error, sizeof(error)); + ASSERT_THAT(m, testing::NotNull()) << error; + + mjData* d = mj_makeData(m); + mj_deleteData(d); + mj_deleteModel(m); +} + // -------------------------------- shell ----------------------------------- TEST_F(ElasticityTest, ElasticEnergyShell) { static constexpr char cantilever_xml[] = R"( @@ -144,6 +176,29 @@ TEST_F(PluginTest, ElasticEnergyMembrane) { mj_deleteModel(m); } +TEST_F(ElasticityTest, InvalidThickness) { + static constexpr char xml[] = R"( + + + + + + + + + + + + + + + )"; + + char error[1024] = {0}; + mjModel* m = LoadModelFromString(xml, error, sizeof(error)); + ASSERT_THAT(m, testing::IsNull()); +} + // -------------------------------- solid ----------------------------------- TEST_F(ElasticityTest, ElasticEnergySolid) { static constexpr char cantilever_xml[] = R"( @@ -202,7 +257,6 @@ TEST_F(ElasticityTest, ElasticEnergySolid) { } // -------------------------------- cable ----------------------------------- - TEST_F(ElasticityTest, CantileverIntoCircle) { static constexpr char cantilever_xml[] = R"( @@ -303,29 +357,6 @@ TEST_F(ElasticityTest, InvalidMixedAttribute) { ASSERT_THAT(m, testing::IsNull()); } -TEST_F(ElasticityTest, InvalidThickness) { - static constexpr char xml[] = R"( - - - - - - - - - - - - - - - )"; - - char error[1024] = {0}; - mjModel* m = LoadModelFromString(xml, error, sizeof(error)); - ASSERT_THAT(m, testing::IsNull()); -} - TEST_F(ElasticityTest, ValidAttributes) { static constexpr char cantilever_xml[] = R"(