graph_optimizer.hpp
Go to the documentation of this file.
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 using namespace std;
00018 
00019 template <typename PG>
00020 GraphOptimizer<PG>::GraphOptimizer() :
00021   PG(),
00022   _verbose(false), _visualizeToStdout(false), _guessOnEdges(false)
00023 {
00024 }
00025 
00026 template <typename PG>
00027 GraphOptimizer<PG>::~GraphOptimizer()
00028 {
00029 }
00030 
00031 template <typename PG>
00032 double GraphOptimizer<PG>::chi2(const typename PG::Edge* e_)
00033 {
00034   const typename PG::Edge* e = _MY_CAST_<const typename PG::Edge*>(e_);
00035   const typename PG::Vertex* v1 = _MY_CAST_<const typename PG::Vertex*>(e->from());
00036   const typename PG::Vertex* v2 = _MY_CAST_<const typename PG::Vertex*>(e->to());
00037   typename PG::TransformationType delta = e->mean(false) * (v1->transformation.inverse() * v2->transformation);
00038   typename PG::TransformationVectorType dp = delta.toVector();
00039   typename PG::TransformationVectorType partial = e->information() * dp;
00040   return dp * partial;
00041 }
00042 
00043 template <typename PG>
00044 double GraphOptimizer<PG>::chi2() const
00045 {
00046   double chi = 0.0;
00047   for (typename PG::EdgeSet::const_iterator it = this->edges().begin(); it != this->edges().end(); it++){
00048     typename PG::Edge* e = _MY_CAST_<typename PG::Edge*>(*it);
00049     chi += chi2(e);
00050   }
00051   return chi;
00052 }
00053 
00054 template <typename PG>
00055 void GraphOptimizer<PG>::absChi(double& rotationalError, double& translationalError, typename PG::Edge* e_)
00056 {
00057   typename PG::Edge* e = _MY_CAST_<typename PG::Edge*>(e_);
00058   typename PG::Vertex* v1 = _MY_CAST_<typename PG::Vertex*>(e->from());
00059   typename PG::Vertex* v2 = _MY_CAST_<typename PG::Vertex*>(e->to());
00060   typename PG::TransformationType delta = (v1->transformation.inverse() * v2->transformation) * e->mean().inverse();
00061   _Vector< PG::TransformationType::RotationType::Angles, double > anglesDelta = delta.rotation().angles();
00062   rotationalError = sqrt(anglesDelta * anglesDelta);
00063   translationalError = sqrt(delta.translation() * delta.translation());
00064 }
00065 
00066 template <typename PG>
00067 void  GraphOptimizer<PG>::chiStat(ChiStatMap& emap)
00068 {
00069   emap.clear();
00070   for (typename PG::EdgeSet::iterator it= this->edges().begin(); it!= this->edges().end(); ++it)
00071     emap.insert(make_pair(_MY_CAST_<typename PG::Edge*>(*it), chi2(*it)));
00072 }
00073 
00074 template <typename PG>
00075 void GraphOptimizer<PG>::sqError(double& are, double& ate, double& mte, double& mre, const typename PG::EdgeSet* eset) const
00076 {
00077   if (! eset)
00078     eset = &this->edges();
00079   double cumTe=0, cumRe=0;
00080   double maxTe=0, maxRe=0;
00081   int count=0;
00082   for (typename PG::EdgeSet::const_iterator it = eset->begin(); it != eset->end(); ++it){
00083     double te=0, re=0;
00084     typename PG::Edge* e = _MY_CAST_<typename PG::Edge*>(*it);
00085     absChi(re, te, e);
00086     maxTe = max(maxTe, te);
00087     maxRe = max(maxRe, re);
00088     cumTe += te;
00089     cumRe += re;
00090     count++;
00091   }
00092   mte = maxTe;
00093   mre = maxRe;
00094   ate = cumTe/(double)count;
00095   are = cumRe/(double)count;
00096 }
00097 
00098 template <typename PG>
00099 void GraphOptimizer<PG>::backup()
00100 {
00101   for (typename PG::VertexIDMap::iterator it=_vertices.begin(); it!=_vertices.end(); it++)
00102   {
00103     typename PG::Vertex* v=_MY_CAST_<typename PG::Vertex*>(it->second);
00104     v->backup();
00105   }
00106 }
00107 
00108 template <typename PG>
00109 void GraphOptimizer<PG>::restore()
00110 {
00111   for (typename PG::VertexIDMap::iterator it=_vertices.begin(); it!=_vertices.end(); it++)
00112   {
00113     typename PG::Vertex* v=_MY_CAST_<typename PG::Vertex*>(it->second);
00114     v->restore();
00115   }
00116 }
00117 
00118 template <typename PG>
00119 void GraphOptimizer<PG>::backupSubset(typename PG::VertexSet& vset){
00120   for (typename PG::VertexSet::iterator it=vset.begin(); it!=vset.end(); it++) {
00121     (*it)->backup();
00122   }
00123 }
00124 
00125 template <typename PG>
00126 void GraphOptimizer<PG>::restoreSubset(typename PG::VertexSet& vset)
00127 {
00128   for (typename PG::VertexSet::iterator it=vset.begin(); it!=vset.end(); it++) {
00129     (*it)->restore();
00130   }
00131 }
00132 
00133 template <typename PG>
00134 void GraphOptimizer<PG>::backupSubset(Graph::VertexSet& vset)
00135 {
00136   for (Graph::VertexSet::iterator it=vset.begin(); it!=vset.end(); it++) {
00137     typename PG::Vertex* v = dynamic_cast<typename PG::Vertex*>(*it);
00138     if (v)
00139       v->backup();
00140   }
00141 }
00142 
00143 template <typename PG>
00144 void GraphOptimizer<PG>::restoreSubset(Graph::VertexSet& vset)
00145 {
00146   for (Graph::VertexSet::iterator it=vset.begin(); it!=vset.end(); it++) {
00147     typename PG::Vertex* v = dynamic_cast<typename PG::Vertex*>(*it);
00148     if (v)
00149       v->restore();
00150   }
00151 }


hogman_minimal
Author(s): Maintained by Juergen Sturm
autogenerated on Mon Oct 6 2014 00:06:58