se3quat.h
Go to the documentation of this file.
00001 // g2o - General Graph Optimization
00002 // Copyright (C) 2011 H. Strasdat
00003 //
00004 // g2o is free software: you can redistribute it and/or modify
00005 // it under the terms of the GNU Lesser General Public License as published
00006 // by the Free Software Foundation, either version 3 of the License, or
00007 // (at your option) any later version.
00008 //
00009 // g2o is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 // GNU Lesser General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU Lesser General Public License
00015 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
00016 
00017 #ifndef __SE3QUAT_H__
00018 #define __SE3QUAT_H__
00019 
00020 #include "g2o/stuff/misc.h"
00021 #include "g2o/stuff/macros.h"
00022 #include <Eigen/Core>
00023 #include <Eigen/Geometry>
00024 #include "se3_ops.h"
00025 
00026 namespace g2o {
00027   using namespace Eigen;
00028 
00029   typedef Matrix<double, 6, 1> Vector6d;
00030   typedef Matrix<double, 7, 1> Vector7d;
00031 
00032   class SE3Quat {
00033    public:
00034     EIGEN_MAKE_ALIGNED_OPERATOR_NEW
00035 
00036 
00037   protected:
00038 
00039     Quaterniond _r;
00040     Vector3d _t;
00041 
00042 
00043   public:
00044     SE3Quat(){
00045       _r.setIdentity();
00046       _t.setZero();
00047     }
00048 
00049     SE3Quat(const Matrix3d& R, const Vector3d t):_r(Quaterniond(R)),_t(t){}
00050     SE3Quat(const Quaterniond& q, const Vector3d t):_r(q),_t(t){}
00051 
00055     template <typename Derived>
00056     explicit SE3Quat(const MatrixBase<Derived>& v)
00057     {
00058       assert(v.size() == 6);
00059       for (int i=0; i<3; i++){
00060         _t[i]=v[i];
00061         _r.coeffs()(i)=v[i+3];
00062       }
00063       _r.w() = 0.;
00064       if (_r.norm()>1.){
00065         _r.normalize();
00066       } else 
00067         _r.w()=sqrt(1.-_r.squaredNorm());
00068     }
00069 
00070     inline const Vector3d& translation() const {return _t;}
00071 
00072     inline Vector3d& translation() {return _t;}
00073 
00074     inline const Quaterniond& rotation() const {return _r;}
00075 
00076     inline Quaterniond& rotation() {return _r;}
00077     
00078     inline SE3Quat operator * (const SE3Quat& tr2) const{
00079       SE3Quat result(*this);
00080       result._t += _r*tr2._t;
00081       result._r*=tr2._r;
00082       result._r.normalize();
00083       return result;
00084     }
00085 
00086     inline SE3Quat& operator *= (const SE3Quat& tr2){
00087       _t+=_r*tr2._t;
00088       _r*=tr2._r;
00089       _r.normalize();
00090       return *this;
00091     }
00092 
00093     inline Vector3d operator * (const Vector3d v) const {
00094       return _t+_r*v;
00095     }
00096 
00097     inline SE3Quat inverse() const{
00098       SE3Quat ret;
00099       ret._r=_r.conjugate();
00100       ret._t=ret._r*(_t*-1.);
00101       return ret;
00102     }
00103     
00104     inline double operator [](int i) const {
00105       assert(i<7);
00106       if (i<3)
00107         return _t[i];
00108       return _r.coeffs()[i-3];
00109     }
00110 
00111     inline double& operator [](int i) {
00112       assert(i<7);
00113       if (i<3)
00114         return _t[i];
00115       return _r.coeffs()[i-3];
00116     }
00117 
00118 
00119     inline Vector7d toVector() const{
00120       Vector7d v;
00121       v[0]=_t(0);
00122       v[1]=_t(1);
00123       v[2]=_t(2);
00124       v[3]=_r.x();
00125       v[4]=_r.y();
00126       v[5]=_r.z();
00127       v[6]=_r.w();
00128       return v;
00129     }
00130 
00131     inline void fromVector(const Vector7d& v){
00132       _r=Quaterniond(v[3], v[4], v[5], v[6]);
00133       _t=Vector3d(v[0], v[1], v[2]);
00134     }
00135 
00136     inline Vector6d toMinimalVector() const{
00137       Vector6d v;
00138       v[0]=_t(0);
00139       v[1]=_t(1);
00140       v[2]=_t(2);
00141       v[3]=_r.x();
00142       v[4]=_r.y();
00143       v[5]=_r.z();
00144       return v;
00145     }
00146 
00147     inline void fromMinimalVector(const Vector6d& v){
00148       double w = 1.-v[3]*v[3]-v[4]*v[4]-v[5]*v[5];
00149       if (w>0){
00150         _r=Quaterniond(v[3], v[4], v[5], w);
00151       } else {
00152         _r=Quaterniond(-v[3], -v[4], -v[5], -w);
00153       }
00154       _t=Vector3d(v[0], v[1], v[2]);
00155     }
00156 
00157 
00158 
00159     Vector6d log() const {
00160       Vector6d res;
00161       Matrix3d _R = _r.toRotationMatrix();
00162       double d =  0.5*(_R(0,0)+_R(1,1)+_R(2,2)-1);
00163       Vector3d omega;
00164       Vector3d upsilon;
00165 
00166 
00167       Vector3d dR = deltaR(_R);
00168       Matrix3d V_inv;
00169 
00170       if (d>0.99999)
00171       {
00172 
00173         omega=0.5*dR;
00174         Matrix3d Omega = skew(omega);
00175         V_inv = Matrix3d::Identity()- 0.5*Omega + (1./12.)*(Omega*Omega);
00176       }
00177       else
00178       {
00179         double theta = acos(d);
00180         omega = theta/(2*sqrt(1-d*d))*dR;
00181         Matrix3d Omega = skew(omega);
00182         V_inv = ( Matrix3d::Identity() - 0.5*Omega
00183                   + ( 1-theta/(2*tan(theta/2)))/(theta*theta)*(Omega*Omega) );
00184       }
00185 
00186       upsilon = V_inv*_t;
00187       for (int i=0; i<3;i++){
00188         res[i]=omega[i];
00189       }
00190       for (int i=0; i<3;i++){
00191         res[i+3]=upsilon[i];
00192       }
00193 
00194       return res;
00195 
00196     }
00197 
00198     Vector3d map(const Vector3d & xyz) const
00199     {
00200       return _r*xyz + _t;
00201     }
00202 
00203 
00204     static SE3Quat exp(const Vector6d & update)
00205 
00206     {
00207 
00208       Vector3d omega;
00209       for (int i=0; i<3; i++)
00210         omega[i]=update[i];
00211       Vector3d upsilon;
00212       for (int i=0; i<3; i++)
00213         upsilon[i]=update[i+3];
00214 
00215       double theta = omega.norm();
00216       Matrix3d Omega = skew(omega);
00217 
00218       Matrix3d R;
00219       Matrix3d V;
00220       if (theta<0.00001)
00221       {
00222         //TODO: CHECK WHETHER THIS IS CORRECT!!!
00223         R = (Matrix3d::Identity() + Omega + Omega*Omega);
00224 
00225         V = R;
00226       }
00227       else
00228       {
00229         Matrix3d Omega2 = Omega*Omega;
00230 
00231         R = (Matrix3d::Identity()
00232              + sin(theta)/theta *Omega
00233              + (1-cos(theta))/(theta*theta)*Omega2);
00234 
00235         V = (Matrix3d::Identity()
00236              + (1-cos(theta))/(theta*theta)*Omega
00237              + (theta-sin(theta))/(pow(theta,3))*Omega2);
00238       }
00239       return SE3Quat(Quaterniond(R),V*upsilon);
00240     }
00241 
00242     Matrix<double, 6, 6> adj() const
00243     {
00244       Matrix3d R = _r.toRotationMatrix();
00245       Matrix<double, 6, 6> res;
00246       res.block(0,0,3,3) = R;
00247       res.block(3,3,3,3) = R;
00248       res.block(3,0,3,3) = skew(_t)*R;
00249       res.block(0,3,3,3) = Matrix3d::Zero(3,3);
00250       return res;
00251     }
00252 
00253     Matrix<double,4,4> to_homogenious_matrix() const
00254     {
00255       Matrix<double,4,4> homogenious_matrix;
00256       homogenious_matrix.setIdentity();
00257       homogenious_matrix.block(0,0,3,3) = _r.toRotationMatrix();
00258       homogenious_matrix.col(3).head(3) = translation();
00259 
00260       return homogenious_matrix;
00261     }
00262   };
00263 
00264 
00265 
00266   inline std::ostream& operator <<(std::ostream& out_str,
00267                                    const SE3Quat& se3)
00268   {
00269     out_str << se3.to_homogenious_matrix()  << std::endl;
00270     return out_str;
00271   }
00272 
00273 } // end namespace
00274 
00275 #endif


re_vision
Author(s): Dorian Galvez-Lopez
autogenerated on Sun Jan 5 2014 11:32:24