00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifndef EIGEN_LGSM_LIE_SE3_H
00011 #define EIGEN_LGSM_LIE_SE3_H
00012
00013 namespace internal {
00014 template<typename Other,
00015 int OtherRows=Other::RowsAtCompileTime,
00016 int OtherCols=Other::ColsAtCompileTime>
00017 struct liegroup_SE3_base_assign_impl;
00018 }
00019
00020
00021
00022
00023
00036 template<class Derived>
00037 class LieGroupBase<Array<typename internal::traits<Derived>::Scalar, 7, 1>, Derived>
00038 {
00039 public:
00040
00042 typedef typename internal::traits<Derived>::Scalar Scalar;
00044 typedef Array<Scalar, 7, 1> BaseType;
00046 typedef typename internal::traits<Derived>::Coefficients Coefficients;
00048 typedef typename internal::traits<Derived>::PlainObject PlainObject;
00049
00051 typedef Matrix<Scalar, 6, 6> AdjointMatrix;
00053 typedef LieAlgebra<Matrix<Scalar, 6, 1> > Algebra;
00055 typedef LieAlgebraDual<Matrix<Scalar, 6, 1> > AlgebraDual;
00056
00058 typedef Matrix<Scalar, 3, 1> Vector3;
00060 typedef LieGroup<Quaternion<Scalar> > SO3Element;
00061
00063 EIGEN_STRONG_INLINE PlainObject inverse() const;
00065 static PlainObject Identity();
00067 template<class OtherDerived> inline PlainObject operator*(const LieGroupBase<BaseType, OtherDerived>& other) const;
00069 template<class OtherDerived> EIGEN_STRONG_INLINE Derived& operator*=(const LieGroupBase<BaseType, OtherDerived>& other);
00071 template<class OtherDerived> inline Vector3 operator*(const MatrixBase<OtherDerived>& d) const;
00072
00074 AdjointMatrix adjoint(void) const;
00076 template<class AlgebraDerived> inline Algebra adjoint(const LieAlgebraBase<Matrix<Scalar, 6, 1>, AlgebraDerived>& ) const;
00078 template<class AlgebraDualDerived> inline AlgebraDual adjointTr(const LieAlgebraDualBase<Matrix<Scalar, 6, 1>, AlgebraDualDerived>& ) const;
00079
00083 inline Algebra log(const Scalar precision = 1e-6) const;
00084
00086 EIGEN_STRONG_INLINE LieGroupBase& operator=(const LieGroupBase& other);
00088 template<class OtherDerived> EIGEN_STRONG_INLINE Derived& operator=(const LieGroupBase<BaseType, OtherDerived>& other);
00090 template<class OtherDerived> Derived& operator=(const MatrixBase<OtherDerived>& m);
00091
00093 inline const Derived& derived() const { return *static_cast<const Derived*>(this); }
00095 inline Derived& derived() { return *static_cast<Derived*>(this); }
00096
00098 inline Map<SO3Element> getSO3Element(){ return Map<SO3Element>(this->derived().get().template head<4>().data()); }
00100 inline Map<const SO3Element> getSO3Element() const{ return Map<const SO3Element>(this->derived().get().template head<4>().data()); }
00102
00103 inline Map<Vector3> getR3Element(){ return Map<Vector3>(this->get().template tail<3>().data()); }
00105 inline Map<const Vector3> getR3Element() const { return Map<const Vector3>(this->get().template tail<3>().data()); }
00106
00108 Coefficients& get() { return derived().get(); }
00110 const Coefficients& get() const { return derived().get(); }
00111
00113 template<class OtherDerived>
00114 friend std::ostream& operator <<(std::ostream& os, const LieGroupBase<Array<typename internal::traits<Derived>::Scalar, 7, 1>, Derived>& g);
00115 };
00116
00117
00118
00119
00120
00121
00122 template<class Derived>
00123 inline LieGroupBase<Array<typename internal::traits<Derived>::Scalar, 7, 1 >, Derived>&
00124 LieGroupBase<Array<typename internal::traits<Derived>::Scalar, 7, 1 >, Derived>::operator=(const LieGroupBase& other)
00125 {
00126 this->get() = other.get();
00127 return *this;
00128 }
00129
00130 template<class Derived>
00131 template<class OtherDerived>
00132 inline Derived&
00133 LieGroupBase<Array<typename internal::traits<Derived>::Scalar, 7, 1 >, Derived>::operator=(const LieGroupBase<BaseType, OtherDerived>& other)
00134 {
00135 this->get() = other.get();
00136 return derived();
00137 }
00138
00139 template<class Derived>
00140 template<class MatrixDerived>
00141 inline Derived&
00142 LieGroupBase<Array<typename internal::traits<Derived>::Scalar, 7, 1 >, Derived>::operator=(const MatrixBase<MatrixDerived>& xpr)
00143 {
00144 EIGEN_STATIC_ASSERT((internal::is_same<typename Derived::Scalar, typename MatrixDerived::Scalar>::value),
00145 YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
00146
00147 internal::liegroup_SE3_base_assign_impl<MatrixDerived>::run(*this, xpr.derived());
00148
00149 return derived();
00150 }
00151
00152 template<class Derived>
00153 typename LieGroupBase<Array<typename internal::traits<Derived>::Scalar, 7, 1 >, Derived>::PlainObject
00154 LieGroupBase<Array<typename internal::traits<Derived>::Scalar, 7, 1 >, Derived>::inverse() const
00155 {
00156 return PlainObject(-(this->getSO3Element().inverse().operator*(this->getR3Element()))
00157 , this->getSO3Element().inverse());
00158 }
00159
00160
00161 template<class Derived>
00162 typename LieGroupBase<Array<typename internal::traits<Derived>::Scalar, 7, 1 >, Derived>::PlainObject
00163 LieGroupBase<Array<typename internal::traits<Derived>::Scalar, 7, 1 >, Derived>::Identity()
00164 {
00165 return PlainObject(Vector3(0,0,0), SO3Element::Identity());
00166 }
00167
00168
00169
00170
00171
00172 template<class Derived>
00173 template<class OtherDerived> EIGEN_STRONG_INLINE
00174 typename LieGroupBase<Array<typename internal::traits<Derived>::Scalar, 7, 1 >, Derived>::PlainObject
00175 LieGroupBase<Array<typename internal::traits<Derived>::Scalar, 7, 1 >, Derived>::operator*(const LieGroupBase<Array<Scalar, 7, 1 >, OtherDerived>& other) const
00176 {
00177 return PlainObject(this->getSO3Element() * other.getR3Element() + this->getR3Element()
00178 , this->getSO3Element() * other.getSO3Element());
00179 }
00180
00181
00182 template<class Derived>
00183 template<class OtherDerived> EIGEN_STRONG_INLINE
00184 Derived&
00185 LieGroupBase<Array<typename internal::traits<Derived>::Scalar, 7, 1 >, Derived>::operator*=(const LieGroupBase<BaseType, OtherDerived>& other) {
00186
00187 this->getR3Element() = this->getSO3Element() * other.getR3Element() + this->getR3Element();
00188 this->getSO3Element() *= other.getSO3Element();
00189
00190 return derived();
00191 }
00192
00193
00194
00195
00196 template<class Derived>
00197 template<class OtherDerived> EIGEN_STRONG_INLINE
00198 typename LieGroupBase<Array<typename internal::traits<Derived>::Scalar, 7, 1 >, Derived>::Vector3
00199 LieGroupBase<Array<typename internal::traits<Derived>::Scalar, 7, 1 >, Derived>::operator*(const MatrixBase<OtherDerived>& vec) const
00200 {
00201 return Vector3(this->getSO3Element() * vec + this->getR3Element());
00202 }
00203
00204
00205 template<class Derived>
00206 typename LieGroupBase<Array<typename internal::traits<Derived>::Scalar, 7, 1 >, Derived>::Algebra
00207 LieGroupBase<Array<typename internal::traits<Derived>::Scalar, 7, 1 >, Derived>::log(const Scalar precision) const
00208 {
00209 typename SO3Element::Algebra ang = this->getSO3Element().log(precision);
00210
00211 const Scalar n2 = ang.squaredNorm();
00212
00213 if(n2 < precision)
00214 return Algebra(ang, this->getR3Element());
00215 else{
00216
00217 const Scalar n = std::sqrt(n2);
00218
00219 #ifndef USE_RLAB_LOG_FUNCTION //Set in Lgsm file
00220 const Scalar sn = std::sin(n);
00221
00222 Scalar val = (Scalar(2.0) * sn - n * (Scalar(1.0) + std::cos(n))) / (Scalar(2.0) *n2 * sn);
00223
00224 Vector3 lin = -0.5*ang.cross(this->getR3Element());
00225 lin += (Scalar(1.0) - val * n2 ) * this->getR3Element();
00226 lin += val * ang.dot(this->getR3Element()) * ang;
00227
00228 return Algebra(ang, lin);
00229
00230 #else
00231
00232
00233
00234
00235
00236 const Scalar n_div2 = n/2.0;
00237 const Scalar s = std::sin(n_div2) / n_div2;
00238 const Scalar c = std::cos(n_div2);
00239 const Scalar gamma = c / s;
00240
00241 Eigen::Matrix<double, 3, 3> dexpinv = Eigen::Matrix<double, 3, 3>::Identity();
00242
00243 double v1 = ang[0];
00244 double v2 = ang[1];
00245 double v3 = ang[2];
00246
00247 Eigen::Matrix<double, 3, 3> w_ceil = Eigen::Matrix<double, 3, 3>::Zero();
00248 w_ceil(0, 1) = -v3;
00249 w_ceil(0, 2) = v2;
00250 w_ceil(1, 0) = v3;
00251 w_ceil(1, 2) = -v1;
00252 w_ceil(2, 0) = -v2;
00253 w_ceil(2, 1) = v1;
00254
00255 Eigen::Matrix<double, 3, 3> w_ceil_sqr = Eigen::Matrix<double, 3, 3>::Zero();
00256 double v1sqr = v1 * v1;
00257 double v2sqr = v2 * v2;
00258 double v3sqr = v3 * v3;
00259 double v12 = v1 * v2;
00260 double v13 = v1 * v3;
00261 double v23 = v2 * v3;
00262
00263 w_ceil_sqr(0, 0) = -v2sqr - v3sqr;
00264 w_ceil_sqr(0, 1) = v12;
00265 w_ceil_sqr(0, 2) = v13;
00266 w_ceil_sqr(1, 0) = v12;
00267 w_ceil_sqr(1, 1) = -v1sqr - v3sqr;
00268 w_ceil_sqr(1, 2) = v23;
00269 w_ceil_sqr(2, 0) = v13;
00270 w_ceil_sqr(2, 1) = v23;
00271 w_ceil_sqr(2, 2) = -v1sqr - v2sqr;
00272
00273 dexpinv += -0.5 * w_ceil + (1 - gamma) / n2 * w_ceil_sqr;
00274
00275 Vector3 lin = dexpinv*this->getR3Element();
00276
00277 return Algebra(ang, lin);
00278 #endif
00279 }
00280 }
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316 template<class Derived>
00317 typename LieGroupBase<Array<typename internal::traits<Derived>::Scalar, 7, 1 >, Derived>::AdjointMatrix
00318 LieGroupBase<Array<typename internal::traits<Derived>::Scalar, 7, 1 >, Derived>::adjoint() const
00319 {
00320 AdjointMatrix res;
00321
00322 res.template block<3,3>(0,0) = this->getSO3Element().adjoint();
00323 res.template block<3,3>(3,3) = res.template block<3,3>(0,0);
00324
00325
00326 res.template block<3,3>(3,0) = (Matrix<Scalar,3,3>() <<
00327 0, -this->getR3Element()[2], this->getR3Element()[1],
00328 this->getR3Element()[2], 0, -this->getR3Element()[0],
00329 -this->getR3Element()[1], this->getR3Element()[0], 0)
00330 .finished()*res.template block<3,3>(0,0);
00331
00332 (res.template block<3,3>(0,3)).setZero();
00333
00334 return res;
00335 }
00336
00337
00338
00339
00340
00341 template<class Derived>
00342 template<class AlgebraDerived>
00343 inline typename LieGroupBase<Array<typename internal::traits<Derived>::Scalar, 7, 1 >, Derived>::Algebra
00344 LieGroupBase<Array<typename internal::traits<Derived>::Scalar, 7, 1 >, Derived>::adjoint(const LieAlgebraBase<Matrix<Scalar, 6, 1>, AlgebraDerived>& a) const
00345 {
00346 Vector3 Rw = this->getSO3Element() * a.getso3Element();
00347
00348 typename SO3Element::Algebra ang(Rw);
00349 Vector3 lin = this->getR3Element().cross(Rw) + this->getSO3Element() * a.getR3Element();
00350
00351 return Algebra(ang, lin);
00352 }
00353
00354
00355
00356
00357
00358 template<class Derived>
00359 template<class AlgebraDualDerived>
00360 inline typename LieGroupBase<Array<typename internal::traits<Derived>::Scalar, 7, 1 >, Derived>::AlgebraDual
00361 LieGroupBase<Array<typename internal::traits<Derived>::Scalar, 7, 1 >, Derived>::adjointTr(const LieAlgebraDualBase<Matrix<Scalar, 6, 1>, AlgebraDualDerived>& ca) const
00362 {
00363 return AlgebraDual(this->getSO3Element().inverse() * (ca.getR3Element().cross(this->getR3Element() ) + ca.getso3Element()),
00364 this->getSO3Element().inverse() * ca.getR3Element());
00365 }
00366
00367
00368
00369
00370
00383 template<typename _Scalar> class LieGroup<Array<_Scalar, 7, 1> > :
00384 public LieGroupBase<Array<_Scalar, 7, 1>, LieGroup<Array<_Scalar, 7, 1> > >
00385 {
00386 protected:
00388 typedef LieGroupBase<Array<_Scalar, 7, 1>, LieGroup<Array<_Scalar, 7, 1> > > Base;
00389 public:
00391 typedef _Scalar Scalar;
00393 typedef typename internal::traits<LieGroup<Array<_Scalar, 7, 1> > >::Coefficients Coefficients;
00394
00395 EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(LieGroup)
00396
00397
00398 inline LieGroup() : m_coeffs() {}
00400 inline LieGroup(const LieGroup& g) : m_coeffs(g.get() ) {}
00402 inline LieGroup(const Array<Scalar, 7, 1>& g) : m_coeffs(g) {}
00403
00410 inline LieGroup(Scalar x, Scalar y, Scalar z, Scalar qw, Scalar qx, Scalar qy, Scalar qz) {
00411
00412 m_coeffs[0] = qx;
00413 m_coeffs[1] = qy;
00414 m_coeffs[2] = qz;
00415 m_coeffs[3] = qw;
00416 m_coeffs[4] = x;
00417 m_coeffs[5] = y;
00418 m_coeffs[6] = z;
00419 }
00421 EIGEN_STRONG_INLINE LieGroup(const typename Base::Vector3& v, const typename Base::SO3Element& r) {
00422 this->getR3Element() = v;
00423 this->getSO3Element() = r;
00424 }
00425 template<typename Derived>
00426 explicit inline LieGroup(const MatrixBase<Derived>& other) { this = other;}
00427
00429 Coefficients& get() { return m_coeffs; }
00431 const Coefficients& get() const { return m_coeffs; }
00432
00433 protected:
00435 Coefficients m_coeffs;
00436 };
00437
00438
00439 namespace internal {
00440 template<typename Other>
00441 struct liegroup_SE3_base_assign_impl<Other,4,4>
00442 {
00443
00444 typedef typename Other::Scalar Scalar;
00445 template<class Derived> inline static void run(LieGroupBase<Array<typename internal::traits<Derived>::Scalar, 7, 1>, Derived>& q, const Other& m)
00446 {
00447 q.getSO3Element().get() = m.template topLeftCorner<3,3>();
00448 q.getR3Element() = m.template topRightCorner<3,1>();
00449 }
00450 };
00451
00452
00453 template<typename Other>
00454 struct liegroup_SE3_base_assign_impl<Other,3,1>
00455 {
00456
00457 typedef typename Other::Scalar Scalar;
00458 template<class Derived> inline static void run(LieGroupBase<Array<typename internal::traits<Derived>::Scalar, 7, 1>, Derived>& q, const Other& vec)
00459 {
00460 q.getR3Element() = vec;
00461 q.getSO3Element() = LieGroupBase<Array<typename internal::traits<Derived>::Scalar, 7, 1>, Derived>::SO3Element::Identity();
00462 }
00463 };
00464 }
00465
00466
00467
00468
00469
00470
00471
00472
00473 #endif