posegraph3d.cpp
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 #include "posegraph3d.h"
00018 
00019 #include <cassert>
00020 #include <queue>
00021 #include <iostream>
00022 #include <iomanip>
00023 #include <cstdlib>
00024 #include <sys/time.h>
00025 
00026 #include <sstream>
00027 #include "hogman_minimal/stuff/os_specific.h"
00028 
00029 using namespace std;
00030 
00031 namespace AISNavigation{
00032   void PoseGraph3D::load(istream& is, bool overrideCovariances, std::vector <PoseGraph3D::Edge*>* orderedEdges)
00033   {
00034     clear();
00035     if (! is)
00036       return;
00037     Vertex* previousVertex=0;
00038     if (orderedEdges)
00039       orderedEdges->clear();
00040     string line;
00041     while (getline(is, line)) {
00042       if (line.size() == 0 || line[0] == '#') // skip comment lines
00043         continue;
00044       istringstream ls(line);
00045       string tag;
00046       ls >> tag;
00047       if (tag == "VERTEX3"){
00048         int id;
00049         Vector6 p;
00050         ls >> id;
00051         for (int i = 0; i < 6; ++i)
00052           ls >> p[i];
00053         Transformation3 t = Transformation3::fromVector(p);
00054         Matrix6 identity = Matrix6::eye(1.0);
00055         Vertex* v=addVertex(id, t, identity);
00056         if (! v) {
00057           cerr << "vertex " << id << " is already in the graph, reassigning "<<  endl;
00058           v = vertex(id);
00059           assert(v);
00060         } 
00061         v->transformation = t;
00062         v->localTransformation = t;
00063         previousVertex = v;
00064       } else if (tag == "EDGE3"){
00065         int id1, id2;
00066         Vector6 p;
00067         ls >> id1 >> id2;
00068         for (int i = 0; i < 6; ++i)
00069           ls >> p[i];
00070         Matrix6 m;
00071         if (overrideCovariances) {
00072           m = Matrix6::eye(1.0);
00073         } else {
00074           for (int i=0; i<6; i++)
00075             for (int j=i; j<6; j++) {
00076               ls >> m[i][j];
00077               if (i != j)
00078                 m[j][i] = m[i][j];
00079             }
00080         }
00081         previousVertex=0;
00082         Vertex* v1=vertex(id1);
00083         Vertex* v2=vertex(id2);
00084         if (! v1 ) {
00085           cerr << "vertex " << id1 << " is not existing, cannot add edge (" << id1 << "," << id2 << ")" << endl; 
00086           continue;
00087         }
00088         if (! v2 ) {
00089           cerr << "vertex " << id2 << " is not existing, cannot add edge (" << id1 << "," << id2 << ")" << endl; 
00090           continue;
00091         }
00092         Transformation3 t = Transformation3::fromVector(p);
00093         Edge* e = addEdge(v1, v2, t, m);
00094         if (! e){
00095           cerr << "error in adding edge " << id1 << "," << id2 << endl;
00096         } else {
00097           if (orderedEdges)
00098             orderedEdges->push_back(e);
00099         }
00100       }
00101     }
00102   }
00103   
00104   void PoseGraph3D::save(ostream& os, const Transformation3& offset, int type, bool onlyMarked) const
00105   {
00106     //os << setprecision(3);
00107 
00108     for (VertexIDMap::const_iterator it = _vertices.begin(); it != _vertices.end(); ++it) {
00109       const Vertex* v=dynamic_cast<const PoseGraph3D::Vertex*>(it->second);
00110       Transformation3 t = v->transformation;
00111       switch (type) {
00112         case 1: t = v->localTransformation; break;
00113       }
00114 
00115       t=offset*t;
00116       Vector6 pose =  t.toVector();
00117       os << "VERTEX3 " << v->id() << " " 
00118        << pose.x() << " " << pose.y() << " " << pose.z() << " "
00119        << pose[3] << " " << pose[4] << " " << pose[5] << endl;
00120 
00121     }
00122 
00123     for (int l = 0; l <= 1; ++l) { // separate writing of loop edges and sequential edges
00124       bool writeLoopEdges = l == 1;
00125       if (writeLoopEdges)
00126         os << "#LOOP EDGES" << endl;
00127       else
00128         os << "#SEQUENTIAL EDGES" << endl;
00129       for (EdgeSet::const_iterator it = _edges.begin(); it != _edges.end(); ++it) {
00130         const Edge* e = dynamic_cast<const PoseGraph3D::Edge*>(*it);
00131         if (onlyMarked && !e->_mark)
00132           continue;
00133         const Vertex* v1 = dynamic_cast<const PoseGraph3D::Vertex*>(e->from());
00134         const Vertex* v2 = dynamic_cast<const PoseGraph3D::Vertex*>(e->to());
00135         bool isLoop = abs(v1->id()-v2->id()) != 1;
00136         if (isLoop == writeLoopEdges) {
00137           os << "EDGE3 " << v1->id() << " " << v2->id() << " ";
00138           Vector6 p = e->mean().toVector();
00139           os << p.x() << " " << p.y() << " " << p.z() << " " << p[3] << " " << p[4] << " " << p[5];
00140           for (int i=0; i<6; i++)
00141             for (int j=i; j<6; j++)
00142               os << " " << e->information()[i][j];
00143           os << endl;
00144         }
00145       }
00146     }
00147   }
00148 
00149 void PoseGraph3D::saveGnuplot(std::ostream& os, const Transformation3& offset, bool onlyMarked) const
00150 {
00151   for (EdgeSet::const_iterator it = _edges.begin(); it != _edges.end(); ++it) {
00152     const Edge* e = dynamic_cast<const PoseGraph3D::Edge*>(*it);
00153     if (onlyMarked && !e->_mark)
00154       continue;
00155     const Vertex* v1 = dynamic_cast<const PoseGraph3D::Vertex*>(e->from());
00156     const Vertex* v2 = dynamic_cast<const PoseGraph3D::Vertex*>(e->to());
00157     Vector6 v1p = (offset * v1->transformation).toVector();
00158     Vector6 v2p = (offset * v2->transformation).toVector();
00159     os << v1p.x() << " " << v1p.y() << " " << v1p.z() << " "
00160        << v1p[3] << " " << v1p[4] << " " << v1p[5] <<endl;
00161     os << v2p.x() << " " << v2p.y() << " " << v2p.z() << " "
00162        << v2p[3] << " " << v2p[4] << " " << v2p[5] <<endl;
00163     os << endl << endl;
00164   }
00165 
00166 }
00167 
00168 void PoseGraph3D::loadBinary(std::istream& is, bool overrideCovariances, std::vector <PoseGraph3D::Edge*> *orderedEdges)
00169 {
00170   clear();
00171   if (! is)
00172     return;
00173   if (orderedEdges)
00174     orderedEdges->clear();
00175   char c = 0;
00176   while (is.get(c)) {
00177     if (c == 'V'){
00178       int id;
00179       Transformation3 t;
00180       Matrix6 identity = Matrix6::eye(1.0);
00181       is.read((char*)&id, sizeof(int));
00182       is.read((char*)&t.translation().x(), sizeof(double));
00183       is.read((char*)&t.translation().y(), sizeof(double));
00184       is.read((char*)&t.translation().z(), sizeof(double));
00185       is.read((char*)&t.rotation().w(), sizeof(double));
00186       is.read((char*)&t.rotation().x(), sizeof(double));
00187       is.read((char*)&t.rotation().y(), sizeof(double));
00188       is.read((char*)&t.rotation().z(), sizeof(double));
00189       Vertex* v=addVertex(id, t, identity);
00190       if (! v) {
00191         cerr << "vertex " << id << " is already in the graph, reassigning "<<  endl;
00192         v = vertex(id);
00193         assert(v);
00194       } 
00195       v->transformation = t;
00196       v->localTransformation = t;
00197     } else if (c == 'E'){
00198       int id1, id2;
00199       Transformation3 t;
00200       Matrix6 m(6, 6);
00201       is.read((char*)&id1, sizeof(int));
00202       is.read((char*)&id2, sizeof(int));
00203       is.read((char*)&t.translation().x(), sizeof(double));
00204       is.read((char*)&t.translation().y(), sizeof(double));
00205       is.read((char*)&t.translation().z(), sizeof(double));
00206       is.read((char*)&t.rotation().w(), sizeof(double));
00207       is.read((char*)&t.rotation().x(), sizeof(double));
00208       is.read((char*)&t.rotation().y(), sizeof(double));
00209       is.read((char*)&t.rotation().z(), sizeof(double));
00210       if (overrideCovariances) {
00211         double dummy; // just read over the information matrix
00212         for (int i=0; i<6; i++)
00213           for (int j=i; j<6; j++)
00214             is.read((char*)&dummy, sizeof(double));
00215       } else {
00216         for (int i=0; i<6; i++)
00217           for (int j=i; j<6; j++) {
00218             is.read((char*)&m[i][j], sizeof(double));
00219             if (i != j)
00220               m[j][i] = m[i][j];
00221           }
00222       }
00223 
00224       Vertex* v1=vertex(id1);
00225       Vertex* v2=vertex(id2);
00226       if (! v1 ) {
00227         cerr << "vertex " << id1 << " is not existing, cannot add edge (" << id1 << "," << id2 << ")" << endl; 
00228         continue;
00229       }
00230       if (! v2 ) {
00231         cerr << "vertex " << id2 << " is not existing, cannot add edge (" << id1 << "," << id2 << ")" << endl; 
00232         continue;
00233       }
00234       Edge* e = addEdge(v1, v2, t, m);
00235       if (! e){
00236         cerr << "error in adding edge " << id1 << "," << id2 << endl;
00237       } else {
00238         if (orderedEdges)
00239           orderedEdges->push_back(e);
00240       }
00241     }
00242   }
00243 
00244 }
00245 
00246 void PoseGraph3D::saveBinary(std::ostream& os, int type, bool onlyMarked) const
00247 {
00248   for (VertexIDMap::const_iterator it = _vertices.begin(); it != _vertices.end(); ++it) {
00249     const Vertex* v=dynamic_cast<const PoseGraph3D::Vertex*>(it->second);
00250     Transformation3 t = v->transformation;
00251     switch (type) {
00252       case 1: t = v->localTransformation; break;
00253     }
00254 
00255     os.put('V');
00256     int id = v->id();
00257     os.write((char*)&id, sizeof(int));
00258     os.write((char*)&t.translation().x(), sizeof(double));
00259     os.write((char*)&t.translation().y(), sizeof(double));
00260     os.write((char*)&t.translation().z(), sizeof(double));
00261     os.write((char*)&t.rotation().w(), sizeof(double));
00262     os.write((char*)&t.rotation().x(), sizeof(double));
00263     os.write((char*)&t.rotation().y(), sizeof(double));
00264     os.write((char*)&t.rotation().z(), sizeof(double));
00265   }
00266 
00267   for (EdgeSet::const_iterator it = _edges.begin(); it != _edges.end(); ++it) {
00268     const Edge* e = dynamic_cast<const PoseGraph3D::Edge*>(*it);
00269     if (onlyMarked && !e->_mark)
00270       continue;
00271     const Vertex* v1 = dynamic_cast<const PoseGraph3D::Vertex*>(e->from());
00272     const Vertex* v2 = dynamic_cast<const PoseGraph3D::Vertex*>(e->to());
00273     os.put('E');
00274     int id1 = v1->id();
00275     int id2 = v2->id();
00276     os.write((char*)&id1, sizeof(int));
00277     os.write((char*)&id2, sizeof(int));
00278     os.write((char*)&e->mean().translation().x(), sizeof(double));
00279     os.write((char*)&e->mean().translation().y(), sizeof(double));
00280     os.write((char*)&e->mean().translation().z(), sizeof(double));
00281     os.write((char*)&e->mean().rotation().w(), sizeof(double));
00282     os.write((char*)&e->mean().rotation().x(), sizeof(double));
00283     os.write((char*)&e->mean().rotation().y(), sizeof(double));
00284     os.write((char*)&e->mean().rotation().z(), sizeof(double));
00285     for (int i=0; i<6; i++)
00286       for (int j=i; j<6; j++)
00287         os.write((char*)&e->information()[i][j], sizeof(double));
00288   }
00289 }
00290 
00291 void PoseGraph3D::visualizeToStream(std::ostream& os) const
00292 {
00293   struct timeval now;
00294   gettimeofday(&now, 0);
00295   double curTime = now.tv_sec + now.tv_usec*1e-6;
00296   saveBinary(os);
00297   os << "T"; // write time spend in optimization, used to record video in realtime
00298   os.write((char*)&curTime, sizeof(double));
00299   os << "F" << flush;
00300 }
00301 
00302 } // end namespace


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