Skip to content

Commit 7fdf775

Browse files
committed
Some minor performance tweaks & prep for M-frame algorithms.
1 parent 0b421dc commit 7fdf775

31 files changed

+539
-477
lines changed

math/cross_product.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,11 @@ drake::Matrix3<typename Derived::Scalar> VectorToSkewSymmetric(
1313
EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Eigen::MatrixBase<Derived>, 3);
1414

1515
drake::Matrix3<typename Derived::Scalar> ret;
16-
ret << 0.0, -p(2), p(1), p(2), 0.0, -p(0), -p(1), p(0), 0.0;
16+
// clang-format off
17+
ret << 0.0, -p(2), p(1),
18+
p(2), 0.0, -p(0),
19+
-p(1), p(0), 0.0;
20+
// clang-format on
1721
return ret;
1822
}
1923

multibody/benchmarking/cassie.cc

Lines changed: 100 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -25,21 +25,19 @@ using systems::System;
2525
// In the benchmark case instantiations at the bottom of this file, we'll use
2626
// a bitmask for the case's "Arg" to denote which quantities are in scope as
2727
// either gradients (for T=AutoDiffXd) or variables (for T=Expression).
28-
constexpr int kWantNoGrad = 0x0;
29-
constexpr int kWantGradQ = 0x1;
30-
constexpr int kWantGradV = 0x2;
31-
constexpr int kWantGradX = kWantGradQ | kWantGradV;
28+
constexpr int kWantNoGrad = 0x0;
29+
constexpr int kWantGradQ = 0x1;
30+
constexpr int kWantGradV = 0x2;
31+
constexpr int kWantGradX = kWantGradQ | kWantGradV;
3232
constexpr int kWantGradVdot = 0x4;
33-
constexpr int kWantGradU = 0x8;
33+
constexpr int kWantGradU = 0x8;
3434

3535
// Fixture that holds a Cassie robot model and offers helper functions to
3636
// configure the benchmark case.
3737
template <typename T>
3838
class Cassie : public benchmark::Fixture {
3939
public:
40-
Cassie() {
41-
tools::performance::AddMinMaxStatistics(this);
42-
}
40+
Cassie() { tools::performance::AddMinMaxStatistics(this); }
4341

4442
void SetUp(benchmark::State& state) override {
4543
SetUpNonZeroState();
@@ -89,24 +87,28 @@ class Cassie : public benchmark::Fixture {
8987
// those would get computed once and re-used (like in real applications) but
9088
// with caching off they would get recalculated repeatedly, affecting the
9189
// timing results.
92-
void InvalidateInput() {
93-
input_.GetMutableData();
94-
}
95-
void InvalidateState() {
96-
context_->NoteContinuousStateChange();
97-
}
90+
void InvalidateInput() { input_.GetMutableData(); }
91+
void InvalidateState() { context_->NoteContinuousStateChange(); }
9892

9993
// Runs the PositionKinematics benchmark.
10094
// NOLINTNEXTLINE(runtime/references)
10195
void DoPositionKinematics(benchmark::State& state) {
10296
DRAKE_DEMAND(want_grad_vdot(state) == false);
10397
DRAKE_DEMAND(want_grad_u(state) == false);
104-
// A distal body. Asking for pose of one body calculates poses of all
105-
// of them in the PositionKinematicsCache.
106-
const RigidBody<T>& toe_right = plant_->GetBodyByName("toe_right");
10798
for (auto _ : state) {
10899
InvalidateState();
109-
plant_->EvalBodyPoseInWorld(*context_, toe_right);
100+
plant_->EvalPositionKinematics(*context_);
101+
}
102+
}
103+
104+
// Runs the CompositeBodyInertiaInWorld benchmark.
105+
// NOLINTNEXTLINE(runtime/references)
106+
void DoCompositeBodyInertiaInWorld(benchmark::State& state) {
107+
DRAKE_DEMAND(want_grad_vdot(state) == false);
108+
DRAKE_DEMAND(want_grad_u(state) == false);
109+
for (auto _ : state) {
110+
InvalidateState();
111+
plant_->EvalCompositeBodyInertiaInWorldCache(*context_);
110112
}
111113
}
112114

@@ -115,13 +117,21 @@ class Cassie : public benchmark::Fixture {
115117
void DoPosAndVelKinematics(benchmark::State& state) {
116118
DRAKE_DEMAND(want_grad_vdot(state) == false);
117119
DRAKE_DEMAND(want_grad_u(state) == false);
118-
// A distal body. Asking for kinematics of one body calculates it for all
119-
// of them in the PositionKinematicsCache and VelocityKinematicsCache.
120-
const RigidBody<T>& toe_right = plant_->GetBodyByName("toe_right");
121120
for (auto _ : state) {
122121
InvalidateState();
123122
// This requires both position and velocity kinematics.
124-
plant_->EvalBodySpatialVelocityInWorld(*context_, toe_right);
123+
plant_->EvalVelocityKinematics(*context_);
124+
}
125+
}
126+
127+
// Runs the MassMatrixViaID benchmark.
128+
// NOLINTNEXTLINE(runtime/references)
129+
void DoMassMatrixViaID(benchmark::State& state) {
130+
DRAKE_DEMAND(want_grad_vdot(state) == false);
131+
DRAKE_DEMAND(want_grad_u(state) == false);
132+
for (auto _ : state) {
133+
InvalidateState();
134+
plant_->CalcMassMatrixViaInverseDynamics(*context_, &mass_matrix_out_);
125135
}
126136
}
127137

@@ -201,8 +211,8 @@ void Cassie<T>::SetUpNonZeroState() {
201211
VectorX<T>::LinSpaced(nq_ + nv_, 0.1, 0.9));
202212
for (const BodyIndex& index : plant_->GetFloatingBaseBodies()) {
203213
const RigidBody<T>& body = plant_->get_body(index);
204-
const RigidTransform<T> pose(
205-
RollPitchYaw<T>(0.1, 0.2, 0.3), Vector3<T>(0.4, 0.5, 0.6));
214+
const RigidTransform<T> pose(RollPitchYaw<T>(0.1, 0.2, 0.3),
215+
Vector3<T>(0.4, 0.5, 0.6));
206216
plant_->SetFreeBodyPose(context_.get(), body, pose);
207217
}
208218

@@ -303,6 +313,15 @@ BENCHMARK_REGISTER_F(CassieDouble, PositionKinematics)
303313
->Unit(benchmark::kMicrosecond)
304314
->Arg(kWantNoGrad);
305315

316+
BENCHMARK_DEFINE_F(CassieDouble, CompositeBodyInertiaInWorld)
317+
// NOLINTNEXTLINE(runtime/references)
318+
(benchmark::State& state) {
319+
DoCompositeBodyInertiaInWorld(state);
320+
}
321+
BENCHMARK_REGISTER_F(CassieDouble, CompositeBodyInertiaInWorld)
322+
->Unit(benchmark::kMicrosecond)
323+
->Arg(kWantNoGrad);
324+
306325
// NOLINTNEXTLINE(runtime/references)
307326
BENCHMARK_DEFINE_F(CassieDouble, PosAndVelKinematics)(benchmark::State& state) {
308327
DoPosAndVelKinematics(state);
@@ -311,29 +330,37 @@ BENCHMARK_REGISTER_F(CassieDouble, PosAndVelKinematics)
311330
->Unit(benchmark::kMicrosecond)
312331
->Arg(kWantNoGrad);
313332

333+
// NOLINTNEXTLINE(runtime/references)
334+
BENCHMARK_DEFINE_F(CassieDouble, MassMatrixViaID)(benchmark::State& state) {
335+
DoMassMatrixViaID(state);
336+
}
337+
BENCHMARK_REGISTER_F(CassieDouble, MassMatrixViaID)
338+
->Unit(benchmark::kMicrosecond)
339+
->Arg(kWantNoGrad);
340+
314341
// NOLINTNEXTLINE(runtime/references)
315342
BENCHMARK_DEFINE_F(CassieDouble, MassMatrix)(benchmark::State& state) {
316343
DoMassMatrix(state);
317344
}
318345
BENCHMARK_REGISTER_F(CassieDouble, MassMatrix)
319-
->Unit(benchmark::kMicrosecond)
320-
->Arg(kWantNoGrad);
346+
->Unit(benchmark::kMicrosecond)
347+
->Arg(kWantNoGrad);
321348

322349
// NOLINTNEXTLINE(runtime/references)
323350
BENCHMARK_DEFINE_F(CassieDouble, InverseDynamics)(benchmark::State& state) {
324351
DoInverseDynamics(state);
325352
}
326353
BENCHMARK_REGISTER_F(CassieDouble, InverseDynamics)
327-
->Unit(benchmark::kMicrosecond)
328-
->Arg(kWantNoGrad);
354+
->Unit(benchmark::kMicrosecond)
355+
->Arg(kWantNoGrad);
329356

330357
// NOLINTNEXTLINE(runtime/references)
331358
BENCHMARK_DEFINE_F(CassieDouble, ForwardDynamics)(benchmark::State& state) {
332359
DoForwardDynamics(state);
333360
}
334361
BENCHMARK_REGISTER_F(CassieDouble, ForwardDynamics)
335-
->Unit(benchmark::kMicrosecond)
336-
->Arg(kWantNoGrad);
362+
->Unit(benchmark::kMicrosecond)
363+
->Arg(kWantNoGrad);
337364

338365
BENCHMARK_DEFINE_F(CassieAutoDiff, PositionKinematics)
339366
// NOLINTNEXTLINE(runtime/references)
@@ -362,41 +389,41 @@ BENCHMARK_DEFINE_F(CassieAutoDiff, MassMatrix)(benchmark::State& state) {
362389
DoMassMatrix(state);
363390
}
364391
BENCHMARK_REGISTER_F(CassieAutoDiff, MassMatrix)
365-
->Unit(benchmark::kMicrosecond)
366-
->Arg(kWantNoGrad)
367-
->Arg(kWantGradQ)
368-
->Arg(kWantGradV)
369-
->Arg(kWantGradX);
392+
->Unit(benchmark::kMicrosecond)
393+
->Arg(kWantNoGrad)
394+
->Arg(kWantGradQ)
395+
->Arg(kWantGradV)
396+
->Arg(kWantGradX);
370397

371398
// NOLINTNEXTLINE(runtime/references)
372399
BENCHMARK_DEFINE_F(CassieAutoDiff, InverseDynamics)(benchmark::State& state) {
373400
DoInverseDynamics(state);
374401
}
375402
BENCHMARK_REGISTER_F(CassieAutoDiff, InverseDynamics)
376-
->Unit(benchmark::kMicrosecond)
377-
->Arg(kWantNoGrad)
378-
->Arg(kWantGradQ)
379-
->Arg(kWantGradV)
380-
->Arg(kWantGradX)
381-
->Arg(kWantGradVdot)
382-
->Arg(kWantGradQ|kWantGradVdot)
383-
->Arg(kWantGradV|kWantGradVdot)
384-
->Arg(kWantGradX|kWantGradVdot);
403+
->Unit(benchmark::kMicrosecond)
404+
->Arg(kWantNoGrad)
405+
->Arg(kWantGradQ)
406+
->Arg(kWantGradV)
407+
->Arg(kWantGradX)
408+
->Arg(kWantGradVdot)
409+
->Arg(kWantGradQ | kWantGradVdot)
410+
->Arg(kWantGradV | kWantGradVdot)
411+
->Arg(kWantGradX | kWantGradVdot);
385412

386413
// NOLINTNEXTLINE(runtime/references)
387414
BENCHMARK_DEFINE_F(CassieAutoDiff, ForwardDynamics)(benchmark::State& state) {
388415
DoForwardDynamics(state);
389416
}
390417
BENCHMARK_REGISTER_F(CassieAutoDiff, ForwardDynamics)
391-
->Unit(benchmark::kMicrosecond)
392-
->Arg(kWantNoGrad)
393-
->Arg(kWantGradQ)
394-
->Arg(kWantGradV)
395-
->Arg(kWantGradX)
396-
->Arg(kWantGradU)
397-
->Arg(kWantGradQ|kWantGradU)
398-
->Arg(kWantGradV|kWantGradU)
399-
->Arg(kWantGradX|kWantGradU);
418+
->Unit(benchmark::kMicrosecond)
419+
->Arg(kWantNoGrad)
420+
->Arg(kWantGradQ)
421+
->Arg(kWantGradV)
422+
->Arg(kWantGradX)
423+
->Arg(kWantGradU)
424+
->Arg(kWantGradQ | kWantGradU)
425+
->Arg(kWantGradV | kWantGradU)
426+
->Arg(kWantGradX | kWantGradU);
400427

401428
BENCHMARK_DEFINE_F(CassieExpression, PositionKinematics)
402429
// NOLINTNEXTLINE(runtime/references)
@@ -425,38 +452,38 @@ BENCHMARK_DEFINE_F(CassieExpression, MassMatrix)(benchmark::State& state) {
425452
DoMassMatrix(state);
426453
}
427454
BENCHMARK_REGISTER_F(CassieExpression, MassMatrix)
428-
->Unit(benchmark::kMicrosecond)
429-
->Arg(kWantNoGrad)
430-
->Arg(kWantGradQ)
431-
->Arg(kWantGradV)
432-
->Arg(kWantGradX);
455+
->Unit(benchmark::kMicrosecond)
456+
->Arg(kWantNoGrad)
457+
->Arg(kWantGradQ)
458+
->Arg(kWantGradV)
459+
->Arg(kWantGradX);
433460

434461
// NOLINTNEXTLINE(runtime/references)
435462
BENCHMARK_DEFINE_F(CassieExpression, InverseDynamics)(benchmark::State& state) {
436463
DoInverseDynamics(state);
437464
}
438465
BENCHMARK_REGISTER_F(CassieExpression, InverseDynamics)
439-
->Unit(benchmark::kMicrosecond)
440-
->Arg(kWantNoGrad)
441-
->Arg(kWantGradQ)
442-
->Arg(kWantGradV)
443-
->Arg(kWantGradX)
444-
->Arg(kWantGradVdot)
445-
->Arg(kWantGradQ|kWantGradVdot)
446-
->Arg(kWantGradV|kWantGradVdot)
447-
->Arg(kWantGradX|kWantGradVdot);
466+
->Unit(benchmark::kMicrosecond)
467+
->Arg(kWantNoGrad)
468+
->Arg(kWantGradQ)
469+
->Arg(kWantGradV)
470+
->Arg(kWantGradX)
471+
->Arg(kWantGradVdot)
472+
->Arg(kWantGradQ | kWantGradVdot)
473+
->Arg(kWantGradV | kWantGradVdot)
474+
->Arg(kWantGradX | kWantGradVdot);
448475

449476
// NOLINTNEXTLINE(runtime/references)
450477
BENCHMARK_DEFINE_F(CassieExpression, ForwardDynamics)(benchmark::State& state) {
451478
DoForwardDynamics(state);
452479
}
453480
BENCHMARK_REGISTER_F(CassieExpression, ForwardDynamics)
454-
->Unit(benchmark::kMicrosecond)
455-
->Arg(kWantNoGrad)
456-
// N.B. MbP does not support forward dynamics with Variables in 'q'.
457-
->Arg(kWantGradV)
458-
->Arg(kWantGradU)
459-
->Arg(kWantGradV|kWantGradU);
481+
->Unit(benchmark::kMicrosecond)
482+
->Arg(kWantNoGrad)
483+
// N.B. MbP does not support forward dynamics with Variables in 'q'.
484+
->Arg(kWantGradV)
485+
->Arg(kWantGradU)
486+
->Arg(kWantGradV | kWantGradU);
460487

461488
} // namespace
462489
} // namespace multibody

multibody/math/spatial_velocity.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ class SpatialVelocity : public SpatialVector<SpatialVelocity, T> {
107107
/// @see ShiftInPlace() for more information and how V_MC_E is calculated.
108108
SpatialVelocity<T> Shift(const Vector3<T>& offset) const {
109109
SpatialVelocity<T> result(*this);
110-
result.ShiftInPlace(offset);
110+
result.ShiftInPlace(offset); // 12 flops
111111
return result;
112112
}
113113

multibody/plant/test/external_forces_test.cc

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
#include <limits>
22

3-
#include <gmock/gmock.h>
43
#include <gtest/gtest.h>
54

6-
#include "drake/common/autodiff.h"
5+
#include "drake/common/fmt_eigen.h"
76
#include "drake/common/test_utilities/eigen_matrix_compare.h"
87
#include "drake/common/test_utilities/limit_malloc.h"
98
#include "drake/multibody/plant/test/kuka_iiwa_model_tests.h"
109
#include "drake/multibody/tree/frame.h"
11-
#include "drake/multibody/tree/rigid_body.h"
1210

1311
namespace drake {
1412

multibody/plant/test/multibody_plant_mass_matrix_test.cc

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,10 @@ namespace {
2323

2424
// We verify the computation of the mass matrix by comparing two significantly
2525
// different implementations:
26-
// - CalcMassMatrix(): uses the Composite Body Algorithm.
26+
// - CalcMassMatrix(): Composite Body Algorithm, via recursion using World
27+
// frame quantities.
2728
// - CalcMassMatrixViaInverseDynamics(): uses inverse dynamics to compute each
28-
// column of the mass matrix at a time.
29+
// column of the mass matrix one at a time.
2930
class MultibodyPlantMassMatrixTests : public ::testing::Test {
3031
public:
3132
void LoadUrl(const std::string& url) {
@@ -60,30 +61,33 @@ class MultibodyPlantMassMatrixTests : public ::testing::Test {
6061
// mass matrix by comparing the results from CalcMassMatrix() and
6162
// CalcMassMatrixViaInverseDynamics().
6263
void VerifyMassMatrixComputation(const Context<double>& context) {
63-
// Compute mass matrix via the Composite Body Algorithm.
64-
MatrixX<double> Mcba(plant_.num_velocities(), plant_.num_velocities());
65-
plant_.CalcMassMatrix(context, &Mcba);
64+
// Compute mass matrix using the Composite Body Algorithm via recursion
65+
// using World frame quantities (indicated by "_via_W" here).
66+
MatrixX<double> Mcba_via_W(plant_.num_velocities(),
67+
plant_.num_velocities());
68+
plant_.CalcMassMatrix(context, &Mcba_via_W);
6669

6770
// After a first warm-up call, subsequent calls to CalcMassMatrix<double>()
6871
// should never allocate.
6972
{
7073
LimitMalloc guard;
71-
plant_.CalcMassMatrix(context, &Mcba);
74+
plant_.CalcMassMatrix(context, &Mcba_via_W);
7275
}
7376

74-
// Compute mass matrix using inverse dynamics for each column.
75-
MatrixX<double> Mid(plant_.num_velocities(), plant_.num_velocities());
76-
plant_.CalcMassMatrixViaInverseDynamics(context, &Mid);
77+
// Compute mass matrix using inverse dynamics for each column (indicated
78+
// by "_via_id" here).
79+
MatrixX<double> M_via_id(plant_.num_velocities(), plant_.num_velocities());
80+
plant_.CalcMassMatrixViaInverseDynamics(context, &M_via_id);
7781

7882
// Compute a suitable tolerance scaled with the norm of the mass matrix.
7983
// Since .norm() computes the Frobenius norm, and num_velocities() is the
8084
// squared root of the number of elements in the matrix, this tolerance is
8185
// effectively being scaled by the RMS value of the elements in the mass
8286
// matrix.
83-
const double kTolerance = 10.0 * std::numeric_limits<double>::epsilon() *
84-
Mcba.norm() / plant_.num_velocities();
85-
EXPECT_TRUE(
86-
CompareMatrices(Mcba, Mid, kTolerance, MatrixCompareType::relative));
87+
const double tolerance = 10.0 * std::numeric_limits<double>::epsilon() *
88+
Mcba_via_W.norm() / plant_.num_velocities();
89+
EXPECT_TRUE(CompareMatrices(Mcba_via_W, M_via_id, tolerance,
90+
MatrixCompareType::relative));
8791
}
8892

8993
protected:

0 commit comments

Comments
 (0)