6 #ifndef __pinocchio_spatial_inertia_hpp__
7 #define __pinocchio_spatial_inertia_hpp__
17 template<
class Derived>
24 return *
static_cast<Derived *
>(
this);
28 return *
static_cast<const Derived *
>(
this);
33 return *
const_cast<Derived *
>(&
derived());
38 return static_cast<const Derived *
>(
this)->
mass();
42 return static_cast<const Derived *
>(
this)->
mass();
46 return static_cast<const Derived *
>(
this)->
lever();
50 return static_cast<const Derived *
>(
this)->
lever();
54 return static_cast<const Derived *
>(
this)->
inertia();
58 return static_cast<const Derived *
>(
this)->
inertia();
61 template<
typename Matrix6Like>
62 void matrix(
const Eigen::MatrixBase<Matrix6Like> & mat)
const
70 operator Matrix6()
const
75 template<
typename Matrix6Like>
76 void inverse(
const Eigen::MatrixBase<Matrix6Like> & mat)
const
82 return derived().inverse_impl();
91 return derived().isEqual(other);
95 return !(*
this == other);
112 return derived().__minus__(Yb);
115 template<
typename MotionDerived>
122 template<
typename MotionDerived>
128 template<
typename MotionDerived>
142 template<
typename MotionDerived,
typename M6>
146 EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(M6, Matrix6);
147 Derived::vxi_impl(
v, I, Iout);
150 template<
typename MotionDerived>
166 template<
typename MotionDerived,
typename M6>
170 EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(M6, Matrix6);
171 Derived::ivx_impl(
v, I, Iout);
174 template<
typename MotionDerived>
196 const Derived & other,
197 const Scalar & prec = Eigen::NumTraits<Scalar>::dummy_precision())
const
199 return derived().isApprox_impl(other, prec);
202 bool isZero(
const Scalar & prec = Eigen::NumTraits<Scalar>::dummy_precision())
const
204 return derived().isZero_impl(prec);
208 template<
typename S2,
int O2>
215 template<
typename S2,
int O2>
218 return derived().se3ActionInverse_impl(
M);
221 void disp(std::ostream & os)
const
223 static_cast<const Derived *
>(
this)->disp_impl(os);
233 template<
typename T,
int U>
263 template<
typename _Scalar,
int _Options>
264 struct InertiaTpl :
public InertiaBase<InertiaTpl<_Scalar, _Options>>
266 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
275 typedef Eigen::Matrix<Scalar, 10, 1, Options>
Vector10;
276 typedef Eigen::Matrix<Scalar, 10, 10, Options>
Matrix10;
294 assert(check_expression_if_real<Scalar>(
pinocchio::isZero(I6 - I6.transpose())));
295 mass() = I6(LINEAR, LINEAR);
296 const typename Matrix6::template ConstFixedBlockXpr<3, 3>::Type mc_cross =
297 I6.template block<3, 3>(ANGULAR, LINEAR);
301 Matrix3 I3(mc_cross * mc_cross);
303 I3 += I6.template block<3, 3>(ANGULAR, ANGULAR);
330 template<
typename S2,
int O2>
333 *
this =
clone.template cast<Scalar>();
441 const Scalar pi = boost::math::constants::pi<Scalar>();
448 const Scalar m_cyl =
mass * (v_cyl / total_v);
465 const Scalar ix = ix_c +
Scalar(2) * (ix_hs + m_hs * math::pow(dist_hc_cyl, 2));
479 template<
typename Matrix6Like>
482 Matrix6Like &
M = M_.const_cast_derived();
484 M.template block<3, 3>(LINEAR, LINEAR).setZero();
485 M.template block<3, 3>(LINEAR, LINEAR).diagonal().fill(
mass());
487 M.template block<3, 3>(LINEAR, ANGULAR) = -
M.template block<3, 3>(ANGULAR, LINEAR);
488 M.template block<3, 3>(ANGULAR, ANGULAR) =
499 template<
typename Matrix6Like>
502 Matrix6Like &
M = M_.const_cast_derived();
505 M.template block<3, 3>(LINEAR, ANGULAR).noalias() =
506 -
M.template block<3, 3>(ANGULAR, ANGULAR).colwise().cross(
lever());
507 M.template block<3, 3>(ANGULAR, LINEAR) =
M.template block<3, 3>(LINEAR, ANGULAR).transpose();
511 M.template block<3, 3>(LINEAR, LINEAR).col(0).noalias() =
512 cy *
M.template block<3, 3>(LINEAR, ANGULAR).col(2)
513 - cz *
M.template block<3, 3>(LINEAR, ANGULAR).col(1);
515 M.template block<3, 3>(LINEAR, LINEAR).col(1).noalias() =
516 cz *
M.template block<3, 3>(LINEAR, ANGULAR).col(0)
517 - cx *
M.template block<3, 3>(LINEAR, ANGULAR).col(2);
519 M.template block<3, 3>(LINEAR, LINEAR).col(2).noalias() =
520 cx *
M.template block<3, 3>(LINEAR, ANGULAR).col(1)
521 - cy *
M.template block<3, 3>(LINEAR, ANGULAR).col(0);
524 M.template block<3, 3>(LINEAR, LINEAR).diagonal().array() += m_inv;
546 v.template segment<3>(1).noalias() =
mass() *
lever();
560 template<
typename Vector10Like>
594 return pseudo_inertia;
622 return (
mass() == Y2.mass()) && (
lever() == Y2.lever()) && (
inertia() == Y2.inertia());
627 const Scalar & prec = Eigen::NumTraits<Scalar>::dummy_precision())
const
630 return fabs(
static_cast<Scalar>(
mass() - other.mass())) <= prec
647 const Scalar eps = ::Eigen::NumTraits<Scalar>::epsilon();
653 mab, (
mass() *
lever() + Yb.mass() * Yb.lever()) * mab_inv,
655 - (
mass() * Yb.mass() * mab_inv) *
typename Symmetric3::SkewSquare(AB));
660 static const Scalar eps = ::Eigen::NumTraits<Scalar>::epsilon();
665 const Vector3 & AB = (Ya.lever() - Yb.lever()).eval();
667 lever() += (Yb.mass() * mab_inv) * Yb.lever();
669 inertia() -= (Ya.mass() * Yb.mass() * mab_inv) *
typename Symmetric3::SkewSquare(AB);
681 const Scalar eps = ::Eigen::NumTraits<Scalar>::epsilon();
684 assert(check_expression_if_real<Scalar>(ma >=
Scalar(0)));
689 const Vector3 AB = c_a - Yb.lever();
693 inertia() - Yb.inertia() + (ma * Yb.mass() /
mass()) *
typename Symmetric3::SkewSquare(AB));
698 static const Scalar eps = ::Eigen::NumTraits<Scalar>::epsilon();
701 assert(check_expression_if_real<Scalar>(ma >=
Scalar(0)));
706 lever().noalias() -= (Yb.mass() * ma_inv) * Yb.lever();
710 inertia() += (ma * Yb.mass() /
mass()) *
typename Symmetric3::SkewSquare(AB);
716 template<
typename MotionDerived>
727 template<
typename MotionDerived,
typename ForceDerived>
730 f.linear().noalias() =
mass() * (
v.linear() -
lever().cross(
v.angular()));
732 f.angular() +=
lever().cross(
f.linear());
736 template<
typename MotionDerived>
742 res +=
v.angular().dot(mcxcxw);
748 template<
typename MotionDerived>
754 res.template block<3, 3>(LINEAR, ANGULAR) =
756 res.template block<3, 3>(ANGULAR, LINEAR) =
757 res.template block<3, 3>(LINEAR, ANGULAR).transpose();
762 res.template block<3, 3>(ANGULAR, ANGULAR) =
765 res.template block<3, 3>(LINEAR, LINEAR) =
768 res.template block<3, 3>(ANGULAR, ANGULAR) -=
769 res.template block<3, 3>(LINEAR, LINEAR) *
skew(
v.angular());
770 res.template block<3, 3>(ANGULAR, ANGULAR) +=
771 cross(
v.angular(),
res.template block<3, 3>(LINEAR, LINEAR));
773 res.template block<3, 3>(LINEAR, LINEAR).setZero();
777 template<
typename MotionDerived,
typename M6>
781 const Eigen::MatrixBase<M6> & Iout)
783 EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(M6, 6, 6);
787 alphaSkew(I.mass(),
v.angular(), Iout_.template block<3, 3>(LINEAR, LINEAR));
789 const Vector3 mc(I.mass() * I.lever());
792 skewSquare(-
v.angular(), mc, Iout_.template block<3, 3>(LINEAR, ANGULAR));
795 alphaSkew(I.mass(),
v.linear(), Iout_.template block<3, 3>(ANGULAR, LINEAR));
796 Iout_.template block<3, 3>(ANGULAR, LINEAR) -= Iout_.template block<3, 3>(LINEAR, ANGULAR);
799 skewSquare(-
v.linear(), mc, Iout_.template block<3, 3>(ANGULAR, ANGULAR));
806 Symmetric3 mcxcx(
typename Symmetric3::AlphaSkewSquare(I.mass(), I.lever()));
807 Iout_.template block<3, 3>(ANGULAR, ANGULAR) += I.inertia().vxs(
v.angular());
808 Iout_.template block<3, 3>(ANGULAR, ANGULAR) -= mcxcx.
vxs(
v.angular());
811 template<
typename MotionDerived,
typename M6>
815 const Eigen::MatrixBase<M6> & Iout)
817 EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(M6, 6, 6);
821 alphaSkew(I.mass(),
v.angular(), Iout_.template block<3, 3>(LINEAR, LINEAR));
824 const Vector3 mc(I.mass() * I.lever());
825 skewSquare(mc,
v.angular(), Iout_.template block<3, 3>(ANGULAR, LINEAR));
828 alphaSkew(I.mass(),
v.linear(), Iout_.template block<3, 3>(LINEAR, ANGULAR));
832 -I.lever(), Iout_.template block<3, 3>(ANGULAR, LINEAR),
833 Iout_.template block<3, 3>(ANGULAR, ANGULAR));
834 Iout_.template block<3, 3>(ANGULAR, ANGULAR) += I.inertia().svx(
v.angular());
835 for (
int k = 0; k < 3; ++k)
836 Iout_.template block<3, 3>(ANGULAR, ANGULAR).col(k) +=
837 I.lever().cross(Iout_.template block<3, 3>(LINEAR, ANGULAR).col(k));
840 Iout_.template block<3, 3>(LINEAR, ANGULAR) -= Iout_.template block<3, 3>(ANGULAR, LINEAR);
871 template<
typename S2,
int O2>
882 template<
typename S2,
int O2>
886 mass(),
M.rotation().transpose() * (
lever() -
M.translation()),
890 template<
typename MotionDerived>
896 v.angular().cross(mv_mcxw),
898 -
v.linear().cross(mcxw));
903 os <<
" m = " <<
mass() <<
"\n"
904 <<
" c = " <<
lever().transpose() <<
"\n"
910 template<
typename NewScalar>
914 pinocchio::cast<NewScalar>(
mass()),
lever().
template cast<NewScalar>(),
915 inertia().
template cast<NewScalar>());
942 template<
typename _Scalar,
int _Options>
950 typedef Eigen::Matrix<Scalar, 4, 4, Options>
Matrix4;
951 typedef Eigen::Matrix<Scalar, 3, 1, Options>
Vector3;
952 typedef Eigen::Matrix<Scalar, 3, 3, Options>
Matrix3;
953 typedef Eigen::Matrix<Scalar, 10, 1, Options>
Vector10;
973 Matrix4 pseudo_inertia = Matrix4::Zero();
974 pseudo_inertia.template block<3, 3>(0, 0) =
sigma;
975 pseudo_inertia.template block<3, 1>(0, 3) =
h;
976 pseudo_inertia.template block<1, 3>(3, 0) =
h.transpose();
977 pseudo_inertia(3, 3) =
mass;
978 return pseudo_inertia;
989 Vector3 h = pseudo_inertia.template block<3, 1>(0, 3);
990 Matrix3 sigma = pseudo_inertia.template block<3, 3>(0, 0);
999 template<
typename Vector10Like>
1005 Vector3 h = dynamic_params.template segment<3>(1);
1008 I_bar << dynamic_params[4], dynamic_params[5], dynamic_params[7],
1009 dynamic_params[5], dynamic_params[6], dynamic_params[8],
1010 dynamic_params[7], dynamic_params[8], dynamic_params[9];
1013 Matrix3 sigma = 0.5 * I_bar.trace() * Matrix3::Identity() - I_bar;
1026 dynamic_params[0] =
mass;
1027 dynamic_params.template segment<3>(1) =
h;
1028 dynamic_params[4] = I_bar(0, 0);
1029 dynamic_params[5] = I_bar(0, 1);
1030 dynamic_params[6] = I_bar(1, 1);
1031 dynamic_params[7] = I_bar(0, 2);
1032 dynamic_params[8] = I_bar(1, 2);
1033 dynamic_params[9] = I_bar(2, 2);
1035 return dynamic_params;
1071 template<
typename NewScalar>
1075 pinocchio::cast<NewScalar>(
mass),
h.template cast<NewScalar>(),
1076 sigma.template cast<NewScalar>());
1081 os <<
" m = " <<
mass <<
"\n"
1082 <<
" h = " <<
h.transpose() <<
"\n"
1101 template<
typename _Scalar,
int _Options>
1102 struct LogCholeskyParametersTpl
1109 typedef Eigen::Matrix<Scalar, 10, 1, Options>
Vector10;
1110 typedef Eigen::Matrix<Scalar, 10, 10, Options>
Matrix10;
1149 dynamic_params[0] = 1;
1150 dynamic_params[1] = t1;
1151 dynamic_params[2] =
t2;
1152 dynamic_params[3] = t3;
1153 dynamic_params[4] = pow(s23, 2) + pow(
t2, 2) + pow(t3, 2) + pow(exp_d2, 2) + pow(exp_d3, 2);
1154 dynamic_params[5] = -s12 * exp_d2 - s13 * s23 - t1 *
t2;
1155 dynamic_params[6] = pow(s12, 2) + pow(s13, 2) + pow(t1, 2) + pow(t3, 2) + pow(exp_d1, 2) + pow(exp_d3, 2);
1156 dynamic_params[7] = -s13 * exp_d3 - t1 * t3;
1157 dynamic_params[8] = -s23 * exp_d3 -
t2 * t3;
1158 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);
1161 dynamic_params *= exp_2_alpha;
1164 return dynamic_params;
1220 jacobian(1, 0) = 2 * t1 * exp_2alpha;
1226 jacobian(3, 0) = 2 * t3 * exp_2alpha;
1229 jacobian(4, 0) = 2 * (pow(s23, 2) + pow(
t2, 2) + pow(t3, 2) + exp_2d2 + exp_2d3) * exp_2alpha;
1230 jacobian(4, 2) = 2 * exp_2alpha * exp_2d2;
1231 jacobian(4, 3) = 2 * exp_2alpha * exp_2d3;
1232 jacobian(4, 5) = 2 * s23 * exp_2alpha;
1234 jacobian(4, 9) = 2 * t3 * exp_2alpha;
1236 jacobian(5, 0) = -2 * (s12 * exp_d2 + s13 * s23 + t1 *
t2) * exp_2alpha;
1237 jacobian(5, 2) = -s12 * exp_2alpha * exp_d2;
1238 jacobian(5, 4) = -exp_2alpha * exp_d2;
1239 jacobian(5, 5) = -s13 * exp_2alpha;
1240 jacobian(5, 6) = -s23 * exp_2alpha;
1244 jacobian(6, 0) = 2 * (pow(s12, 2) + pow(s13, 2) + pow(t1, 2) + pow(t3, 2) + exp_2d1 + exp_2d3) * exp_2alpha;
1245 jacobian(6, 1) = 2 * exp_2alpha * exp_2d1;
1246 jacobian(6, 3) = 2 * exp_2alpha * exp_2d3;
1247 jacobian(6, 4) = 2 * s12 * exp_2alpha;
1248 jacobian(6, 6) = 2 * s13 * exp_2alpha;
1249 jacobian(6, 7) = 2 * t1 * exp_2alpha;
1250 jacobian(6, 9) = 2 * t3 * exp_2alpha;
1252 jacobian(7, 0) = -2 * (s13 * exp_d3 + t1 * t3) * exp_2alpha;
1253 jacobian(7, 3) = -s13 * exp_2alpha * exp_d3;
1254 jacobian(7, 6) = -exp_2alpha * exp_d3;
1258 jacobian(8, 0) = -2 * (s23 * exp_d3 +
t2 * t3) * exp_2alpha;
1259 jacobian(8, 3) = -s23 * exp_2alpha * exp_d3;
1260 jacobian(8, 5) = -exp_2alpha * exp_d3;
1264 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;
1265 jacobian(9, 1) = 2 * exp_2alpha * exp_2d1;
1266 jacobian(9, 2) = 2 * exp_2alpha * exp_2d2;
1267 jacobian(9, 4) = 2 * s12 * exp_2alpha;
1268 jacobian(9, 5) = 2 * s23 * exp_2alpha;
1269 jacobian(9, 6) = 2 * s13 * exp_2alpha;
1270 jacobian(9, 7) = 2 * t1 * exp_2alpha;
1278 template<
typename NewScalar>
1307 #endif // ifndef __pinocchio_spatial_inertia_hpp__