posegraph.hxx

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 
00045 /*********************** IMPLEMENTATION PART ***********************/
00046 template <typename Ops>
00047 typename TreePoseGraph<Ops>::Vertex* TreePoseGraph<Ops>::vertex(int id){
00048   typename VertexMap::iterator it=vertices.find(id);
00049   if (it==vertices.end())
00050     return 0;
00051   return it->second;
00052 }
00053 
00054 template <typename Ops>
00055 const typename TreePoseGraph<Ops>::Vertex * TreePoseGraph<Ops>::vertex (int id) const{
00056   typename VertexMap::const_iterator it=vertices.find(id);
00057   if (it==edges.end())
00058     return 0;
00059   return it->second;
00060 }
00061 
00062 template <class Ops>
00063 typename TreePoseGraph<Ops>::Edge* TreePoseGraph<Ops>::edge(int id1, int id2){
00064   Vertex* v1=vertex(id1);
00065   if (!v1)
00066     return false;
00067   typename EdgeList::iterator it=v1->edges.begin();
00068   while(it!=v1->edges.end()){
00069     if ((*it)->v1->id==id1 && (*it)->v2->id==id2)
00070       return *it;
00071     it++;
00072   }
00073   return 0;
00074 }
00075 
00076 template <class Ops>
00077 const typename TreePoseGraph<Ops>::Edge * TreePoseGraph<Ops>::edge(int id1, int id2) const{
00078   const Vertex* v1=vertex(id1);
00079   if (!v1)
00080     return false;
00081   typename EdgeList::const_iterator it=v1->edges.begin();
00082   while(it!=v1->edges.end()){
00083     if ((*it)->v1->id==id1 && (*it)->v2->id==id2)
00084       return *it;
00085     it++;
00086   }
00087   return 0;
00088 }
00089 
00090 template <class Ops>
00091 void TreePoseGraph<Ops>::revertEdge(TreePoseGraph<Ops>::Edge * e){
00092   revertEdgeInfo(e);
00093   Vertex* ap=e->v2; 
00094   e->v2=e->v1; 
00095   e->v1=ap; 
00096 }
00097 
00098 template <class Ops>
00099 typename TreePoseGraph<Ops>::Vertex* TreePoseGraph<Ops>::addVertex(int id, const TreePoseGraph<Ops>::Pose& pose){
00100   Vertex* v=vertex(id);
00101   if (v)
00102     return 0;
00103   v=new Vertex;
00104   v->id=id;
00105   v->pose=pose;
00106   v->parent=0;
00107   v->mark=false;
00108   vertices.insert(make_pair(id,v));
00109   return v;
00110 }
00111 
00112 template <class Ops>
00113 typename TreePoseGraph<Ops>::Vertex* TreePoseGraph<Ops>::removeVertex (int id){
00114   typename VertexMap::iterator it=vertices.find(id);
00115   if (it==vertices.end())
00116     return 0;
00117   Vertex* v=it->second;
00118 
00119   if (v==0)
00120     return false;
00121 
00122   typename TreePoseGraph<Ops>::EdgeList el=v->edges;
00123   for(typename EdgeList::iterator it=el.begin(); it!=el.end(); it++){
00124     removeEdge(*it);
00125   }
00126   delete v;
00127   vertices.erase(it);
00128   return v;
00129 }
00130 
00131 template <class Ops>
00132 typename TreePoseGraph<Ops>::Edge* TreePoseGraph<Ops>::addEdge(TreePoseGraph<Ops>::Vertex* v1, TreePoseGraph<Ops>::Vertex* v2, 
00133                                                                  const TreePoseGraph<Ops>::Transformation& t, const TreePoseGraph<Ops>::Information& i){
00134   Edge* e=edge(v1->id, v2->id);
00135   if (e)
00136     return 0;
00137   
00138   e=new Edge;
00139   e->mark=false;
00140   e->v1=v1;
00141   e->v2=v2;
00142   e->top=0;
00143   e->transformation=t;
00144   e->informationMatrix=i;
00145   v1->edges.push_back(e);
00146   v2->edges.push_back(e);
00147   edges.insert(make_pair(e,e));
00148   return e;
00149 }
00150 
00151 template <class Ops>
00152 typename TreePoseGraph<Ops>::Edge* TreePoseGraph<Ops>::addIncrementalEdge(int id1, int id2, 
00153                                                                const TreePoseGraph<Ops>::Transformation& t, const TreePoseGraph<Ops>::Information& i){
00154   EVComparator<Edge*> comp;
00155   comp.mode=edgeCompareMode;
00156   if (! sortedEdges)
00157     sortedEdges=new EdgeSet(comp);
00158 
00159   typename VertexMap::iterator it1=vertices.find(id1);
00160   typename VertexMap::iterator it2=vertices.find(id2);
00161   Vertex* v1, *v2, *addedVertex=0;
00162   if (it1==vertices.end() && it2==vertices.end()){
00163     return 0;
00164   }
00165   
00166   if (it1==vertices.end()){
00167     typename TreePoseGraph<Ops>::Pose p;
00168     v1=addedVertex=addVertex(id1,p); 
00169   } else {
00170     v1=it1->second;
00171   }
00172   if (it2==vertices.end()){
00173     typename TreePoseGraph<Ops>::Pose p;
00174     v2=addedVertex=addVertex(id2,p); 
00175   } else {
00176     v2=it2->second;
00177   }
00178 
00179   Edge* e=addEdge(v1,v2,t,i);
00180   if (!e){
00181     return 0;
00182   }
00183   
00184   if (addedVertex){
00185     Vertex* otherVertex= (addedVertex==v1)? v2:v1;
00186     addedVertex->parent=otherVertex;
00187     addedVertex->parentEdge=e;
00188     addedVertex->level=otherVertex->level+1;
00189     otherVertex->children.push_back(e);
00190   }
00191   if(v1->id>v2->id){
00192     revertEdge(e);
00193   }
00194   
00195   fillEdgeInfo(e);
00196   sortedEdges->insert(e);
00197 
00198   if (addedVertex){
00199     initializeFromParentEdge(addedVertex);
00200   }
00201   return e;
00202 }
00203 
00204 
00205 template <class Ops>
00206 typename TreePoseGraph<Ops>::Edge* TreePoseGraph<Ops>::removeEdge(TreePoseGraph<Ops>::Edge* e){
00207   {
00208     typename EdgeMap::iterator it=edges.find(e);
00209     if (it==edges.end()){
00210       return 0;
00211     }
00212     edges.erase(it);
00213   }
00214 
00215 
00216   Vertex* v1=e->v1;
00217   Vertex* v2=e->v2;
00218 
00219   {
00220     typename EdgeList::iterator it=v1->edges.begin();
00221     while(it!=v1->edges.end()){
00222       if (*it==e){
00223         v1->edges.erase(it);
00224         break;
00225       }
00226       it++;
00227     }
00228   }
00229 
00230   {
00231     typename EdgeList::iterator it=v2->edges.begin();
00232     while(it!=v2->edges.end()){
00233       if ((*it)==e){
00234         delete *it;
00235         v2->edges.erase(it);
00236         break;
00237       }
00238       it++;
00239     }
00240   }
00241   
00242   return e;
00243 }
00244 
00245 template <class Ops>
00246 template <class Action>
00247 void TreePoseGraph<Ops>::treeBreadthVisit(Action& act){
00248   typedef std::deque<Vertex*> VertexDeque;
00249   VertexDeque q;
00250   q.push_back(root);
00251   while (!q.empty()){
00252     Vertex* current=q.front();
00253     act.perform(current);
00254     q.pop_front();
00255     typename EdgeList::iterator it=current->children.begin();
00256     while(it!=current->children.end()){
00257       typename TreePoseGraph::Edge* e=(*it);
00258       q.push_back(e->v2);
00259       if(e->v2==current){
00260         //std::cerr << "error in the link direction v=" << current->id << std::endl;
00261         //std::cerr << " v1=" << e->v1->id << " v2=" << e->v2->id <<  std::endl;
00262         assert(0);
00263 
00264       }
00265       it++;
00266     }
00267   }
00268 }
00269 
00270 template <class Ops>
00271 template <class Action>
00272 void TreePoseGraph<Ops>::treeDepthVisit(Action& act, Vertex* v){
00273   act.perform(v);
00274   typename EdgeList::iterator it=v->children.begin();
00275   while(it!=v->children.end()){
00276     treeDepthVisit(act, (*it)->v2);
00277     it++;
00278   }
00279 }
00280 
00281 template <class Ops>
00282 bool TreePoseGraph<Ops>::buildMST(int id){
00283   typedef std::deque<Vertex*> VertexDeque;
00284   typename VertexMap::iterator it=vertices.begin();
00285   while (it!=vertices.end()){
00286     it->second->parent=0;
00287     it->second->parentEdge=0;
00288     it->second->children.clear(); 
00289     it++;
00290   }
00291   Vertex* v=vertex(id);
00292   if (!v)
00293     return false;
00294   root=v;
00295   root->level=0;
00296   VertexDeque q;
00297   q.push_back(v);
00298   //std::cerr << "v=" << v->id << std::endl;
00299   while (!q.empty()){
00300     v=q.front();
00301     typename EdgeList::iterator it=v->edges.begin();
00302     while (it!=v->edges.end()){
00303       Edge* e=(*it);
00304       bool invertedEdge=false;
00305       Vertex* other=e->v2;
00306       if (other==v){
00307         other=e->v1;
00308         invertedEdge=true;
00309       }
00310       if (other!=root && other->parent==0){
00311         if (invertedEdge){
00312           revertEdge(e);
00313         }
00314         //std::cerr << "INSERT v=" << v->id<< " " << "e=(" << e->v1->id << "," << e->v2->id << ")" << std::endl; 
00315         other->parent=v;
00316         other->parentEdge=e;
00317         other->level=v->level+1;
00318         q.push_back(other);
00319         v->children.push_back(e);
00320         //std::cerr << "v=" << other->id << std::endl;
00321       }
00322       it++;
00323     }
00324     q.pop_front();
00325   }
00326   fillEdgesInfo();
00327   return true;
00328 }
00329 
00331 template <class TPG>
00332 struct LevelAssigner{
00334   void perform(typename TPG::Vertex* v){
00335     if (v->parent)
00336       v->level=v->parent->level+1;
00337     else
00338       v->level=0;
00339   }
00340 };
00341 
00342 
00343 
00344 
00345 template <class Ops>
00346 bool TreePoseGraph<Ops>::buildSimpleTree(){
00347   root=0;
00348   //rectify all the constraints, so that the v1<v2
00349   for (typename EdgeMap::iterator it=edges.begin(); it!=edges.end(); it++){
00350     Edge* e=it->second;
00351     if (e->v1->id > e->v2->id)
00352       revertEdge(e);
00353   }
00354 
00355   //clear the tree data
00356   for (typename VertexMap::iterator it=vertices.begin(); it!=vertices.end(); it++){
00357     Vertex* v=it->second;
00358     v->parent=0;
00359     v->parentEdge=0;
00360     v->children.clear();
00361   }
00362 
00363   //fill the structure
00364   for (typename VertexMap::iterator it=vertices.begin(); it!=vertices.end(); it++){
00365     Vertex* v=it->second;
00366     if (v->edges.empty()){
00367       assert(0);
00368       continue;
00369     }
00370     Edge* bestEdge=v->edges.front();
00371     int bestId=MAXINT;
00372     bool found=false;
00373     typename EdgeList::iterator li=v->edges.begin();
00374     while(li!=v->edges.end()){
00375       Edge* e =*li;
00376       if (e->v2==v && e->v1->id<bestId){ //consider only the entering edges
00377         bestId=e->v1->id;
00378         bestEdge=e;
00379         found=true;
00380       }
00381       li++;
00382     }
00383     if (found){
00384       v->parentEdge=bestEdge;
00385       v->parent=bestEdge->v1;
00386       v->parent->children.push_back(bestEdge);
00387     } else {
00388       assert(! root);
00389       root=v;
00390     }
00391   }
00392 //   std::cerr << "root="  << root << std::endl;
00393   assert(root);
00394 
00395   //assign the level
00396   LevelAssigner< TreePoseGraph<Ops> > oa;
00397   treeDepthVisit(oa, root);
00398 
00399   fillEdgesInfo();
00400   return true;
00401 }
00402 
00403 template <class Ops>
00404 TreePoseGraph<Ops>::~TreePoseGraph(){
00405   clear();
00406 }
00407 
00408 template <class Ops>
00409 void TreePoseGraph<Ops>::clear(){
00410   for (typename VertexMap::iterator it=vertices.begin(); it!=vertices.end(); it++){
00411     delete it->second;
00412     it->second=0;
00413   }
00414   for (typename EdgeMap::iterator it=edges.begin(); it!=edges.end(); it++){
00415     delete it->second;
00416     it->second=0;
00417   }
00418   vertices.clear();
00419   edges.clear();
00420   if ( sortedEdges )
00421     delete sortedEdges;
00422   sortedEdges=0;
00423 }
00424 
00425 template <class Ops>
00426 void TreePoseGraph<Ops>::fillEdgeInfo(Edge* e){
00427   Vertex* v1=e->v1;
00428   Vertex* v2=e->v2;
00429   int length=0;
00430   while (v1!=v2) {
00431     if (v1->level > v2->level){
00432       v1=v1->parent;
00433       length++;
00434     } else if (v2->level > v1->level){
00435       v2=v2->parent;
00436       length++;
00437     } else if (v1->level==v2->level){
00438       v1=v1->parent;
00439       v2=v2->parent;
00440       length+=2;
00441     }
00442   }
00443   e->length=length;
00444   e->top=v1;
00445 }
00446 
00447 template <class Ops>
00448 void TreePoseGraph<Ops>::fillEdgesInfo(){
00449   typename TreePoseGraph<Ops>::EdgeMap em=edges;
00450   for(typename EdgeMap::iterator it=em.begin(); it!=em.end(); it++){
00451     fillEdgeInfo(it->second);
00452   }
00453 }
00454 
00455 
00456 template <class Ops>
00457 typename TreePoseGraph<Ops>::EdgeSet* TreePoseGraph<Ops>::sortEdges(){
00458   EVComparator<Edge*> comp;
00459   comp.mode=edgeCompareMode;
00460   EdgeSet * el=new EdgeSet(comp);
00461   typename EdgeMap::iterator it=edges.begin();
00462   while(it!=edges.end()){
00463     el->insert(it->second);
00464     it++;
00465   }
00466   return el;
00467 }
00468 
00469 template <class Ops>
00470 typename TreePoseGraph<Ops>::EdgeSet* TreePoseGraph<Ops>::affectedEdges(Vertex* v){
00471   EVComparator<Edge*> comp;
00472   comp.mode=edgeCompareMode;
00473   EdgeSet * es=new EdgeSet(comp);
00474   std::deque<Vertex*> frontier;
00475   std::list<Vertex*> markedVertices;
00476  
00477   //frontier.push_back(v);
00478   //v->mark=true;
00479  
00480   for (typename EdgeList::iterator it=v->children.begin(); it!=v->children.end(); it++){
00481     Edge* e=*it;
00482     Vertex* other=(e->v1==v)?e->v2:e->v1;
00483     frontier.push_back(other);
00484     other->mark=true;
00485     markedVertices.push_back(other);
00486     e->mark=true;
00487     es->insert(e);
00488    }
00489 
00490   while (! frontier.empty()){
00491     Vertex* c=frontier.front();
00492     frontier.pop_front();
00493     markedVertices.push_back(c);
00494     EdgeList& el=c->edges;
00495     for (typename EdgeList::iterator it=el.begin(); it!=el.end(); it++){
00496       Edge* e=*it;
00497       if (e->mark)
00498         continue;
00499       Vertex* other= (e->v1==c)?e->v2:e->v1;
00500       if (other==c->parent)
00501         continue;
00502       if (other!=e->top && ! e->top->mark){
00503         e->top->mark=true;
00504         frontier.push_back(e->top);
00505       }
00506       e->mark=true;
00507       es->insert(e);
00508       if (!other->mark){
00509         other->mark=true;
00510         frontier.push_back(other);
00511       }
00512     }
00513   }
00514   for (typename std::list<Vertex*>::iterator it=markedVertices.begin(); it!=markedVertices.end(); it++){
00515     (*it)->mark=false;
00516   }
00517 
00518   for (typename EdgeSet::iterator it=es->begin(); it!=es->end(); it++){
00519     (*it)->mark=false;
00520   }
00521   return es;
00522 }
00523 
00524 template <class Ops>
00525 typename TreePoseGraph<Ops>::EdgeSet* TreePoseGraph<Ops>::affectedEdges(typename TreePoseGraph<Ops>::VertexSet& vl){
00526   EVComparator<Edge*> comp;
00527   comp.mode=edgeCompareMode;
00528   EdgeSet * es=new EdgeSet(comp);
00529   std::deque<Vertex*> frontier;
00530   std::list<Vertex*> markedVertices;
00531 
00532 //   for (typename VertexSet::iterator it=vl.begin(); it!=vl.end(); it++){
00533 //     frontier.push_back(*it);
00534 //     (*it)->mark=true;
00535 //   }
00536 
00537   for (typename VertexSet::iterator it=vl.begin(); it!=vl.end(); it++){
00538     Vertex* v=*it;
00539     for (typename EdgeList::iterator it=v->children.begin(); it!=v->children.end(); it++){
00540       Edge* e=*it;
00541       Vertex* other=(e->v1==v)?e->v2:e->v1;
00542       frontier.push_back(other);
00543       other->mark=true;
00544       markedVertices.push_back(other);
00545       e->mark=true;
00546       es->insert(e);
00547     }
00548   }
00549 
00550 
00551 
00552 
00553   while (! frontier.empty()){
00554     Vertex* c=frontier.front();
00555     frontier.pop_front();
00556     markedVertices.push_back(c);
00557     EdgeList& el=c->edges;
00558     for (typename EdgeList::iterator it=el.begin(); it!=el.end(); it++){
00559       Edge* e=*it;
00560       if (e->mark)
00561         continue;
00562       Vertex* other= (e->v1==c)?e->v2:e->v1;
00563       if (other==c->parent)
00564         continue;
00565       if (other!=e->top && ! e->top->mark){
00566         e->top->mark=true;
00567         frontier.push_back(e->top);
00568       }
00569       e->mark=true;
00570       es->insert(e);
00571       if (!other->mark){
00572         other->mark=true;
00573         frontier.push_back(other);
00574       }
00575     }
00576   }
00577   for (typename std::list<Vertex*>::iterator it=markedVertices.begin(); it!=markedVertices.end(); it++){
00578     (*it)->mark=false;
00579   }
00580 
00581   for (typename EdgeSet::iterator it=es->begin(); it!=es->end(); it++){
00582     (*it)->mark=false;
00583   }
00584   return es;
00585 }
00586 
00587 
00588 
00589 template <class Ops>
00590 int TreePoseGraph<Ops>::maxPathLength(){
00591   int max=0;
00592   typename EdgeMap::const_iterator it=edges.begin();
00593   while(it!=edges.end()){
00594     int l=it->second->length;
00595     max=l>max?l:max;
00596     it++;
00597   }
00598   return max;
00599 }
00600 
00601 template <class Ops>
00602 int TreePoseGraph<Ops>::totalPathLength(){
00603   int t=0;
00604   typename EdgeMap::const_iterator it=edges.begin();
00605   while(it!=edges.end()){
00606     t+=it->second->length;
00607     it++;
00608   }
00609   return t;
00610 }
00611 
00612 
00613 template <class Ops>
00614 void TreePoseGraph<Ops>::compressIndices(){
00615   VertexMap vmap;
00616   int i=0;
00617   for (typename VertexMap::iterator it=vertices.begin(); it!=vertices.end(); it++){
00618     Vertex* v=it->second;
00619     v->id=i;
00620     vmap.insert(make_pair(i,v));
00621     i++;
00622   }
00623   vertices=vmap;
00624 }
00625 
00626 template <class Ops>
00627 int TreePoseGraph<Ops>::maxIndex(){
00628   typename VertexMap::reverse_iterator it=vertices.rbegin();
00629   if (it!=vertices.rend())
00630     return it->second->id;
00631   return -1;
00632 }
00633 
00634 
00636 template <class TPG>
00637 struct CompressedNodesMarker{
00638   typename TPG::BaseType distance;
00639   int marked;
00640   CompressedNodesMarker(){
00641     distance=0;
00642     marked=0;
00643   }
00645   void perform(typename TPG::Vertex* v){
00646     typename TPG::Vertex* aux=v;
00647     typename TPG::Transformation vt=v->transformation;
00648     while (aux && ! aux->mark && aux->parent){
00649       aux=aux->parent;
00650     }
00651     if (! aux)
00652       return;
00653     typename TPG::Transformation at=aux->transformation;
00654     typename TPG::Transformation dt=at.inv()*vt;
00655     typename TPG::Translation dtrans=dt.translation();
00656     typename TPG::BaseType d=sqrt(dtrans*dtrans);
00657     if (d<distance)
00658       v->mark=false;
00659     else {
00660       v->mark=true;
00661       marked++;
00662     }
00663   }
00664 };
00665 
00666 template <class Ops>
00667 int TreePoseGraph<Ops>::markNodesToCompress( TreePoseGraph<Ops>::BaseType distance){
00668   for (typename VertexMap::iterator it=vertices.begin(); it!=vertices.end(); it++){
00669     Vertex* v=it->second;
00670     v->mark=false;
00671   }
00672   assert(root);
00673   root->mark=true;
00674   CompressedNodesMarker< TreePoseGraph<Ops> > nc;
00675   nc.distance=distance;
00676   treeDepthVisit(nc, root);
00677   return nc.marked;
00678 }

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