g2o
tutorial_slam2d.cpp
Go to the documentation of this file.
1 // g2o - General Graph Optimization
2 // Copyright (C) 2011 R. Kuemmerle, G. Grisetti, W. Burgard
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 // * Redistributions of source code must retain the above copyright notice,
10 // this list of conditions and the following disclaimer.
11 // * Redistributions in binary form must reproduce the above copyright
12 // notice, this list of conditions and the following disclaimer in the
13 // documentation and/or other materials provided with the distribution.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
16 // IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17 // TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
18 // PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 // HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
21 // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 
27 #include <iostream>
28 #include <cmath>
29 
30 #include "simulator.h"
31 
32 #include "vertex_se2.h"
33 #include "vertex_point_xy.h"
34 #include "edge_se2.h"
35 #include "edge_se2_pointxy.h"
36 #include "types_tutorial_slam2d.h"
37 
39 #include "g2o/core/block_solver.h"
40 #include "g2o/core/factory.h"
44 
45 using namespace std;
46 using namespace g2o;
47 using namespace g2o::tutorial;
48 
49 int main()
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
int main()
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