pinocchio  UNKNOWN
se3.hpp
1 //
2 // Copyright (c) 2015-2016 CNRS
3 // Copyright (c) 2016 Wandercraft, 86 rue de Paris 91400 Orsay, France.
4 //
5 // This file is part of Pinocchio
6 // Pinocchio is free software: you can redistribute it
7 // and/or modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation, either version
9 // 3 of the License, or (at your option) any later version.
10 //
11 // Pinocchio is distributed in the hope that it will be
12 // useful, but WITHOUT ANY WARRANTY; without even the implied warranty
13 // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // General Lesser Public License for more details. You should have
15 // received a copy of the GNU Lesser General Public License along with
16 // Pinocchio If not, see
17 // <http://www.gnu.org/licenses/>.
18 
19 #ifndef __se3_se3_hpp__
20 #define __se3_se3_hpp__
21 
22 #include <Eigen/Geometry>
23 #include "pinocchio/spatial/fwd.hpp"
24 #include "pinocchio/spatial/skew.hpp"
25 #include "pinocchio/macros.hpp"
26 
27 namespace se3
28 {
29 
30  /* Type returned by the "se3Action" and "se3ActionInverse" functions. */
31  namespace internal
32  {
33  template<typename D>
34  struct SE3GroupAction { typedef D ReturnType; };
35  }
36 
49  template<class Derived>
50  class SE3Base
51  {
52  protected:
53 
54  typedef Derived Derived_t;
55  SPATIAL_TYPEDEF_TEMPLATE(Derived_t);
56 
57  public:
58  Derived_t & derived() { return *static_cast<Derived_t*>(this); }
59  const Derived_t& derived() const { return *static_cast<const Derived_t*>(this); }
60 
61  ConstAngular_t & rotation() const { return derived().rotation_impl(); }
62  ConstLinear_t & translation() const { return derived().translation_impl(); }
63  Angular_t & rotation() { return derived().rotation_impl(); }
64  Linear_t & translation() { return derived().translation_impl(); }
65  void rotation(const Angular_t & R) { derived().rotation_impl(R); }
66  void translation(const Linear_t & R) { derived().translation_impl(R); }
67 
68 
69  Matrix4 toHomogeneousMatrix() const
70  {
71  return derived().toHomogeneousMatrix_impl();
72  }
73  operator Matrix4() const { return toHomogeneousMatrix(); }
74 
75  Matrix6 toActionMatrix() const
76  {
77  return derived().toActionMatrix_impl();
78  }
79  operator Matrix6() const { return toActionMatrix(); }
80 
81  Matrix6 toDualActionMatrix() const { return derived().toDualActionMatrix_impl(); }
82 
83 
84 
85  void disp(std::ostream & os) const
86  {
87  static_cast<const Derived_t*>(this)->disp_impl(os);
88  }
89 
90  Derived_t operator*(const Derived_t & m2) const { return derived().__mult__(m2); }
91 
93  template<typename D>
94  typename internal::SE3GroupAction<D>::ReturnType act (const D & d) const
95  {
96  return derived().act_impl(d);
97  }
98 
100  template<typename D> typename internal::SE3GroupAction<D>::ReturnType actInv(const D & d) const
101  {
102  return derived().actInv_impl(d);
103  }
104 
105 
106  Derived_t act (const Derived_t& m2) const { return derived().act_impl(m2); }
107  Derived_t actInv(const Derived_t& m2) const { return derived().actInv_impl(m2); }
108 
109 
110  bool operator==(const Derived_t & other) const { return derived().__equal__(other); }
111  bool operator!=(const Derived_t & other) const { return !(*this == other); }
112 
113  bool isApprox (const Derived_t & other, const Scalar & prec = Eigen::NumTraits<Scalar>::dummy_precision()) const
114  {
115  return derived().isApprox_impl(other, prec);
116  }
117 
118  friend std::ostream & operator << (std::ostream & os,const SE3Base<Derived> & X)
119  {
120  X.disp(os);
121  return os;
122  }
123 
127  bool isIdentity(const typename traits<Derived>::Scalar & prec = Eigen::NumTraits<typename traits<Derived>::Scalar>::dummy_precision()) const
128  {
129  return derived().isIdentity(prec);
130  }
131 
132  }; // class SE3Base
133 
134 
135  template<typename T, int U>
136  struct traits< SE3Tpl<T, U> >
137  {
138  typedef T Scalar;
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 Matrix3 Angular_t;
146  typedef const Matrix3 ConstAngular_t;
147  typedef Vector3 Linear_t;
148  typedef const Vector3 ConstLinear_t;
149  typedef Matrix6 ActionMatrix_t;
150  typedef Eigen::Quaternion<T,U> Quaternion_t;
151  typedef SE3Tpl<T,U> SE3;
152  typedef ForceTpl<T,U> Force;
153  typedef MotionTpl<T,U> Motion;
155  enum {
156  LINEAR = 0,
157  ANGULAR = 3
158  };
159  }; // traits SE3Tpl
160 
161  template<typename _Scalar, int _Options>
162  class SE3Tpl : public SE3Base< SE3Tpl< _Scalar, _Options > >
163  {
164 
165  public:
166  friend class SE3Base< SE3Tpl< _Scalar, _Options > >;
167  SPATIAL_TYPEDEF_TEMPLATE(SE3Tpl);
168  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
169 
170 
171  SE3Tpl(): rot(), trans() {};
172 
173 
174  template<typename M3,typename v3>
175  SE3Tpl(const Eigen::MatrixBase<M3> & R, const Eigen::MatrixBase<v3> & p)
176  : rot(R), trans(p)
177  {
178  EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(v3,3)
179  EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(M3,3,3)
180  }
181 
182  template<typename M4>
183  explicit SE3Tpl(const Eigen::MatrixBase<M4> & m)
184  : rot(m.template block<3,3>(LINEAR,LINEAR)), trans(m.template block<3,1>(LINEAR,ANGULAR))
185  {
186  EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(M4,4,4);
187  }
188 
189  SE3Tpl(int) : rot(Matrix3::Identity()), trans(Vector3::Zero()) {}
190 
191  template<typename S2, int O2>
192  SE3Tpl( const SE3Tpl<S2,O2> & clone )
193  : rot(clone.rotation()),trans(clone.translation()) {}
194 
195 
196  template<typename S2, int O2>
197  SE3Tpl & operator= (const SE3Tpl<S2,O2> & other)
198  {
199  rot = other.rotation ();
200  trans = other.translation ();
201  return *this;
202  }
203 
204  static SE3Tpl Identity()
205  {
206  return SE3Tpl(1);
207  }
208 
209  SE3Tpl & setIdentity () { rot.setIdentity (); trans.setZero (); return *this;}
210 
212  SE3Tpl inverse() const
213  {
214  return SE3Tpl(rot.transpose(), -rot.transpose()*trans);
215  }
216 
217  static SE3Tpl Random()
218  {
219  Quaternion_t q(Vector4::Random());
220  q.normalize();
221  return SE3Tpl(q.matrix(),Vector3::Random());
222  }
223 
224  SE3Tpl & setRandom ()
225  {
226  Quaternion_t q(Vector4::Random());
227  q.normalize ();
228  rot = q.matrix ();
229  trans.setRandom ();
230 
231  return *this;
232  }
233 
234  Matrix4 toHomogeneousMatrix_impl() const
235  {
236  Matrix4 M;
237  M.template block<3,3>(LINEAR,LINEAR) = rot;
238  M.template block<3,1>(LINEAR,ANGULAR) = trans;
239  M.template block<1,3>(ANGULAR,LINEAR).setZero();
240  M(3,3) = 1;
241  return M;
242  }
243 
245  Matrix6 toActionMatrix_impl() const
246  {
247  typedef Eigen::Block<Matrix6,3,3> Block3;
248  Matrix6 M;
249  M.template block<3,3>(ANGULAR,ANGULAR)
250  = M.template block<3,3>(LINEAR,LINEAR) = rot;
251  M.template block<3,3>(ANGULAR,LINEAR).setZero();
252  Block3 B = M.template block<3,3>(LINEAR,ANGULAR);
253 
254  B.col(0) = trans.cross(rot.col(0));
255  B.col(1) = trans.cross(rot.col(1));
256  B.col(2) = trans.cross(rot.col(2));
257  return M;
258  }
259 
260  Matrix6 toDualActionMatrix_impl() const
261  {
262  typedef Eigen::Block<Matrix6,3,3> Block3;
263  Matrix6 M;
264  M.template block<3,3>(ANGULAR,ANGULAR)
265  = M.template block<3,3>(LINEAR,LINEAR) = rot;
266  M.template block<3,3>(LINEAR,ANGULAR).setZero();
267  Block3 B = M.template block<3,3>(ANGULAR,LINEAR);
268 
269  B.col(0) = trans.cross(rot.col(0));
270  B.col(1) = trans.cross(rot.col(1));
271  B.col(2) = trans.cross(rot.col(2));
272  return M;
273  }
274 
275  void disp_impl(std::ostream & os) const
276  {
277  os << " R =\n" << rot << std::endl
278  << " p = " << trans.transpose() << std::endl;
279  }
280 
282 
284  template<typename D>
285  typename internal::SE3GroupAction<D>::ReturnType act_impl (const D & d) const
286  {
287  return d.se3Action(*this);
288  }
290  template<typename D> typename internal::SE3GroupAction<D>::ReturnType actInv_impl(const D & d) const
291  {
292  return d.se3ActionInverse(*this);
293  }
294 
295  template<typename EigenDerived>
296  typename EigenDerived::PlainObject actOnEigenObject(const Eigen::MatrixBase<EigenDerived> & p) const
297  { return (rot*p+trans).eval(); }
298 
299  template<typename MapDerived>
300  Vector3 actOnEigenObject(const Eigen::MapBase<MapDerived> & p) const
301  { return Vector3(rot*p+trans); }
302 
303  template<typename EigenDerived>
304  typename EigenDerived::PlainObject actInvOnEigenObject(const Eigen::MatrixBase<EigenDerived> & p) const
305  { return (rot.transpose()*(p-trans)).eval(); }
306 
307  template<typename MapDerived>
308  Vector3 actInvOnEigenObject(const Eigen::MapBase<MapDerived> & p) const
309  { return Vector3(rot.transpose()*(p-trans)); }
310 
311  Vector3 act_impl (const Vector3& p) const { return Vector3(rot*p+trans); }
312  Vector3 actInv_impl(const Vector3& p) const { return Vector3(rot.transpose()*(p-trans)); }
313 
314  SE3Tpl act_impl (const SE3Tpl& m2) const { return SE3Tpl( rot*m2.rot,trans+rot*m2.trans);}
315  SE3Tpl actInv_impl (const SE3Tpl& m2) const { return SE3Tpl( rot.transpose()*m2.rot, rot.transpose()*(m2.trans-trans));}
316 
317 
318  SE3Tpl __mult__(const SE3Tpl & m2) const { return this->act(m2);}
319 
320  bool __equal__( const SE3Tpl & m2 ) const
321  {
322  return (rotation_impl() == m2.rotation() && translation_impl() == m2.translation());
323  }
324 
325  bool isApprox_impl (const SE3Tpl & m2, const Scalar & prec = Eigen::NumTraits<Scalar>::dummy_precision()) const
326  {
327  return rot.isApprox(m2.rot, prec) && trans.isApprox(m2.trans, prec);
328  }
329 
330  bool isIdentity(const Scalar & prec = Eigen::NumTraits<Scalar>::dummy_precision()) const
331  {
332  return rot.isIdentity(prec) && trans.isZero(prec);
333  }
334 
335  ConstAngular_t & rotation_impl() const { return rot; }
336  Angular_t & rotation_impl() { return rot; }
337  void rotation_impl(const Angular_t & R) { rot = R; }
338  ConstLinear_t & translation_impl() const { return trans;}
339  Linear_t & translation_impl() { return trans;}
340  void translation_impl(const Linear_t & p) { trans=p; }
341 
342  protected:
343  Angular_t rot;
344  Linear_t trans;
345 
346  }; // class SE3Tpl
347 
348 } // namespace se3
349 
350 #endif // ifndef __se3_se3_hpp__
351 
Matrix6 toActionMatrix_impl() const
Vb.toVector() = bXa.toMatrix() * Va.toVector()
Definition: se3.hpp:245
SE3Tpl inverse() const
aXb = bXa.inverse()
Definition: se3.hpp:212
bool isIdentity(const typename traits< Derived >::Scalar &prec=Eigen::NumTraits< typename traits< Derived >::Scalar >::dummy_precision()) const
Definition: se3.hpp:127
internal::SE3GroupAction< D >::ReturnType act_impl(const D &d) const
— GROUP ACTIONS ON M6, F6 and I6 —
Definition: se3.hpp:285
internal::SE3GroupAction< D >::ReturnType act(const D &d) const
ay = aXb.act(by)
Definition: se3.hpp:94
internal::SE3GroupAction< D >::ReturnType actInv(const D &d) const
by = aXb.actInv(ay)
Definition: se3.hpp:100
internal::SE3GroupAction< D >::ReturnType actInv_impl(const D &d) const
by = aXb.actInv(ay)
Definition: se3.hpp:290