g2o
optimizable_graph.h
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 #ifndef G2O_AIS_OPTIMIZABLE_GRAPH_HH_
28 #define G2O_AIS_OPTIMIZABLE_GRAPH_HH_
29 
30 #include <set>
31 #include <iostream>
32 #include <list>
33 #include <limits>
34 #include <cmath>
35 #include <typeinfo>
36 
37 #include "openmp_mutex.h"
38 #include "hyper_graph.h"
39 #include "parameter.h"
40 #include "parameter_container.h"
41 #include "jacobian_workspace.h"
42 
43 #include "g2o/stuff/macros.h"
44 #include "g2o_core_api.h"
45 
46 namespace g2o {
47 
48  class HyperGraphAction;
49  struct OptimizationAlgorithmProperty;
50  class Cache;
51  class CacheContainer;
52  class RobustKernel;
53 
66 
67  enum ActionType {
68  AT_PREITERATION, AT_POSTITERATION,
69  AT_NUM_ELEMENTS, // keep as last element
70  };
71 
72  typedef std::set<HyperGraphAction*> HyperGraphActionSet;
73 
74  // forward declarations
77 
78 
83  bool operator() (const Vertex* v1, const Vertex* v2) const
84  {
85  return v1->id() < v2->id();
86  }
87  };
88 
93  bool operator() (const Edge* e1, const Edge* e2) const
94  {
95  return e1->internalId() < e2->internalId();
96  }
97  };
98 
100  typedef std::vector<OptimizableGraph::Vertex*> VertexContainer;
102  typedef std::vector<OptimizableGraph::Edge*> EdgeContainer;
103 
108  private:
109  friend struct OptimizableGraph;
110  public:
111  Vertex();
112 
114  virtual Vertex* clone() const ;
115 
116  virtual ~Vertex();
117 
119  void setToOrigin() { setToOriginImpl(); updateCache();}
120 
122  virtual const double& hessian(int i, int j) const = 0;
123  virtual double& hessian(int i, int j) = 0;
124  virtual double hessianDeterminant() const = 0;
125  virtual double* hessianData() = 0;
126 
128  virtual void mapHessianMemory(double* d) = 0;
129 
134  virtual int copyB(double* b_) const = 0;
135 
137  virtual const double& b(int i) const = 0;
138  virtual double& b(int i) = 0;
140  virtual double* bData() = 0;
141 
145  virtual void clearQuadraticForm() = 0;
146 
151  virtual double solveDirect(double lambda=0) = 0;
152 
158  bool setEstimateData(const double* estimate);
159 
165  bool setEstimateData(const std::vector<double>& estimate) {
166 #ifndef NDEBUG
167  int dim = estimateDimension();
168  assert((dim == -1) || (estimate.size() == std::size_t(dim)));
169 #endif
170  return setEstimateData(&estimate[0]);
171  };
172 
177  virtual bool getEstimateData(double* estimate) const;
178 
183  virtual bool getEstimateData(std::vector<double>& estimate) const {
184  int dim = estimateDimension();
185  if (dim < 0)
186  return false;
187  estimate.resize(dim);
188  return getEstimateData(&estimate[0]);
189  };
190 
195  virtual int estimateDimension() const;
196 
202  bool setMinimalEstimateData(const double* estimate);
203 
209  bool setMinimalEstimateData(const std::vector<double>& estimate) {
210 #ifndef NDEBUG
211  int dim = minimalEstimateDimension();
212  assert((dim == -1) || (estimate.size() == std::size_t(dim)));
213 #endif
214  return setMinimalEstimateData(&estimate[0]);
215  };
216 
221  virtual bool getMinimalEstimateData(double* estimate) const ;
222 
227  virtual bool getMinimalEstimateData(std::vector<double>& estimate) const {
228  int dim = minimalEstimateDimension();
229  if (dim < 0)
230  return false;
231  estimate.resize(dim);
232  return getMinimalEstimateData(&estimate[0]);
233  };
234 
239  virtual int minimalEstimateDimension() const;
240 
242  virtual void push() = 0;
243 
245  virtual void pop() = 0;
246 
248  virtual void discardTop() = 0;
249 
251  virtual int stackSize() const = 0;
252 
259  void oplus(const double* v)
260  {
261  oplusImpl(v);
262  updateCache();
263  }
264 
266  int hessianIndex() const { return _hessianIndex;}
267  int G2O_ATTRIBUTE_DEPRECATED(tempIndex() const) { return hessianIndex();}
269  void setHessianIndex(int ti) { _hessianIndex = ti;}
270  void G2O_ATTRIBUTE_DEPRECATED(setTempIndex(int ti)) { setHessianIndex(ti);}
271 
273  bool fixed() const {return _fixed;}
275  void setFixed(bool fixed) { _fixed = fixed;}
276 
278  bool marginalized() const {return _marginalized;}
280  void setMarginalized(bool marginalized) { _marginalized = marginalized;}
281 
283  int dimension() const { return _dimension;}
284 
286  virtual void setId(int id) {_id = id;}
287 
289  void setColInHessian(int c) { _colInHessian = c;}
291  int colInHessian() const {return _colInHessian;}
292 
293  const OptimizableGraph* graph() const {return _graph;}
294  OptimizableGraph* graph() {return _graph;}
295 
300  void lockQuadraticForm() { _quadraticFormMutex.lock();}
304  void unlockQuadraticForm() { _quadraticFormMutex.unlock();}
305 
307  virtual bool read(std::istream& is) = 0;
309  virtual bool write(std::ostream& os) const = 0;
310 
311  virtual void updateCache();
312 
313  CacheContainer* cacheContainer();
314  protected:
316  Data* _userData;
318  bool _fixed;
323 
325 
330  virtual void oplusImpl(const double* v) = 0;
331 
333  virtual void setToOriginImpl() = 0;
334 
339  virtual bool setEstimateDataImpl(const double* ) { return false;}
340 
345  virtual bool setMinimalEstimateDataImpl(const double* ) { return false;}
346 
347  };
348 
350  private:
351  friend struct OptimizableGraph;
352 
353  public:
354  Edge();
355  virtual ~Edge();
356  virtual Edge* clone() const;
357 
358  // indicates if all vertices are fixed
359  virtual bool allVerticesFixed() const = 0;
360 
361  // computes the error of the edge and stores it in an internal structure
362  virtual void computeError() = 0;
363 
366  virtual bool setMeasurementData(const double* m);
367 
370  virtual bool getMeasurementData(double* m) const;
371 
374  virtual int measurementDimension() const;
375 
380  virtual bool setMeasurementFromState();
381 
383  RobustKernel* robustKernel() const { return _robustKernel;}
387  void setRobustKernel(RobustKernel* ptr);
388 
390  virtual const double* errorData() const = 0;
391  virtual double* errorData() = 0;
392 
394  virtual const double* informationData() const = 0;
395  virtual double* informationData() = 0;
396 
398  virtual double chi2() const = 0;
399 
406  virtual void constructQuadraticForm() = 0;
407 
416  virtual void mapHessianMemory(double* d, int i, int j, bool rowMajor) = 0;
417 
422  virtual void linearizeOplus(JacobianWorkspace& jacobianWorkspace) = 0;
423 
425  virtual void initialEstimate(const OptimizableGraph::VertexSet& from, OptimizableGraph::Vertex* to) = 0;
426 
432  virtual double initialEstimatePossible(const OptimizableGraph::VertexSet& from, OptimizableGraph::Vertex* to) { (void) from; (void) to; return -1.;}
433 
435  int level() const { return _level;}
437  void setLevel(int l) { _level=l;}
438 
440  int dimension() const { return _dimension;}
441 
442  G2O_ATTRIBUTE_DEPRECATED(virtual Vertex* createFrom()) {return 0;}
443  G2O_ATTRIBUTE_DEPRECATED(virtual Vertex* createTo()) {return 0;}
444  virtual Vertex* createVertex(int) {return 0;}
445 
447  virtual bool read(std::istream& is) = 0;
449  virtual bool write(std::ostream& os) const = 0;
450 
452  long long internalId() const { return _internalId;}
453 
455  const OptimizableGraph* graph() const;
456 
457  bool setParameterId(int argNum, int paramId);
458  inline const Parameter* parameter(int argNo) const {return *_parameters.at(argNo);}
459  inline size_t numParameters() const {return _parameters.size();}
460  inline void resizeParameters(size_t newSize) {
461  _parameters.resize(newSize, 0);
462  _parameterIds.resize(newSize, -1);
463  _parameterTypes.resize(newSize, typeid(void*).name());
464  }
465  protected:
467  int _level;
469  long long _internalId;
470  std::vector<int> _cacheIds;
471 
472  template <typename ParameterType>
473  bool installParameter(ParameterType*& p, size_t argNo, int paramId=-1){
474  if (argNo>=_parameters.size())
475  return false;
476  _parameterIds[argNo] = paramId;
477  _parameters[argNo] = (Parameter**)&p;
478  _parameterTypes[argNo] = typeid(ParameterType).name();
479  return true;
480  }
481 
482  template <typename CacheType>
483  void resolveCache(CacheType*& cache, OptimizableGraph::Vertex*,
484  const std::string& _type,
485  const ParameterVector& parameters);
486 
487  bool resolveParameters();
488  virtual bool resolveCaches();
489 
490  std::vector<std::string> _parameterTypes;
491  std::vector<Parameter**> _parameters;
492  std::vector<int> _parameterIds;
493  };
494 
496  inline Vertex* vertex(int id) { return reinterpret_cast<Vertex*>(HyperGraph::vertex(id));}
497 
499  inline const Vertex* vertex (int id) const{ return reinterpret_cast<const Vertex*>(HyperGraph::vertex(id));}
500 
503  virtual ~OptimizableGraph();
504 
506  void addGraph(OptimizableGraph* g);
507 
512  virtual bool addVertex(HyperGraph::Vertex* v, Data* userData);
513  virtual bool addVertex(HyperGraph::Vertex* v) { return addVertex(v, 0);}
514 
520  virtual bool addEdge(HyperGraph::Edge* e);
521 
526  virtual bool setEdgeVertex(HyperGraph::Edge* e, int pos, HyperGraph::Vertex* v);
527 
529  double chi2() const;
530 
532  int maxDimension() const;
533 
537  std::set<int> dimensions() const;
538 
543  virtual int optimize(int iterations, bool online=false);
544 
546  virtual void preIteration(int);
548  virtual void postIteration(int);
549 
551  bool addPreIterationAction(HyperGraphAction* action);
553  bool addPostIterationAction(HyperGraphAction* action);
554 
556  bool removePreIterationAction(HyperGraphAction* action);
558  bool removePostIterationAction(HyperGraphAction* action);
559 
561  virtual void push();
563  virtual void pop();
565  virtual void discardTop();
566 
568  virtual bool load(std::istream& is, bool createEdges=true);
569  bool load(const char* filename, bool createEdges=true);
571  virtual bool save(std::ostream& os, int level = 0) const;
573  bool save(const char* filename, int level = 0) const;
574 
575 
577  bool saveSubset(std::ostream& os, HyperGraph::VertexSet& vset, int level = 0);
578 
580  bool saveSubset(std::ostream& os, HyperGraph::EdgeSet& eset);
581 
583  virtual void push(HyperGraph::VertexSet& vset);
585  virtual void pop(HyperGraph::VertexSet& vset);
587  virtual void discardTop(HyperGraph::VertexSet& vset);
588 
590  virtual void setFixed(HyperGraph::VertexSet& vset, bool fixed);
591 
597  void setRenamedTypesFromString(const std::string& types);
598 
604  bool isSolverSuitable(const OptimizationAlgorithmProperty& solverProperty, const std::set<int>& vertDims = std::set<int>()) const;
605 
609  virtual void clearParameters();
610 
612  return _parameters.addParameter(p);
613  }
614 
615  Parameter* parameter(int id) {
616  return _parameters.getParameter(id);
617  }
618 
625  bool verifyInformationMatrices(bool verbose = false) const;
626 
627  // helper functions to save an individual vertex
628  bool saveVertex(std::ostream& os, Vertex* v) const;
629 
630  // helper function to save an individual parameter
631  bool saveParameter(std::ostream& os, Parameter* v) const;
632 
633  // helper functions to save an individual edge
634  bool saveEdge(std::ostream& os, Edge* e) const;
635 
636  // helper functions to save the data packets
637  bool saveUserData(std::ostream& os, HyperGraph::Data* v) const;
638 
640  JacobianWorkspace& jacobianWorkspace() { return _jacobianWorkspace;}
641  const JacobianWorkspace& jacobianWorkspace() const { return _jacobianWorkspace;}
642 
649  static bool initMultiThreading();
650 
651  inline ParameterContainer& parameters() {return _parameters;}
652  inline const ParameterContainer& parameters() const {return _parameters;}
653 
654  protected:
655  std::map<std::string, std::string> _renamedTypesLookup;
656  long long _nextEdgeId;
657  std::vector<HyperGraphActionSet> _graphActions;
658 
659  // do not watch this. To be removed soon, or integrated in a nice way
661 
664  };
665 
670 } // end namespace
671 
672 #endif
stuff to open files and other unsorted components ProjectiveCamera types
bool installParameter(ParameterType *&p, size_t argNo, int paramId=-1)
int id() const
returns the id
Definition: hyper_graph.h:148
std::vector< OptimizableGraph::Vertex * > VertexContainer
vector container for vertices
void setColInHessian(int c)
set the row of this vertex in the Hessian
void setHessianIndex(int ti)
set the temporary index of the vertex in the parameter blocks
const OptimizableGraph * graph() const
data packet for a vertex. Extend this class to store in the vertices the potential additional informa...
Definition: hyper_graph.h:97
std::vector< std::string > _parameterTypes
int dimension() const
returns the dimensions of the error function
describe the properties of a solver
void G2O_ATTRIBUTE_DEPRECATED(setTempIndex(int ti))
long long internalId() const
the internal ID of the edge
virtual Vertex * createVertex(int)
int G2O_ATTRIBUTE_DEPRECATED(tempIndex() const)
G2O_ATTRIBUTE_DEPRECATED(virtual Vertex *createTo())
virtual bool getMinimalEstimateData(std::vector< double > &estimate) const
std::set< Vertex * > VertexSet
Definition: hyper_graph.h:136
virtual double initialEstimatePossible(const OptimizableGraph::VertexSet &from, OptimizableGraph::Vertex *to)
int level() const
returns the level of the edge
int hessianIndex() const
temporary index of this node in the parameter vector obtained from linearization
Vertex * vertex(int id)
returns a vertex id in the hyper-graph, or 0 if the vertex id is not present
Definition: hyper_graph.cpp:78
virtual bool setMinimalEstimateDataImpl(const double *)
bool setMinimalEstimateData(const std::vector< double > &estimate)
base for all robust cost functions
Definition: robust_kernel.h:48
Vertex * vertex(int id)
returns the vertex number id appropriately casted
const JacobianWorkspace & jacobianWorkspace() const
JacobianWorkspace & jacobianWorkspace()
the workspace for storing the Jacobians of the graph
std::vector< Parameter ** > _parameters
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 ...
virtual bool setEstimateDataImpl(const double *)
std::vector< OptimizableGraph::Edge * > EdgeContainer
vector container for edges
std::set< Edge * > EdgeSet
Definition: hyper_graph.h:135
int dimension() const
dimension of the estimated state belonging to this node
int colInHessian() const
get the row of this vertex in the Hessian
RobustKernel * robustKernel() const
if NOT NULL, error of this edge will be robustifed with the kernel
std::vector< int > _parameterIds
std::vector< Parameter * > ParameterVector
Definition: parameter.h:52
G2O_ATTRIBUTE_DEPRECATED(virtual Vertex *createFrom())
order vertices based on their ID
std::map< std::string, std::string > _renamedTypesLookup
bool addParameter(Parameter *p)
const Parameter * parameter(int argNo) const
bool marginalized() const
true => this node is marginalized out during the optimization
order edges based on the internal ID, which is assigned to the edge in addEdge()
A general case Vertex for optimization.
virtual bool addVertex(HyperGraph::Vertex *v)
abstract Vertex, your types must derive from that one
Definition: hyper_graph.h:142
void setToOrigin()
sets the node to the origin (used in the multilevel stuff)
void resizeParameters(size_t newSize)
map id to parameters
Parameter * parameter(int id)
JacobianWorkspace _jacobianWorkspace
void setMarginalized(bool marginalized)
true => this node should be marginalized out during the optimization
bool fixed() const
true => this node is fixed during the optimization
std::set< HyperGraphAction * > HyperGraphActionSet
void setFixed(bool fixed)
true => this node should be considered fixed during the optimization
const Vertex * vertex(int id) const
returns the vertex number id appropriately casted
void setLevel(int l)
sets the level of the edge
Container class that implements an interface for adding/removing Data elements in a linked list...
Definition: hyper_graph.h:121
ParameterContainer _parameters
virtual bool getEstimateData(std::vector< double > &estimate) const
provide memory workspace for computing the Jacobians
std::vector< HyperGraphActionSet > _graphActions
bool setEstimateData(const std::vector< double > &estimate)
#define G2O_CORE_API
Definition: g2o_core_api.h:29
Protocol The SLAM executable accepts such as solving the and retrieving or vertices in the graph
Definition: protocol.txt:7
const ParameterContainer & parameters() const
Abstract action that operates on an entire graph.
ParameterContainer & parameters()