treeoptimizer3.cpp

Go to the documentation of this file.
00001 /**********************************************************************
00002  *
00003  * This source code is part of the Tree-based Network Optimizer (TORO)
00004  *
00005  * TORO Copyright (c) 2007 Giorgio Grisetti, Cyrill Stachniss, and
00006  * Wolfram Burgard
00007  *
00008  * TORO is licences under the Common Creative License,
00009  * Attribution-NonCommercial-ShareAlike 3.0
00010  *
00011  * You are free:
00012  *   - to Share - to copy, distribute and transmit the work
00013  *   - to Remix - to adapt the work
00014  *
00015  * Under the following conditions:
00016  *
00017  *   - Attribution. You must attribute the work in the manner specified
00018  *     by the author or licensor (but not in any way that suggests that
00019  *     they endorse you or your use of the work).
00020  *  
00021  *   - Noncommercial. You may not use this work for commercial purposes.
00022  *  
00023  *   - Share Alike. If you alter, transform, or build upon this work,
00024  *     you may distribute the resulting work only under the same or
00025  *     similar license to this one.
00026  *
00027  * Any of the above conditions can be waived if you get permission
00028  * from the copyright holder.  Nothing in this license impairs or
00029  * restricts the author's moral rights.
00030  *
00031  * TORO is distributed in the hope that it will be useful,
00032  * but WITHOUT ANY WARRANTY; without even the implied 
00033  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
00034  * PURPOSE.  
00035  **********************************************************************/
00036 
00044 #include "treeoptimizer3.hh"
00045 #include <fstream>
00046 #include <sstream>
00047 #include <string>
00048 
00049 using namespace std;
00050 
00051 #define DEBUG(i) \
00052         if (verboseLevel>i) cerr
00053 
00054 
00056 struct ParameterPropagator{
00057   void perform(TreePoseGraph3::Vertex* v){
00058     if (!v->parent){
00059       v->parameters=TreePoseGraph3::Transformation(0.,0.,0.,0.,0.,0.);
00060      return;
00061     }
00062     v->parameters=v->parent->transformation.inv()*v->transformation;
00063   }
00064 };
00065 
00067 struct TransformationPropagator{
00068   void perform(TreePoseGraph3::Vertex* v){
00069     if (!v->parent){
00070      return;
00071     }
00072     v->transformation=v->parent->transformation*v->parameters;
00073   }
00074 };
00075 
00076 TreeOptimizer3::TreeOptimizer3(){
00077   restartOnDivergence=false;
00078   sortedEdges=0;
00079   mpl=-1;
00080   edgeCompareMode=EVComparator<Edge*>::CompareLevel;
00081 }
00082 
00083 
00084 TreeOptimizer3::~TreeOptimizer3(){
00085 }
00086 
00087 void TreeOptimizer3::initializeTreeParameters(){
00088   ParameterPropagator pp;
00089   treeDepthVisit(pp, root);
00090 }
00091 
00092 void TreeOptimizer3::recomputeAllTransformations(){
00093   TransformationPropagator tp;
00094   treeDepthVisit(tp, root);
00095 }
00096 
00097 
00098 void TreeOptimizer3::iterate(TreePoseGraph3::EdgeSet* eset, bool noPreconditioner){
00099   TreePoseGraph3::EdgeSet* temp=sortedEdges;
00100   if (eset){
00101     sortedEdges=eset;
00102   }
00103 
00104   if (noPreconditioner)
00105     propagateErrors();
00106   else {
00107     if (iteration==1)
00108       computePreconditioner();  
00109     propagateErrorsPreconditioner();
00110   }
00111 
00112   if (restartOnDivergence){
00113     double mte, ate;
00114     double mre, are;
00115     error(&mre, &mte, &are, &ate);
00116     maxTranslationalErrors.push_back(mte);
00117     maxRotationalErrors.push_back(mre);
00118     int interval=3;
00119     if ((int)maxRotationalErrors.size()>=interval){
00120       uint s=maxRotationalErrors.size();
00121       double re0 = maxRotationalErrors[s-interval];
00122       double re1 = maxRotationalErrors[s-1];
00123 
00124       if ((re1-re0)>are || sqrt(re1)>0.99*M_PI){
00125         double rg=rotGain;
00126         if (sqrt(re1)>M_PI/4){
00127           cerr << "RESTART!!!!! : Angular wraparound may be occourring" << endl;
00128           cerr << " err=" << re0 << " -> " << re1 << endl; 
00129           cerr << "Restarting optimization and reducing the rotation factor" << endl;
00130           cerr << rg << " -> ";
00131           initializeOnTree();
00132           initializeTreeParameters();
00133           initializeOptimization();
00134           error(&mre, &mte);
00135           maxTranslationalErrors.push_back(mte);
00136           maxRotationalErrors.push_back(mre);
00137           rg*=0.1;
00138           rotGain=rg;
00139           cerr << rotGain << endl;
00140         }
00141         else {
00142           cerr << "decreasing angular gain" << rotGain*0.1 << endl;
00143           rotGain*=0.1;
00144         }
00145       }
00146     }
00147   }
00148   sortedEdges=temp;
00149 }
00150 
00151 
00152 void TreeOptimizer3::recomputeTransformations(Vertex*v, Vertex* top){
00153   if (v==top)
00154     return;
00155   recomputeTransformations(v->parent, top);
00156   v->transformation=v->parent->transformation*v->parameters;
00157 }
00158 
00159 
00160 void TreeOptimizer3::recomputeParameters(Vertex*v, Vertex* top){
00161   while (v!=top){
00162     v->parameters=v->parent->transformation.inv()*v->transformation;
00163     v=v->parent;
00164   }
00165 }
00166 
00167 
00168 TreeOptimizer3::Transformation TreeOptimizer3::getPose(Vertex*v, Vertex* top){
00169   Transformation t(0.,0.,0.,0.,0.,0.);
00170   if (v==top)
00171     return v->transformation;
00172   while (v!=top){
00173     t=v->parameters*t;
00174     v=v->parent;
00175   }
00176   return top->transformation*t;
00177 }
00178 
00179 TreeOptimizer3::Rotation TreeOptimizer3::getRotation(Vertex*v, Vertex* top){
00180   Rotation r(0.,0.,0.);
00181   if (v==top)
00182     return v->transformation.rotation();
00183   while (v!=top){
00184     r=v->parameters.rotation()*r;
00185     v=v->parent;
00186   }
00187   return top->transformation.rotation()*r;
00188 }
00189 
00190 
00191 
00192 double TreeOptimizer3::error(const Edge* e) const{
00193   const Vertex* v1=e->v1;
00194   const Vertex* v2=e->v2;
00195   
00196   Transformation et=e->transformation;
00197   Transformation t1=v1->transformation;
00198   Transformation t2=v2->transformation;
00199   
00200   Transformation t12=(t1*et)*t2.inv();
00201   Pose p12=t12.toPoseType();
00202 
00203   Pose ps=e->informationMatrix*p12;
00204   double err=p12*ps;
00205   DEBUG(100) << "e(" << v1->id << "," << v2->id << ")" << err << endl;
00206   return err;
00207  
00208 }
00209 
00210 double TreeOptimizer3::traslationalError(const Edge* e) const{
00211   const Vertex* v1=e->v1;
00212   const Vertex* v2=e->v2;
00213   
00214   Transformation et=e->transformation;
00215   Transformation t1=v1->transformation;
00216   Transformation t2=v2->transformation;
00217   
00218   Translation t12=(t2.inv()*(t1*et)).translation();
00219   return t12*t12;;
00220  
00221 }
00222 
00223 double TreeOptimizer3::rotationalError(const Edge* e) const{
00224   const Vertex* v1=e->v1;
00225   const Vertex* v2=e->v2;
00226   
00227   Rotation er=e->transformation.rotation();
00228   Rotation r1=v1->transformation.rotation();
00229   Rotation r2=v2->transformation.rotation();
00230   
00231   Rotation r12=r2.inverse()*(r1*er);
00232   double r=r12.angle();
00233   return r*r;
00234 }
00235 
00236 
00237 double TreeOptimizer3::error(double* mre, double* mte, double* are, double* ate, TreePoseGraph3::EdgeSet* eset) const{
00238   double globalRotError=0.;
00239   double maxRotError=0;
00240   double globalTrasError=0.;
00241   double maxTrasError=0;
00242 
00243   int c=0;
00244   if (! eset){
00245     for (TreePoseGraph3::EdgeMap::const_iterator it=edges.begin(); it!=edges.end(); it++){
00246       double re=rotationalError(it->second);
00247       globalRotError+=re;
00248       maxRotError=maxRotError>re?maxRotError:re;
00249       double te=traslationalError(it->second);
00250       globalTrasError+=te;
00251       maxTrasError=maxTrasError>te?maxTrasError:te;
00252       c++;
00253     }
00254   } else {
00255     for (TreePoseGraph3::EdgeSet::const_iterator it=eset->begin(); it!=eset->end(); it++){
00256       const TreePoseGraph3::Edge* edge=*it;
00257       double re=rotationalError(edge);
00258       globalRotError+=re;
00259       maxRotError=maxRotError>re?maxRotError:re;
00260       double te=traslationalError(edge);
00261       globalTrasError+=te;
00262       maxTrasError=maxTrasError>te?maxTrasError:te;
00263       c++;
00264     }
00265   }
00266 
00267   if (mte)
00268     *mte=maxTrasError;
00269   if (mre)
00270     *mre=maxRotError;
00271   if (ate)
00272     *ate=globalTrasError/c;
00273   if (are)
00274     *are=globalRotError/c;
00275   return globalRotError+globalTrasError;
00276 }
00277 
00278 
00279 
00280 void TreeOptimizer3::initializeOptimization(EdgeCompareMode mode){
00281   edgeCompareMode=mode;
00282   // compute the size of the preconditioning matrix
00283   int sz=maxIndex()+1;
00284   DEBUG(1) << "Size= " << sz << endl;
00285   M.resize(sz);
00286 
00287   DEBUG(1) << "allocating M(" << sz << ")" << endl;
00288   iteration=1;
00289 
00290   // sorting edges
00291   if (sortedEdges!=0){
00292     delete sortedEdges;
00293     sortedEdges=0;
00294   }
00295   sortedEdges=sortEdges();
00296   mpl=maxPathLength();
00297   rotGain=1.;
00298   trasGain=1.;
00299 }
00300 
00301 void TreeOptimizer3::initializeOnlineIterations(){
00302   int sz=maxIndex()+1;
00303   DEBUG(1) << "Size= " << sz << endl;
00304   M.resize(sz);
00305   DEBUG(1) << "allocating M(" << sz << ")" << endl;
00306   iteration=1;
00307   maxRotationalErrors.clear();
00308   maxTranslationalErrors.clear();
00309   rotGain=1.;
00310   trasGain=1.;
00311 }
00312 
00313 void TreeOptimizer3::initializeOnlineOptimization(EdgeCompareMode mode){
00314   edgeCompareMode=mode;
00315   // compute the size of the preconditioning matrix
00316   clear();
00317   Vertex* v0=addVertex(0,Pose(0,0,0,0,0,0));
00318   root=v0;
00319   v0->parameters=Transformation(v0->pose);
00320   v0->parentEdge=0;
00321   v0->parent=0;
00322   v0->level=0;
00323   v0->transformation=Transformation(TreePoseGraph3::Pose(0,0,0,0,0,0));
00324 }
00325 
00326 void TreeOptimizer3::onStepStart(Edge* e){ 
00327   (void) e;
00328 }
00329 
00330 void TreeOptimizer3::onStepFinished(Edge* e){ 
00331   (void) e;
00332 }
00333 
00334 void TreeOptimizer3::onIterationStart(int iteration){ 
00335   (void) iteration;
00336 }
00337 
00338 void TreeOptimizer3::onIterationFinished(int iteration){ 
00339   (void) iteration;
00340 }
00341 
00342 bool TreeOptimizer3::isDone(){ 
00343   return false; 
00344 }
00345 
00346 

Generated on Mon Nov 12 11:43:00 2007 for TORO by  doxygen 1.5.0