g2o
Public Member Functions | Protected Attributes | List of all members
g2o::StructureOnlySolver< PointDoF > Class Template Reference

This is a solver for "structure-only" optimization". More...

#include <structure_only_solver.h>

Inheritance diagram for g2o::StructureOnlySolver< PointDoF >:
Inheritance graph
[legend]
Collaboration diagram for g2o::StructureOnlySolver< PointDoF >:
Collaboration graph
[legend]

Public Member Functions

 StructureOnlySolver ()
 
virtual OptimizationAlgorithm::SolverResult solve (int iteration, bool online=false)
 
OptimizationAlgorithm::SolverResult calc (OptimizableGraph::VertexContainer &vertices, int num_iters, int num_max_trials=10)
 
virtual bool init (bool)
 
virtual bool computeMarginals (SparseBlockMatrix< MatrixXD > &, const std::vector< std::pair< int, int > > &)
 
virtual bool updateStructure (const std::vector< HyperGraph::Vertex * > &, const HyperGraph::EdgeSet &)
 
OptimizableGraph::VertexContainerpoints ()
 return the points of the optimization problem More...
 
const OptimizableGraph::VertexContainerpoints () const
 
- Public Member Functions inherited from g2o::OptimizationAlgorithm
 OptimizationAlgorithm ()
 
virtual ~OptimizationAlgorithm ()
 
virtual void printVerbose (std::ostream &os) const
 
const SparseOptimizeroptimizer () const
 return the optimizer operating on More...
 
SparseOptimizeroptimizer ()
 
void setOptimizer (SparseOptimizer *optimizer)
 
const PropertyMapproperties () const
 return the properties of the solver More...
 
bool updatePropertiesFromString (const std::string &propString)
 
void printProperties (std::ostream &os) const
 

Protected Attributes

bool _verbose
 
OptimizableGraph::VertexContainer _points
 
- Protected Attributes inherited from g2o::OptimizationAlgorithm
SparseOptimizer_optimizer
 the optimizer the solver is working on More...
 
PropertyMap _properties
 the properties of your solver, use this to store the parameters of your solver More...
 

Detailed Description

template<int PointDoF>
class g2o::StructureOnlySolver< PointDoF >

This is a solver for "structure-only" optimization".

Given the problem of landmark-based SLAM or bundle adjustment, this class performs optimization on the landmarks while the poses are kept fixed. This can be done very efficiently, since the position on the landmarks are indepdented given the poses are known.

This class slightly misuses the API of g2o. It is designed in a way, it can work on the very same graph which reflects the problem of landmark-based SLAM, bundle adjustment and which is meant to be solved using the Schur complement. Thus, it can be called just before or after joint-optimization without the need of additional setup. Call calc() with the point features you want to optimize.

This class is still considered as being experimentally!

Definition at line 57 of file structure_only_solver.h.

Constructor & Destructor Documentation

template<int PointDoF>
g2o::StructureOnlySolver< PointDoF >::StructureOnlySolver ( )
inline

Definition at line 60 of file structure_only_solver.h.

References g2o::StructureOnlySolver< PointDoF >::_verbose.

61  {
62  _verbose = true;
63  }

Member Function Documentation

template<int PointDoF>
OptimizationAlgorithm::SolverResult g2o::StructureOnlySolver< PointDoF >::calc ( OptimizableGraph::VertexContainer vertices,
int  num_iters,
int  num_max_trials = 10 
)
inline

Definition at line 72 of file structure_only_solver.h.

References g2o::JacobianWorkspace::allocate(), g2o::OptimizableGraph::Vertex::bData(), g2o::OptimizableGraph::Edge::chi2(), g2o::OptimizableGraph::Vertex::clearQuadraticForm(), g2o::OptimizableGraph::Edge::computeError(), g2o::OptimizableGraph::Edge::constructQuadraticForm(), g2o::OptimizableGraph::Vertex::dimension(), g2o::OptimizableGraph::Vertex::discardTop(), g2o::HyperGraph::Vertex::edges(), g2o::OptimizableGraph::Vertex::fixed(), g2o_isfinite, g2o_isnan, g2o::OptimizableGraph::Edge::linearizeOplus(), g2o::OptimizableGraph::Vertex::mapHessianMemory(), OK, g2o::OptimizableGraph::Vertex::oplus(), g2o::OptimizableGraph::Vertex::pop(), g2o::OptimizableGraph::Vertex::push(), g2o::OptimizableGraph::Vertex::setFixed(), g2o::JacobianWorkspace::updateSize(), g2o::HyperGraph::Edge::vertex(), and g2o::HyperGraph::Edge::vertices().

Referenced by main(), and g2o::StructureOnlySolver< PointDoF >::solve().

73  {
74  JacobianWorkspace auxWorkspace;
75  auxWorkspace.updateSize(2, 50);
76  auxWorkspace.allocate();
77 
78  for (OptimizableGraph::VertexContainer::iterator it_v=vertices.begin(); it_v!=vertices.end(); ++it_v) {
79  bool stop = false;
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 = 0.01;
87  double nu = 2;
88 
89  for (g2o::HyperGraph::EdgeSet::iterator it_t=track.begin(); it_t!=track.end(); ++it_t) {
90  g2o::OptimizableGraph::Edge* e = dynamic_cast<g2o::OptimizableGraph::Edge *>(*it_t);
91  e->computeError();
92  chi2 += e->chi2();
93  }
94 
95  if (v->fixed() == false) {
96  Eigen::Matrix<double, PointDoF, PointDoF, Eigen::ColMajor> H_pp;
97  H_pp.resize(v->dimension(), v->dimension());
98  v->mapHessianMemory(H_pp.data());
99  for (int i_g = 0; i_g < num_iters; ++i_g) {
100  H_pp.setZero();
101  v->clearQuadraticForm();
102 
103  g2o::HyperGraph::EdgeSet& track = v->edges();
104  assert(track.size()>=1);
105 
106  for (g2o::HyperGraph::EdgeSet::iterator it_t=track.begin(); it_t!=track.end(); ++it_t) {
107  g2o::OptimizableGraph::Edge* e = dynamic_cast<g2o::OptimizableGraph::Edge *>(*it_t);
108 
109  // fix all the other vertices and remember their fix value
110 #ifdef WINDOWS
111  std::vector<bool> remember_fix_status(e->vertices().size());
112 #else
113  bool remember_fix_status[e->vertices().size()];
114 #endif
115  for (size_t k = 0; k < e->vertices().size(); ++k) {
116  OptimizableGraph::Vertex* otherV = static_cast<OptimizableGraph::Vertex*>(e->vertex(k));
117  if (otherV != v) {
118  remember_fix_status[k] = otherV->fixed();
119  otherV->setFixed(true);
120  }
121  }
122 
123  // build the matrix
124  e->computeError();
125  e->linearizeOplus(auxWorkspace);
127 
128  // Restore frame's initial fixed() values
129  for (size_t k = 0; k < e->vertices().size(); ++k) {
130  OptimizableGraph::Vertex* otherV = static_cast<g2o::OptimizableGraph::Vertex*>(e->vertex(k));
131  if (otherV != v) {
132  otherV->setFixed(remember_fix_status[k]);
133  }
134  }
135  }
136 
137  Eigen::Map<Eigen::Matrix<double,PointDoF,1,Eigen::ColMajor> > b(v->bData(), v->dimension());
138 
139  if (b.norm()<0.001) {
140  stop = true;
141  break;
142  }
143 
144  int trial=0;
145  do {
146  Eigen::Matrix<double,PointDoF,PointDoF,Eigen::ColMajor> H_pp_mu = H_pp;
147  H_pp_mu.diagonal().array() += mu;
148  Eigen::LDLT<Eigen::Matrix<double,PointDoF,PointDoF,Eigen::ColMajor> > chol_H_pp(H_pp_mu);
149  bool goodStep = false;
150  if (chol_H_pp.isPositive()) {
151  Eigen::Matrix<double,PointDoF,1,Eigen::ColMajor> delta_p = chol_H_pp.solve(b);
152  v->push();
153  v->oplus(delta_p.data());
154  double new_chi2 = 0.;
155  for (g2o::HyperGraph::EdgeSet::iterator it_t=track.begin(); it_t!=track.end(); ++it_t) {
156  g2o::OptimizableGraph::Edge* e = dynamic_cast<g2o::OptimizableGraph::Edge *>(*it_t);
157  e->computeError();
158  new_chi2 += e->chi2();
159  }
160  assert(g2o_isnan(new_chi2)==false && "Chi is NaN");
161  double rho = (chi2 - new_chi2);
162  if (rho > 0 && g2o_isfinite(new_chi2)) {
163  goodStep = true;
164  chi2 = new_chi2;
165  v->discardTop();
166  } else {
167  goodStep = false;
168  v->pop();
169  }
170  }
171 
172  // update the damping factor based on the result of the last increment
173  if (goodStep) {
174  mu *= 1./3.;
175  nu = 2.;
176  trial=0;
177  break;
178  } else {
179  mu *= nu;
180  nu *= 2.;
181  ++trial;
182  if (trial >= num_max_trials) {
183  stop=true;
184  break;
185  }
186  }
187  } while(!stop);
188  if (stop)
189  break;
190  }
191  }
192  }
193  return OK;
194  }
const Vertex * vertex(size_t i) const
Definition: hyper_graph.h:186
virtual void discardTop()=0
pop the last element from the stack, without restoring the current estimate
virtual double chi2() const =0
computes the chi2 based on the cached error value, only valid after computeError has been called...
virtual void linearizeOplus(JacobianWorkspace &jacobianWorkspace)=0
std::set< Edge * > EdgeSet
Definition: hyper_graph.h:135
int dimension() const
dimension of the estimated state belonging to this node
Protocol The SLAM executable accepts such as solving the and retrieving or vertices in the explicitly state the reprensentation poses are represented by poses by VERTEX_XYZRPY In the Quaternions and other representations could be but note that it is up to the SLAM algorithm to choose the internal representation of the angles The keyword is followed by a unique vertex ID and an optional initialization of the or edges in the explicitly state the type of the constraint pose constraints are given by pose constraints by EDGE_XYZRPY The keyword is followed by a unique edge the IDs of the referenced vertices
Definition: protocol.txt:7
class G2O_CORE_API Vertex
const VertexContainer & vertices() const
Definition: hyper_graph.h:178
const EdgeSet & edges() const
returns the set of hyper-edges that are leaving/entering in this vertex
Definition: hyper_graph.h:151
virtual void constructQuadraticForm()=0
virtual double * bData()=0
return a pointer to the b vector associated with this vertex
virtual void computeError()=0
virtual void push()=0
backup the position of the vertex to a stack
virtual void pop()=0
restore the position of the vertex by retrieving the position from the stack
virtual void mapHessianMemory(double *d)=0
virtual void clearQuadraticForm()=0
A general case Vertex for optimization.
#define g2o_isfinite(x)
Definition: macros.h:101
#define g2o_isnan(x)
Definition: macros.h:99
bool fixed() const
true => this node is fixed during the optimization
void setFixed(bool fixed)
true => this node should be considered fixed during the optimization
template<int PointDoF>
virtual bool g2o::StructureOnlySolver< PointDoF >::computeMarginals ( SparseBlockMatrix< MatrixXD > &  spinv,
const std::vector< std::pair< int, int > > &  blockIndices 
)
inlinevirtual

computes the block diagonal elements of the pattern specified in the input and stores them in given SparseBlockMatrix. If your solver does not support computing the marginals, return false.

Implements g2o::OptimizationAlgorithm.

Definition at line 209 of file structure_only_solver.h.

209 { return false;}
template<int PointDoF>
virtual bool g2o::StructureOnlySolver< PointDoF >::init ( bool  online)
inlinevirtual

initialize the solver, called once before the first call to solve()

Implements g2o::OptimizationAlgorithm.

Definition at line 196 of file structure_only_solver.h.

References g2o::StructureOnlySolver< PointDoF >::_points, g2o::SparseOptimizer::activeVertices(), g2o::OptimizableGraph::Vertex::marginalized(), and g2o::OptimizationAlgorithm::optimizer().

197  {
198  // collect the vertices
199  _points.clear();
200  for (OptimizableGraph::VertexContainer::const_iterator it = optimizer()->activeVertices().begin(); it != optimizer()->activeVertices().end(); ++it) {
201  OptimizableGraph::Vertex* v = *it;
202  if (v->marginalized()) {
203  _points.push_back(v);
204  }
205  }
206  return true;
207  }
const SparseOptimizer * optimizer() const
return the optimizer operating on
class G2O_CORE_API Vertex
const VertexContainer & activeVertices() const
the vertices active in the current optimization
OptimizableGraph::VertexContainer _points
template<int PointDoF>
OptimizableGraph::VertexContainer& g2o::StructureOnlySolver< PointDoF >::points ( )
inline

return the points of the optimization problem

Definition at line 214 of file structure_only_solver.h.

References g2o::StructureOnlySolver< PointDoF >::_points.

214 { return _points;}
OptimizableGraph::VertexContainer _points
template<int PointDoF>
const OptimizableGraph::VertexContainer& g2o::StructureOnlySolver< PointDoF >::points ( ) const
inline

Definition at line 215 of file structure_only_solver.h.

References g2o::StructureOnlySolver< PointDoF >::_points.

215 { return _points;}
OptimizableGraph::VertexContainer _points
template<int PointDoF>
virtual OptimizationAlgorithm::SolverResult g2o::StructureOnlySolver< PointDoF >::solve ( int  iteration,
bool  online = false 
)
inlinevirtual

Solve one iteration. The SparseOptimizer running on-top will call this for the given number of iterations.

Parameters
iterationindicates the current iteration

Implements g2o::OptimizationAlgorithm.

Definition at line 65 of file structure_only_solver.h.

References g2o::StructureOnlySolver< PointDoF >::_points, and g2o::StructureOnlySolver< PointDoF >::calc().

66  {
67  (void) iteration;
68  (void) online;
69  return calc(_points, 1);
70  }
OptimizableGraph::VertexContainer _points
OptimizationAlgorithm::SolverResult calc(OptimizableGraph::VertexContainer &vertices, int num_iters, int num_max_trials=10)
template<int PointDoF>
virtual bool g2o::StructureOnlySolver< PointDoF >::updateStructure ( const std::vector< HyperGraph::Vertex * > &  vset,
const HyperGraph::EdgeSet edges 
)
inlinevirtual

update the structures for online processing

Implements g2o::OptimizationAlgorithm.

Definition at line 211 of file structure_only_solver.h.

211 { return true;}

Member Data Documentation

template<int PointDoF>
OptimizableGraph::VertexContainer g2o::StructureOnlySolver< PointDoF >::_points
protected
template<int PointDoF>
bool g2o::StructureOnlySolver< PointDoF >::_verbose
protected

The documentation for this class was generated from the following file: