g2o
Static Public Member Functions | Static Public Attributes | List of all members
g2o::Gm2dlIO Class Reference

read / write gm2dl file into / out of a SparseOptimizer More...

#include <gm2dl_io.h>

Static Public Member Functions

static bool readGm2dl (const std::string &filename, SparseOptimizer &optimizer, bool overrideCovariances=false)
 
static bool updateLaserData (SparseOptimizer &optimizer)
 
static bool writeGm2dl (const std::string &filename, const SparseOptimizer &optimizer)
 
static int readRobotLaser (const std::string &filename, DataQueue &queue)
 

Static Public Attributes

static const int ID_LASERPOSE = numeric_limits<int>::max()
 
static const int ID_ODOMCALIB = numeric_limits<int>::max() - 1
 

Detailed Description

read / write gm2dl file into / out of a SparseOptimizer

Definition at line 39 of file gm2dl_io.h.

Member Function Documentation

bool g2o::Gm2dlIO::readGm2dl ( const std::string &  filename,
SparseOptimizer optimizer,
bool  overrideCovariances = false 
)
static

Definition at line 48 of file gm2dl_io.cpp.

References g2o::OptimizableGraph::addEdge(), g2o::OptimizableGraph::addVertex(), g2o::SparseOptimizer::clear(), g2o::BaseVertex< D, T >::estimate(), g2o::SE2::fromVector(), g2o::BaseEdge< D, E >::information(), g2o::SE2::inverse(), g2o::RawLaser::laserParams(), g2o::LaserParameters::laserPose, g2o::RobotLaser::read(), g2o::readLine(), g2o::BaseVertex< D, T >::setEstimate(), g2o::OptimizableGraph::Vertex::setId(), g2o::EdgeSE2SensorCalib::setMeasurement(), g2o::HyperGraph::DataContainer::setUserData(), g2o::HyperGraph::Edge::setVertex(), and g2o::OptimizableGraph::vertex().

49  {
50  optimizer.clear();
51  ifstream is(filename.c_str());
52  if (! is.good())
53  return false;
54 
55  bool laserOffsetInitDone = false;
56  VertexSE2* laserOffset = new VertexSE2;
57  //laserOffset->fixed() = true;
58  laserOffset->setId(ID_LASERPOSE);
59  if (! optimizer.addVertex(laserOffset)) {
60  cerr << "Unable to add laser offset" << endl;
61  return false;
62  }
63 
64  // parse the GM2DL file an extract the vertices, edges, and the laser data
65  stringstream currentLine;
66  VertexSE2* previousVertex = 0;
67  while(1) {
68  int bytesRead = readLine(is, currentLine);
69  if (bytesRead == -1)
70  break;
71  string tag;
72  currentLine >> tag;
73  if (tag == "VERTEX" || tag == "VERTEX2" || tag == "VERTEX_SE2"){
74  int id;
75  Eigen::Vector3d p;
76  currentLine >> id >> p.x() >> p.y() >> p.z();
77  // adding the robot pose
78  VertexSE2* v = new VertexSE2;
79  v->setId(id);
80  //cerr << "Read vertex id " << id << endl;
81  if (! optimizer.addVertex(v)) {
82  cerr << "vertex " << id << " is already in the graph, reassigning "<< endl;
83  delete v;
84  v = dynamic_cast<VertexSE2*>(optimizer.vertex(id));
85  assert(v);
86  }
87  v->setEstimate(p);
88  previousVertex = v;
89 
90  } else if (tag == "EDGE" || tag == "EDGE2" || tag == "EDGE_SE2"){
91  if (! laserOffsetInitDone) {
92  cerr << "Error: need laser offset" << endl;
93  return false;
94  }
95  int id1, id2;
96  EdgeSE2SensorCalib* e = new EdgeSE2SensorCalib;
97  Eigen::Vector3d p;
98  Eigen::Matrix3d& m = e->information();
99  currentLine >> id1 >> id2 >> p.x() >> p.y() >> p.z();
100  if (overrideCovariances){
101  m = Eigen::Matrix3d::Identity();
102  } else {
103  if (tag == "EDGE_SE2")
104  currentLine >> m(0, 0) >> m(0, 1) >> m(0, 2) >> m(1, 1) >> m(1, 2) >> m(2, 2);
105  else // old stupid order of the information matrix
106  currentLine >> m(0, 0) >> m(0, 1) >> m(1, 1) >> m(2, 2) >> m(0, 2) >> m(1, 2);
107  m(1, 0) = m(0, 1);
108  m(2, 0) = m(0, 2);
109  m(2, 1) = m(1, 2);
110  }
111  previousVertex = 0;
112  VertexSE2* v1 = dynamic_cast<VertexSE2*>(optimizer.vertex(id1));
113  VertexSE2* v2 = dynamic_cast<VertexSE2*>(optimizer.vertex(id2));
114  if (! v1) {
115  cerr << "vertex " << id1 << " is not existing, cannot add edge (" << id1 << "," << id2 << ")" << endl;
116  delete e;
117  continue;
118  }
119  if (! v2) {
120  cerr << "vertex " << id2 << " is not existing, cannot add edge (" << id1 << "," << id2 << ")" << endl;
121  delete e;
122  continue;
123  }
124 
125  //if (0)
126  //if (abs(id1 - id2) != 1)
127  //m *= 1e-6;
128 
129  // TODO transform measurement covariance by considering the laserOffset to measurement between the lasers
130  SE2 transf; transf.fromVector(p);
131  e->setMeasurement(laserOffset->estimate().inverse() * transf * laserOffset->estimate());
132  //e->inverseMeasurement() = e->measurement().inverse();
133 
134  e->setVertex(0, v1);
135  e->setVertex(1, v2);
136  e->setVertex(2, laserOffset);
137  if (! optimizer.addEdge(e)){
138  cerr << "error in adding edge " << id1 << "," << id2 << endl;
139  delete e;
140  }
141  //cerr << PVAR(e->inverseMeasurement().toVector().transpose()) << endl;
142  //cerr << PVAR(e->information()) << endl;
143 
144  } else if (tag == "ROBOTLASER1") {
145  if (previousVertex) {
146  RobotLaser* rl2 = new RobotLaser;
147  rl2->read(currentLine);
148  if (! laserOffsetInitDone) {
149  laserOffsetInitDone = true;
150  //cerr << "g2o Laseroffset is " << rl2->laserParams().laserPose.toVector().transpose() << endl;
151  laserOffset->setEstimate(rl2->laserParams().laserPose);
152  }
153  previousVertex->setUserData(rl2);
154  previousVertex = 0;
155  }
156  }
157  }
158 
159  return true;
160  }
static const int ID_LASERPOSE
Definition: gm2dl_io.h:45
int readLine(std::istream &is, std::stringstream &currentLine)
int g2o::Gm2dlIO::readRobotLaser ( const std::string &  filename,
DataQueue queue 
)
static

Definition at line 238 of file gm2dl_io.cpp.

References g2o::DataQueue::add(), g2o::RobotLaser::read(), and g2o::readLine().

239  {
240  ifstream is(filename.c_str());
241  if (! is.good())
242  return false;
243 
244  int cnt = 0;
245 
246  // parse the GM2DL file and extract the vertices, edges, and the laser data
247  stringstream currentLine;
248  while(1) {
249  int bytesRead = readLine(is, currentLine);
250  if (bytesRead == -1)
251  break;
252  string tag;
253  currentLine >> tag;
254  if (tag == "ROBOTLASER1") {
255  RobotLaser* rl2 = new RobotLaser;
256  rl2->read(currentLine);
257  queue.add(rl2);
258  cnt++;
259  }
260  }
261  return cnt;
262  }
int readLine(std::istream &is, std::stringstream &currentLine)
bool g2o::Gm2dlIO::updateLaserData ( SparseOptimizer optimizer)
static

Definition at line 213 of file gm2dl_io.cpp.

References g2o::BaseVertex< D, T >::estimate(), g2o::HyperGraph::Vertex::id(), g2o::RawLaser::laserParams(), g2o::LaserParameters::laserPose, g2o::RawLaser::setLaserParams(), g2o::RobotLaser::setOdomPose(), g2o::HyperGraph::DataContainer::userData(), g2o::OptimizableGraph::vertex(), and g2o::HyperGraph::vertices().

214  {
215  VertexSE2* laserOffset = dynamic_cast<VertexSE2*>(optimizer.vertex(ID_LASERPOSE));
216  if (! laserOffset) {
217  cerr << "Laser offset not found" << endl;
218  return false;
219  }
220 
221  for (SparseOptimizer::VertexIDMap::const_iterator it = optimizer.vertices().begin(); it != optimizer.vertices().end(); ++it) {
222  VertexSE2* v = dynamic_cast<VertexSE2*>(it->second);
223  if (! v)
224  continue;
225  if (v->id() == ID_LASERPOSE)
226  continue;
227  RobotLaser* robotLaser = dynamic_cast<RobotLaser*>(v->userData());
228  if (robotLaser) { // writing the data via the factory
229  robotLaser->setOdomPose(v->estimate());
230  LaserParameters params = robotLaser->laserParams();
231  params.laserPose = laserOffset->estimate();
232  robotLaser->setLaserParams(params);
233  }
234  }
235  return true;
236  }
static const int ID_LASERPOSE
Definition: gm2dl_io.h:45
bool g2o::Gm2dlIO::writeGm2dl ( const std::string &  filename,
const SparseOptimizer optimizer 
)
static

Definition at line 162 of file gm2dl_io.cpp.

References g2o::HyperGraph::edges(), g2o::HyperGraph::Vertex::id(), g2o::BaseEdge< D, E >::information(), g2o::BaseEdge< D, E >::measurement(), g2o::Factory::tag(), g2o::SE2::toVector(), g2o::HyperGraph::DataContainer::userData(), g2o::HyperGraph::Edge::vertex(), g2o::HyperGraph::vertices(), g2o::HyperGraph::Data::write(), and g2o::OptimizableGraph::Vertex::write().

163  {
164  ofstream fout(filename.c_str());
165  if (! fout.good()) {
166  return false;
167  }
168  Factory* factory = Factory::instance();
169 
170  for (SparseOptimizer::VertexIDMap::const_iterator it = optimizer.vertices().begin(); it != optimizer.vertices().end(); ++it) {
171  OptimizableGraph::Vertex* v = static_cast<OptimizableGraph::Vertex*>(it->second);
172  fout << "VERTEX2 " << v->id() << " ";
173  v->write(fout);
174  fout << endl;
175  HyperGraph::Data* data = v->userData();
176  if (data) { // writing the data via the factory
177  string tag = factory->tag(data);
178  if (tag.size() > 0) {
179  fout << tag << " ";
180  data->write(fout);
181  fout << endl;
182  }
183  }
184  }
185 
186  OptimizableGraph::EdgeContainer edgesToSave; // sorting edges to have them in the order of insertion again
187  for (HyperGraph::EdgeSet::const_iterator it = optimizer.edges().begin(); it != optimizer.edges().end(); ++it) {
188  const OptimizableGraph::Edge* e = static_cast<const OptimizableGraph::Edge*>(*it);
189  edgesToSave.push_back(const_cast<OptimizableGraph::Edge*>(e));
190  }
191  sort(edgesToSave.begin(), edgesToSave.end(), OptimizableGraph::EdgeIDCompare());
192 
193  for (OptimizableGraph::EdgeContainer::const_iterator it = edgesToSave.begin(); it != edgesToSave.end(); ++it) {
194  OptimizableGraph::Edge* e = *it;
195  EdgeSE2SensorCalib* calibEdge = dynamic_cast<EdgeSE2SensorCalib*>(e);
196  if (calibEdge) {
197  // write back in the gm2dl format
198  fout << "EDGE2 " << calibEdge->vertex(0)->id() << " " << calibEdge->vertex(1)->id();
199  Eigen::Vector3d meas = calibEdge->measurement().toVector();
200  fout << " " << meas.x() << " " << meas.y() << " " << meas.z();
201  const Eigen::Matrix3d& m = calibEdge->information();
202  fout << " " << m(0, 0) << " " << m(0, 1) << " " << m(1, 1) << " "
203  << m(2, 2) << " " << m(0, 2) << " " << m(1, 2);
204  fout << endl;
205  } else {
206  //cerr << "Strange Edge Type: " << factory->tag(e) << endl;
207  }
208  }
209 
210  return fout.good();
211  }
static Factory * instance()
return the instance
Definition: factory.cpp:61
std::vector< OptimizableGraph::Edge * > EdgeContainer
vector container for edges
class G2O_CORE_API Vertex
class G2O_CORE_API Edge
class G2O_CORE_API Data
Definition: hyper_graph.h:76

Member Data Documentation

const int g2o::Gm2dlIO::ID_LASERPOSE = numeric_limits<int>::max()
static

the global ID we assign the laser pose vertex

Definition at line 45 of file gm2dl_io.h.

const int g2o::Gm2dlIO::ID_ODOMCALIB = numeric_limits<int>::max() - 1
static

Definition at line 46 of file gm2dl_io.h.


The documentation for this class was generated from the following files: