Support pinned flex vertices with bending

The flexcomp compiler previously rejected pins on dim-2 flexes with
bending (elastic2d bend/both). Allow them: mj_flexPassiveBend treats a
pinned vertex (body without 3 free slide dofs) as static -- zero
velocity, and no bending force applied to it (the reaction is carried
by the pin) -- while its position still enters every neighbor's
bending force, which is exactly what the pin constrains.

PiperOrigin-RevId: 944410969
Change-Id: Ib0a69c8d5fb6f64d3e2a76af3b6b2c7be1898191
This commit is contained in:
Alessio Quaglino
2026-07-08 04:01:51 -07:00
committed by Copybara-Service
parent c4c2cad503
commit fb6d1cf18f
4 changed files with 107 additions and 11 deletions
+41
View File
@@ -965,5 +965,46 @@ TEST_F(ElasticityTest, InterpBendingRigidRotationInvariance) {
}
}
// verify that a pinned vertex (on a static body) gets zero bending force
// while its free neighbors get nonzero bending force
TEST_F(ElasticityTest, PinnedVertexBendingForce) {
static constexpr char xml[] = R"(
<mujoco>
<worldbody>
<body name="parent">
<flexcomp name="test" type="grid" count="3 3 1" spacing="1 1 1"
radius="0.01" dim="2">
<elasticity young="1" poisson="0" thickness="1" elastic2d="bend"/>
<pin id="0"/>
</flexcomp>
</body>
</worldbody>
</mujoco>
)";
char error[1024] = {0};
MjModelPtr m = LoadModelFromString(xml, error, sizeof(error));
ASSERT_THAT(m.get(), testing::NotNull()) << error;
MjDataPtr d = MakeData(m);
// displace a free vertex out of plane to create bending
d->qpos[3] = 0.1;
mj_forward(m.get(), d.get());
// vertex 0 is pinned to the world body (body 0), which has 0 dofs,
// so no bending force is written for it — the reaction is absorbed by the pin
// verify that at least some free vertices have nonzero spring force
bool has_nonzero = false;
for (int i = 0; i < m->nv; i++) {
if (d->qfrc_spring[i] != 0) {
has_nonzero = true;
break;
}
}
EXPECT_TRUE(has_nonzero) << "bending should produce nonzero spring forces";
}
} // namespace
} // namespace mujoco