Add membrane plugin (2D Flex elastic stiffness).

PiperOrigin-RevId: 574109411
Change-Id: I4a701d8189cecf540cd200bd30cb4582f3c7dd43
This commit is contained in:
Alessio Quaglino
2023-10-17 04:54:37 -07:00
committed by Copybara-Service
parent 110ade1435
commit d67b8c6251
13 changed files with 586 additions and 115 deletions
+60
View File
@@ -22,6 +22,7 @@
#include <gtest/gtest.h>
#include <mujoco/mujoco.h>
#include "test/fixture.h"
#include "plugin/elasticity/membrane.h"
#include "plugin/elasticity/shell.h"
#include "plugin/elasticity/solid.h"
@@ -84,6 +85,65 @@ TEST_F(ElasticityTest, ElasticEnergyShell) {
mj_deleteModel(m);
}
// -------------------------------- membrane -----------------------------------
TEST_F(PluginTest, ElasticEnergyMembrane) {
static constexpr char cantilever_xml[] = R"(
<mujoco>
<extension>
<plugin plugin="mujoco.elasticity.membrane"/>
</extension>
<worldbody>
<flexcomp type="grid" count="8 8 1" spacing="1 1 1"
radius=".025" name="test" dim="2">
<plugin plugin="mujoco.elasticity.membrane">
<config key="poisson" value="0"/>
<config key="young" value="2"/>
<config key="thickness" value="1"/>
</plugin>
<edge equality="false"/>
</flexcomp>
</worldbody>
</mujoco>
)";
char error[1024] = {0};
mjModel* m = LoadModelFromString(cantilever_xml, error, sizeof(error));
ASSERT_THAT(m, testing::NotNull()) << error;
mjData* d = mj_makeData(m);
auto* membrane =
reinterpret_cast<plugin::elasticity::Membrane*>(d->plugin_data[0]);
mj_kinematics(m, d);
mj_flex(m, d);
// check that if the entire geometry is rescaled by a factor "scale", then
// trace(strain^2) = 2*scale^2
for (mjtNum scale = 1; scale < 4; scale++) {
for (int t = 0; t < membrane->nt; t++) {
mjtNum energy = 0;
mjtNum volume = 1./2.;
for (int e1 = 0; e1 < 3; e1++) {
for (int e2 = 0; e2 < 3; e2++) {
int idx1 = membrane->elements[t].edges[e1] + m->flex_edgeadr[0];
int idx2 = membrane->elements[t].edges[e2] + m->flex_edgeadr[0];
mjtNum elongation1 =
scale * m->flexedge_length0[idx1] * m->flexedge_length0[idx1];
mjtNum elongation2 =
scale * m->flexedge_length0[idx2] * m->flexedge_length0[idx2];
energy += membrane->metric[9*t+3*e2+e1] * elongation1 * elongation2;
}
}
EXPECT_NEAR(
4*energy/volume, 2*scale*scale, std::numeric_limits<float>::epsilon());
}
}
mj_deleteData(d);
mj_deleteModel(m);
}
// -------------------------------- solid -----------------------------------
TEST_F(ElasticityTest, ElasticEnergySolid) {
static constexpr char cantilever_xml[] = R"(