@@ -167,21 +167,32 @@ void BodyNodeImpl<T, ConcreteMobilizer>::
167
167
// Fmᵀ = Hᵀ * I. We'll do 6 applications of Hᵀ to columns of I to give
168
168
// columns of Fmᵀ which are rows of Fm. Then to compute M = Hᵀ⋅Fm we'll
169
169
// do m more applications of Hᵀ to columns of Fm to yield columns of M.
170
+
171
+ // This ugly code is just calculating Fm_BMo_M = H_FM_Mᵀ * I_BMo_M, with
172
+ // the inertia considered as a 6x6 matrix. But that's not how we represent
173
+ // spatial inertia! We have cheap (1 flop) inline methods for constructing
174
+ // columns of a _unit_ spatial inertia suitable for our specialized inline
175
+ // methods for multiplying by H_FM_Mᵀ. For a revolute mobilizer that is
176
+ // just a 0-flop extraction of one of the elements of the I_BMo_M column.
177
+ // And since everything is inline, it is possible for the compiler to
178
+ // turn all of this into 6 loads and 6 scalar multiplies.
170
179
Eigen::Matrix<T, 6 , kNv > Fm_BMo_M;
171
- Eigen::Matrix<T, 1 , kNv > Fm_row_i; // Contiguous storage needed.
172
- const T& mass = I_BMo_M.get_mass ();
173
- mobilizer_->calc_tau_from_M (X_FM, q, I_BMo_M.unit_col0 (), Fm_row_i.data ());
174
- Fm_BMo_M.row (0 ) = mass * Fm_row_i;
175
- mobilizer_->calc_tau_from_M (X_FM, q, I_BMo_M.unit_col1 (), Fm_row_i.data ());
176
- Fm_BMo_M.row (1 ) = mass * Fm_row_i;
177
- mobilizer_->calc_tau_from_M (X_FM, q, I_BMo_M.unit_col2 (), Fm_row_i.data ());
178
- Fm_BMo_M.row (2 ) = mass * Fm_row_i;
179
- mobilizer_->calc_tau_from_M (X_FM, q, I_BMo_M.unit_col3 (), Fm_row_i.data ());
180
- Fm_BMo_M.row (3 ) = mass * Fm_row_i;
181
- mobilizer_->calc_tau_from_M (X_FM, q, I_BMo_M.unit_col4 (), Fm_row_i.data ());
182
- Fm_BMo_M.row (4 ) = mass * Fm_row_i;
183
- mobilizer_->calc_tau_from_M (X_FM, q, I_BMo_M.unit_col5 (), Fm_row_i.data ());
184
- Fm_BMo_M.row (5 ) = mass * Fm_row_i;
180
+ {
181
+ Eigen::Matrix<T, 1 , kNv > Fm_i; // Contiguous storage needed.
182
+ const T& mass = I_BMo_M.get_mass ();
183
+ mobilizer_->calc_tau_from_M (X_FM, q, I_BMo_M.unit_col0 (), Fm_i.data ());
184
+ Fm_BMo_M.row (0 ) = mass * Fm_i;
185
+ mobilizer_->calc_tau_from_M (X_FM, q, I_BMo_M.unit_col1 (), Fm_i.data ());
186
+ Fm_BMo_M.row (1 ) = mass * Fm_i;
187
+ mobilizer_->calc_tau_from_M (X_FM, q, I_BMo_M.unit_col2 (), Fm_i.data ());
188
+ Fm_BMo_M.row (2 ) = mass * Fm_i;
189
+ mobilizer_->calc_tau_from_M (X_FM, q, I_BMo_M.unit_col3 (), Fm_i.data ());
190
+ Fm_BMo_M.row (3 ) = mass * Fm_i;
191
+ mobilizer_->calc_tau_from_M (X_FM, q, I_BMo_M.unit_col4 (), Fm_i.data ());
192
+ Fm_BMo_M.row (4 ) = mass * Fm_i;
193
+ mobilizer_->calc_tau_from_M (X_FM, q, I_BMo_M.unit_col5 (), Fm_i.data ());
194
+ Fm_BMo_M.row (5 ) = mass * Fm_i;
195
+ }
185
196
186
197
const int B_start_in_v = mobilizer ().velocity_start_in_v ();
187
198
0 commit comments