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); }
61 Force operator*(
const Motion & v)
const {
return derived().__mult__(v); }
63 Scalar vtiv(
const Motion & v)
const {
return derived().vtiv_impl(v); }
64 Matrix6 variation(
const Motion & v)
const {
return derived().variation_impl(v); }
66 void setZero() { derived().setZero(); }
67 void setIdentity() { derived().setIdentity(); }
68 void setRandom() { derived().setRandom(); }
70 bool isApprox (
const Derived & other,
const Scalar & prec = Eigen::NumTraits<Scalar>::dummy_precision())
const 71 {
return derived().isApprox_impl(other, prec); }
74 Derived_t
se3Action(
const SE3 & M)
const {
return derived().se3Action_impl(M); }
79 void disp(std::ostream & os)
const {
static_cast<const Derived_t*
>(
this)->disp_impl(os); }
80 friend std::ostream & operator << (std::ostream & os,const InertiaBase<Derived_t> & X)
89 template<
typename T,
int U>
93 typedef Eigen::Matrix<T,3,1,U> Vector3;
94 typedef Eigen::Matrix<T,4,1,U> Vector4;
95 typedef Eigen::Matrix<T,6,1,U> Vector6;
96 typedef Eigen::Matrix<T,3,3,U> Matrix3;
97 typedef Eigen::Matrix<T,4,4,U> Matrix4;
98 typedef Eigen::Matrix<T,6,6,U> Matrix6;
99 typedef Matrix6 ActionMatrix_t;
100 typedef Vector3 Angular_t;
101 typedef Vector3 Linear_t;
102 typedef const Vector3 ConstAngular_t;
103 typedef const Vector3 ConstLinear_t;
104 typedef Eigen::Quaternion<T,U> Quaternion_t;
115 template<
typename _Scalar,
int _Options>
119 friend class InertiaBase< InertiaTpl< _Scalar, _Options > >;
120 SPATIAL_TYPEDEF_TEMPLATE(InertiaTpl);
121 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
127 InertiaTpl() : m(), c(), I() {}
129 InertiaTpl(
const Scalar m_,
const Vector3 &c_,
const Matrix3 &I_)
130 : m(m_), c(c_), I(I_)
133 InertiaTpl(
const Matrix6 & I6)
135 assert((I6 - I6.transpose()).isMuchSmallerThan(I6));
136 m = I6(LINEAR, LINEAR);
137 const Matrix3 & mc_cross = I6.template block <3,3> (ANGULAR,LINEAR);
138 c = unSkew(mc_cross);
141 Matrix3 I3 (mc_cross * mc_cross);
143 I3 += I6.template block<3,3>(ANGULAR,ANGULAR);
147 InertiaTpl(Scalar _m,
156 InertiaTpl(
const InertiaTpl & clone)
164 template<
typename S2,
int O2>
168 I(clone.inertia().matrix())
174 static InertiaTpl Zero()
176 return InertiaTpl(0.,
181 void setZero() { m = 0.; c.setZero(); I.setZero(); }
183 static InertiaTpl Identity()
185 return InertiaTpl(1.,
187 Symmetric3::Identity());
190 void setIdentity () { m = 1.; c.setZero(); I.setIdentity(); }
192 static InertiaTpl Random()
195 return InertiaTpl(Eigen::internal::random<Scalar>()+1,
197 Symmetric3::RandomPositive());
200 static InertiaTpl FromEllipsoid(
201 const Scalar m,
const Scalar x,
const Scalar y,
const Scalar z)
203 Scalar a = m * (y*y + z*z) / 5;
204 Scalar b = m * (x*x + z*z) / 5;
205 Scalar c = m * (y*y + x*x) / 5;
206 return InertiaTpl(m, Vector3::Zero(),
Symmetric3(a, 0, b, 0, 0, c));
209 static InertiaTpl FromCylinder(
210 const Scalar m,
const Scalar r,
const Scalar l)
212 Scalar a = m * (r*r / 4 + l*l / 12);
213 Scalar c = m * (r*r / 2);
214 return InertiaTpl(m, Vector3::Zero(),
Symmetric3(a, 0, a, 0, 0, c));
217 static InertiaTpl FromBox(
218 const Scalar m,
const Scalar x,
const Scalar y,
const Scalar z)
220 Scalar a = m * (y*y + z*z) / 12;
221 Scalar b = m * (x*x + z*z) / 12;
222 Scalar c = m * (y*y + x*x) / 12;
223 return InertiaTpl(m, Vector3::Zero(),
Symmetric3(a, 0, b, 0, 0, c));
229 m =
static_cast<Scalar
> (std::rand()) / static_cast<Scalar> (RAND_MAX);
230 c.setRandom(); I.setRandom();
233 Matrix6 matrix_impl()
const 237 M.template block<3,3>(LINEAR, LINEAR ).setZero ();
238 M.template block<3,3>(LINEAR, LINEAR ).diagonal ().fill (m);
239 M.template block<3,3>(ANGULAR,LINEAR ) = alphaSkew(m,c);
240 M.template block<3,3>(LINEAR, ANGULAR) = -M.template block<3,3> (ANGULAR, LINEAR);
241 M.template block<3,3>(ANGULAR,ANGULAR) = (I - AlphaSkewSquare(m,c)).matrix();
247 InertiaTpl& __equl__ (
const InertiaTpl& clone)
249 m=clone.m; c=clone.c; I=clone.I;
254 bool isEqual(
const InertiaTpl& Y2 )
const 256 return (m==Y2.m) && (c==Y2.c) && (I==Y2.I);
259 bool isApprox_impl(
const InertiaTpl & other,
const Scalar & prec = Eigen::NumTraits<Scalar>::dummy_precision())
const 262 return fabs(m - other.m) <= prec
263 && c.isApprox(other.c,prec)
264 && I.isApprox(other.I,prec);
267 InertiaTpl __plus__(
const InertiaTpl &Yb)
const 274 const double & mab = m+Yb.m;
275 const Vector3 & AB = (c-Yb.c).eval();
276 return InertiaTpl( mab,
281 InertiaTpl& __pequ__(
const InertiaTpl &Yb)
283 const InertiaTpl& Ya = *
this;
284 const double & mab = Ya.m+Yb.m;
285 const Vector3 & AB = (Ya.c-Yb.c).eval();
286 c *= m; c += Yb.m*Yb.c; c /= mab;
295 f.
linear() = m*(v.linear() - c.cross(v.angular()));
300 Scalar vtiv_impl(
const Motion & v)
const 302 const Vector3 cxw (c.cross(v.angular()));
303 Scalar res = m * (v.linear().squaredNorm() - 2.*v.linear().dot(cxw));
304 const Vector3 mcxcxw (-m*c.cross(cxw));
305 res += v.angular().dot(mcxcxw);
306 res += I.vtiv(v.angular());
311 Matrix6 variation(
const Motion & v)
const 316 res.template block<3,3>(LINEAR,ANGULAR) = -skew(mv.linear()) - skewSquare(mv.angular(),c) + skewSquare(c,mv.angular());
317 res.template block<3,3>(ANGULAR,LINEAR) = res.template block<3,3>(LINEAR,ANGULAR).transpose();
319 res.template block<3,3>(LINEAR,LINEAR) = mv.linear()*c.transpose();
320 res.template block<3,3>(ANGULAR,ANGULAR) = res.template block<3,3>(LINEAR,LINEAR) - res.template block<3,3>(LINEAR,LINEAR).transpose();
321 res.template block<3,3>(ANGULAR,ANGULAR) = -skewSquare(mv.linear(),c) - skewSquare(c,mv.linear());
323 res.template block<3,3>(LINEAR,LINEAR) = (I - AlphaSkewSquare(m,c)).matrix();
325 res.template block<3,3>(ANGULAR,ANGULAR) -= res.template block<3,3>(LINEAR,LINEAR) * skew(v.angular());
326 res.template block<3,3>(ANGULAR,ANGULAR) += cross(v.angular(),res.template block<3,3>(LINEAR,LINEAR));
328 res.template block<3,3>(LINEAR,LINEAR).setZero();
333 Scalar mass()
const {
return m; }
334 const Vector3 & lever()
const {
return c; }
335 const Symmetric3 & inertia()
const {
return I; }
337 Scalar & mass() {
return m; }
338 Vector3 & lever() {
return c; }
347 return InertiaTpl( m,
348 M.translation()+M.rotation()*c,
349 I.rotate(M.rotation()) );
356 M.rotation().transpose()*(c-M.translation()),
357 I.rotate(M.rotation().transpose()) );
362 const Vector3 & mcxw = m*c.cross(v.angular());
363 const Vector3 & mv_mcxw = m*v.linear()-mcxw;
364 return Force( v.angular().cross(mv_mcxw),
365 v.angular().cross(c.cross(mv_mcxw)+I*v.angular())-v.linear().cross(mcxw) );
368 void disp_impl(std::ostream & os)
const 370 os <<
" m = " << m <<
"\n" 371 <<
" c = " << c.transpose() <<
"\n" 372 <<
" I = \n" << I.matrix() <<
"";
384 #endif // ifndef __se3_inertia_hpp__
Concreate Class representing a force.
InertiaTpl se3Action_impl(const SE3 &M) const
aI = aXb.act(bI)
ConstAngular_t angular() const
Return the angular part of the force vector.
InertiaTpl se3ActionInverse_impl(const SE3 &M) const
bI = aXb.actInv(aI)
Derived_t se3ActionInverse(const SE3 &M) const
bI = aXb.actInv(aI)
ConstLinear_t linear() const
Return the linear part of the force vector.
Derived_t se3Action(const SE3 &M) const
aI = aXb.act(bI)