g2o
Public Member Functions | Protected Member Functions | Protected Attributes | List of all members
g2o::EdgeLabeler Struct Reference

#include <edge_labeler.h>

Collaboration diagram for g2o::EdgeLabeler:
Collaboration graph
[legend]

Public Member Functions

 EdgeLabeler (SparseOptimizer *optimizer)
 
int labelEdges (std::set< OptimizableGraph::Edge * > &edges)
 

Protected Member Functions

void augmentSparsePattern (std::set< std::pair< int, int > > &pattern, OptimizableGraph::Edge *e)
 
bool computePartialInverse (SparseBlockMatrix< Eigen::MatrixXd > &spinv, const std::set< std::pair< int, int > > &pattern)
 
bool labelEdge (const SparseBlockMatrix< Eigen::MatrixXd > &spinv, OptimizableGraph::Edge *e)
 

Protected Attributes

SparseOptimizer_optimizer
 

Detailed Description

This class implements the functions to label an edge (measurement) based on the actual configuration of the nodes. It does so by

Definition at line 20 of file edge_labeler.h.

Constructor & Destructor Documentation

g2o::EdgeLabeler::EdgeLabeler ( SparseOptimizer optimizer)

constructs an edge labeler that operates on the optimizer passed as argument

Parameters
optimizerthe optimizer

Definition at line 12 of file edge_labeler.cpp.

12  {
13  _optimizer = optimizer;
14  }
SparseOptimizer * _optimizer
Definition: edge_labeler.h:47

Member Function Documentation

void g2o::EdgeLabeler::augmentSparsePattern ( std::set< std::pair< int, int > > &  pattern,
OptimizableGraph::Edge e 
)
protected

helper function that augments the sparse pattern of the inverse based on an edge

Parameters
patternthe blocks of the inverse covered by the edge
ethe edge

Definition at line 41 of file edge_labeler.cpp.

References g2o::OptimizableGraph::Vertex::hessianIndex(), and g2o::HyperGraph::Edge::vertices().

41  {
42  for (size_t i=0; i<e->vertices().size(); i++){
43  const OptimizableGraph::Vertex* v=(const OptimizableGraph::Vertex*) e->vertices()[i];
44  int ti=v->hessianIndex();
45  if (ti==-1)
46  continue;
47  for (size_t j=i; j<e->vertices().size(); j++){
48  const OptimizableGraph::Vertex* v=(const OptimizableGraph::Vertex*) e->vertices()[j];
49  int tj = v->hessianIndex();
50  if (tj==-1)
51  continue;
52  if(tj<ti)
53  swap(ti,tj);
54  pattern.insert(std::make_pair(ti, tj));
55  }
56  }
57  }
class G2O_CORE_API Vertex
bool g2o::EdgeLabeler::computePartialInverse ( SparseBlockMatrix< Eigen::MatrixXd > &  spinv,
const std::set< std::pair< int, int > > &  pattern 
)
protected

helper function that computes the inverse based on the sparse pattenrn

Parameters
spinvthe output block inverse
patternthe blocks of the inverse covered by the edge
Returns
true on successm, false on failure, .

Definition at line 59 of file edge_labeler.cpp.

59  {
60  std::vector<std::pair<int, int> > blockIndices(pattern.size());
61  // Why this does not work???
62  //std::copy(pattern.begin(),pattern.end(),blockIndices.begin());
63 
64  int k=0;
65  for(std::set<std::pair<int, int> >::const_iterator it= pattern.begin(); it!=pattern.end(); it++){
66  blockIndices[k++]=*it;
67  }
68 
69  //cerr << "sparse pattern contains " << blockIndices.size() << " blocks" << endl;
70  return _optimizer->computeMarginals(spinv, blockIndices);
71  }
SparseOptimizer * _optimizer
Definition: edge_labeler.h:47
bool computeMarginals(SparseBlockMatrix< MatrixXD > &spinv, const std::vector< std::pair< int, int > > &blockIndices)
bool g2o::EdgeLabeler::labelEdge ( const SparseBlockMatrix< Eigen::MatrixXd > &  spinv,
OptimizableGraph::Edge e 
)
protected

helper function that labes a specific edge based on the marginals in the sparse block inverse

Returns
true on success, false on failure

Definition at line 73 of file edge_labeler.cpp.

References g2o::SparseBlockMatrix< MatrixType >::block(), g2o::OptimizableGraph::Edge::computeError(), g2o::OptimizableGraph::Edge::dimension(), g2o::OptimizableGraph::Edge::errorData(), g2o::OptimizableGraph::Vertex::hessianIndex(), g2o::OptimizableGraph::Edge::informationData(), g2o::OptimizableGraph::Vertex::minimalEstimateDimension(), g2o::OptimizableGraph::Vertex::oplus(), g2o::OptimizableGraph::Vertex::pop(), g2o::OptimizableGraph::Vertex::push(), g2o::reconstructGaussian(), g2o::sampleUnscented(), g2o::OptimizableGraph::Edge::setMeasurementFromState(), and g2o::HyperGraph::Edge::vertices().

73  {
74 
75  Eigen::Map<MatrixXd> info(e->informationData(), e->dimension(), e->dimension());
76  // cerr << "original information matrix" << endl;
77  // cerr << info << endl;
78 
79  int maxDim=0;
80  for (size_t i=0; i<e->vertices().size(); i++){
81  const OptimizableGraph::Vertex* v=(const OptimizableGraph::Vertex*) e->vertices()[i];
82  int ti=v->hessianIndex();
83  if (ti==-1)
84  continue;
85  maxDim+=v->minimalEstimateDimension();
86  }
87 
88 
89  //cerr << "maxDim= " << maxDim << endl;
90  MatrixXd cov(maxDim, maxDim);
91  int cumRow=0;
92  for (size_t i=0; i<e->vertices().size(); i++){
93  const OptimizableGraph::Vertex* vr=(const OptimizableGraph::Vertex*) e->vertices()[i];
94  int ti=vr->hessianIndex();
95  if (ti>-1) {
96  int cumCol=0;
97  for (size_t j=0; j<e->vertices().size(); j++){
98  const OptimizableGraph::Vertex* vc=(const OptimizableGraph::Vertex*) e->vertices()[j];
99  int tj = vc->hessianIndex();
100  if (tj>-1){
101  // cerr << "ti=" << ti << " tj=" << tj
102  // << " cumRow=" << cumRow << " cumCol=" << cumCol << endl;
103  if (ti<=tj){
104  assert(spinv.block(ti, tj));
105  // cerr << "cblock_ptr" << spinv.block(ti, tj) << endl;
106  // cerr << "cblock.size=" << spinv.block(ti, tj)->rows() << "," << spinv.block(ti, tj)->cols() << endl;
107  // cerr << "cblock" << endl;
108  // cerr << *spinv.block(ti, tj) << endl;
109  cov.block(cumRow, cumCol, vr->minimalEstimateDimension(), vc->minimalEstimateDimension()) =
110  *spinv.block(ti, tj);
111  } else {
112  assert(spinv.block(tj, ti));
113  // cerr << "cblock.size=" << spinv.block(tj, ti)->cols() << "," << spinv.block(tj, ti)->rows() << endl;
114  // cerr << "cblock" << endl;
115  // cerr << spinv.block(tj, ti)->transpose() << endl;
116  cov.block(cumRow, cumCol, vr->minimalEstimateDimension(), vc->minimalEstimateDimension()) =
117  spinv.block(tj, ti)->transpose();
118  }
119  cumCol += vc->minimalEstimateDimension();
120  }
121  }
122  cumRow += vr->minimalEstimateDimension();
123  }
124  }
125 
126  // cerr << "covariance assembled" << endl;
127  // cerr << cov << endl;
128  // now cov contains the aggregate marginals of the state variables in the edge
129  VectorXd incMean(maxDim);
130  incMean.fill(0);
131  std::vector<MySigmaPoint, Eigen::aligned_allocator<MySigmaPoint> > incrementPoints;
132  if (! sampleUnscented(incrementPoints, incMean, cov)){
133  cerr << "sampleUnscented fail" << endl;
134  return false;
135  }
136  // now determine the zero-error measure by applying the error function of the edge
137  // with a zero measurement
138  // TODO!!!
139  bool smss = e->setMeasurementFromState();
140  if (! smss) {
141  cerr << "FATAL: Edge::setMeasurementFromState() not implemented" << endl;
142  }
143  assert(smss && "Edge::setMeasurementFromState() not implemented");
144 
145  //std::vector<MySigmaPoint> globalPoints(incrementPoints.size());
146  std::vector<MySigmaPoint, Eigen::aligned_allocator<MySigmaPoint> > errorPoints(incrementPoints.size());
147 
148  // for each sigma point, project it to the global space, by considering those variables
149  // that are involved
150  //cerr << "sigma points are extracted, remapping to measurement space" << endl;
151  for (size_t i=0; i<incrementPoints.size(); i++) {
152  int cumPos=0;
153  //VectorXd globalPoint(maxDim);
154 
155  // push all the "active" state variables
156  for (size_t j=0; j<e->vertices().size(); j++){
157  OptimizableGraph::Vertex* vr=(OptimizableGraph::Vertex*) e->vertices()[j];
158  int tj=vr->hessianIndex();
159  if (tj==-1)
160  continue;
161  vr->push();
162  }
163 
164  for (size_t j=0; j<e->vertices().size(); j++){
165  OptimizableGraph::Vertex* vr=(OptimizableGraph::Vertex*) e->vertices()[j];
166  int tj=vr->hessianIndex();
167  if (tj==-1)
168  continue;
169  vr->oplus(&incrementPoints[i]._sample[cumPos]);
170  //assert(vr->getMinimalEstimateData(&globalPoint[cumPos]) && "Vertex::getMinimalEstimateData(...) not implemented");
171  cumPos+=vr->minimalEstimateDimension();
172  }
173 
174  // construct the sigma point in the global space
175  // globalPoints[i]._sample=globalPoint;
176  // globalPoints[i]._wi=incrementPoints[i]._wi;
177  // globalPoints[i]._wp=incrementPoints[i]._wp;
178 
179  // construct the sigma point in the error space
180  e->computeError();
181  Map<VectorXd> errorPoint(e->errorData(),e->dimension());
182 
183  errorPoints[i]._sample=errorPoint;
184  errorPoints[i]._wi=incrementPoints[i]._wi;
185  errorPoints[i]._wp=incrementPoints[i]._wp;
186 
187  // pop all the "active" state variables
188  for (size_t j=0; j<e->vertices().size(); j++){
189  OptimizableGraph::Vertex* vr=(OptimizableGraph::Vertex*) e->vertices()[j];
190  int tj=vr->hessianIndex();
191  if (tj==-1)
192  continue;
193  vr->pop();
194  }
195 
196  }
197 
198  // reconstruct the covariance of the error by the sigma points
199  MatrixXd errorCov(e->dimension(), e->dimension());
200  VectorXd errorMean(e->dimension());
201  reconstructGaussian(errorMean, errorCov, errorPoints);
202  info=errorCov.inverse();
203 
204  // cerr << "remapped information matrix" << endl;
205  // cerr << info << endl;
206  return true;
207  }
SparseMatrixBlock * block(int r, int c, bool alloc=false)
returns the block at location r,c. if alloc=true he block is created if it does not exist ...
void reconstructGaussian(SampleType &mean, CovarianceType &covariance, const std::vector< SigmaPoint< SampleType >, Eigen::aligned_allocator< SigmaPoint< SampleType > > > &sigmaPoints)
Definition: unscented.h:78
class G2O_CORE_API Vertex
bool sampleUnscented(std::vector< SigmaPoint< SampleType >, Eigen::aligned_allocator< SigmaPoint< SampleType > > > &sigmaPoints, const SampleType &mean, const CovarianceType &covariance)
Definition: unscented.h:49
int g2o::EdgeLabeler::labelEdges ( std::set< OptimizableGraph::Edge * > &  edges)

Labels the set of edges passed as argument. It computes the cholesky information matrix. This method only woorks aftec having called an optimize(...) in the connected optimizer. The labeling is performed based on the actual configuration of the nodes in the optimized subgraph.

Parameters
edgesthe edges to label
Returns
-1 if the inverse cholesky cannot be computed, otherwise the number of edges where the labeling was successful

Definition at line 16 of file edge_labeler.cpp.

Referenced by g2o::Star::labelStarEdges().

16  {
17  // assume the system is "solved"
18  // compute the sparse pattern of the inverse
19  std::set<std::pair<int, int> > pattern;
20  for (std::set<OptimizableGraph::Edge*>::iterator it=edges.begin(); it!=edges.end(); it++){
21  augmentSparsePattern(pattern, *it);
22  }
23 
24 
25  SparseBlockMatrix<MatrixXd> spInv;
26 
27  bool result = computePartialInverse(spInv, pattern);
28  //cerr << "partial inverse computed = " << result << endl;
29  //cerr << "non zero blocks" << spInv.nonZeroBlocks() << endl;
30 
31  if (! result ){
32  return -1;
33  }
34  int count=0;
35  for (std::set<OptimizableGraph::Edge*>::iterator it=edges.begin(); it!=edges.end(); it++){
36  count += labelEdge(spInv, *it) ? 1 : 0;
37  }
38  return count;
39  }
void augmentSparsePattern(std::set< std::pair< int, int > > &pattern, OptimizableGraph::Edge *e)
bool labelEdge(const SparseBlockMatrix< Eigen::MatrixXd > &spinv, OptimizableGraph::Edge *e)
bool computePartialInverse(SparseBlockMatrix< Eigen::MatrixXd > &spinv, const std::set< std::pair< int, int > > &pattern)

Member Data Documentation

SparseOptimizer* g2o::EdgeLabeler::_optimizer
protected

Definition at line 47 of file edge_labeler.h.


The documentation for this struct was generated from the following files: