7 #ifndef __pinocchio_spatial_inertia_hpp__
8 #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>
264 template<
typename _Scalar,
int _Options>
265 struct InertiaTpl :
public InertiaBase<InertiaTpl<_Scalar, _Options>>
267 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
276 typedef Eigen::Matrix<Scalar, 10, 1, Options>
Vector10;
277 typedef Eigen::Matrix<Scalar, 10, 10, Options>
Matrix10;
295 assert(check_expression_if_real<Scalar>(
pinocchio::isZero(I6 - I6.transpose())));
296 mass() = I6(LINEAR, LINEAR);
297 const typename Matrix6::template ConstFixedBlockXpr<3, 3>::Type mc_cross =
298 I6.template block<3, 3>(ANGULAR, LINEAR);
302 Matrix3 I3(mc_cross * mc_cross);
304 I3 += I6.template block<3, 3>(ANGULAR, ANGULAR);
331 template<
typename S2,
int O2>
334 *
this =
clone.template cast<Scalar>();
442 const Scalar pi = boost::math::constants::pi<Scalar>();
449 const Scalar m_cyl =
mass * (v_cyl / total_v);
466 const Scalar ix = ix_c +
Scalar(2) * (ix_hs + m_hs * math::pow(dist_hc_cyl, 2));
480 template<
typename Matrix6Like>
483 Matrix6Like &
M = M_.const_cast_derived();
485 M.template block<3, 3>(LINEAR, LINEAR).setZero();
486 M.template block<3, 3>(LINEAR, LINEAR).diagonal().fill(
mass());
488 M.template block<3, 3>(LINEAR, ANGULAR) = -
M.template block<3, 3>(ANGULAR, LINEAR);
489 M.template block<3, 3>(ANGULAR, ANGULAR) =
500 template<
typename Matrix6Like>
503 Matrix6Like &
M = M_.const_cast_derived();
506 M.template block<3, 3>(LINEAR, ANGULAR).noalias() =
507 -
M.template block<3, 3>(ANGULAR, ANGULAR).colwise().cross(
lever());
508 M.template block<3, 3>(ANGULAR, LINEAR) =
M.template block<3, 3>(LINEAR, ANGULAR).transpose();
512 M.template block<3, 3>(LINEAR, LINEAR).col(0).noalias() =
513 cy *
M.template block<3, 3>(LINEAR, ANGULAR).col(2)
514 - cz *
M.template block<3, 3>(LINEAR, ANGULAR).col(1);
516 M.template block<3, 3>(LINEAR, LINEAR).col(1).noalias() =
517 cz *
M.template block<3, 3>(LINEAR, ANGULAR).col(0)
518 - cx *
M.template block<3, 3>(LINEAR, ANGULAR).col(2);
520 M.template block<3, 3>(LINEAR, LINEAR).col(2).noalias() =
521 cx *
M.template block<3, 3>(LINEAR, ANGULAR).col(1)
522 - cy *
M.template block<3, 3>(LINEAR, ANGULAR).col(0);
525 M.template block<3, 3>(LINEAR, LINEAR).diagonal().array() += m_inv;
547 v.template segment<3>(1).noalias() =
mass() *
lever();
561 template<
typename Vector10Like>
567 Vector3
lever = params.template segment<3>(1);
595 return pseudo_inertia;
623 return (
mass() == Y2.mass()) && (
lever() == Y2.lever()) && (
inertia() == Y2.inertia());
628 const Scalar & prec = Eigen::NumTraits<Scalar>::dummy_precision())
const
631 return fabs(
static_cast<Scalar>(
mass() - other.mass())) <= prec
648 const Scalar eps = ::Eigen::NumTraits<Scalar>::epsilon();
652 const Vector3 & AB = (
lever() - Yb.lever()).eval();
654 mab, (
mass() *
lever() + Yb.mass() * Yb.lever()) * mab_inv,
656 - (
mass() * Yb.mass() * mab_inv) *
typename Symmetric3::SkewSquare(AB));
661 static const Scalar eps = ::Eigen::NumTraits<Scalar>::epsilon();
666 const Vector3 & AB = (Ya.lever() - Yb.lever()).eval();
668 lever() += (Yb.mass() * mab_inv) * Yb.lever();
670 inertia() -= (Ya.mass() * Yb.mass() * mab_inv) *
typename Symmetric3::SkewSquare(AB);
682 const Scalar eps = ::Eigen::NumTraits<Scalar>::epsilon();
685 assert(check_expression_if_real<Scalar>(ma >=
Scalar(0)));
688 const Vector3 c_a((
mass() *
lever() - Yb.mass() * Yb.lever()) * ma_inv);
690 const Vector3 AB = c_a - Yb.lever();
694 inertia() - Yb.inertia() + (ma * Yb.mass() /
mass()) *
typename Symmetric3::SkewSquare(AB));
699 static const Scalar eps = ::Eigen::NumTraits<Scalar>::epsilon();
702 assert(check_expression_if_real<Scalar>(ma >=
Scalar(0)));
707 lever().noalias() -= (Yb.mass() * ma_inv) * Yb.lever();
709 const Vector3 AB =
lever() - Yb.lever();
711 inertia() += (ma * Yb.mass() /
mass()) *
typename Symmetric3::SkewSquare(AB);
717 template<
typename MotionDerived>
728 template<
typename MotionDerived,
typename ForceDerived>
731 f.linear().noalias() =
mass() * (
v.linear() -
lever().cross(
v.angular()));
733 f.angular() +=
lever().cross(
f.linear());
737 template<
typename MotionDerived>
743 res +=
v.angular().dot(mcxcxw);
749 template<
typename MotionDerived>
755 res.template block<3, 3>(LINEAR, ANGULAR) =
757 res.template block<3, 3>(ANGULAR, LINEAR) =
758 res.template block<3, 3>(LINEAR, ANGULAR).transpose();
763 res.template block<3, 3>(ANGULAR, ANGULAR) =
766 res.template block<3, 3>(LINEAR, LINEAR) =
769 res.template block<3, 3>(ANGULAR, ANGULAR) -=
770 res.template block<3, 3>(LINEAR, LINEAR) *
skew(
v.angular());
771 res.template block<3, 3>(ANGULAR, ANGULAR) +=
772 cross(
v.angular(),
res.template block<3, 3>(LINEAR, LINEAR));
774 res.template block<3, 3>(LINEAR, LINEAR).setZero();
778 template<
typename MotionDerived,
typename M6>
782 const Eigen::MatrixBase<M6> & Iout)
784 EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(M6, 6, 6);
788 alphaSkew(I.mass(),
v.angular(), Iout_.template block<3, 3>(LINEAR, LINEAR));
790 const Vector3 mc(I.mass() * I.lever());
793 skewSquare(-
v.angular(), mc, Iout_.template block<3, 3>(LINEAR, ANGULAR));
796 alphaSkew(I.mass(),
v.linear(), Iout_.template block<3, 3>(ANGULAR, LINEAR));
797 Iout_.template block<3, 3>(ANGULAR, LINEAR) -= Iout_.template block<3, 3>(LINEAR, ANGULAR);
800 skewSquare(-
v.linear(), mc, Iout_.template block<3, 3>(ANGULAR, ANGULAR));
807 Symmetric3 mcxcx(
typename Symmetric3::AlphaSkewSquare(I.mass(), I.lever()));
808 Iout_.template block<3, 3>(ANGULAR, ANGULAR) += I.inertia().vxs(
v.angular());
809 Iout_.template block<3, 3>(ANGULAR, ANGULAR) -= mcxcx.
vxs(
v.angular());
812 template<
typename MotionDerived,
typename M6>
816 const Eigen::MatrixBase<M6> & Iout)
818 EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(M6, 6, 6);
822 alphaSkew(I.mass(),
v.angular(), Iout_.template block<3, 3>(LINEAR, LINEAR));
825 const Vector3 mc(I.mass() * I.lever());
826 skewSquare(mc,
v.angular(), Iout_.template block<3, 3>(ANGULAR, LINEAR));
829 alphaSkew(I.mass(),
v.linear(), Iout_.template block<3, 3>(LINEAR, ANGULAR));
833 -I.lever(), Iout_.template block<3, 3>(ANGULAR, LINEAR),
834 Iout_.template block<3, 3>(ANGULAR, ANGULAR));
835 Iout_.template block<3, 3>(ANGULAR, ANGULAR) += I.inertia().svx(
v.angular());
836 for (
int k = 0; k < 3; ++k)
837 Iout_.template block<3, 3>(ANGULAR, ANGULAR).col(k) +=
838 I.lever().cross(Iout_.template block<3, 3>(LINEAR, ANGULAR).col(k));
841 Iout_.template block<3, 3>(LINEAR, ANGULAR) -= Iout_.template block<3, 3>(ANGULAR, LINEAR);
872 template<
typename S2,
int O2>
883 template<
typename S2,
int O2>
887 mass(),
M.rotation().transpose() * (
lever() -
M.translation()),
891 template<
typename MotionDerived>
894 const Vector3 & mcxw =
mass() *
lever().cross(
v.angular());
895 const Vector3 & mv_mcxw =
mass() *
v.linear() - mcxw;
897 v.angular().cross(mv_mcxw),
899 -
v.linear().cross(mcxw));
904 os <<
" m = " <<
mass() <<
"\n"
905 <<
" c = " <<
lever().transpose() <<
"\n"
911 template<
typename NewScalar>
915 pinocchio::cast<NewScalar>(
mass()),
lever().
template cast<NewScalar>(),
916 inertia().
template cast<NewScalar>());
943 template<
typename _Scalar,
int _Options>
951 typedef Eigen::Matrix<Scalar, 4, 4, Options>
Matrix4;
952 typedef Eigen::Matrix<Scalar, 3, 1, Options>
Vector3;
953 typedef Eigen::Matrix<Scalar, 3, 3, Options>
Matrix3;
954 typedef Eigen::Matrix<Scalar, 10, 1, Options>
Vector10;
974 Matrix4 pseudo_inertia = Matrix4::Zero();
975 pseudo_inertia.template block<3, 3>(0, 0) =
sigma;
976 pseudo_inertia.template block<3, 1>(0, 3) =
h;
977 pseudo_inertia.template block<1, 3>(3, 0) =
h.transpose();
978 pseudo_inertia(3, 3) =
mass;
979 return pseudo_inertia;
990 Vector3 h = pseudo_inertia.template block<3, 1>(0, 3);
991 Matrix3 sigma = pseudo_inertia.template block<3, 3>(0, 0);
1000 template<
typename Vector10Like>
1006 Vector3 h = dynamic_params.template segment<3>(1);
1009 I_bar << dynamic_params[4], dynamic_params[5], dynamic_params[7],
1010 dynamic_params[5], dynamic_params[6], dynamic_params[8],
1011 dynamic_params[7], dynamic_params[8], dynamic_params[9];
1014 Matrix3 sigma = 0.5 * I_bar.trace() * Matrix3::Identity() - I_bar;
1027 dynamic_params[0] =
mass;
1028 dynamic_params.template segment<3>(1) =
h;
1029 dynamic_params[4] = I_bar(0, 0);
1030 dynamic_params[5] = I_bar(0, 1);
1031 dynamic_params[6] = I_bar(1, 1);
1032 dynamic_params[7] = I_bar(0, 2);
1033 dynamic_params[8] = I_bar(1, 2);
1034 dynamic_params[9] = I_bar(2, 2);
1036 return dynamic_params;
1072 template<
typename NewScalar>
1076 pinocchio::cast<NewScalar>(
mass),
h.template cast<NewScalar>(),
1077 sigma.template cast<NewScalar>());
1082 os <<
" m = " <<
mass <<
"\n"
1083 <<
" h = " <<
h.transpose() <<
"\n"
1102 template<
typename _Scalar,
int _Options>
1103 struct LogCholeskyParametersTpl
1110 typedef Eigen::Matrix<Scalar, 10, 1, Options>
Vector10;
1111 typedef Eigen::Matrix<Scalar, 10, 10, Options>
Matrix10;
1150 dynamic_params[0] = 1;
1151 dynamic_params[1] = t1;
1152 dynamic_params[2] =
t2;
1153 dynamic_params[3] = t3;
1154 dynamic_params[4] = pow(s23, 2) + pow(
t2, 2) + pow(t3, 2) + pow(exp_d2, 2) + pow(exp_d3, 2);
1155 dynamic_params[5] = -s12 * exp_d2 - s13 * s23 - t1 *
t2;
1156 dynamic_params[6] = pow(s12, 2) + pow(s13, 2) + pow(t1, 2) + pow(t3, 2) + pow(exp_d1, 2) + pow(exp_d3, 2);
1157 dynamic_params[7] = -s13 * exp_d3 - t1 * t3;
1158 dynamic_params[8] = -s23 * exp_d3 -
t2 * t3;
1159 dynamic_params[9] = pow(s12, 2) + pow(s13, 2) + pow(s23, 2) + pow(t1, 2) + pow(
t2, 2) + pow(exp_d1, 2) + pow(exp_d2, 2);
1162 dynamic_params *= exp_2_alpha;
1165 return dynamic_params;
1221 jacobian(1, 0) = 2 * t1 * exp_2alpha;
1227 jacobian(3, 0) = 2 * t3 * exp_2alpha;
1230 jacobian(4, 0) = 2 * (pow(s23, 2) + pow(
t2, 2) + pow(t3, 2) + exp_2d2 + exp_2d3) * exp_2alpha;
1231 jacobian(4, 2) = 2 * exp_2alpha * exp_2d2;
1232 jacobian(4, 3) = 2 * exp_2alpha * exp_2d3;
1233 jacobian(4, 5) = 2 * s23 * exp_2alpha;
1235 jacobian(4, 9) = 2 * t3 * exp_2alpha;
1237 jacobian(5, 0) = -2 * (s12 * exp_d2 + s13 * s23 + t1 *
t2) * exp_2alpha;
1238 jacobian(5, 2) = -s12 * exp_2alpha * exp_d2;
1239 jacobian(5, 4) = -exp_2alpha * exp_d2;
1240 jacobian(5, 5) = -s13 * exp_2alpha;
1241 jacobian(5, 6) = -s23 * exp_2alpha;
1245 jacobian(6, 0) = 2 * (pow(s12, 2) + pow(s13, 2) + pow(t1, 2) + pow(t3, 2) + exp_2d1 + exp_2d3) * exp_2alpha;
1246 jacobian(6, 1) = 2 * exp_2alpha * exp_2d1;
1247 jacobian(6, 3) = 2 * exp_2alpha * exp_2d3;
1248 jacobian(6, 4) = 2 * s12 * exp_2alpha;
1249 jacobian(6, 6) = 2 * s13 * exp_2alpha;
1250 jacobian(6, 7) = 2 * t1 * exp_2alpha;
1251 jacobian(6, 9) = 2 * t3 * exp_2alpha;
1253 jacobian(7, 0) = -2 * (s13 * exp_d3 + t1 * t3) * exp_2alpha;
1254 jacobian(7, 3) = -s13 * exp_2alpha * exp_d3;
1255 jacobian(7, 6) = -exp_2alpha * exp_d3;
1259 jacobian(8, 0) = -2 * (s23 * exp_d3 +
t2 * t3) * exp_2alpha;
1260 jacobian(8, 3) = -s23 * exp_2alpha * exp_d3;
1261 jacobian(8, 5) = -exp_2alpha * exp_d3;
1265 jacobian(9, 0) = 2 * (pow(s12, 2) + pow(s13, 2) + pow(s23, 2) + pow(t1, 2) + pow(
t2, 2) + exp_2d1 + exp_2d2) * exp_2alpha;
1266 jacobian(9, 1) = 2 * exp_2alpha * exp_2d1;
1267 jacobian(9, 2) = 2 * exp_2alpha * exp_2d2;
1268 jacobian(9, 4) = 2 * s12 * exp_2alpha;
1269 jacobian(9, 5) = 2 * s23 * exp_2alpha;
1270 jacobian(9, 6) = 2 * s13 * exp_2alpha;
1271 jacobian(9, 7) = 2 * t1 * exp_2alpha;
1279 template<
typename NewScalar>
1308 #endif // ifndef __pinocchio_spatial_inertia_hpp__