You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Conception/drake-master/multibody/math/spatial_momentum.h

200 lines
11 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#pragma once
#ifndef DRAKE_SPATIAL_ALGEBRA_HEADER
#error Please include "drake/multibody/math/spatial_algebra.h", not this file.
#endif
#include <limits>
#include "drake/common/default_scalars.h"
#include "drake/common/drake_assert.h"
#include "drake/common/drake_copyable.h"
#include "drake/common/eigen_types.h"
#include "drake/multibody/math/spatial_vector.h"
namespace drake {
namespace multibody {
// Forward declaration to define dot product with a spatial velocity.
template <typename T> class SpatialVelocity;
/// This class represents a _spatial momentum_ L and has 6 elements with an
/// angular (rotational) momentum 𝐡 (3-element vector) on top of a translational
/// (linear) momentum 𝐥 (3-element vector). A spatial momentum L stores the
/// angular momentum 𝐡 and translational momentum 𝐥 of a system S about a point
/// P, measured in a frame M, and expressed in a frame E. The system S may be a
/// particle, a rigid or deformable body, or a set of particles and/or bodies.
/// This class assumes that both the angular momentum 𝐡 and translational
/// momentum 𝐥 are expressed in the same _expressed-in_ frame E. This class only
/// stores 6 elements (namely 𝐡 and 𝐥) and does not store the underlying
/// system S, about-point P, measured-in frame M, or expressed-in frame E.
/// The user is responsible for explicitly tracking the underlying system,
/// about-point, and frames with @ref multibody_quantities "monogram notation".
/// For example, L_MSP_E denotes a system S's spatial momentum about point P,
/// measured in frame M, and expressed in frame E. L_MSP_E contains h_MSP_E
/// (S's angular momentum about point P, measured in M, expressed in E) and
/// l_MS_E (S's translational momentum measured in M, expressed in E). A body
/// B's spatial momentum about point Bo (B's origin), measured in frame M,
/// expressed in frame E has explicit monogram notation L_MBBo_E which can be
/// abbreviated L_MBo_E. Similarly L_MSScm_E is abbreviated L_MScm_E (Scm is
/// S's center of mass). Details on spatial vectors and monogram notation are in
/// sections @ref multibody_spatial_vectors and @ref multibody_quantities.
///
/// The typeset for L_MSP_E is @f$[^ML^{S/P}]_E@f$. For a set S of particles Qᵢ,
/// L_MSP contains S's angular momentum 𝐡 about-point P, measured in frame M
/// and S's translational momentum 𝐥 measured in frame M, defined as <pre>
/// h_MSP = ∑ h_MQᵢP = ∑ p_PQᵢ x l_MQᵢ where l_MQᵢ = mᵢ v_MQᵢ.
/// l_MS = ∑ l_MQᵢ = ∑ mᵢ v_MQᵢ
/// </pre>
/// where mᵢ is the mass of particle Qᵢ, v_MQᵢ is Qᵢ's translational velocity
/// measured in frame M, l_MQᵢ = mᵢ v_MQQᵢ is Qᵢ's translational momentum
/// measured in frame M, h_MQᵢP is Qᵢ's angular momentum about point P
/// measured in frame M, and p_PQᵢ is the position vector from point P to Qᵢ.
/// These definitions extend to a body (continuum of particles) by using the
/// density ρ(r) of the body at each material location r as: <pre>
/// h_MSP = ∫p_PQ(r) x v_MQ(r) ρ(r) d³r
/// l_MS = ∫v_MQ(r) ρ(r) d³r
/// </pre>
///
/// @tparam_default_scalar
template <typename T>
class SpatialMomentum : public SpatialVector<SpatialMomentum, T> {
// We need the fully qualified class name below for the clang compiler to
// work. Without qualifiers the code is legal according to the C++11 standard
// but the clang compiler still gets confused. See:
// http://stackoverflow.com/questions/17687459/clang-not-accepting-use-of-template-template-parameter-when-using-crtp
typedef SpatialVector<::drake::multibody::SpatialMomentum, T> Base;
public:
DRAKE_DEFAULT_COPY_AND_MOVE_AND_ASSIGN(SpatialMomentum)
/// Default constructor. In Release builds, all 6 elements of a newly
/// constructed spatial momentum are uninitialized (for speed). In Debug
/// builds, the 6 elements are set to NaN so that invalid operations on an
/// uninitialized spatial momentum fail fast (fast bug detection).
SpatialMomentum() : Base() {}
/// Constructs a spatial momentum L from an angular momentum 𝐡
/// and a translational momentum 𝐥.
SpatialMomentum(const Eigen::Ref<const Vector3<T>>& h,
const Eigen::Ref<const Vector3<T>>& l) : Base(h, l) {}
/// Constructs a spatial momentum L from an Eigen expression that represents
/// a 6-element vector, i.e., a 3-element angular momentum 𝐡 and a
/// 3-element translational momentum 𝐥. This constructor will assert the
/// size of L is six (6) either at compile-time for fixed sized Eigen
/// expressions or at run-time for dynamic sized Eigen expressions.
template <typename Derived>
explicit SpatialMomentum(const Eigen::MatrixBase<Derived>& L) : Base(L) {}
/// In-place shift of a %SpatialMomentum from an about-point P to an
/// about-point Q, On entry, `this` is L_MSP_E (system S's spatial momentum
/// about point P, measured in a frame M and expressed in a frame E). On
/// return `this` is modified to L_MSQ_E (S's spatial momentum about point Q,
/// measured in frame M and expressed in frame E).
/// @param[in] offset which is the position vector p_PQ_E from point P to
/// point Q, with the same expressed-in frame E as `this` spatial momentum.
/// @retval L_MSQ_E reference to `this` spatial momentum which has been
/// modified to be system S's spatial momentum about point Q, measured in
/// frame M and expressed in frame E. The components of L_MSQ_E are: <pre>
/// l_MS_E = l_MS_E (translational momentum of `this` is unchanged).
/// h_MSQ_E = h_MSP_E + p_QP_E x l_MS_E
/// = h_MSP_E - p_PQ_E x l_MS_E
/// </pre>
/// Note: Spatial momenta shift similar to spatial force (see SpatialForce)
/// and in a related/different way for spatial velocity (see SpatialVelocity).
/// @see Shift() to shift spatial momentum without modifying `this`.
SpatialMomentum<T>& ShiftInPlace(const Vector3<T>& offset) {
this->rotational() -= offset.cross(this->translational());
return *this;
// Note: this operation is linear. [Jain 2010], (§2.1, page 22) uses the
// "rigid body transformation operator" to write this as:
// L_MSQ = Φ(-p_PQ) L_MSP
// = Φ(p_QP) L_MSP where Φ(p) is the linear operator:
// Φ(p) = | I₃ pₓ |
// | 0₃ I₃ | I₃ is the 3x3 identity matrix, 0₃ is the 3x3
// zero matrix and pₓ denotes the skew-symmetric cross product matrix such
// that pₓvec = p x vec (where vec is any vector).
// This same Φ operator shifts spatial force in an analogous way (see
// SpatialForce::Shift()) whereas Φᵀ (the transpose of this operator)
// shifts spatial velocity (see SpatialVelocity::Shift()).
//
// - [Jain 2010] Jain, A., 2010. Robot and multibody dynamics: analysis and
// algorithms. Springer Science & Business Media, pp. 123-130.
}
/// Shifts a %SpatialMomentum from an about-point P to an about-point Q.
/// @param[in] offset which is the position vector p_PQ_E from point P to
/// point Q, expressed in frame E. p_PQ_E must have the same expressed-in
/// frame E as `this` spatial momentum, where `this` is L_MSP_E (system S's
/// spatial momentum about P, measured in frame M, expressed in frame E).
/// @retval L_MSQ_E which is system S's spatial momentum about point Q,
/// measured in frame M, expressed in frame E.
/// @note Shift() differs from ShiftInPlace() in that Shift() does not modify
/// `this` whereas ShiftInPlace() does modify `this`.
/// @see ShiftInPlace() for more information and how L_MSQ_E is calculated.
SpatialMomentum<T> Shift(const Vector3<T>& offset) const {
return SpatialMomentum<T>(*this).ShiftInPlace(offset);
}
/// Calculates twice (2x) a body B's kinetic energy measured in a frame M.
/// For any frame (e.g., an @ref multibody_frames_and_bodies "offset frame")
/// Bp that is fixed to a rigid body B, calculates the dot-product of
/// `this` = L_MBp_E (body B's spatial momentum measured in frame M, about
/// Bp's origin, expressed in frame E) with V_MBp_E (frame Bp's spatial
/// velocity measured in frame M, expressed in frame E).
/// @param[in] velocity which is V_MBp_E, frame Bp's spatial velocity measured
/// in frame M, and expressed in the same frame E as `this` = L_MBp_E.
/// @returns 2*K_MB, twice (2x) body B's kinetic energy measured in frame M.
/// @note In general, kinetic energy calculations are only useful when frame M
/// is a world frame (also called a Newtonian or inertial frame). Hence, it
/// is unusual to use this method unless frame M is the world frame W.
/// @note Although the spatial vectors V_MBp_E and L_MBp_E must have the same
/// expressed-in frame E, the resulting scalar K_MB is independent of frame E.
/// @note As shown below, K_MB can be calculated from any frame Bp fixed on B,
/// including body B's center of mass frame Bcm. This is due to how spatial
/// momentum and spatial velocity shift from Bcm to Bp. For more information,
/// see SpatialMomentum::Shift() and SpatialVelocity::Shift(). <pre>
/// K_MB = 1/2 (L_MBp · V_MBp) = 1/2 (L_MBcm · V_MBcm)
/// </pre>
inline T dot(const SpatialVelocity<T>& velocity) const;
// The dot() method is implemented in spatial_velocity.h. We need the inline
// keyword to ensure the method is still inlined even with `extern template`.
};
/// Adds two spatial momenta by simply adding their 6 underlying elements.
/// @param[in] L1_E spatial momentum expressed in the same frame E as L2_E.
/// @param[in] L2_E spatial momentum expressed in the same frame E as L1_E.
/// @note The general utility of this operator+() function seems limited to
/// situations when L1 and L2 are associated with different systems (S1 and S2),
/// but have the same about-point P, same measured-in frame M, and same
/// expressed-in frame E.
/// @relates SpatialMomentum
template <typename T>
inline SpatialMomentum<T> operator+(const SpatialMomentum<T>& L1_E,
const SpatialMomentum<T>& L2_E) {
// Although this operator+() function simply calls an associated
// SpatialVector operator+=() function, it is needed for documentation.
return SpatialMomentum<T>(L1_E) += L2_E;
}
/// Subtracts spatial momenta by simply subtracting their 6 underlying elements.
/// @param[in] L1_E spatial momentum expressed in the same frame E as L2_E.
/// @param[in] L2_E spatial momentum expressed in the same frame E as L1_E.
/// @note The general utility of this operator-() function is questionable and
/// it should only be used if you are sure it makes sense.
/// @relates SpatialMomentum
template <typename T>
inline SpatialMomentum<T> operator-(const SpatialMomentum<T>& L1_E,
const SpatialMomentum<T>& L2_E) {
// Although this operator-() function simply calls an associated
// SpatialVector operator-=() function, it is needed for documentation.
return SpatialMomentum<T>(L1_E) -= L2_E;
}
} // namespace multibody
} // namespace drake
DRAKE_DECLARE_CLASS_TEMPLATE_INSTANTIATIONS_ON_DEFAULT_SCALARS(
class ::drake::multibody::SpatialMomentum)