6 #ifndef __pinocchio_spatial_inertia_hpp__
7 #define __pinocchio_spatial_inertia_hpp__
18 template<
class Derived>
25 return *
static_cast<Derived *
>(
this);
29 return *
static_cast<const Derived *
>(
this);
34 return *
const_cast<Derived *
>(&
derived());
39 return static_cast<const Derived *
>(
this)->
mass();
43 return static_cast<const Derived *
>(
this)->
mass();
47 return static_cast<const Derived *
>(
this)->
lever();
51 return static_cast<const Derived *
>(
this)->
lever();
55 return static_cast<const Derived *
>(
this)->
inertia();
59 return static_cast<const Derived *
>(
this)->
inertia();
62 template<
typename Matrix6Like>
63 void matrix(
const Eigen::MatrixBase<Matrix6Like> & mat)
const
71 operator Matrix6()
const
76 template<
typename Matrix6Like>
77 void inverse(
const Eigen::MatrixBase<Matrix6Like> & mat)
const
83 return derived().inverse_impl();
92 return derived().isEqual(other);
96 return !(*
this == other);
113 return derived().__minus__(Yb);
116 template<
typename MotionDerived>
123 template<
typename MotionDerived>
129 template<
typename MotionDerived>
143 template<
typename MotionDerived,
typename M6>
147 EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(M6, Matrix6);
148 Derived::vxi_impl(
v, I, Iout);
151 template<
typename MotionDerived>
167 template<
typename MotionDerived,
typename M6>
171 EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(M6, Matrix6);
172 Derived::ivx_impl(
v, I, Iout);
175 template<
typename MotionDerived>
197 const Derived & other,
198 const Scalar & prec = Eigen::NumTraits<Scalar>::dummy_precision())
const
200 return derived().isApprox_impl(other, prec);
203 bool isZero(
const Scalar & prec = Eigen::NumTraits<Scalar>::dummy_precision())
const
205 return derived().isZero_impl(prec);
209 template<
typename S2,
int O2>
216 template<
typename S2,
int O2>
219 return derived().se3ActionInverse_impl(
M);
222 void disp(std::ostream & os)
const
224 static_cast<const Derived *
>(
this)->disp_impl(os);
234 template<
typename T,
int U>
261 template<
typename _Scalar,
int _Options>
262 struct InertiaTpl :
public InertiaBase<InertiaTpl<_Scalar, _Options>>
264 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
273 typedef typename Eigen::Matrix<Scalar, 10, 1, Options>
Vector10;
289 assert(check_expression_if_real<Scalar>(
isZero(I6 - I6.transpose())));
290 mass() = I6(LINEAR, LINEAR);
291 const typename Matrix6::template ConstFixedBlockXpr<3, 3>::Type mc_cross =
292 I6.template block<3, 3>(ANGULAR, LINEAR);
296 Matrix3 I3(mc_cross * mc_cross);
298 I3 += I6.template block<3, 3>(ANGULAR, ANGULAR);
325 template<
typename S2,
int O2>
328 *
this =
clone.template cast<Scalar>();
436 const Scalar pi = boost::math::constants::pi<Scalar>();
443 const Scalar m_cyl =
mass * (v_cyl / total_v);
460 const Scalar ix = ix_c +
Scalar(2) * (ix_hs + m_hs * math::pow(dist_hc_cyl, 2));
474 template<
typename Matrix6Like>
477 Matrix6Like &
M = M_.const_cast_derived();
479 M.template block<3, 3>(LINEAR, LINEAR).setZero();
480 M.template block<3, 3>(LINEAR, LINEAR).diagonal().fill(
mass());
482 M.template block<3, 3>(LINEAR, ANGULAR) = -
M.template block<3, 3>(ANGULAR, LINEAR);
483 M.template block<3, 3>(ANGULAR, ANGULAR) =
494 template<
typename Matrix6Like>
497 Matrix6Like &
M = M_.const_cast_derived();
500 M.template block<3, 3>(LINEAR, ANGULAR).noalias() =
501 -
M.template block<3, 3>(ANGULAR, ANGULAR).colwise().cross(
lever());
502 M.template block<3, 3>(ANGULAR, LINEAR) =
M.template block<3, 3>(LINEAR, ANGULAR).transpose();
506 M.template block<3, 3>(LINEAR, LINEAR).col(0).noalias() =
507 cy *
M.template block<3, 3>(LINEAR, ANGULAR).col(2)
508 - cz *
M.template block<3, 3>(LINEAR, ANGULAR).col(1);
510 M.template block<3, 3>(LINEAR, LINEAR).col(1).noalias() =
511 cz *
M.template block<3, 3>(LINEAR, ANGULAR).col(0)
512 - cx *
M.template block<3, 3>(LINEAR, ANGULAR).col(2);
514 M.template block<3, 3>(LINEAR, LINEAR).col(2).noalias() =
515 cx *
M.template block<3, 3>(LINEAR, ANGULAR).col(1)
516 - cy *
M.template block<3, 3>(LINEAR, ANGULAR).col(0);
519 M.template block<3, 3>(LINEAR, LINEAR).diagonal().array() += m_inv;
541 v.template segment<3>(1).noalias() =
mass() *
lever();
555 template<
typename Vector10Like>
580 return (
mass() == Y2.mass()) && (
lever() == Y2.lever()) && (
inertia() == Y2.inertia());
585 const Scalar & prec = Eigen::NumTraits<Scalar>::dummy_precision())
const
588 return fabs(
static_cast<Scalar>(
mass() - other.mass())) <= prec
605 const Scalar eps = ::Eigen::NumTraits<Scalar>::epsilon();
611 mab, (
mass() *
lever() + Yb.mass() * Yb.lever()) * mab_inv,
613 - (
mass() * Yb.mass() * mab_inv) *
typename Symmetric3::SkewSquare(AB));
618 static const Scalar eps = ::Eigen::NumTraits<Scalar>::epsilon();
623 const Vector3 & AB = (Ya.lever() - Yb.lever()).eval();
625 lever() += (Yb.mass() * mab_inv) * Yb.lever();
627 inertia() -= (Ya.mass() * Yb.mass() * mab_inv) *
typename Symmetric3::SkewSquare(AB);
639 const Scalar eps = ::Eigen::NumTraits<Scalar>::epsilon();
642 assert(check_expression_if_real<Scalar>(ma >=
Scalar(0)));
647 const Vector3 AB = c_a - Yb.lever();
651 inertia() - Yb.inertia() + (ma * Yb.mass() /
mass()) *
typename Symmetric3::SkewSquare(AB));
656 static const Scalar eps = ::Eigen::NumTraits<Scalar>::epsilon();
659 assert(check_expression_if_real<Scalar>(ma >=
Scalar(0)));
664 lever().noalias() -= (Yb.mass() * ma_inv) * Yb.lever();
668 inertia() += (ma * Yb.mass() /
mass()) *
typename Symmetric3::SkewSquare(AB);
674 template<
typename MotionDerived>
685 template<
typename MotionDerived,
typename ForceDerived>
688 f.linear().noalias() =
mass() * (
v.linear() -
lever().cross(
v.angular()));
690 f.angular() +=
lever().cross(
f.linear());
694 template<
typename MotionDerived>
700 res +=
v.angular().dot(mcxcxw);
706 template<
typename MotionDerived>
712 res.template block<3, 3>(LINEAR, ANGULAR) =
714 res.template block<3, 3>(ANGULAR, LINEAR) =
715 res.template block<3, 3>(LINEAR, ANGULAR).transpose();
720 res.template block<3, 3>(ANGULAR, ANGULAR) =
723 res.template block<3, 3>(LINEAR, LINEAR) =
726 res.template block<3, 3>(ANGULAR, ANGULAR) -=
727 res.template block<3, 3>(LINEAR, LINEAR) *
skew(
v.angular());
728 res.template block<3, 3>(ANGULAR, ANGULAR) +=
729 cross(
v.angular(),
res.template block<3, 3>(LINEAR, LINEAR));
731 res.template block<3, 3>(LINEAR, LINEAR).setZero();
735 template<
typename MotionDerived,
typename M6>
739 const Eigen::MatrixBase<M6> & Iout)
741 EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(M6, 6, 6);
745 alphaSkew(I.mass(),
v.angular(), Iout_.template block<3, 3>(LINEAR, LINEAR));
747 const Vector3 mc(I.mass() * I.lever());
750 skewSquare(-
v.angular(), mc, Iout_.template block<3, 3>(LINEAR, ANGULAR));
753 alphaSkew(I.mass(),
v.linear(), Iout_.template block<3, 3>(ANGULAR, LINEAR));
754 Iout_.template block<3, 3>(ANGULAR, LINEAR) -= Iout_.template block<3, 3>(LINEAR, ANGULAR);
757 skewSquare(-
v.linear(), mc, Iout_.template block<3, 3>(ANGULAR, ANGULAR));
764 Symmetric3 mcxcx(
typename Symmetric3::AlphaSkewSquare(I.mass(), I.lever()));
765 Iout_.template block<3, 3>(ANGULAR, ANGULAR) += I.inertia().vxs(
v.angular());
766 Iout_.template block<3, 3>(ANGULAR, ANGULAR) -= mcxcx.
vxs(
v.angular());
769 template<
typename MotionDerived,
typename M6>
773 const Eigen::MatrixBase<M6> & Iout)
775 EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(M6, 6, 6);
779 alphaSkew(I.mass(),
v.angular(), Iout_.template block<3, 3>(LINEAR, LINEAR));
782 const Vector3 mc(I.mass() * I.lever());
783 skewSquare(mc,
v.angular(), Iout_.template block<3, 3>(ANGULAR, LINEAR));
786 alphaSkew(I.mass(),
v.linear(), Iout_.template block<3, 3>(LINEAR, ANGULAR));
790 -I.lever(), Iout_.template block<3, 3>(ANGULAR, LINEAR),
791 Iout_.template block<3, 3>(ANGULAR, ANGULAR));
792 Iout_.template block<3, 3>(ANGULAR, ANGULAR) += I.inertia().svx(
v.angular());
793 for (
int k = 0; k < 3; ++k)
794 Iout_.template block<3, 3>(ANGULAR, ANGULAR).col(k) +=
795 I.lever().cross(Iout_.template block<3, 3>(LINEAR, ANGULAR).col(k));
798 Iout_.template block<3, 3>(LINEAR, ANGULAR) -= Iout_.template block<3, 3>(ANGULAR, LINEAR);
829 template<
typename S2,
int O2>
840 template<
typename S2,
int O2>
844 mass(),
M.rotation().transpose() * (
lever() -
M.translation()),
848 template<
typename MotionDerived>
854 v.angular().cross(mv_mcxw),
856 -
v.linear().cross(mcxw));
861 os <<
" m = " <<
mass() <<
"\n"
862 <<
" c = " <<
lever().transpose() <<
"\n"
868 template<
typename NewScalar>
872 pinocchio::cast<NewScalar>(
mass()),
lever().
template cast<NewScalar>(),
873 inertia().
template cast<NewScalar>());
894 #endif // ifndef __pinocchio_spatial_inertia_hpp__