read_spa.cpp
Go to the documentation of this file.
00001 /*********************************************************************
00002 * Software License Agreement (BSD License)
00003 *
00004 *  Copyright (c) 2009, Willow Garage, Inc.
00005 *  All rights reserved.
00006 *
00007 *  Redistribution and use in source and binary forms, with or without
00008 *  modification, are permitted provided that the following conditions
00009 *  are met:
00010 *
00011 *   * Redistributions of source code must retain the above copyright
00012 *     notice, this list of conditions and the following disclaimer.
00013 *   * Redistributions in binary form must reproduce the above
00014 *     copyright notice, this list of conditions and the following
00015 *     disclaimer in the documentation and/or other materials provided
00016 *     with the distribution.
00017 *   * Neither the name of the Willow Garage nor the names of its
00018 *     contributors may be used to endorse or promote products derived
00019 *     from this software without specific prior written permission.
00020 *
00021 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032 *  POSSIBILITY OF SUCH DAMAGE.
00033 *********************************************************************/
00034 
00035 // convert a file in Freiburg's VERTEX / EDGE format into a set of constraints
00036 
00037 #include "sba/read_spa.h"
00038 #include <iostream>
00039 #include <iomanip>
00040 #include <fstream>
00041 #include <sstream>
00042 #include <sys/time.h>
00043 
00044 using namespace std;
00045 using namespace Eigen;
00046 
00047 //
00048 // read in an SPA file
00049 //
00050 
00051 //
00052 // Format:
00053 //  # XXXX  - comment line
00054 //  VERTEX3 n xyz rpy  - node line
00055 //  EDGE3 n1 n2 xyz rpy - edge line
00056 //
00057 
00058 // NOTE: assumes vertices are in order starting with index 0
00059 
00060 // makes a quaternion from fixed Euler RPY angles
00061 // see the Wikipedia article on Euler anlges
00062 void make_qrot(double rr, double rp, double ry, Vector4d &v)
00063 {
00064   double sr = sin(rr/2.0);
00065   double cr = cos(rr/2.0);
00066   double sp = sin(rp/2.0);
00067   double cp = cos(rp/2.0);
00068   double sy = sin(ry/2.0);
00069   double cy = cos(ry/2.0);
00070   v[0] = sr*cp*cy - cr*sp*sy;   // qx
00071   v[1] = cr*sp*cy + sr*cp*sy;   // qy
00072   v[2] = cr*cp*sy - sr*sp*cy;   // qz
00073   v[3] = cr*cp*cy + sr*sp*sy;   // qw
00074 }
00075 
00076 // cv is upper triangular
00077 void make_covar(double *cv, Matrix<double,6,6> &m)
00078 {
00079   m.setZero();
00080 
00081   int i = 0;
00082   m(0,0) = cv[i++];
00083   m(0,1) = cv[i++];
00084   m(0,2) = cv[i++];
00085   m(0,3) = cv[i++];
00086   m(0,4) = cv[i++];
00087   m(0,5) = cv[i++];
00088 
00089   m(1,1) = cv[i++];
00090   m(1,2) = cv[i++];
00091   m(1,3) = cv[i++];
00092   m(1,4) = cv[i++];
00093   m(1,5) = cv[i++];
00094 
00095   m(2,2) = cv[i++];
00096   m(2,3) = cv[i++];
00097   m(2,4) = cv[i++];
00098   m(2,5) = cv[i++];
00099 
00100   m(3,3) = cv[i++];
00101   m(3,4) = cv[i++];
00102   m(3,5) = cv[i++];
00103 
00104   m(4,4) = cv[i++];
00105   m(4,5) = cv[i++];
00106 
00107   m(5,5) = cv[i++];
00108 
00109   // make symmetric
00110   Matrix<double,6,6> mt = m.transpose();
00111   mt.diagonal().setZero();
00112   m = m+mt;
00113 }
00114 
00115 
00116 int
00117 ReadSPAFile(char *fin,          // input file
00118             // node translation
00119             std::vector< Eigen::Vector3d, Eigen::aligned_allocator<Eigen::Vector3d> > &ntrans,
00120             // node rotation
00121             std::vector< Eigen::Vector4d, Eigen::aligned_allocator<Eigen::Vector4d> > &nqrot,
00122             // constraint indices
00123             std::vector< Eigen::Vector2i, Eigen::aligned_allocator<Eigen::Vector2i> > &cind,
00124             // constraint local translation 
00125             std::vector< Eigen::Vector3d, Eigen::aligned_allocator<Eigen::Vector3d> > &ctrans,
00126             // constraint local rotation as quaternion
00127             std::vector< Eigen::Vector4d, Eigen::aligned_allocator<Eigen::Vector4d> > &cqrot,
00128             // constraint covariance
00129             std::vector< Eigen::Matrix<double,6,6>, Eigen::aligned_allocator<Eigen::Matrix<double,6,6> > > &cvar,
00130             // track info: point projections, see format description in IntelSeattle files
00131             std::vector<struct tinfo> &tracks
00132             )
00133 {
00134   ifstream ifs(fin);
00135   if (ifs == NULL)
00136     {
00137       cout << "Can't open file " << fin << endl;
00138       return -1;
00139     }
00140   ifs.precision(10);
00141 
00142   // loop over lines
00143   string line;
00144   int nline = 0;
00145   bool first = true;
00146   while (getline(ifs,line))
00147     {
00148       nline++;
00149       stringstream ss(line);    // make a string stream
00150       string type;
00151       ss >> type;
00152       size_t pos = type.find("#");
00153       if (pos != string::npos)
00154         continue;               // comment line
00155 
00156       if (type == "VERTEX3")    // have a vertex
00157         {
00158           int n;
00159           double tx,ty,tz,rr,rp,ry;
00160           if (!(ss >> n >> tx >> ty >> tz >> rr >> rp >> ry))
00161             {
00162               cout << "[ReadSPA] Bad VERTEX3 at line " << nline << endl;
00163               return -1;
00164             }
00165           ntrans.push_back(Vector3d(tx,ty,tz));
00166           Vector4d v;
00167           make_qrot(rr,rp,ry,v);
00168           nqrot.push_back(v);
00169         }
00170 
00171       if (type == "EDGE3")      // have an edge
00172         {
00173           int n1,n2;
00174           double tx,ty,tz,rr,rp,ry;
00175           double cv[21];
00176 
00177           // indices and measurement
00178           if (!(ss >> n1 >> n2 >> tx >> ty >> tz >> rr >> rp >> ry))
00179             {
00180               cout << "[ReadSPA] Bad EDGE3 at line " << nline << endl;
00181               return -1;
00182             }
00183           cind.push_back(Vector2i(n1,n2));
00184           ctrans.push_back(Vector3d(tx,ty,tz));
00185           Vector4d v;
00186           make_qrot(rr,rp,ry,v);
00187           cqrot.push_back(v);
00188 
00189           // covar
00190           if (!(ss >> cv[0] >> cv[1] >> cv[2] >> cv[3] >> cv[4] 
00191                 >> cv[5] >> cv[6] >> cv[7] >> cv[8] >> cv[9] 
00192                 >> cv[10] >> cv[11] >> cv[12] >> cv[13] >> cv[14] 
00193                 >> cv[15] >> cv[16] >> cv[17] >> cv[18] >> cv[19] >> cv[20]))
00194             {
00195               cout << "[ReadSPA] Bad EDGE3 at line " << nline << endl;
00196               return -1;
00197             }
00198           Matrix<double,6,6> m;
00199           make_covar(cv,m);
00200           if (first)
00201             {
00202               //cout << endl;
00203               //for (int j=0; j<21; j++);
00204                 //cout << cv[j] << " ";
00205               //cout << endl << endl << << m << endl;
00206               first = false;
00207             }
00208           cvar.push_back(m);
00209         }
00210 
00211 
00212       if (type == "TRACK32")      // have a point projection pair
00213         {
00214           struct tinfo tt;
00215           int pi,fi,fpi;
00216           double tx,ty,tz,u,v;
00217 
00218           // indices and measurement
00219           if (!(ss >> pi >> fi >> fpi >> tx >> ty >> tz >> u >> v))
00220             {
00221               cout << "[ReadSPA] Bad TRACK32 at line " << nline << endl;
00222               return -1;
00223             }
00224           tt.pn = pi;
00225           tt.fn0 = fi;
00226           tt.fpn0 = fpi;
00227           tt.x0 = tx;
00228           tt.y0 = ty;
00229           tt.z0 = tz;
00230           tt.u0 = u;
00231           tt.v0 = v;
00232 
00233           // second projection of pair
00234           if (!(ss >> fi >> fpi >> tx >> ty >> tz >> u >> v))
00235             {
00236               cout << "[ReadSPA] Bad TRACK32 at line " << nline << endl;
00237               return -1;
00238             }
00239           tt.fn1 = fi;
00240           tt.fpn1 = fpi;
00241           tt.x1 = tx;
00242           tt.y1 = ty;
00243           tt.z1 = tz;
00244           tt.u1 = u;
00245           tt.v1 = v;
00246 
00247           tracks.push_back(tt);
00248 
00249         }
00250 
00251     }
00252 
00253   return 0;
00254 }
00255 
00256 
00257 // 2D code
00258 
00259 // cv is upper triangular
00260 void make_covar_2d(double *cv, Matrix<double,3,3> &m, bool useFreiburg)
00261 {
00262   m.setZero();
00263 
00264   int i = 0;
00265   if (useFreiburg)
00266     {
00267       m(0,0) = cv[i++];
00268       m(0,1) = cv[i++];
00269       m(1,1) = cv[i++];
00270 
00271       m(2,2) = cv[i++];
00272       m(0,2) = cv[i++];
00273       m(1,2) = cv[i++];
00274     }
00275   else
00276     {
00277       m(0,0) = cv[i++];
00278       m(0,1) = cv[i++];
00279       m(0,2) = cv[i++];
00280 
00281       m(1,1) = cv[i++];
00282       m(1,2) = cv[i++];
00283 
00284       m(2,2) = cv[i++];
00285     }
00286 
00287   // make symmetric
00288   Matrix<double,3,3> mt = m.transpose();
00289   mt.diagonal().setZero();
00290   m = m+mt;
00291 }
00292 
00293 
00294 int
00295 ReadSPA2dFile(char *fin,          // input file
00296             // node translation
00297             std::vector< Eigen::Vector2d, Eigen::aligned_allocator<Eigen::Vector2d> > &ntrans,
00298             // node rotation
00299             std::vector< double > &narot,
00300             // constraint indices
00301             std::vector< Eigen::Vector2i, Eigen::aligned_allocator<Eigen::Vector2i> > &cind,
00302             // constraint local translation 
00303             std::vector< Eigen::Vector2d, Eigen::aligned_allocator<Eigen::Vector2d> > &ctrans,
00304             // constraint local rotation as angle
00305             std::vector< double > &carot,
00306             // constraint covariance
00307             std::vector< Eigen::Matrix<double,3,3>, Eigen::aligned_allocator<Eigen::Matrix<double,3,3> > > &cvar,
00308             // scan points
00309             std::vector< std::vector< Eigen::Vector2d, Eigen::aligned_allocator<Eigen::Vector2d> > > &scans
00310             )
00311 {
00312   ifstream ifs(fin);
00313   if (ifs == NULL)
00314     {
00315       cout << "Can't open file " << fin << endl;
00316       return -1;
00317     }
00318   ifs.precision(10);
00319 
00320   VectorXi ind;                 // indices
00321   ind.setConstant(1000000,-1);  // invalid 
00322   int cur = 0;                  // current index
00323   bool useFreiburg = false;     // for Freiburg odd covariances
00324 
00325   // loop over lines
00326   string line;
00327   int nline = 0;
00328   bool first = true;
00329   while (getline(ifs,line))
00330     {
00331       nline++;
00332       stringstream ss(line);    // make a string stream
00333       string type;
00334       ss >> type;
00335       size_t pos = type.find("#");
00336       if (pos != string::npos)
00337         {
00338           pos = type.find("#FCOVAR");
00339           if (pos != string::npos)
00340             {
00341               useFreiburg = true;
00342               cout << "Using Freiburg covariances" << endl;
00343             }
00344           continue;             // comment line
00345         }
00346 
00347       if (type == "VERTEX2")    // have a vertex
00348         {
00349           int n;
00350           double tx,ty,rr;
00351           if (!(ss >> n >> tx >> ty >> rr))
00352             {
00353               cout << "[ReadSPA2d] Bad VERTEX2 " << n << " at line " << nline << endl;
00354               return -1;
00355             }
00356           ntrans.push_back(Vector2d(tx,ty));
00357           narot.push_back(rr);
00358           ind[n] = cur++;
00359         }
00360 
00361       if (type == "EDGE2")      // have an edge
00362         {
00363           int n1,n2;
00364           double tx,ty,rr;
00365           double cv[6];
00366 
00367           // indices and measurement
00368           if (!(ss >> n1 >> n2 >> tx >> ty >> rr))
00369             {
00370               cout << "[ReadSPA2d] Bad EDGE2 at line " << nline << endl;
00371               return -1;
00372             }
00373 
00374           n1 = ind[n1];
00375           n2 = ind[n2];
00376 
00377           if (n1 < 0 || n2 < 0)
00378             {
00379               cout << "[ReadSPA2d] Bad EDGE2 indices at line " << nline << endl << line << endl;
00380               return -1;
00381             }
00382 
00383           cind.push_back(Vector2i(n1,n2));
00384           ctrans.push_back(Vector2d(tx,ty));
00385           carot.push_back(rr);
00386 
00387           // covar
00388           if (!(ss >> cv[0] >> cv[1] >> cv[2] >> cv[3] >> cv[4] 
00389                 >> cv[5]))
00390             {
00391               cout << "[ReadSPA2d] Bad EDGE2 at line " << nline << endl;
00392               return -1;
00393             }
00394           Matrix<double,3,3> m;
00395           make_covar_2d(cv,m,useFreiburg);
00396           if (first)
00397             {
00398               // cout << endl;
00399               // for (int j=0; j<6; j++)
00400               //   cout << cv[j] << " ";
00401               // cout << endl << endl << m << endl;
00402               first = false;
00403             }
00404           cvar.push_back(m);
00405         }
00406 
00407       if (type == "POINT2")     // have a scan
00408         {
00409           int n;
00410           double px,py;
00411           if (!(ss >> n ))
00412             {
00413               cout << "[ReadSPA2d] Bad POINT2 size " << n << " at line " << nline << endl;
00414               return -1;
00415             }
00416           if (n >= (int)scans.size()) // n is the scan number
00417             scans.resize(n+1);
00418 
00419           // coords of scan points are in world system!!!!
00420           double a = narot[n];  // angle of node for this scan
00421           Vector3d tr;
00422           tr.head(2) = ntrans[n]; // translation
00423           tr[2] = 1.0;
00424           Matrix<double,2,3> w2n;
00425           w2n(0,0) = w2n(1,1) = cos(a);
00426           w2n(0,1) = sin(a);
00427           w2n(1,0) = -w2n(0,1);
00428           w2n.col(2).setZero();
00429           w2n.col(2) = -w2n*tr;
00430 
00431           std::vector< Eigen::Vector2d, Eigen::aligned_allocator<Eigen::Vector2d> > scan;
00432           string str;
00433           getline(ss,str);
00434           istringstream sss(str);
00435           while ((sss >> px >> py))
00436             {
00437               Vector3d pw(px,py,1.0);
00438               Vector2d pn = w2n*pw;
00439               scan.push_back(pn);
00440             }
00441           scans[n] = scan;
00442         }
00443     }
00444 
00445   return 0;
00446 }
00447 


vslam_system
Author(s): Kurt Konolige, Patrick Mihelich, Helen Oleynikova
autogenerated on Thu Jan 2 2014 12:12:31