@@ -187,6 +187,7 @@ class BodyNode : public MultibodyElement<T> {
187
187
// in the tree.)
188
188
void CalcPositionKinematicsCache_BaseToTip (
189
189
const systems::Context<T>& context,
190
+ const FrameBodyPoseCache<T>& frame_body_pose_cache,
190
191
PositionKinematicsCache<T>* pc) const {
191
192
// This method must not be called for the "world" body node.
192
193
DRAKE_ASSERT (topology_.rigid_body != world_index ());
@@ -203,7 +204,7 @@ class BodyNode : public MultibodyElement<T> {
203
204
// mobilizer. q(W:P) denotes all generalized positions in the kinematics
204
205
// path between World and the parent body P. It assumes we are in a
205
206
// base-to-tip recursion and therefore `X_WP` has already been updated.
206
- CalcAcrossMobilizerBodyPoses_BaseToTip (context , pc);
207
+ CalcAcrossMobilizerBodyPoses_BaseToTip (frame_body_pose_cache , pc);
207
208
208
209
// TODO(amcastro-tri):
209
210
// Update Body specific kinematics. These include:
@@ -381,6 +382,7 @@ class BodyNode : public MultibodyElement<T> {
381
382
// MultibodyTree::CalcAccelerationKinematicsCache().
382
383
void CalcSpatialAcceleration_BaseToTip (
383
384
const systems::Context<T>& context,
385
+ const FrameBodyPoseCache<T>& frame_body_poses_cache,
384
386
const PositionKinematicsCache<T>& pc,
385
387
const VelocityKinematicsCache<T>* vc,
386
388
const VectorX<T>& mbt_vdot,
@@ -456,12 +458,11 @@ class BodyNode : public MultibodyElement<T> {
456
458
// =========================================================================
457
459
// Computation of A_PB = DtP(V_PB), Eq. (4).
458
460
459
- // TODO(amcastro-tri): consider caching these. Also used in velocity
460
- // kinematics.
461
- const math::RotationMatrix<T> R_PF =
462
- frame_F.CalcRotationMatrixInBodyFrame (context);
463
- const math::RigidTransform<T> X_MB =
464
- frame_M.CalcPoseInBodyFrame (context).inverse ();
461
+ const math::RigidTransform<T>& X_PF =
462
+ frame_F.get_X_BF (frame_body_poses_cache);
463
+ const math::RotationMatrix<T>& R_PF = X_PF.rotation ();
464
+ const math::RigidTransform<T>& X_MB =
465
+ frame_M.get_X_FB (frame_body_poses_cache);
465
466
466
467
// Form the rotation matrix relating the world frame W and parent body P.
467
468
// Available since we are called within a base-to-tip recursion.
@@ -595,6 +596,7 @@ class BodyNode : public MultibodyElement<T> {
595
596
// MultibodyTree::CalcInverseDynamics().
596
597
void CalcInverseDynamics_TipToBase (
597
598
const systems::Context<T>& context,
599
+ const FrameBodyPoseCache<T>& frame_body_pose_cache,
598
600
const PositionKinematicsCache<T>& pc,
599
601
const std::vector<SpatialInertia<T>>& M_B_W_cache,
600
602
const std::vector<SpatialForce<T>>* Fb_Bo_W_cache,
@@ -675,7 +677,8 @@ class BodyNode : public MultibodyElement<T> {
675
677
// Compute shift vector from Bo to Mo expressed in the world frame W.
676
678
const Frame<T>& frame_M = outboard_frame ();
677
679
DRAKE_DEMAND (frame_M.body ().index () == body_B.index ());
678
- const math::RigidTransform<T> X_BM = frame_M.CalcPoseInBodyFrame (context);
680
+ const math::RigidTransform<T>& X_BM =
681
+ frame_M.get_X_BF (frame_body_pose_cache); // F==M
679
682
const Vector3<T>& p_BoMo_B = X_BM.translation ();
680
683
const math::RigidTransform<T>& X_WB = get_X_WB (pc);
681
684
const math::RotationMatrix<T>& R_WB = X_WB.rotation ();
@@ -700,8 +703,8 @@ class BodyNode : public MultibodyElement<T> {
700
703
// p_CoMc_W:
701
704
const Frame<T>& frame_Mc = child_node->outboard_frame ();
702
705
const math::RotationMatrix<T>& R_WC = child_node->get_X_WB (pc).rotation ();
703
- const math::RigidTransform<T> X_CMc =
704
- frame_Mc.CalcPoseInBodyFrame (context);
706
+ const math::RigidTransform<T>& X_CMc =
707
+ frame_Mc.get_X_BF (frame_body_pose_cache); // B==C, F==Mc
705
708
const Vector3<T>& p_CoMc_W = R_WC * X_CMc.translation ();
706
709
707
710
// Shift position vector from child C outboard mobilizer frame Mc to body
@@ -775,6 +778,7 @@ class BodyNode : public MultibodyElement<T> {
775
778
// with `context` by MultibodyTree::CalcPositionKinematicsCache().
776
779
void CalcAcrossNodeJacobianWrtVExpressedInWorld (
777
780
const systems::Context<T>& context,
781
+ const FrameBodyPoseCache<T>& frame_body_pose_cache,
778
782
const PositionKinematicsCache<T>& pc,
779
783
EigenPtr<MatrixX<T>> H_PB_W) const {
780
784
// Checks on the input arguments.
@@ -788,10 +792,11 @@ class BodyNode : public MultibodyElement<T> {
788
792
// Outboard frame M of this node's mobilizer.
789
793
const Frame<T>& frame_M = outboard_frame ();
790
794
791
- const math::RotationMatrix<T> R_PF =
792
- frame_F.CalcRotationMatrixInBodyFrame (context);
793
- const math::RigidTransform<T> X_MB =
794
- frame_M.CalcPoseInBodyFrame (context).inverse ();
795
+ const math::RigidTransform<T>& X_PF =
796
+ frame_F.get_X_BF (frame_body_pose_cache); // B==P
797
+ const math::RotationMatrix<T>& R_PF = X_PF.rotation ();
798
+ const math::RigidTransform<T>& X_MB =
799
+ frame_M.get_X_FB (frame_body_pose_cache); // F==M
795
800
796
801
// Form the rotation matrix relating the world frame W and parent body P.
797
802
const math::RotationMatrix<T>& R_WP = get_R_WP (pc);
@@ -1296,10 +1301,12 @@ class BodyNode : public MultibodyElement<T> {
1296
1301
// @pre pc and vc previously computed to be in sync with `context.
1297
1302
//
1298
1303
// @throws when `Ab_WB` is nullptr.
1299
- void CalcSpatialAccelerationBias (const systems::Context<T>& context,
1300
- const PositionKinematicsCache<T>& pc,
1301
- const VelocityKinematicsCache<T>& vc,
1302
- SpatialAcceleration<T>* Ab_WB) const {
1304
+ void CalcSpatialAccelerationBias (
1305
+ const systems::Context<T>& context,
1306
+ const FrameBodyPoseCache<T>& frame_body_pose_cache,
1307
+ const PositionKinematicsCache<T>& pc,
1308
+ const VelocityKinematicsCache<T>& vc,
1309
+ SpatialAcceleration<T>* Ab_WB) const {
1303
1310
DRAKE_THROW_UNLESS (Ab_WB != nullptr );
1304
1311
// As a guideline for developers, please refer to @ref
1305
1312
// abi_computing_accelerations for a detailed description and derivation of
@@ -1311,10 +1318,11 @@ class BodyNode : public MultibodyElement<T> {
1311
1318
const Frame<T>& frame_M = outboard_frame ();
1312
1319
1313
1320
// Compute R_PF and X_MB.
1314
- const math::RotationMatrix<T> R_PF =
1315
- frame_F.CalcRotationMatrixInBodyFrame (context);
1316
- const math::RigidTransform<T> X_MB =
1317
- frame_M.CalcPoseInBodyFrame (context).inverse ();
1321
+ const math::RigidTransform<T>& X_PF =
1322
+ frame_F.get_X_BF (frame_body_pose_cache); // B==P
1323
+ const math::RotationMatrix<T>& R_PF = X_PF.rotation ();
1324
+ const math::RigidTransform<T>& X_MB =
1325
+ frame_M.get_X_FB (frame_body_pose_cache); // F==M
1318
1326
1319
1327
// Parent position in the world is available from the position kinematics.
1320
1328
const math::RotationMatrix<T>& R_WP = get_R_WP (pc);
@@ -1733,7 +1741,7 @@ class BodyNode : public MultibodyElement<T> {
1733
1741
// between the world and the parent body P. It assumes we are in a base-to-tip
1734
1742
// recursion and therefore `X_WP` has already been updated.
1735
1743
void CalcAcrossMobilizerBodyPoses_BaseToTip (
1736
- const systems::Context <T>& context ,
1744
+ const FrameBodyPoseCache <T>& frame_body_pose_cache ,
1737
1745
PositionKinematicsCache<T>* pc) const {
1738
1746
// RigidBody for this node.
1739
1747
const RigidBody<T>& body_B = body ();
@@ -1753,8 +1761,10 @@ class BodyNode : public MultibodyElement<T> {
1753
1761
// - X_FM(q_B)
1754
1762
// - X_WP(q(W:B)), where q(W:B) includes all positions in the kinematics
1755
1763
// path from body B to the world W.
1756
- const math::RigidTransform<T> X_MB =
1757
- frame_M.CalcPoseInBodyFrame (context).inverse ();
1764
+ const math::RigidTransform<T>& X_MB =
1765
+ frame_M.get_X_FB (frame_body_pose_cache); // F==M
1766
+ const math::RigidTransform<T>& X_PF =
1767
+ frame_F.get_X_BF (frame_body_pose_cache); // B==P
1758
1768
const math::RigidTransform<T>& X_FM =
1759
1769
get_X_FM (*pc); // mobilizer.Eval_X_FM(ctx)
1760
1770
const math::RigidTransform<T>& X_WP =
@@ -1771,12 +1781,7 @@ class BodyNode : public MultibodyElement<T> {
1771
1781
// In that case X_FB = X_FM as suggested by setting X_MB = Identity.
1772
1782
const math::RigidTransform<T> X_FB = X_FM * X_MB;
1773
1783
1774
- // Given the pose X_FB of body frame B measured in the mobilizer inboard
1775
- // frame F, we can ask frame F (who's parent body is P) for the pose of body
1776
- // B measured in the frame of the parent body P.
1777
- // In the particular case F = B, this method directly returns X_FB.
1778
- X_PB = frame_F.CalcOffsetPoseInBody (context, X_FB);
1779
-
1784
+ X_PB = X_PF * X_FB;
1780
1785
X_WB = X_WP * X_PB;
1781
1786
1782
1787
// Compute shift vector p_PoBo_W from the parent origin to the body origin.
0 commit comments