g2o
Loading...
Searching...
No Matches
structure_only_solver.h
Go to the documentation of this file.
1// g2o - General Graph Optimization
2// Copyright (C) 2011 H. Strasdat
3// Copyright (C) 2012 R. Kuemmerle
4// All rights reserved.
5//
6// Redistribution and use in source and binary forms, with or without
7// modification, are permitted provided that the following conditions are
8// met:
9//
10// * Redistributions of source code must retain the above copyright notice,
11// this list of conditions and the following disclaimer.
12// * Redistributions in binary form must reproduce the above copyright
13// notice, this list of conditions and the following disclaimer in the
14// documentation and/or other materials provided with the distribution.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
17// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
19// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
22// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#ifndef G2O_STRUCTURE_ONLY_SOLVER_H
29#define G2O_STRUCTURE_ONLY_SOLVER_H
30
31#include <cassert>
32
37
38namespace g2o {
39
57template <int PointDoF>
59 public:
61
62 virtual OptimizationAlgorithm::SolverResult solve(int iteration,
63 bool online = false) {
64 (void)iteration;
65 (void)online;
66 return calc(_points, 1);
67 }
68
69 OptimizationAlgorithm::SolverResult calc(
70 OptimizableGraph::VertexContainer& vertices, int num_iters,
71 int num_max_trials = 10) {
72 JacobianWorkspace auxWorkspace;
73 auxWorkspace.updateSize(2, 50);
74 auxWorkspace.allocate();
75
76 for (OptimizableGraph::VertexContainer::iterator it_v = vertices.begin();
77 it_v != vertices.end(); ++it_v) {
78 bool stop = false;
80 dynamic_cast<OptimizableGraph::Vertex*>(*it_v);
81 assert(v->dimension() == PointDoF);
82 g2o::HyperGraph::EdgeSet& track = v->edges();
83 assert(track.size() >= 2);
84 double chi2 = 0;
85 // TODO make these parameters
86 double mu = cst(0.01);
87 double nu = 2;
88
89 for (g2o::HyperGraph::EdgeSet::iterator it_t = track.begin();
90 it_t != track.end(); ++it_t) {
92 dynamic_cast<g2o::OptimizableGraph::Edge*>(*it_t);
93 e->computeError();
94 if (e->robustKernel()) {
95 Vector3 rho;
96 e->robustKernel()->robustify(e->chi2(), rho);
97 chi2 += rho[0];
98 } else {
99 chi2 += e->chi2();
100 }
101 }
102
103 if (v->fixed() == false) {
104 Eigen::Matrix<double, PointDoF, PointDoF, Eigen::ColMajor> H_pp;
105 H_pp.resize(v->dimension(), v->dimension());
106 v->mapHessianMemory(H_pp.data());
107 for (int i_g = 0; i_g < num_iters; ++i_g) {
108 H_pp.setZero();
110
111 g2o::HyperGraph::EdgeSet& track = v->edges();
112 assert(track.size() >= 1);
113
114 for (g2o::HyperGraph::EdgeSet::iterator it_t = track.begin();
115 it_t != track.end(); ++it_t) {
117 dynamic_cast<g2o::OptimizableGraph::Edge*>(*it_t);
118
119 // fix all the other vertices and remember their fix value
120#ifdef WINDOWS
121 std::vector<bool> remember_fix_status(e->vertices().size());
122#else
123 bool remember_fix_status[e->vertices().size()];
124#endif
125 for (size_t k = 0; k < e->vertices().size(); ++k) {
127 static_cast<OptimizableGraph::Vertex*>(e->vertex(k));
128 if (otherV != v) {
129 remember_fix_status[k] = otherV->fixed();
130 otherV->setFixed(true);
131 }
132 }
133
134 // build the matrix
135 e->computeError();
136 e->linearizeOplus(auxWorkspace);
138
139 // Restore frame's initial fixed() values
140 for (size_t k = 0; k < e->vertices().size(); ++k) {
142 static_cast<g2o::OptimizableGraph::Vertex*>(e->vertex(k));
143 if (otherV != v) {
144 otherV->setFixed(remember_fix_status[k]);
145 }
146 }
147 }
148
149 Eigen::Map<Eigen::Matrix<double, PointDoF, 1, Eigen::ColMajor> > b(
150 v->bData(), v->dimension());
151
152 if (b.norm() < 0.001) {
153 stop = true;
154 break;
155 }
156
157 int trial = 0;
158 do {
159 Eigen::Matrix<double, PointDoF, PointDoF, Eigen::ColMajor> H_pp_mu =
160 H_pp;
161 H_pp_mu.diagonal().array() += mu;
162 Eigen::LDLT<
163 Eigen::Matrix<double, PointDoF, PointDoF, Eigen::ColMajor> >
164 chol_H_pp(H_pp_mu);
165 bool goodStep = false;
166 if (chol_H_pp.isPositive()) {
167 Eigen::Matrix<double, PointDoF, 1, Eigen::ColMajor> delta_p =
168 chol_H_pp.solve(b);
169 v->push();
170 v->oplus(delta_p.data());
171 double new_chi2 = 0;
172 for (g2o::HyperGraph::EdgeSet::iterator it_t = track.begin();
173 it_t != track.end(); ++it_t) {
175 dynamic_cast<g2o::OptimizableGraph::Edge*>(*it_t);
176 e->computeError();
177 if (e->robustKernel()) {
178 Vector3 rho;
179 e->robustKernel()->robustify(e->chi2(), rho);
180 new_chi2 += rho[0];
181 } else {
182 new_chi2 += e->chi2();
183 }
184 }
185 assert(g2o_isnan(new_chi2) == false && "Chi is NaN");
186 double rho = (chi2 - new_chi2);
187 if (rho > 0 && g2o_isfinite(new_chi2)) {
188 goodStep = true;
189 chi2 = new_chi2;
190 v->discardTop();
191 } else {
192 goodStep = false;
193 v->pop();
194 }
195 }
196
197 // update the damping factor based on the result of the last
198 // increment
199 if (goodStep) {
200 mu *= cst(1. / 3.);
201 nu = 2.;
202 trial = 0;
203 break;
204 } else {
205 mu *= nu;
206 nu *= 2.;
207 ++trial;
208 if (trial >= num_max_trials) {
209 stop = true;
210 break;
211 }
212 }
213 } while (!stop);
214 if (stop) break;
215 }
216 }
217 }
218 return OK;
219 }
220
221 virtual bool init(bool) {
222 // collect the vertices
223 _points.clear();
224 for (OptimizableGraph::VertexContainer::const_iterator it =
225 optimizer()->activeVertices().begin();
226 it != optimizer()->activeVertices().end(); ++it) {
228 if (v->marginalized()) {
229 _points.push_back(v);
230 }
231 }
232 return true;
233 }
234
236 const std::vector<std::pair<int, int> >&) {
237 return false;
238 }
239
240 virtual bool updateStructure(const std::vector<HyperGraph::Vertex*>&,
241 const HyperGraph::EdgeSet&) {
242 return true;
243 }
244
248
249 protected:
252};
253
254} // namespace g2o
255
256#endif
const VertexContainer & vertices() const
const Vertex * vertex(size_t i) const
const EdgeSet & edges() const
returns the set of hyper-edges that are leaving/entering in this vertex
std::set< Edge * > EdgeSet
provide memory workspace for computing the Jacobians
void updateSize(const HyperGraph::Edge *e, bool reset)
virtual void linearizeOplus(JacobianWorkspace &jacobianWorkspace)=0
virtual double chi2() const =0
virtual void computeError()=0
RobustKernel * robustKernel() const
if NOT NULL, error of this edge will be robustifed with the kernel
virtual void constructQuadraticForm()=0
A general case Vertex for optimization.
virtual void mapHessianMemory(double *d)=0
bool marginalized() const
true => this node is marginalized out during the optimization
virtual void clearQuadraticForm()=0
int dimension() const
dimension of the estimated state belonging to this node
bool fixed() const
true => this node is fixed during the optimization
virtual void push()=0
backup the position of the vertex to a stack
virtual double * bData()=0
return a pointer to the b vector associated with this vertex
void setFixed(bool fixed)
true => this node should be considered fixed during the optimization
Generic interface for a non-linear solver operating on a graph.
const SparseOptimizer * optimizer() const
return the optimizer operating on
virtual void robustify(double squaredError, Vector3 &rho) const =0
Sparse matrix which uses blocks.
const VertexContainer & activeVertices() const
the vertices active in the current optimization
This is a solver for "structure-only" optimization".
const OptimizableGraph::VertexContainer & points() const
OptimizationAlgorithm::SolverResult calc(OptimizableGraph::VertexContainer &vertices, int num_iters, int num_max_trials=10)
virtual OptimizationAlgorithm::SolverResult solve(int iteration, bool online=false)
virtual bool computeMarginals(SparseBlockMatrix< MatrixX > &, const std::vector< std::pair< int, int > > &)
OptimizableGraph::VertexContainer _points
virtual bool updateStructure(const std::vector< HyperGraph::Vertex * > &, const HyperGraph::EdgeSet &)
OptimizableGraph::VertexContainer & points()
return the points of the optimization problem
#define g2o_isfinite(x)
Definition macros.h:102
#define g2o_isnan(x)
Definition macros.h:100
VectorN< 3 > Vector3
Definition eigen_types.h:51
constexpr double cst(long double v)
Definition misc.h:60
std::vector< OptimizableGraph::Vertex * > VertexContainer
vector container for vertices