@@ -2843,16 +2843,35 @@ Vector3<T> MultibodyTree<T>::CalcCenterOfMassTranslationalAccelerationInWorld(
28432843template <typename T>
28442844SpatialMomentum<T> MultibodyTree<T>::CalcSpatialMomentumInWorldAboutPoint(
28452845 const systems::Context<T>& context, const Vector3<T>& p_WoP_W) const {
2846- // Assemble a list of ModelInstanceIndex.
2847- // Skip model_instance_index(0) which always contains the "world" body. The
2848- // spatial momentum of the world body measured in the world is always zero.
2849- std::vector<ModelInstanceIndex> model_instances;
2850- for (ModelInstanceIndex model_instance_index (1 );
2851- model_instance_index < num_model_instances (); ++model_instance_index)
2852- model_instances.push_back (model_instance_index);
2846+ // Efficienctly evaluate all mobods' spatial inertias, velocities, and poses.
2847+ const std::vector<SpatialInertia<T>>& M_Bi_W =
2848+ EvalSpatialInertiaInWorldCache (context);
2849+ const PositionKinematicsCache<T>& pc = EvalPositionKinematics (context);
2850+ const VelocityKinematicsCache<T>& vc = EvalVelocityKinematics (context);
2851+
2852+ // Form L_WSWo_W, the system S's spatial momentum in world W about Wo (world
2853+ // origin) expressed in W by doing a sum over all mobods in S.
2854+ SpatialMomentum<T> L_WSWo_W = SpatialMomentum<T>::Zero ();
2855+ for (const SpanningForest::Mobod& mobod : forest ().mobods ()) {
2856+ if (mobod.is_world ()) continue ; // No contribution from the world.
2857+
2858+ // Form each mobod B's spatial momentum in W about Bo, expressed in W.
2859+ const MobodIndex mobod_index = mobod.index ();
2860+ const SpatialInertia<T>& M_BBo_W = M_Bi_W[mobod_index];
2861+ const SpatialVelocity<T>& V_WBo_W = vc.get_V_WB (mobod_index);
2862+ SpatialMomentum<T> L_WBBo_W = M_BBo_W * V_WBo_W;
2863+
2864+ // Shift L_WBBo_W from "about Bo" to "about Wo" and accumulate the sum.
2865+ const RigidTransform<T>& X_WB = pc.get_X_WB (mobod_index);
2866+ const Vector3<T>& p_WoBo_W = X_WB .translation ();
2867+ // After ShiftInPlace, L_WBBo_W is no longer "about Bo", instead L_WBBo_W
2868+ // is now L_WBWo_W (B's spatial momentum in W "about Wo", expressed in W).
2869+ L_WBBo_W.ShiftInPlace (-p_WoBo_W); // After this, L_WBBo_W is now L_WBWo_W.
2870+ L_WSWo_W += L_WBBo_W; // Actually is L_WSWo_W += L_WBWo_W.
2871+ }
28532872
2854- return CalcSpatialMomentumInWorldAboutPoint (context, model_instances,
2855- p_WoP_W);
2873+ // Shift system S's spatial momentum from "about Wo" to "about point P".
2874+ return L_WSWo_W. Shift (p_WoP_W); // returns L_WSP_W.
28562875}
28572876
28582877template <typename T>
0 commit comments