Replace flex_xvert0 with flex_vert0

`flex_xvert0` stored the Cartesian position of the vertices in `qpos0`. This array was unused, so it is now replaced with `flex_vert0`, which still contains the positions of the vertices, but normalized on the bounding box of the flex so that the coordinates are in `[0,1]^m->flex_dim`. This will be useful in the future for using different interpolation methods for computing flex deformations.

PiperOrigin-RevId: 691779361
Change-Id: I5c4223103cd4558f4e268fe3e8d8177541e4754f
This commit is contained in:
Alessio Quaglino
2024-10-31 06:29:39 -07:00
committed by Copybara-Service
parent 26ccaeb78e
commit 94bbf297fc
7 changed files with 77 additions and 19 deletions
+1 -1
View File
@@ -1170,7 +1170,7 @@ struct mjModel_ {
int* flex_shell; // shell fragment vertex ids (dim per frag) (nflexshelldata x 1)
int* flex_evpair; // (element, vertex) collision pairs (nflexevpair x 2)
mjtNum* flex_vert; // vertex positions in local body frames (nflexvert x 3)
mjtNum* flex_xvert0; // Cartesian vertex positions in qpos0 (nflexvert x 3)
mjtNum* flex_vert0; // vertex positions in qpos0 on [0, 1]^d (nflexvert x 3)
mjtNum* flexedge_length0; // edge lengths in qpos0 (nflexedge x 1)
mjtNum* flexedge_invweight0; // edge inv. weight in qpos0 (nflexedge x 1)
mjtNum* flex_radius; // radius around primitive element (nflex x 1)
+1 -1
View File
@@ -877,7 +877,7 @@ struct mjModel_ {
int* flex_shell; // shell fragment vertex ids (dim per frag) (nflexshelldata x 1)
int* flex_evpair; // (element, vertex) collision pairs (nflexevpair x 2)
mjtNum* flex_vert; // vertex positions in local body frames (nflexvert x 3)
mjtNum* flex_xvert0; // Cartesian vertex positions in qpos0 (nflexvert x 3)
mjtNum* flex_vert0; // vertex positions in qpos0 on [0, 1]^d (nflexvert x 3)
mjtNum* flexedge_length0; // edge lengths in qpos0 (nflexedge x 1)
mjtNum* flexedge_invweight0; // edge inv. weight in qpos0 (nflexedge x 1)
mjtNum* flex_radius; // radius around primitive element (nflex x 1)
+1 -1
View File
@@ -346,7 +346,7 @@
XMJV( int, flex_shell, nflexshelldata,1 ) \
X ( int, flex_evpair, nflexevpair, 2 ) \
X ( mjtNum, flex_vert, nflexvert, 3 ) \
X ( mjtNum, flex_xvert0, nflexvert, 3 ) \
X ( mjtNum, flex_vert0, nflexvert, 3 ) \
X ( mjtNum, flexedge_length0, nflexedge, 1 ) \
X ( mjtNum, flexedge_invweight0, nflexedge, 1 ) \
XMJV( mjtNum, flex_radius, nflex, 1 ) \
+2 -2
View File
@@ -2603,11 +2603,11 @@ STRUCTS: Mapping[str, StructDecl] = dict([
array_extent=('nflexvert', 3),
),
StructFieldDecl(
name='flex_xvert0',
name='flex_vert0',
type=PointerType(
inner_type=ValueType(name='mjtNum'),
),
doc='Cartesian vertex positions in qpos0',
doc='vertex positions in qpos0 on [0, 1]^d',
array_extent=('nflexvert', 3),
),
StructFieldDecl(
+12 -1
View File
@@ -118,8 +118,19 @@ static void set0(mjModel* m, mjData* d) {
m->light_mode[i] = lightmode[i];
}
// compute bounding box coordinates
for (int i=0; i < m->nflex; i++) {
int bvhadr = m->flex_bvhadr[i];
const mjtNum* bvh = d->bvh_aabb_dyn + 6*(bvhadr - m->nbvhstatic);
for (int j=0; j < m->nflexvert; j++) {
for (int k=0; k < 3; k++) {
mjtNum size = 2*(bvh[3+k] - m->flex_radius[i]);
m->flex_vert0[3*j+k] = (d->flexvert_xpos[3*j+k] - bvh[k]) / size + 0.5;
}
}
}
// copy fields
mju_copy(m->flex_xvert0, d->flexvert_xpos, 3*m->nflexvert);
mju_copy(m->flexedge_length0, d->flexedge_length, m->nflexedge);
mju_copy(m->tendon_length0, d->ten_length, m->ntendon);
mju_copy(m->actuator_length0, d->actuator_length, m->nu);
+59 -12
View File
@@ -242,6 +242,45 @@ TEST_F(UserFlexTest, RigidFlex) {
mj_deleteModel(m);
mj_deleteData(d);
}
TEST_F(UserFlexTest, BoundingBoxCoordinates) {
static constexpr char xml[] = R"(
<mujoco>
<worldbody>
<flexcomp name="test" pos="1 0 -1" type="grid"
count="5 5 5" spacing="1 1 1" dim="3"/>
</worldbody>
</mujoco>
)";
std::array<char, 1024> error;
mjModel* m = LoadModelFromString(xml, error.data(), error.size());
ASSERT_THAT(m, NotNull()) << error.data();
mjData* d = mj_makeData(m);
mj_kinematics(m, d);
mj_flex(m, d);
EXPECT_EQ(m->nflexvert, 5*5*5);
EXPECT_EQ(m->nflexelem, 4*4*4*6);
EXPECT_EQ(m->flex_dim[0], 3);
// Cartesian coordinates
EXPECT_EQ(d->flexvert_xpos[0], -1);
EXPECT_EQ(d->flexvert_xpos[1], -2);
EXPECT_EQ(d->flexvert_xpos[2], -3);
EXPECT_EQ(d->flexvert_xpos[3*m->nflexvert-3], 3);
EXPECT_EQ(d->flexvert_xpos[3*m->nflexvert-2], 2);
EXPECT_EQ(d->flexvert_xpos[3*m->nflexvert-1], 1);
// bounding box coordinates
EXPECT_EQ(m->flex_vert0[0], 0);
EXPECT_EQ(m->flex_vert0[1], 0);
EXPECT_EQ(m->flex_vert0[2], 0);
EXPECT_EQ(m->flex_vert0[3*m->nflexvert-3], 1);
EXPECT_EQ(m->flex_vert0[3*m->nflexvert-2], 1);
EXPECT_EQ(m->flex_vert0[3*m->nflexvert-1], 1);
mj_deleteModel(m);
mj_deleteData(d);
}
TEST_F(UserFlexTest, LoadMSHBinary_41_Success) {
const std::string xml_path =
@@ -280,14 +319,16 @@ TEST_F(UserFlexTest, LoadMSHSurfaceBinary_41_Success) {
mjModel* m = mj_loadXML(xml_path.c_str(), 0, error.data(), error.size());
ASSERT_THAT(m, NotNull()) << error.data();
mjData* d = mj_makeData(m);
mj_kinematics(m, d);
mj_flex(m, d);
EXPECT_EQ(m->nflexvert, 14);
EXPECT_EQ(m->nflexelem, 24);
EXPECT_EQ(m->flex_dim[0], 2);
// first node x y z
EXPECT_EQ(m->flex_xvert0[0], -0.5 );
EXPECT_EQ(m->flex_xvert0[1], -0.5 );
EXPECT_EQ(m->flex_xvert0[2], 0 );
EXPECT_EQ(d->flexvert_xpos[0], -0.5 );
EXPECT_EQ(d->flexvert_xpos[1], -0.5 );
EXPECT_EQ(d->flexvert_xpos[2], 0 );
// first element
EXPECT_EQ(m->flex_elem[0], 9-1 );
@@ -306,14 +347,16 @@ TEST_F(UserFlexTest, LoadMSHSurfaceBinary_22_Success) {
mjModel* m = mj_loadXML(xml_path.c_str(), 0, error.data(), error.size());
ASSERT_THAT(m, NotNull()) << error.data();
mjData* d = mj_makeData(m);
mj_kinematics(m, d);
mj_flex(m, d);
EXPECT_EQ(m->nflexvert, 14);
EXPECT_EQ(m->nflexelem, 24);
EXPECT_EQ(m->flex_dim[0], 2);
// first node x y z
EXPECT_EQ(m->flex_xvert0[0], -0.5 );
EXPECT_EQ(m->flex_xvert0[1], -0.5 );
EXPECT_EQ(m->flex_xvert0[2], 0 );
EXPECT_EQ(d->flexvert_xpos[0], -0.5 );
EXPECT_EQ(d->flexvert_xpos[1], -0.5 );
EXPECT_EQ(d->flexvert_xpos[2], 0 );
// first element
EXPECT_EQ(m->flex_elem[0], 9-1 );
@@ -377,14 +420,16 @@ TEST_F(UserFlexTest, LoadMSHSurfaceASCII_41_Success) {
mjModel* m = mj_loadXML(xml_path.c_str(), 0, error.data(), error.size());
ASSERT_THAT(m, NotNull()) << error.data();
mjData* d = mj_makeData(m);
mj_kinematics(m, d);
mj_flex(m, d);
EXPECT_EQ(m->nflexvert, 14);
EXPECT_EQ(m->nflexelem, 24);
EXPECT_EQ(m->flex_dim[0], 2);
// first node x y z
EXPECT_EQ(m->flex_xvert0[0], -0.5 );
EXPECT_EQ(m->flex_xvert0[1], -0.5 );
EXPECT_EQ(m->flex_xvert0[2], 0 );
EXPECT_EQ(d->flexvert_xpos[0], -0.5 );
EXPECT_EQ(d->flexvert_xpos[1], -0.5 );
EXPECT_EQ(d->flexvert_xpos[2], 0 );
// first element
EXPECT_EQ(m->flex_elem[0], 9-1 );
@@ -403,14 +448,16 @@ TEST_F(UserFlexTest, LoadMSHSurfaceASCII_22_Success) {
mjModel* m = mj_loadXML(xml_path.c_str(), 0, error.data(), error.size());
ASSERT_THAT(m, NotNull()) << error.data();
mjData* d = mj_makeData(m);
mj_kinematics(m, d);
mj_flex(m, d);
EXPECT_EQ(m->nflexvert, 14);
EXPECT_EQ(m->nflexelem, 24);
EXPECT_EQ(m->flex_dim[0], 2);
// first node x y z
EXPECT_EQ(m->flex_xvert0[0], -0.5 );
EXPECT_EQ(m->flex_xvert0[1], -0.5 );
EXPECT_EQ(m->flex_xvert0[2], 0 );
EXPECT_EQ(d->flexvert_xpos[0], -0.5 );
EXPECT_EQ(d->flexvert_xpos[1], -0.5 );
EXPECT_EQ(d->flexvert_xpos[2], 0 );
// first element
EXPECT_EQ(m->flex_elem[0], 9-1 );
+1 -1
View File
@@ -5428,7 +5428,7 @@ public unsafe struct mjModel_ {
public int* flex_shell;
public int* flex_evpair;
public double* flex_vert;
public double* flex_xvert0;
public double* flex_vert0;
public double* flexedge_length0;
public double* flexedge_invweight0;
public double* flex_radius;