g2o
Loading...
Searching...
No Matches
constant_velocity_target.cpp
Go to the documentation of this file.
1// g2o - General Graph Optimization
2// Copyright (C) 2011 R. Kuemmerle, G. Grisetti, H. Strasdat, 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// This example consists of a single constant velocity target which
28// moves under piecewise constant velocity in 3D. Its position is
29// measured by an idealised GPS receiver.
30
33#include <g2o/core/solver.h>
37#include <g2o/stuff/sampler.h>
38#include <stdint.h>
39
40#include <iostream>
41
43#include "targetTypes6D.hpp"
44
45using namespace Eigen;
46using namespace std;
47using namespace g2o;
48
49int main() {
50 // Set up the parameters of the simulation
51 int numberOfTimeSteps = 1000;
52 const double processNoiseSigma = 1;
53 const double accelerometerNoiseSigma = 1;
54 const double gpsNoiseSigma = 1;
55 const double dt = 1;
56
57 // Set up the optimiser and block solver
58 SparseOptimizer optimizer;
59 optimizer.setVerbose(false);
60
62
63 OptimizationAlgorithm* optimizationAlgorithm =
64 new OptimizationAlgorithmGaussNewton(std::make_unique<BlockSolver>(
66
67 optimizer.setAlgorithm(optimizationAlgorithm);
68
69 // Sample the start location of the target
70 Vector6d state;
71 state.setZero();
72 for (int k = 0; k < 3; k++) {
73 state[k] = 1000 * sampleGaussian();
74 }
75
76 // Construct the first vertex; this corresponds to the initial
77 // condition and register it with the optimiser
79 stateNode->setEstimate(state);
80 stateNode->setId(0);
81 optimizer.addVertex(stateNode);
82
83 // Set up last estimate
84 VertexPositionVelocity3D* lastStateNode = stateNode;
85
86 // Iterate over the simulation steps
87 for (int k = 1; k <= numberOfTimeSteps; ++k) {
88 // Simulate the next step; update the state and compute the observation
89 Vector3d processNoise(processNoiseSigma * sampleGaussian(),
90 processNoiseSigma * sampleGaussian(),
91 processNoiseSigma * sampleGaussian());
92
93 for (int m = 0; m < 3; m++) {
94 state[m] += dt * (state[m + 3] + 0.5 * dt * processNoise[m]);
95 }
96
97 for (int m = 0; m < 3; m++) {
98 state[m + 3] += dt * processNoise[m];
99 }
100
101 // Construct the accelerometer measurement
102 Vector3d accelerometerMeasurement;
103 for (int m = 0; m < 3; m++) {
104 accelerometerMeasurement[m] =
105 processNoise[m] + accelerometerNoiseSigma * sampleGaussian();
106 }
107
108 // Construct the GPS observation
109 Vector3d gpsMeasurement;
110 for (int m = 0; m < 3; m++) {
111 gpsMeasurement[m] = state[m] + gpsNoiseSigma * sampleGaussian();
112 }
113
114 // Construct vertex which corresponds to the current state of the target
116
117 stateNode->setId(k);
118 stateNode->setMarginalized(false);
119 optimizer.addVertex(stateNode);
120
122 new TargetOdometry3DEdge(dt, accelerometerNoiseSigma);
123 toe->setVertex(0, lastStateNode);
124 toe->setVertex(1, stateNode);
126 dynamic_cast<VertexPositionVelocity3D*>(lastStateNode);
128 dynamic_cast<VertexPositionVelocity3D*>(stateNode);
129 toe->setMeasurement(accelerometerMeasurement);
130 optimizer.addEdge(toe);
131
132 // compute the initial guess via the odometry
134 vPrevSet.insert(vPrev);
135 toe->initialEstimate(vPrevSet, vCurr);
136
137 lastStateNode = stateNode;
138
139 // Add the GPS observation
141 new GPSObservationEdgePositionVelocity3D(gpsMeasurement, gpsNoiseSigma);
142 goe->setVertex(0, stateNode);
143 optimizer.addEdge(goe);
144 }
145
146 // Configure and set things going
147 optimizer.initializeOptimization();
148 optimizer.setVerbose(true);
149 optimizer.optimize(5);
150 cerr << "number of vertices:" << optimizer.vertices().size() << endl;
151 cerr << "number of edges:" << optimizer.edges().size() << endl;
152
153 // Print the results
154
155 cout << "state=\n" << state << endl;
156
157#if 0
158 for (int k = 0; k < numberOfTimeSteps; k++)
159 {
160 cout << "computed estimate " << k << "\n"
161 << dynamic_cast<VertexPositionVelocity3D*>(optimizer.vertices().find(k)->second)->estimate() << endl;
162 }
163#endif
164
165 Vector6d v1 = dynamic_cast<VertexPositionVelocity3D*>(
166 optimizer.vertices()
167 .find((std::max)(numberOfTimeSteps - 2, 0))
168 ->second)
169 ->estimate();
170 Vector6d v2 = dynamic_cast<VertexPositionVelocity3D*>(
171 optimizer.vertices()
172 .find((std::max)(numberOfTimeSteps - 1, 0))
173 ->second)
174 ->estimate();
175 cout << "v1=\n" << v1 << endl;
176 cout << "v2=\n" << v2 << endl;
177 cout << "delta state=\n" << v2 - v1 << endl;
178}
virtual void initialEstimate(const g2o::OptimizableGraph::VertexSet &from, g2o::OptimizableGraph::Vertex *to)
virtual void setMeasurement(const Measurement &m)
Definition base_edge.h:122
void setEstimate(const EstimateType &et)
set the estimate for the vertex also calls updateCache()
Implementation of a solver operating on the blocks of the Hessian.
void setVertex(size_t i, Vertex *v)
std::set< Vertex * > VertexSet
const EdgeSet & edges() const
const VertexIDMap & vertices() const
linear solver which uses the sparse Cholesky solver from Eigen
void setMarginalized(bool marginalized)
true => this node should be marginalized out during the optimization
Implementation of the Gauss Newton Algorithm.
Generic interface for a non-linear solver operating on a graph.
int optimize(int iterations, bool online=false)
void setVerbose(bool verbose)
virtual bool initializeOptimization(HyperGraph::EdgeSet &eset)
void setAlgorithm(OptimizationAlgorithm *algorithm)
Definition jet.h:938
double sampleGaussian(std::mt19937 *generator)
Definition sampler.cpp:40
Definition jet.h:876
virtual bool addEdge(HyperGraph::Edge *e)
virtual bool addVertex(HyperGraph::Vertex *v, Data *userData)
Eigen::Matrix< double, 6, 1 > Vector6d