g2o
Functions | Variables
sclam_laser_calib.cpp File Reference
#include <iostream>
#include <map>
#include <csignal>
#include <fstream>
#include "g2o/types/sclam2d/types_sclam2d.h"
#include "g2o/types/data/types_data.h"
#include "gm2dl_io.h"
#include "g2o/stuff/macros.h"
#include "g2o/stuff/color_macros.h"
#include "g2o/stuff/command_args.h"
#include "g2o/stuff/filesys_tools.h"
#include "g2o/stuff/string_tools.h"
#include "g2o/stuff/timeutil.h"
#include "g2o/core/sparse_optimizer.h"
#include "g2o/core/hyper_dijkstra.h"
#include "g2o/core/optimization_algorithm_factory.h"
#include "g2o/core/factory.h"
Include dependency graph for sclam_laser_calib.cpp:

Go to the source code of this file.

Functions

 G2O_USE_OPTIMIZATION_LIBRARY (csparse)
 
 G2O_USE_TYPE_GROUP (slam2d)
 
void sigquit_handler (int sig)
 
int main (int argc, char **argv)
 

Variables

static bool hasToStop = false
 

Function Documentation

G2O_USE_OPTIMIZATION_LIBRARY ( csparse  )
G2O_USE_TYPE_GROUP ( slam2d  )
int main ( int  argc,
char **  argv 
)

Definition at line 68 of file sclam_laser_calib.cpp.

References g2o::OptimizableGraph::chi2(), CL_RED, g2o::SparseOptimizer::computeActiveErrors(), g2o::OptimizationAlgorithmFactory::construct(), g2o::BaseVertex< D, T >::estimate(), g2o::SparseOptimizer::findGauge(), g2o::SparseOptimizer::gaugeFreedom(), hasToStop, g2o::HyperGraph::Vertex::id(), g2o::SparseOptimizer::initializeOptimization(), g2o::SparseOptimizer::optimize(), g2o::CommandArgs::param(), g2o::CommandArgs::paramLeftOver(), g2o::CommandArgs::parseArgs(), g2o::SparseOptimizer::setAlgorithm(), g2o::OptimizableGraph::Vertex::setFixed(), g2o::SparseOptimizer::setForceStopFlag(), g2o::SparseOptimizer::setVerbose(), g2o::HyperDijkstra::shortestPaths(), sigquit_handler(), g2o::SE2::toVector(), g2o::OptimizableGraph::vertex(), g2o::HyperGraph::vertices(), and g2o::HyperDijkstra::visited().

69 {
70  int maxIterations;
71  bool verbose;
72  string inputFilename;
73  string gnudump;
74  string outputfilename;
75  bool initialGuess;
76  // command line parsing
77  CommandArgs commandLineArguments;
78  commandLineArguments.param("i", maxIterations, 10, "perform n iterations");
79  commandLineArguments.param("v", verbose, false, "verbose output of the optimization process");
80  commandLineArguments.param("guess", initialGuess, false, "initial guess based on spanning tree");
81  commandLineArguments.param("gnudump", gnudump, "", "dump to gnuplot data file");
82  commandLineArguments.param("o", outputfilename, "", "output final version of the graph");
83  commandLineArguments.paramLeftOver("gm2dl-input", inputFilename, "", "gm2dl file which will be processed");
84 
85  commandLineArguments.parseArgs(argc, argv);
86 
87  OptimizationAlgorithmFactory* solverFactory = OptimizationAlgorithmFactory::instance();
88 
89  SparseOptimizer optimizer;
90  optimizer.setVerbose(verbose);
91  optimizer.setForceStopFlag(&hasToStop);
92 
93  OptimizationAlgorithmProperty solverProperty;
94  optimizer.setAlgorithm(solverFactory->construct("lm_var", solverProperty));
95 
96  // loading
97  if (! Gm2dlIO::readGm2dl(inputFilename, optimizer, false)) {
98  cerr << "Error while loading gm2dl file" << endl;
99  }
100 
101  VertexSE2* laserOffset = dynamic_cast<VertexSE2*>(optimizer.vertex(numeric_limits<int>::max()));
102  //laserOffset->setEstimate(SE2()); // set to Identity
103  if (laserOffset) {
104  cerr << "Initial laser offset " << laserOffset->estimate().toVector().transpose() << endl;
105  }
106  bool gaugeFreedom = optimizer.gaugeFreedom();
107 
108  OptimizableGraph::Vertex* gauge = optimizer.findGauge();
109  if (gaugeFreedom) {
110  if (! gauge) {
111  cerr << "# cannot find a vertex to fix in this thing" << endl;
112  return 2;
113  } else {
114  cerr << "# graph is fixed by node " << gauge->id() << endl;
115  gauge->setFixed(true);
116  }
117  } else {
118  cerr << "# graph is fixed by priors" << endl;
119  }
120 
121  // sanity check
122  HyperDijkstra d(&optimizer);
124  d.shortestPaths(gauge, &f);
125  //cerr << PVAR(d.visited().size()) << endl;
126 
127  if (d.visited().size()!=optimizer.vertices().size()) {
128  cerr << CL_RED("Warning: d.visited().size() != optimizer.vertices().size()") << endl;
129  cerr << "visited: " << d.visited().size() << endl;
130  cerr << "vertices: " << optimizer.vertices().size() << endl;
131  if (1)
132  for (SparseOptimizer::VertexIDMap::const_iterator it = optimizer.vertices().begin(); it != optimizer.vertices().end(); ++it) {
133  OptimizableGraph::Vertex* v = static_cast<OptimizableGraph::Vertex*>(it->second);
134  if (d.visited().count(v) == 0) {
135  cerr << "\t unvisited vertex " << it->first << " " << (void*)v << endl;
136  v->setFixed(true);
137  }
138  }
139  }
140 
141  optimizer.initializeOptimization();
142  optimizer.computeActiveErrors();
143  cerr << "Initial chi2 = " << FIXED(optimizer.chi2()) << endl;
144 
145  //if (guessCostFunction)
146  //optimizer.computeInitialGuess(guessCostFunction);
147 
148  signal(SIGINT, sigquit_handler);
149 
150  int i=optimizer.optimize(maxIterations);
151  if (maxIterations > 0 && !i){
152  cerr << "optimize failed, result might be invalid" << endl;
153  }
154 
155  if (laserOffset) {
156  cerr << "Calibrated laser offset " << laserOffset->estimate().toVector().transpose() << endl;
157  }
158 
159  if (outputfilename.size() > 0) {
160  Gm2dlIO::updateLaserData(optimizer);
161  cerr << "Writing " << outputfilename << " ... ";
162  bool writeStatus = Gm2dlIO::writeGm2dl(outputfilename, optimizer);
163  cerr << (writeStatus ? "done." : "failed") << endl;
164  }
165 
166  if (gnudump.size() > 0) {
167  ofstream fout(gnudump.c_str());
168  for (SparseOptimizer::VertexIDMap::const_iterator it = optimizer.vertices().begin(); it != optimizer.vertices().end(); ++it) {
169  VertexSE2* v = dynamic_cast<VertexSE2*>(it->second);
170  fout << v->estimate().toVector().transpose() << endl;
171  }
172  }
173 
174  return true;
175 }
int id() const
returns the id
Definition: hyper_graph.h:148
Command line parsing of argc and argv.
Definition: command_args.h:46
Vector3D toVector() const
convert to a 3D vector (x, y, theta)
Definition: se2.h:108
describe the properties of a solver
int optimize(int iterations, bool online=false)
#define CL_RED(s)
Definition: color_macros.h:46
2D pose Vertex, (x,y,theta)
Definition: vertex_se2.h:41
create solvers based on their short name
const VertexIDMap & vertices() const
Definition: hyper_graph.h:225
Vertex * vertex(int id)
returns the vertex number id appropriately casted
virtual Vertex * findGauge()
finds a gauge in the graph to remove the undefined dof.
static bool hasToStop
double chi2() const
returns the chi2 of the current configuration
bool parseArgs(int argc, char **argv, bool exitOnError=true)
void setVerbose(bool verbose)
void setForceStopFlag(bool *flag)
void paramLeftOver(const std::string &name, std::string &p, const std::string &defValue, const std::string &desc, bool optional=false)
void setAlgorithm(OptimizationAlgorithm *algorithm)
void param(const std::string &name, bool &p, bool defValue, const std::string &desc)
A general case Vertex for optimization.
void sigquit_handler(int sig)
const EstimateType & estimate() const
return the current estimate of the vertex
Definition: base_vertex.h:99
void setFixed(bool fixed)
true => this node should be considered fixed during the optimization
virtual bool initializeOptimization(HyperGraph::EdgeSet &eset)
OptimizationAlgorithm * construct(const std::string &tag, OptimizationAlgorithmProperty &solverProperty) const
void sigquit_handler ( int  sig)

Definition at line 56 of file sclam_laser_calib.cpp.

References __PRETTY_FUNCTION__, and hasToStop.

Referenced by main().

57 {
58  if (sig == SIGINT) {
59  hasToStop = 1;
60  static int cnt = 0;
61  if (cnt++ == 2) {
62  cerr << __PRETTY_FUNCTION__ << " forcing exit" << endl;
63  exit(1);
64  }
65  }
66 }
#define __PRETTY_FUNCTION__
Definition: macros.h:89
static bool hasToStop

Variable Documentation

bool hasToStop = false
static

Definition at line 51 of file sclam_laser_calib.cpp.

Referenced by main(), and sigquit_handler().