g2o
Functions
tutorial_slam2d.cpp File Reference
#include <iostream>
#include <cmath>
#include "simulator.h"
#include "vertex_se2.h"
#include "vertex_point_xy.h"
#include "edge_se2.h"
#include "edge_se2_pointxy.h"
#include "types_tutorial_slam2d.h"
#include "g2o/core/sparse_optimizer.h"
#include "g2o/core/block_solver.h"
#include "g2o/core/factory.h"
#include "g2o/core/optimization_algorithm_factory.h"
#include "g2o/core/optimization_algorithm_gauss_newton.h"
#include "g2o/solvers/csparse/linear_solver_csparse.h"
Include dependency graph for tutorial_slam2d.cpp:

Go to the source code of this file.

Functions

int main ()
 

Function Documentation

int main ( )

Definition at line 49 of file tutorial_slam2d.cpp.

References g2o::OptimizableGraph::addEdge(), g2o::OptimizableGraph::addParameter(), g2o::OptimizableGraph::addVertex(), g2o::SparseOptimizer::clear(), g2o::Parameter::id(), g2o::SparseOptimizer::initializeOptimization(), g2o::tutorial::Simulator::landmarkObservations(), g2o::tutorial::Simulator::landmarks(), g2o::tutorial::Simulator::odometry(), g2o::SparseOptimizer::optimize(), g2o::tutorial::Simulator::poses(), g2o::OptimizableGraph::save(), g2o::SparseOptimizer::setAlgorithm(), g2o::BaseVertex< D, T >::setEstimate(), g2o::OptimizableGraph::Vertex::setFixed(), g2o::Parameter::setId(), g2o::OptimizableGraph::Vertex::setId(), g2o::BaseEdge< D, E >::setInformation(), g2o::tutorial::EdgeSE2::setMeasurement(), g2o::BaseEdge< D, E >::setMeasurement(), g2o::tutorial::ParameterSE2Offset::setOffset(), g2o::OptimizableGraph::Edge::setParameterId(), g2o::SparseOptimizer::setVerbose(), g2o::tutorial::Simulator::simulate(), g2o::OptimizableGraph::vertex(), and g2o::HyperGraph::Edge::vertices().

50 {
51  // TODO simulate different sensor offset
52  // simulate a robot observing landmarks while travelling on a grid
53  SE2 sensorOffsetTransf(0.2, 0.1, -0.1);
54  int numNodes = 300;
55  Simulator simulator;
56  simulator.simulate(numNodes, sensorOffsetTransf);
57 
58  /*********************************************************************************
59  * creating the optimization problem
60  ********************************************************************************/
61 
62  typedef BlockSolver< BlockSolverTraits<-1, -1> > SlamBlockSolver;
64 
65  // allocating the optimizer
66  SparseOptimizer optimizer;
67  SlamLinearSolver* linearSolver = new SlamLinearSolver();
68  linearSolver->setBlockOrdering(false);
69  SlamBlockSolver* blockSolver = new SlamBlockSolver(linearSolver);
71 
72  optimizer.setAlgorithm(solver);
73 
74  // add the parameter representing the sensor offset
75  ParameterSE2Offset* sensorOffset = new ParameterSE2Offset;
76  sensorOffset->setOffset(sensorOffsetTransf);
77  sensorOffset->setId(0);
78  optimizer.addParameter(sensorOffset);
79 
80  // adding the odometry to the optimizer
81  // first adding all the vertices
82  cerr << "Optimization: Adding robot poses ... ";
83  for (size_t i = 0; i < simulator.poses().size(); ++i) {
84  const Simulator::GridPose& p = simulator.poses()[i];
85  const SE2& t = p.simulatorPose;
86  VertexSE2* robot = new VertexSE2;
87  robot->setId(p.id);
88  robot->setEstimate(t);
89  optimizer.addVertex(robot);
90  }
91  cerr << "done." << endl;
92 
93  // second add the odometry constraints
94  cerr << "Optimization: Adding odometry measurements ... ";
95  for (size_t i = 0; i < simulator.odometry().size(); ++i) {
96  const Simulator::GridEdge& simEdge = simulator.odometry()[i];
97 
98  EdgeSE2* odometry = new EdgeSE2;
99  odometry->vertices()[0] = optimizer.vertex(simEdge.from);
100  odometry->vertices()[1] = optimizer.vertex(simEdge.to);
101  odometry->setMeasurement(simEdge.simulatorTransf);
102  odometry->setInformation(simEdge.information);
103  optimizer.addEdge(odometry);
104  }
105  cerr << "done." << endl;
106 
107  // add the landmark observations
108  cerr << "Optimization: add landmark vertices ... ";
109  for (size_t i = 0; i < simulator.landmarks().size(); ++i) {
110  const Simulator::Landmark& l = simulator.landmarks()[i];
111  VertexPointXY* landmark = new VertexPointXY;
112  landmark->setId(l.id);
113  landmark->setEstimate(l.simulatedPose);
114  optimizer.addVertex(landmark);
115  }
116  cerr << "done." << endl;
117 
118  cerr << "Optimization: add landmark observations ... ";
119  for (size_t i = 0; i < simulator.landmarkObservations().size(); ++i) {
120  const Simulator::LandmarkEdge& simEdge = simulator.landmarkObservations()[i];
121  EdgeSE2PointXY* landmarkObservation = new EdgeSE2PointXY;
122  landmarkObservation->vertices()[0] = optimizer.vertex(simEdge.from);
123  landmarkObservation->vertices()[1] = optimizer.vertex(simEdge.to);
124  landmarkObservation->setMeasurement(simEdge.simulatorMeas);
125  landmarkObservation->setInformation(simEdge.information);
126  landmarkObservation->setParameterId(0, sensorOffset->id());
127  optimizer.addEdge(landmarkObservation);
128  }
129  cerr << "done." << endl;
130 
131 
132  /*********************************************************************************
133  * optimization
134  ********************************************************************************/
135 
136  // dump initial state to the disk
137  optimizer.save("tutorial_before.g2o");
138 
139  // prepare and run the optimization
140  // fix the first robot pose to account for gauge freedom
141  VertexSE2* firstRobotPose = dynamic_cast<VertexSE2*>(optimizer.vertex(0));
142  firstRobotPose->setFixed(true);
143  optimizer.setVerbose(true);
144 
145  cerr << "Optimizing" << endl;
146  optimizer.initializeOptimization();
147  optimizer.optimize(10);
148  cerr << "done." << endl;
149 
150  optimizer.save("tutorial_after.g2o");
151 
152  // freeing the graph memory
153  optimizer.clear();
154 
155  // destroy all the singletons
156  Factory::destroy();
157  OptimizationAlgorithmFactory::destroy();
158  HyperGraphActionLibrary::destroy();
159 
160  return 0;
161 }
const PosesVector & poses() const
Definition: simulator.h:108
int optimize(int iterations, bool online=false)
traits to summarize the properties of the fixed size optimization problem
Definition: block_solver.h:43
const LandmarkEdgeVector & landmarkObservations() const
Definition: simulator.h:111
virtual void setMeasurement(const Measurement &m)
Definition: base_edge.h:76
void setId(int id_)
Definition: parameter.cpp:35
Implementation of the Gauss Newton Algorithm.
Vertex * vertex(int id)
returns the vertex number id appropriately casted
void setOffset(const SE2 &offset=SE2())
virtual void setId(int id)
sets the id of the node in the graph be sure that the graph keeps consistent after changing the id ...
bool setParameterId(int argNum, int paramId)
const VertexContainer & vertices() const
Definition: hyper_graph.h:178
virtual bool save(std::ostream &os, int level=0) const
save the graph to a stream. Again uses the Factory system.
void setVerbose(bool verbose)
linear solver which uses CSparse
void setAlgorithm(OptimizationAlgorithm *algorithm)
EIGEN_STRONG_INLINE void setInformation(const InformationType &information)
Definition: base_edge.h:69
const LandmarkVector & landmarks() const
Definition: simulator.h:109
int id() const
Definition: parameter.h:45
bool addParameter(Parameter *p)
void setEstimate(const EstimateType &et)
set the estimate for the vertex also calls updateCache()
Definition: base_vertex.h:101
void setMeasurement(const SE2 &m)
Definition: edge_se2.h:55
const GridEdgeVector & odometry() const
Definition: simulator.h:110
2D edge between two Vertex2, i.e., the odometry
Definition: edge_se2.h:41
Implementation of a solver operating on the blocks of the Hessian.
Definition: block_solver.h:96
void setFixed(bool fixed)
true => this node should be considered fixed during the optimization
virtual bool initializeOptimization(HyperGraph::EdgeSet &eset)
void simulate(int numPoses, const SE2 &sensorOffset=SE2())
Definition: simulator.cpp:60
virtual bool addEdge(HyperGraph::Edge *e)
virtual bool addVertex(HyperGraph::Vertex *v, Data *userData)
2D pose Vertex, (x,y,theta)
Definition: vertex_se2.h:41