$search
00001 // HOG-Man - Hierarchical Optimization for Pose Graphs on Manifolds 00002 // Copyright (C) 2010 G. Grisetti, R. Kümmerle, C. Stachniss 00003 // 00004 // HOG-Man 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 // HOG-Man 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 POSEGRAPH_2D_HH 00018 #define POSEGRAPH_2D_HH 00019 00020 #include "hogman_minimal/math/transformation.h" 00021 00022 #include "posegraph.h" 00023 00024 namespace AISNavigation{ 00025 00026 struct PoseGraph2D: public PoseGraph<Transformation2, Matrix3> { 00027 00028 virtual void load(std::istream& is, bool overrideCovariances=false, std::vector <Edge*> *orderedEdges=0); 00029 virtual void save(std::ostream& os, const Transformation2& offset=Transformation2(), int type=0, bool onlyMarked=false) const; 00030 00031 virtual void visualizeToStream(std::ostream& os) const; 00032 00033 virtual void saveAsGnuplot(ostream& os, bool onlyMarked=false) const; 00034 00035 }; 00036 00037 template <> 00038 struct MotionJacobian< PoseGraph<Transformation2, Matrix3 > >{ 00039 Matrix3 state(const Transformation2& t, const Transformation2& movement){ 00040 Matrix3 j; 00041 double dx=movement.translation().x(); 00042 double dy=movement.translation().y(); 00043 double theta=t.rotation(); 00044 double s=sin(theta), c=cos(theta); 00045 j[0][0]=1.; j[0][1]=0.; j[0][2]=-s*dx-c*dy; 00046 j[1][0]=0.; j[1][1]=1.; j[1][2]=+c*dx-s*dy; 00047 j[2][0]=0.; j[2][1]=0.; j[2][2]=1; 00048 return j; 00049 } 00050 00051 Matrix3 measurement(const Transformation2& t, const Transformation2& movement __attribute__((unused))){ 00052 Matrix3 Ju; 00053 double s=sin(t.rotation()), c=cos(t.rotation()); 00054 Ju[0][0]=c; Ju[0][1]=-s; Ju[0][2]=0; 00055 Ju[1][0]=s; Ju[1][1]=c; Ju[1][2]=0; 00056 Ju[2][0]=0.; Ju[2][1]=0.; Ju[2][2]=1; 00057 return Ju; 00058 } 00059 }; 00060 00061 template <> 00062 struct TaylorTerms< PoseGraph2D > { 00063 typedef PoseGraph2D PG; 00064 00065 void operator()(PG::TransformationType& fij, PG::InformationType& dfij_dxi, PG::InformationType& dfij_dxj, const PG::Edge& e) { 00066 const PG::Vertex* vi = reinterpret_cast<const PG::Vertex*>(e.from()); 00067 const PG::Vertex* vj = reinterpret_cast<const PG::Vertex*>(e.to()); 00068 00069 fij=vi->transformation.inverse()*vj->transformation; 00070 double thetai=vi->transformation.rotation(); 00071 Vector2 dt=vj->transformation.translation()-vi->transformation.translation(); 00072 double si=sin(thetai), ci=cos(thetai); 00073 00074 dfij_dxi[0][0]=-ci; dfij_dxi[0][1]=-si; dfij_dxi[0][2]= -si*dt.x()+ci*dt.y(); 00075 dfij_dxi[1][0]= si; dfij_dxi[1][1]=-ci; dfij_dxi[1][2]= -ci*dt.x()-si*dt.y(); 00076 dfij_dxi[2][0]= 0; dfij_dxi[2][1]=0; dfij_dxi[2][2]= -1; 00077 00078 dfij_dxj[0][0]= ci; dfij_dxj[0][1]= si; dfij_dxj[0][2]= 0; 00079 dfij_dxj[1][0]=-si; dfij_dxj[1][1]= ci; dfij_dxj[1][2]= 0; 00080 dfij_dxj[2][0]= 0; dfij_dxj[2][1]=0; dfij_dxj[2][2]= 1; 00081 00082 } 00083 }; 00084 00085 template < > 00086 struct Gradient < PoseGraph2D >{ 00087 typedef PoseGraph2D PG; 00088 00089 void operator()( PG::TransformationVectorType& eij, PG::InformationType& deij_dxi, PG::InformationType& deij_dxj, const PG::Edge& e) { 00090 00091 const PG::Vertex* vi = reinterpret_cast<const PG::Vertex*>(e.from()); 00092 const PG::Vertex* vj = reinterpret_cast<const PG::Vertex*>(e.to()); 00093 00094 PG::TransformationType Tj=vi->transformation*e.mean(); 00095 eij=vj->transformation.toVector(); 00096 00097 PG::TransformationVectorType pj=Tj.toVector(); 00098 eij-=pj; 00099 00100 double thetai=vi->transformation.rotation(); 00101 Vector2 dt=e.mean().translation(); 00102 double si=sin(thetai), ci=cos(thetai); 00103 00104 deij_dxi[0][0]=-1; deij_dxi[0][1]= 0; deij_dxi[0][2]= -si*dt.x()+ci*dt.y(); 00105 deij_dxi[1][0]= 0; deij_dxi[1][1]=-1; deij_dxi[1][2]= -ci*dt.x()-si*dt.y(); 00106 deij_dxi[2][0]= 0; deij_dxi[2][1]=0; deij_dxi[2][2]= -1; 00107 00108 deij_dxj[0][0]= 1; deij_dxj[0][1]= 0; deij_dxj[0][2]= 0; 00109 deij_dxj[1][0]= 0; deij_dxj[1][1]= 1; deij_dxj[1][2]= 0; 00110 deij_dxj[2][0]= 0; deij_dxj[2][1]=0; deij_dxj[2][2]= 1; 00111 } 00112 00113 }; 00114 00115 template <> 00116 struct LocalGradient < PoseGraph2D >{ 00117 typedef PoseGraph2D PG; 00118 00119 void operator()( PG::TransformationVectorType& eij, PG::InformationType& deij_dxi, PG::InformationType& deij_dxj, const PG::Edge& e) { 00120 TaylorTerms<PG> taylorTerms; 00121 PG::TransformationType fij; 00122 taylorTerms(fij, deij_dxi, deij_dxj, e); 00123 PG::TransformationType rmean=e.mean(false); 00124 eij=(rmean*fij).toVector(); 00125 Matrix3 z=rmean.toMatrix(); 00126 z[0][2]=0; 00127 z[1][2]=0; 00128 deij_dxi = z * deij_dxi; 00129 deij_dxj = z * deij_dxj; 00130 } 00131 }; 00132 00133 template <> 00134 struct ManifoldGradient < PoseGraph2D >{ 00135 typedef PoseGraph2D PG; 00136 00137 void operator()( PG::TransformationVectorType& eij, PG::InformationType& deij_dxi, PG::InformationType& deij_dxj, const PG::Edge& e) { 00138 TaylorTerms<PG> taylorTerms; 00139 PG::TransformationType fij; 00140 taylorTerms(fij, deij_dxi, deij_dxj, e); 00141 PG::TransformationType rmean=e.mean(false); 00142 eij=(rmean*fij).toVector(); 00143 Matrix3 z=rmean.toMatrix(); 00144 z[0][2]=0; 00145 z[1][2]=0; 00146 deij_dxi = z * deij_dxi; 00147 deij_dxj = z * deij_dxj; 00148 } 00149 }; 00150 00151 template <> 00152 struct TransformCovariance<PoseGraph2D> { 00153 typedef PoseGraph2D PG; 00154 void operator()(PG::InformationType& covariance, const PG::TransformationType& t, const PG::TransformationType& ) 00155 { 00156 PG::InformationType J = t.inverse().toMatrix(); 00157 J[0][2]=0.; 00158 J[1][2]=0.; 00159 J[2][0]=0.; 00160 J[2][1]=0.; 00161 J[2][2]=1.; 00162 covariance = J * covariance * J.transpose(); 00163 } 00164 }; 00165 00166 template <> 00167 struct PoseUpdate<PoseGraph2D> { 00168 typedef PoseGraph2D PG; 00169 void operator()(PG::TransformationType& t, PG::TransformationVectorType::BaseType* update) 00170 { 00171 PG::TransformationVectorType p = t.toVector(); 00172 for (int k=0; k<3; k++){ 00173 if (k==2 && fabs(update[k])>M_PI){ 00174 update[k] = update[k]>0?M_PI:-M_PI; 00175 } 00176 p[k]+=update[k]; 00177 } 00178 t = PG::TransformationType::fromVector(p); 00179 } 00180 }; 00181 00182 } 00183 00184 #endif