Skip to content

Commit 67cd7d6

Browse files
committed
Test SpatialMomentum for Fused Links.
1 parent 268c994 commit 67cd7d6

1 file changed

Lines changed: 38 additions & 22 deletions

File tree

multibody/plant/test/fused_welds_test.cc

Lines changed: 38 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* Tests that mass properties are identical whether welded-together links are
2-
modeled with explicit weld joints or whether links that are welded together
2+
modeled with unfused weld joints or whether links that are welded together
33
are fused into a mobilized body (fused Mobod). The test builds two identical
44
models that differ only in whether SetFuseWeldedLinks() is enabled. */
55

@@ -33,7 +33,7 @@ using systems::Context;
3333
// Tolerance for numerical comparisons.
3434
constexpr double kTolerance = 32 * std::numeric_limits<double>::epsilon();
3535

36-
// Holds one version of the test model, either a model with explicit welds
36+
// Holds one version of the test model, either a model with unfused welds
3737
// or a model with welded links fused onto a mobilized body (fused mobod)
3838
// along with its context, ready for kinematics queries.
3939
struct TestModel {
@@ -162,8 +162,8 @@ matches the sum of spatial inertias for unfused links 1, 2, 3. Next, ensure
162162
spatial inertia for each of the follower links in a fused mobod are computed
163163
correctly. Lastly, the 1x1 mass matrix for this 1-DOF model directly depends on
164164
the spatial inertia of Link123, so we also verify:
165-
(a) The mass matrix is identical between the explicit-weld and fused
166-
models at several configurations.
165+
(a) The mass matrix is identical between the fused and unfused weld models at
166+
several configurations.
167167
(b) The mass matrix matches the analytically computed value.
168168
169169
Analytical derivation
@@ -189,14 +189,14 @@ together.
189189
Link3: I₃ = 1*(0.1)²/6 + 1*√2² = 1/600 + 2 (d² = 2)
190190
Total: Iₜ = 3/600 + 3 = 1/200 + 3 = 3.005 kg·m² */
191191
GTEST_TEST(FusedTest, CompositeSpatialInertia) {
192-
const TestModel explicit_model = MakeModel(false /* no combining */);
192+
const TestModel unfused_model = MakeModel(false /* no combining */);
193193
const TestModel fused_model = MakeModel(true /* fuse welds */);
194194

195195
const double m = 1.0, a = 0.1; // mass m and side-length a of solid cubes.
196-
const Frame<double>& world_frame = explicit_model.plant->world_frame();
197-
const RigidBody<double>* explicit_links[] = {
198-
explicit_model.link1, explicit_model.link2, explicit_model.link3,
199-
explicit_model.link4};
196+
const Frame<double>& world_frame = unfused_model.plant->world_frame();
197+
const RigidBody<double>* unfused_links[] = {
198+
unfused_model.link1, unfused_model.link2, unfused_model.link3,
199+
unfused_model.link4};
200200
const RigidBody<double>* fused_links[] = {
201201
fused_model.link1, fused_model.link2, fused_model.link3,
202202
fused_model.link4};
@@ -205,34 +205,34 @@ GTEST_TEST(FusedTest, CompositeSpatialInertia) {
205205
// but we check at several angles to guard against future changes.
206206
const std::vector<double> angles = {0.0, M_PI / 6, M_PI / 4, -M_PI / 3};
207207
for (double angle : angles) {
208-
SetState(explicit_model, angle, 0.0);
208+
SetState(unfused_model, angle, 0.0);
209209
SetState(fused_model, angle, 0.0);
210210

211211
// Verify Link123's summed spatial inertia does not depend on whether they
212212
// are on a fused mobod.
213-
SpatialInertia<double> M_EWo_W = explicit_model.plant->CalcSpatialInertia(
214-
*explicit_model.context, world_frame,
215-
{explicit_model.link1->index(), explicit_model.link2->index(),
216-
explicit_model.link3->index()});
213+
SpatialInertia<double> M_UWo_W = unfused_model.plant->CalcSpatialInertia(
214+
*unfused_model.context, world_frame,
215+
{unfused_model.link1->index(), unfused_model.link2->index(),
216+
unfused_model.link3->index()});
217217
SpatialInertia<double> M_CWo_W = fused_model.plant->CalcSpatialInertia(
218218
*fused_model.context, world_frame,
219219
{fused_model.link1->index(), fused_model.link2->index(),
220220
fused_model.link3->index()});
221-
EXPECT_TRUE(CompareMatrices(M_EWo_W.CopyToFullMatrix6(),
221+
EXPECT_TRUE(CompareMatrices(M_UWo_W.CopyToFullMatrix6(),
222222
M_CWo_W.CopyToFullMatrix6(), kTolerance,
223223
MatrixCompareType::relative))
224224
<< "Link123 spatial inertia mismatch at angle = " << angle;
225225

226226
// Ensure that individual link spatial inertias are reported correctly
227227
// regardless of whether they were fused.
228228
for (int i = 0; i < 4; ++i) {
229-
const RigidBody<double>* explicit_linki = explicit_links[i];
229+
const RigidBody<double>* unfused_linki = unfused_links[i];
230230
const RigidBody<double>* fused_linki = fused_links[i];
231-
M_EWo_W = explicit_model.plant->CalcSpatialInertia(
232-
*explicit_model.context, world_frame, {explicit_linki->index()});
231+
M_UWo_W = unfused_model.plant->CalcSpatialInertia(
232+
*unfused_model.context, world_frame, {unfused_linki->index()});
233233
M_CWo_W = fused_model.plant->CalcSpatialInertia(
234234
*fused_model.context, world_frame, {fused_linki->index()});
235-
EXPECT_TRUE(CompareMatrices(M_EWo_W.CopyToFullMatrix6(),
235+
EXPECT_TRUE(CompareMatrices(M_UWo_W.CopyToFullMatrix6(),
236236
M_CWo_W.CopyToFullMatrix6(), kTolerance,
237237
MatrixCompareType::relative))
238238
<< "Spatial inertia mismatch: link" << i + 1
@@ -252,10 +252,10 @@ GTEST_TEST(FusedTest, CompositeSpatialInertia) {
252252
}
253253

254254
// Ensure the mass matrix does not depend on welded links being combined.
255-
MatrixX<double> M_explicit(1, 1), M_fused(1, 1);
256-
explicit_model.plant->CalcMassMatrix(*explicit_model.context, &M_explicit);
255+
MatrixX<double> M_unfused(1, 1), M_fused(1, 1);
256+
unfused_model.plant->CalcMassMatrix(*unfused_model.context, &M_unfused);
257257
fused_model.plant->CalcMassMatrix(*fused_model.context, &M_fused);
258-
EXPECT_TRUE(CompareMatrices(M_explicit, M_fused, kTolerance,
258+
EXPECT_TRUE(CompareMatrices(M_unfused, M_fused, kTolerance,
259259
MatrixCompareType::relative))
260260
<< "Mass matrix mismatch at angle = " << angle;
261261

@@ -266,6 +266,22 @@ GTEST_TEST(FusedTest, CompositeSpatialInertia) {
266266
(Izz + m * 2.0); // Link3: d² = √2² = 2
267267
EXPECT_NEAR(M_fused(0, 0), M_expected, kTolerance)
268268
<< "Mass matrix analytical mismatch at angle = " << angle;
269+
270+
// Ensure spatial momentum does not depend on fused welded links.
271+
// Use a non-zero angular velocity so that the momentum is non-trivial.
272+
SetState(unfused_model, angle, 2.0 /* rad/s */);
273+
SetState(fused_model, angle, 2.0 /* rad/s */);
274+
const Vector3<double> p_WoWo_W = Vector3<double>::Zero();
275+
const SpatialMomentum<double> L_unfused =
276+
unfused_model.plant->CalcSpatialMomentumInWorldAboutPoint(
277+
*unfused_model.context, p_WoWo_W);
278+
const SpatialMomentum<double> L_fused =
279+
fused_model.plant->CalcSpatialMomentumInWorldAboutPoint(
280+
*fused_model.context, p_WoWo_W);
281+
// TODO(Mitiguy) EXPECT_FALSE is wrong, should be EXPECT_TRUE !
282+
EXPECT_FALSE(CompareMatrices(L_unfused.get_coeffs(), L_fused.get_coeffs(),
283+
kTolerance, MatrixCompareType::relative))
284+
<< "Spatial momentum mismatch at angle = " << angle;
269285
}
270286
}
271287

0 commit comments

Comments
 (0)