LieGroup_SE3.h
Go to the documentation of this file.
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2009-2013 CEA LIST (DIASI/LSI) <xde-support@saxifrage.cea.fr>
5 //
6 // This Source Code Form is subject to the terms of the Mozilla
7 // Public License v. 2.0. If a copy of the MPL was not distributed
8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 
10 #ifndef EIGEN_LGSM_LIE_SE3_H
11 #define EIGEN_LGSM_LIE_SE3_H
12 
13 namespace internal {
14 template<typename Other,
15  int OtherRows=Other::RowsAtCompileTime,
16  int OtherCols=Other::ColsAtCompileTime>
18 }
19 
20 /*******************************************************************************
21 * Definition/implementation of LieGroupBase<Array<Scalar, 7, 1, Derived>
22 ********************************************************************************/
23 
36 template<class Derived>
37 class LieGroupBase<Array<typename internal::traits<Derived>::Scalar, 7, 1>, Derived>
38 {
39 public:
40  /* List of typedef */
42  typedef typename internal::traits<Derived>::Scalar Scalar;
44  typedef Array<Scalar, 7, 1> BaseType;
46  typedef typename internal::traits<Derived>::Coefficients Coefficients;
48  typedef typename internal::traits<Derived>::PlainObject PlainObject;
49 
51  typedef Matrix<Scalar, 6, 6> AdjointMatrix;
56 
58  typedef Matrix<Scalar, 3, 1> Vector3;
60  typedef LieGroup<Quaternion<Scalar> > SO3Element; // an element of SO(3)
61 
63  EIGEN_STRONG_INLINE PlainObject inverse() const;
65  static PlainObject Identity();
67  template<class OtherDerived> inline PlainObject operator*(const LieGroupBase<BaseType, OtherDerived>& other) const;
69  template<class OtherDerived> EIGEN_STRONG_INLINE Derived& operator*=(const LieGroupBase<BaseType, OtherDerived>& other);
71  template<class OtherDerived> inline Vector3 operator*(const MatrixBase<OtherDerived>& d) const;
72 
74  AdjointMatrix adjoint(void) const;
76  template<class AlgebraDerived> inline Algebra adjoint(const LieAlgebraBase<Matrix<Scalar, 6, 1>, AlgebraDerived>& ) const;
78  template<class AlgebraDualDerived> inline AlgebraDual adjointTr(const LieAlgebraDualBase<Matrix<Scalar, 6, 1>, AlgebraDualDerived>& ) const;
79 
83  inline Algebra log(const Scalar precision = 1e-6) const;
84 
86  EIGEN_STRONG_INLINE LieGroupBase& operator=(const LieGroupBase& other);
88  template<class OtherDerived> EIGEN_STRONG_INLINE Derived& operator=(const LieGroupBase<BaseType, OtherDerived>& other);
90  template<class OtherDerived> Derived& operator=(const MatrixBase<OtherDerived>& m);
91 
93  inline const Derived& derived() const { return *static_cast<const Derived*>(this); }
95  inline Derived& derived() { return *static_cast<Derived*>(this); }
96 
98  inline Map<SO3Element> getSO3Element(){ return Map<SO3Element>(this->derived().get().template head<4>().data()); }
100  inline Map<const SO3Element> getSO3Element() const{ return Map<const SO3Element>(this->derived().get().template head<4>().data()); }
102  // a map is prefered to a VectorBlock, because the underlying data is an array and not a matrix
103  inline Map<Vector3> getR3Element(){ return Map<Vector3>(this->get().template tail<3>().data()); }
105  inline Map<const Vector3> getR3Element() const { return Map<const Vector3>(this->get().template tail<3>().data()); }
106 
108  Coefficients& get() { return derived().get(); }
110  const Coefficients& get() const { return derived().get(); }
111 
113  template<class OtherDerived>
114  friend std::ostream& operator <<(std::ostream& os, const LieGroupBase<Array<typename internal::traits<Derived>::Scalar, 7, 1>, Derived>& g);
115 };
116 
117 /***************************************************************
118  * Implementation of LieGroupBase<Array<Scalar, 7, 1> > methods
119  ***************************************************************/
120 
121 // assignation
122 template<class Derived>
125 {
126  this->get() = other.get();
127  return *this;
128 }
129 
130 template<class Derived>
131 template<class OtherDerived>
132 inline Derived&
134 {
135  this->get() = other.get();
136  return derived();
137 }
138 
139 template<class Derived>
140 template<class MatrixDerived>
141 inline Derived&
142  LieGroupBase<Array<typename internal::traits<Derived>::Scalar, 7, 1 >, Derived>::operator=(const MatrixBase<MatrixDerived>& xpr)
143  {
144  EIGEN_STATIC_ASSERT((internal::is_same<typename Derived::Scalar, typename MatrixDerived::Scalar>::value),
145  YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
146 
148 
149  return derived();
150  }
151 // inverse
152 template<class Derived>
155 {
156  return PlainObject(-(this->getSO3Element().inverse().operator*(this->getR3Element())) // -rot^-1*trans
157  , this->getSO3Element().inverse()); // rot^-1
158 }
159 
160 // identity
161 template<class Derived>
164 {
165  return PlainObject(Vector3(0,0,0), SO3Element::Identity());
166 }
167 
168 // composition
169 //
170 // [ R1 p1 ] * [ R2 p2 ] = [ (R1*p2 + p1) (R1*R2) ]
171 //
172 template<class Derived>
173 template<class OtherDerived> EIGEN_STRONG_INLINE
175  LieGroupBase<Array<typename internal::traits<Derived>::Scalar, 7, 1 >, Derived>::operator*(const LieGroupBase<Array<Scalar, 7, 1 >, OtherDerived>& other) const
176 {
177  return PlainObject(this->getSO3Element() * other.getR3Element() + this->getR3Element() // rot1 * trans2 + trans1
178  , this->getSO3Element() * other.getSO3Element()); // rot1 * rot2
179 }
180 
181 
182 template<class Derived>
183 template<class OtherDerived> EIGEN_STRONG_INLINE
184  Derived&
186 
187  this->getR3Element() = this->getSO3Element() * other.getR3Element() + this->getR3Element();
188  this->getSO3Element() *= other.getSO3Element();
189 
190  return derived();
191 }
192 
193 // composition
194 // [ R1 p1 ] * [ p2 ] = [ R1*p2 + p1 ]
195 //
196 template<class Derived>
197 template<class OtherDerived> EIGEN_STRONG_INLINE
199  LieGroupBase<Array<typename internal::traits<Derived>::Scalar, 7, 1 >, Derived>::operator*(const MatrixBase<OtherDerived>& vec) const
200 {
201  return Vector3(this->getSO3Element() * vec + this->getR3Element());
202 }
203 
204 // log
205 template<class Derived>
207  LieGroupBase<Array<typename internal::traits<Derived>::Scalar, 7, 1 >, Derived>::log(const Scalar precision) const
208 {
209  typename SO3Element::Algebra ang = this->getSO3Element().log(precision);
210 
211  const Scalar n2 = ang.squaredNorm(); // ||wtidle||^2
212 
213  if(n2 < precision)
214  return Algebra(ang, this->getR3Element());
215  else{
216 
217  const Scalar n = std::sqrt(n2);
218 
219 #ifndef USE_RLAB_LOG_FUNCTION //Set in Lgsm file
220  const Scalar sn = std::sin(n);
221 
222  Scalar val = (Scalar(2.0) * sn - n * (Scalar(1.0) + std::cos(n))) / (Scalar(2.0) *n2 * sn);
223 
224  Vector3 lin = -0.5*ang.cross(this->getR3Element());
225  lin += (Scalar(1.0) - val * n2 ) * this->getR3Element();
226  lin += val * ang.dot(this->getR3Element()) * ang;
227 
228  return Algebra(ang, lin);
229 
230 #else
231  // The previous code is unstable when the norm of the rotation gets close to pi
232  // because we divide by sn=sin(n) that is close to zero to obtain val
233  // We replace that code with code from RLab -> they work with the norm/2, sin(norm/2) and cos(norm/2)/sin(norm/2)
234  // and given that norm is between pi and -pi, sin(norm/2) is not going to be close to zero
235  // (see HTransform.cpp, Vector3D.cpp and Rotation.cpp from RLab)
236  const Scalar n_div2 = n/2.0;
237  const Scalar s = std::sin(n_div2) / n_div2;
238  const Scalar c = std::cos(n_div2);
239  const Scalar gamma = c / s;
240 
241  Eigen::Matrix<double, 3, 3> dexpinv = Eigen::Matrix<double, 3, 3>::Identity();
242 
243  double v1 = ang[0];
244  double v2 = ang[1];
245  double v3 = ang[2];
246 
247  Eigen::Matrix<double, 3, 3> w_ceil = Eigen::Matrix<double, 3, 3>::Zero();
248  w_ceil(0, 1) = -v3;
249  w_ceil(0, 2) = v2;
250  w_ceil(1, 0) = v3;
251  w_ceil(1, 2) = -v1;
252  w_ceil(2, 0) = -v2;
253  w_ceil(2, 1) = v1;
254 
255  Eigen::Matrix<double, 3, 3> w_ceil_sqr = Eigen::Matrix<double, 3, 3>::Zero();
256  double v1sqr = v1 * v1;
257  double v2sqr = v2 * v2;
258  double v3sqr = v3 * v3;
259  double v12 = v1 * v2;
260  double v13 = v1 * v3;
261  double v23 = v2 * v3;
262 
263  w_ceil_sqr(0, 0) = -v2sqr - v3sqr;
264  w_ceil_sqr(0, 1) = v12;
265  w_ceil_sqr(0, 2) = v13;
266  w_ceil_sqr(1, 0) = v12;
267  w_ceil_sqr(1, 1) = -v1sqr - v3sqr;
268  w_ceil_sqr(1, 2) = v23;
269  w_ceil_sqr(2, 0) = v13;
270  w_ceil_sqr(2, 1) = v23;
271  w_ceil_sqr(2, 2) = -v1sqr - v2sqr;
272 
273  dexpinv += -0.5 * w_ceil + (1 - gamma) / n2 * w_ceil_sqr;
274 
275  Vector3 lin = dexpinv*this->getR3Element();
276 
277  return Algebra(ang, lin);
278 #endif
279  }
280 }
281 
282 
283 //RLab code
284 //dMatrix dexpinv;
285 //dExpInv_SO3(xi.w, dexpinv);
286 //xi.v = dexpinv*r;
287 
288 //void dExpInv_SO3(const Vector3D& w, dMatrix& dexpinv)
289 //{
290 // double wnorm = w.Norm();
291 
292 // dexpinv.resize(3, 3);
293 // dexpinv.identity();
294 
295 // if (wnorm > RMATH_ZERO)
296 // {
297 // double half_wnorm = wnorm / 2;
298 // double s = sin(half_wnorm) / half_wnorm;
299 // double c = cos(half_wnorm);
300 
301 // double gamma = c / s;
302 // double wnorm_sqr = wnorm * wnorm;
303 
304 // //dMatrix temp1 = -0.5*w.Ceil(); temp1.print("-1/2*w.Ceil()");
305 // //dMatrix temp2 = (1 - gamma)/wnorm_sqr*w.CeilSqr(); temp2.print("(1 - gamma)/wnorm_sqr*w.CeilSqr()");
306 
307 // dexpinv += -0.5 * w.Ceil() + (1 - gamma) / wnorm_sqr * w.CeilSqr();
308 // }
309 //}
310 
311 // adjoint
312 //
313 // Ad_H = [ R 0 ]
314 // [ ptilde*R R ]
315 //
316 template<class Derived>
319 {
320  AdjointMatrix res;
321 
322  res.template block<3,3>(0,0) = this->getSO3Element().adjoint();
323  res.template block<3,3>(3,3) = res.template block<3,3>(0,0);
324 
325 
326  res.template block<3,3>(3,0) = (Matrix<Scalar,3,3>() <<
327  0, -this->getR3Element()[2], this->getR3Element()[1], // 0 -z y
328  this->getR3Element()[2], 0, -this->getR3Element()[0], // z 0 -x
329  -this->getR3Element()[1], this->getR3Element()[0], 0) //-y x 0
330  .finished()*res.template block<3,3>(0,0);
331 
332  (res.template block<3,3>(0,3)).setZero();
333 
334  return res;
335 }
336 
337 //
338 // Ad_H * T = [ R 0 ] * [ w ] = [ R*w ]
339 // [ ptilde*R R ] [ v ] [ (p^R*w)+R*v ]
340 //
341 template<class Derived>
342 template<class AlgebraDerived>
344  LieGroupBase<Array<typename internal::traits<Derived>::Scalar, 7, 1 >, Derived>::adjoint(const LieAlgebraBase<Matrix<Scalar, 6, 1>, AlgebraDerived>& a) const
345 {
346  Vector3 Rw = this->getSO3Element() * a.getso3Element(); // R*w
347 
348  typename SO3Element::Algebra ang(Rw);
349  Vector3 lin = this->getR3Element().cross(Rw) + this->getSO3Element() * a.getR3Element(); // (p^R*w)+R*v
350 
351  return Algebra(ang, lin);
352 }
353 
354 //
355 // (Ad_H)' * W = [ R' -R'*ptilde ] * [ t ] = [ R'*(f^p+t) ]
356 // [ 0 R' ] [ f ] [ R'*f ]
357 //
358 template<class Derived>
359 template<class AlgebraDualDerived>
361  LieGroupBase<Array<typename internal::traits<Derived>::Scalar, 7, 1 >, Derived>::adjointTr(const LieAlgebraDualBase<Matrix<Scalar, 6, 1>, AlgebraDualDerived>& ca) const
362 {
363  return AlgebraDual(this->getSO3Element().inverse() * (ca.getR3Element().cross(this->getR3Element() ) + ca.getso3Element()), // R'*(f^p+t)
364  this->getSO3Element().inverse() * ca.getR3Element()); // R'*f
365 }
366 
367 /***************************************************************************
368 * Definition/implementation of LieGroup<Array<Scalar, 7, 1> >
369 ***************************************************************************/
370 
383 template<typename _Scalar> class LieGroup<Array<_Scalar, 7, 1> > :
384  public LieGroupBase<Array<_Scalar, 7, 1>, LieGroup<Array<_Scalar, 7, 1> > >
385 {
386 protected:
389 public:
391  typedef _Scalar Scalar;
393  typedef typename internal::traits<LieGroup<Array<_Scalar, 7, 1> > >::Coefficients Coefficients;
394  // inherit assignement operator
395  EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(LieGroup)
396 
397 
398  inline LieGroup() : m_coeffs() {}
400  inline LieGroup(const LieGroup& g) : m_coeffs(g.get() ) {}
402  inline LieGroup(const Array<Scalar, 7, 1>& g) : m_coeffs(g) {}
403 
410  inline LieGroup(Scalar x, Scalar y, Scalar z, Scalar qw, Scalar qx, Scalar qy, Scalar qz) {
411  // m_coeffs << qx, qy, qz, qw, x, y, z // operator<< is not inlined
412  m_coeffs[0] = qx;
413  m_coeffs[1] = qy;
414  m_coeffs[2] = qz;
415  m_coeffs[3] = qw;
416  m_coeffs[4] = x;
417  m_coeffs[5] = y;
418  m_coeffs[6] = z;
419  }
421  EIGEN_STRONG_INLINE LieGroup(const typename Base::Vector3& v, const typename Base::SO3Element& r) {
422  this->getR3Element() = v;
423  this->getSO3Element() = r;
424  }
425  template<typename Derived>
426  explicit inline LieGroup(const MatrixBase<Derived>& other) { this = other;}
427 
429  Coefficients& get() { return m_coeffs; }
431  const Coefficients& get() const { return m_coeffs; }
432 
433 protected:
435  Coefficients m_coeffs;
436 };
437 
438 // set from a rotation matrix
439 namespace internal {
440  template<typename Other>
442  {
443  // Other and LieGroup Scalar must have the same type (it's already checked in the calling function)
444  typedef typename Other::Scalar Scalar;
445  template<class Derived> inline static void run(LieGroupBase<Array<typename internal::traits<Derived>::Scalar, 7, 1>, Derived>& q, const Other& m)
446  {
447  q.getSO3Element().get() = m.template topLeftCorner<3,3>();
448  q.getR3Element() = m.template topRightCorner<3,1>();
449  }
450  };
451 
452  // set from a vector of coefficients assumed to be a quaternion
453  template<typename Other>
455  {
456  // Other and LieGroup Scalar must have the same type (it's already checked in the calling function)
457  typedef typename Other::Scalar Scalar;
458  template<class Derived> inline static void run(LieGroupBase<Array<typename internal::traits<Derived>::Scalar, 7, 1>, Derived>& q, const Other& vec)
459  {
460  q.getR3Element() = vec;
461  q.getSO3Element() = LieGroupBase<Array<typename internal::traits<Derived>::Scalar, 7, 1>, Derived>::SO3Element::Identity();
462  }
463  };
464 } // namespace
465 
466 /***************************************************************************
467 * Definition/implementation of Map<LieGroup<Array<Scalar, 7, 1> > >
468 ***************************************************************************/
469 
470 // we don't need anything new
471 
472 
473 #endif
EIGEN_STRONG_INLINE LieGroup(const typename Base::Vector3 &v, const typename Base::SO3Element &r)
Definition: LieGroup_SE3.h:421
LieGroup(const Array< Scalar, 7, 1 > &g)
Definition: LieGroup_SE3.h:402
LieGroup< G >::Algebra Algebra
Definition: LieGroup.h:53
Class describing an element of a Lie Algebra.
Definition: LieAlgebra.h:168
AdjointMatrix adjoint(void) const
LieGroup(const MatrixBase< Derived > &other)
Definition: LieGroup_SE3.h:426
Base class for all Lie Group class.
Definition: LieGroup.h:39
static void run(LieGroupBase< Array< typename internal::traits< Derived >::Scalar, 7, 1 >, Derived > &q, const Other &vec)
Definition: LieGroup_SE3.h:458
Base class for all Lie Algebra class.
Definition: Displacement.h:139
static void run(LieGroupBase< Array< typename internal::traits< Derived >::Scalar, 7, 1 >, Derived > &q, const Other &m)
Definition: LieGroup_SE3.h:445
internal::traits< LieGroup< Array< _Scalar, 7, 1 > > >::Coefficients Coefficients
Definition: LieGroup_SE3.h:393
Class describing an element of a Lie Group.
Definition: LieGroup.h:117
Class describing an element of a Lie algebra dual.
Definition: LieAlgebra.h:216
Coefficients & get()
Algebra log(const Scalar precision=1e-6) const
LieGroupBase< Array< _Scalar, 7, 1 >, LieGroup< Array< _Scalar, 7, 1 > > > Base
Definition: LieGroup_SE3.h:388
LieGroup(Scalar x, Scalar y, Scalar z, Scalar qw, Scalar qx, Scalar qy, Scalar qz)
Definition: LieGroup_SE3.h:410


lgsm
Author(s): Roberto Martín-Martín
autogenerated on Mon Jun 10 2019 14:05:58