19 #ifndef __se3_inertia_hpp__ 20 #define __se3_inertia_hpp__ 25 #include "pinocchio/spatial/symmetric3.hpp" 26 #include "pinocchio/spatial/force.hpp" 27 #include "pinocchio/spatial/motion.hpp" 28 #include "pinocchio/spatial/skew.hpp" 33 template<
class Derived>
38 typedef Derived Derived_t;
39 SPATIAL_TYPEDEF_TEMPLATE(Derived_t);
42 Derived_t & derived() {
return *
static_cast<Derived_t*
>(
this); }
43 const Derived_t & derived()
const {
return *
static_cast<const Derived_t*
>(
this); }
45 Scalar mass()
const {
return static_cast<const Derived_t*
>(
this)->mass(); }
46 Scalar & mass() {
return static_cast<const Derived_t*
>(
this)->mass(); }
47 const Vector3 & lever()
const {
return static_cast<const Derived_t*
>(
this)->lever(); }
48 Vector3 & lever() {
return static_cast<const Derived_t*
>(
this)->lever(); }
49 const Symmetric3 & inertia()
const {
return static_cast<const Derived_t*
>(
this)->inertia(); }
50 Symmetric3 & inertia() {
return static_cast<const Derived_t*
>(
this)->inertia(); }
52 Matrix6 matrix()
const {
return derived().matrix_impl(); }
53 operator Matrix6 ()
const {
return matrix(); }
55 Derived_t& operator= (
const Derived_t& clone){
return derived().__equl__(clone);}
56 bool operator==(
const Derived_t & other)
const {
return derived().isEqual(other);}
57 bool operator!=(
const Derived_t & other)
const {
return !(*
this == other); }
59 Derived_t& operator+= (
const Derived_t & Yb) {
return derived().__pequ__(Yb); }
60 Derived_t operator+(
const Derived_t & Yb)
const {
return derived().__plus__(Yb); }
62 template<
typename MotionDerived>
65 {
return derived().__mult__(v); }
67 Scalar vtiv(
const Motion & v)
const {
return derived().vtiv_impl(v); }
68 Matrix6 variation(
const Motion & v)
const {
return derived().variation_impl(v); }
78 static void vxi(
const Motion & v,
const Derived & I,
const Eigen::MatrixBase<M6> & Iout)
80 EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(M6, Matrix6);
81 Derived::vxi_impl(v,I,Iout);
87 vxi(v,derived(),Iout);
99 static void ivx(
const Motion & v,
const Derived & I,
const Eigen::MatrixBase<M6> & Iout)
101 EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(M6, Matrix6);
102 Derived::ivx_impl(v,I,Iout);
108 ivx(v,derived(),Iout);
112 void setZero() { derived().setZero(); }
113 void setIdentity() { derived().setIdentity(); }
114 void setRandom() { derived().setRandom(); }
116 bool isApprox (
const Derived & other,
const Scalar & prec = Eigen::NumTraits<Scalar>::dummy_precision())
const 117 {
return derived().isApprox_impl(other, prec); }
120 Derived_t
se3Action(
const SE3 & M)
const {
return derived().se3Action_impl(M); }
125 void disp(std::ostream & os)
const {
static_cast<const Derived_t*
>(
this)->disp_impl(os); }
126 friend std::ostream & operator << (std::ostream & os,const InertiaBase<Derived_t> & X)
135 template<
typename T,
int U>
139 typedef Eigen::Matrix<T,3,1,U> Vector3;
140 typedef Eigen::Matrix<T,4,1,U> Vector4;
141 typedef Eigen::Matrix<T,6,1,U> Vector6;
142 typedef Eigen::Matrix<T,3,3,U> Matrix3;
143 typedef Eigen::Matrix<T,4,4,U> Matrix4;
144 typedef Eigen::Matrix<T,6,6,U> Matrix6;
145 typedef Matrix6 ActionMatrix_t;
146 typedef Vector3 Angular_t;
147 typedef Vector3 Linear_t;
148 typedef const Vector3 ConstAngular_t;
149 typedef const Vector3 ConstLinear_t;
150 typedef Eigen::Quaternion<T,U> Quaternion_t;
161 template<
typename _Scalar,
int _Options>
165 friend class InertiaBase< InertiaTpl< _Scalar, _Options > >;
166 SPATIAL_TYPEDEF_TEMPLATE(InertiaTpl);
167 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
173 InertiaTpl() : m(), c(), I() {}
175 InertiaTpl(
const Scalar m_,
const Vector3 &c_,
const Matrix3 &I_)
176 : m(m_), c(c_), I(I_)
179 InertiaTpl(
const Matrix6 & I6)
181 assert((I6 - I6.transpose()).isMuchSmallerThan(I6));
182 m = I6(LINEAR, LINEAR);
183 const Matrix3 & mc_cross = I6.template block <3,3> (ANGULAR,LINEAR);
187 Matrix3 I3 (mc_cross * mc_cross);
189 I3 += I6.template block<3,3>(ANGULAR,ANGULAR);
193 InertiaTpl(Scalar _m,
202 InertiaTpl(
const InertiaTpl & clone)
210 template<
typename S2,
int O2>
214 I(clone.inertia().matrix())
220 static InertiaTpl Zero()
222 return InertiaTpl(0.,
227 void setZero() { m = 0.; c.setZero(); I.setZero(); }
229 static InertiaTpl Identity()
231 return InertiaTpl(1.,
233 Symmetric3::Identity());
236 void setIdentity () { m = 1.; c.setZero(); I.setIdentity(); }
238 static InertiaTpl Random()
241 return InertiaTpl(Eigen::internal::random<Scalar>()+1,
243 Symmetric3::RandomPositive());
246 static InertiaTpl FromEllipsoid(
247 const Scalar m,
const Scalar x,
const Scalar y,
const Scalar z)
249 Scalar a = m * (y*y + z*z) / 5;
250 Scalar b = m * (x*x + z*z) / 5;
251 Scalar c = m * (y*y + x*x) / 5;
252 return InertiaTpl(m, Vector3::Zero(),
Symmetric3(a, 0, b, 0, 0, c));
255 static InertiaTpl FromCylinder(
256 const Scalar m,
const Scalar r,
const Scalar l)
258 Scalar a = m * (r*r / 4 + l*l / 12);
259 Scalar c = m * (r*r / 2);
260 return InertiaTpl(m, Vector3::Zero(),
Symmetric3(a, 0, a, 0, 0, c));
263 static InertiaTpl FromBox(
264 const Scalar m,
const Scalar x,
const Scalar y,
const Scalar z)
266 Scalar a = m * (y*y + z*z) / 12;
267 Scalar b = m * (x*x + z*z) / 12;
268 Scalar c = m * (y*y + x*x) / 12;
269 return InertiaTpl(m, Vector3::Zero(),
Symmetric3(a, 0, b, 0, 0, c));
275 m =
static_cast<Scalar
> (std::rand()) / static_cast<Scalar> (RAND_MAX);
276 c.setRandom(); I.setRandom();
279 Matrix6 matrix_impl()
const 283 M.template block<3,3>(LINEAR, LINEAR ).setZero ();
284 M.template block<3,3>(LINEAR, LINEAR ).diagonal ().fill (m);
285 M.template block<3,3>(ANGULAR,LINEAR ) =
alphaSkew(m,c);
286 M.template block<3,3>(LINEAR, ANGULAR) = -M.template block<3,3> (ANGULAR, LINEAR);
287 M.template block<3,3>(ANGULAR,ANGULAR) = (I - AlphaSkewSquare(m,c)).matrix();
293 InertiaTpl& __equl__ (
const InertiaTpl& clone)
295 m=clone.m; c=clone.c; I=clone.I;
300 bool isEqual(
const InertiaTpl& Y2 )
const 302 return (m==Y2.m) && (c==Y2.c) && (I==Y2.I);
305 bool isApprox_impl(
const InertiaTpl & other,
const Scalar & prec = Eigen::NumTraits<Scalar>::dummy_precision())
const 308 return fabs(m - other.m) <= prec
309 && c.isApprox(other.c,prec)
310 && I.isApprox(other.I,prec);
313 InertiaTpl __plus__(
const InertiaTpl &Yb)
const 320 const double & mab = m+Yb.m;
321 const double mab_inv = 1./mab;
322 const Vector3 & AB = (c-Yb.c).eval();
323 return InertiaTpl( mab,
324 (m*c+Yb.m*Yb.c)*mab_inv,
328 InertiaTpl& __pequ__(
const InertiaTpl &Yb)
330 const InertiaTpl& Ya = *
this;
331 const double & mab = Ya.m+Yb.m;
332 const double mab_inv = 1./mab;
333 const Vector3 & AB = (Ya.c-Yb.c).eval();
334 c *= (m*mab_inv); c += (Yb.m*mab_inv)*Yb.c;
340 template<
typename MotionDerived>
350 template<
typename MotionDerived,
typename ForceDerived>
353 f.
linear() = m*(v.linear() - c.cross(v.angular()));
357 Scalar vtiv_impl(
const Motion & v)
const 359 const Vector3 cxw (c.cross(v.angular()));
360 Scalar res = m * (v.linear().squaredNorm() - 2.*v.linear().dot(cxw));
361 const Vector3 mcxcxw (-m*c.cross(cxw));
362 res += v.angular().dot(mcxcxw);
363 res += I.vtiv(v.angular());
368 Matrix6 variation(
const Motion & v)
const 373 res.template block<3,3>(LINEAR,ANGULAR) = -
skew(mv.linear()) -
skewSquare(mv.angular(),c) +
skewSquare(c,mv.angular());
374 res.template block<3,3>(ANGULAR,LINEAR) = res.template block<3,3>(LINEAR,ANGULAR).transpose();
378 res.template block<3,3>(ANGULAR,ANGULAR) = -
skewSquare(mv.linear(),c) -
skewSquare(c,mv.linear());
380 res.template block<3,3>(LINEAR,LINEAR) = (I - AlphaSkewSquare(m,c)).matrix();
382 res.template block<3,3>(ANGULAR,ANGULAR) -= res.template block<3,3>(LINEAR,LINEAR) *
skew(v.angular());
383 res.template block<3,3>(ANGULAR,ANGULAR) +=
cross(v.angular(),res.template block<3,3>(LINEAR,LINEAR));
385 res.template block<3,3>(LINEAR,LINEAR).setZero();
389 template<
typename M6>
390 static void vxi_impl(
const Motion & v,
const InertiaTpl & I,
const Eigen::MatrixBase<M6> & Iout)
392 EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(M6,6,6);
393 M6 & Iout_ =
const_cast<Eigen::MatrixBase<M6> &
>(Iout).derived();
396 alphaSkew(I.mass(),v.angular(),Iout_.template block<3,3>(LINEAR,LINEAR));
398 const Vector3 mc(I.mass()*I.lever());
401 skewSquare(-v.angular(),mc,Iout_.template block<3,3>(LINEAR,ANGULAR));
405 alphaSkew(I.mass(),v.linear(),Iout_.template block<3,3>(ANGULAR,LINEAR));
406 Iout_.template block<3,3>(ANGULAR,LINEAR) -= Iout_.template block<3,3>(LINEAR,ANGULAR);
409 skewSquare(-v.linear(),mc,Iout_.template block<3,3>(ANGULAR,ANGULAR));
417 Iout_.template block<3,3>(ANGULAR,ANGULAR) += I.inertia().
vxs(v.angular());
418 Iout_.template block<3,3>(ANGULAR,ANGULAR) -= mcxcx.
vxs(v.angular());
422 template<
typename M6>
423 static void ivx_impl(
const Motion & v,
const InertiaTpl & I,
const Eigen::MatrixBase<M6> & Iout)
425 EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(M6,6,6);
426 M6 & Iout_ =
const_cast<Eigen::MatrixBase<M6> &
>(Iout).derived();
429 alphaSkew(I.mass(),v.angular(),Iout_.template block<3,3>(LINEAR,LINEAR));
432 const Vector3 mc(I.mass()*I.lever());
433 skewSquare(mc,v.angular(),Iout_.template block<3,3>(ANGULAR,LINEAR));
436 alphaSkew(I.mass(),v.linear(),Iout_.template block<3,3>(LINEAR,ANGULAR));
439 cross(-I.lever(),Iout_.template block<3,3>(ANGULAR,LINEAR),Iout_.template block<3,3>(ANGULAR,ANGULAR));
440 Iout_.template block<3,3>(ANGULAR,ANGULAR) += I.inertia().
svx(v.angular());
441 for(
int k = 0; k < 3; ++k)
442 Iout_.template block<3,3>(ANGULAR,ANGULAR).col(k) += I.lever().cross(Iout_.template block<3,3>(LINEAR,ANGULAR).col(k));
445 Iout_.template block<3,3>(LINEAR,ANGULAR) -= Iout_.template block<3,3>(ANGULAR,LINEAR);
450 Scalar mass()
const {
return m; }
451 const Vector3 & lever()
const {
return c; }
452 const Symmetric3 & inertia()
const {
return I; }
454 Scalar & mass() {
return m; }
455 Vector3 & lever() {
return c; }
464 return InertiaTpl( m,
465 M.translation()+M.rotation()*c,
466 I.rotate(M.rotation()) );
473 M.rotation().transpose()*(c-M.translation()),
474 I.rotate(M.rotation().transpose()) );
479 const Vector3 & mcxw = m*c.cross(v.angular());
480 const Vector3 & mv_mcxw = m*v.linear()-mcxw;
481 return Force( v.angular().cross(mv_mcxw),
482 v.angular().cross(c.cross(mv_mcxw)+I*v.angular())-v.linear().cross(mcxw) );
485 void disp_impl(std::ostream & os)
const 487 os <<
" m = " << m <<
"\n" 488 <<
" c = " << c.transpose() <<
"\n" 489 <<
" I = \n" << I.matrix() <<
"";
501 #endif // ifndef __se3_inertia_hpp__ static void svx(const Eigen::MatrixBase< Vector3 > &v, const Symmetric3Tpl &S3, const Eigen::MatrixBase< Matrix3 > &M)
Performs the operation .
static void vxi(const Motion &v, const Derived &I, const Eigen::MatrixBase< M6 > &Iout)
Time variation operator. It computes the time derivative of an inertia I corresponding to the formula...
void skewSquare(const Eigen::MatrixBase< V1 > &u, const Eigen::MatrixBase< V2 > &v, const Eigen::MatrixBase< Matrix3 > &C)
Computes the square cross product linear operator C(u,v) such that for any vector w...
void alphaSkew(const Scalar alpha, const Eigen::MatrixBase< Vector3 > &v, const Eigen::MatrixBase< Matrix3 > &M)
Computes the skew representation of a given 3d vector multiplied by a given scalar. i.e. the antisymmetric matrix representation of the cross product operator ( )
ConstAngularType angular() const
Return the angular part of the force vector.
void skew(const Eigen::MatrixBase< Vector3 > &v, const Eigen::MatrixBase< Matrix3 > &M)
Computes the skew representation of a given 3d vector, i.e. the antisymmetric matrix representation o...
InertiaTpl se3Action_impl(const SE3 &M) const
aI = aXb.act(bI)
void unSkew(const Eigen::MatrixBase< Matrix3 > &M, const Eigen::MatrixBase< Vector3 > &v)
Inverse of skew operator. From a given skew-symmetric matrix M of dimension 3x3, it extracts the supp...
ConstLinearType linear() const
Return the linear part of the force vector.
InertiaTpl se3ActionInverse_impl(const SE3 &M) const
bI = aXb.actInv(aI)
static void vxs(const Eigen::MatrixBase< Vector3 > &v, const Symmetric3Tpl &S3, const Eigen::MatrixBase< Matrix3 > &M)
Performs the operation . This operation is equivalent to applying the cross product of v on each colu...
Derived_t se3ActionInverse(const SE3 &M) const
bI = aXb.actInv(aI)
static void ivx(const Motion &v, const Derived &I, const Eigen::MatrixBase< M6 > &Iout)
Time variation operator. It computes the time derivative of an inertia I corresponding to the formula...
void cross(const Eigen::MatrixBase< Vector3 > &v, const Eigen::MatrixBase< Matrix3xIn > &Min, const Eigen::MatrixBase< Matrix3xOut > &Mout)
Applies the cross product onto the columns of M.
Derived_t se3Action(const SE3 &M) const
aI = aXb.act(bI)