g2o
base_unary_edge.hpp
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 template <int D, typename E, typename VertexXiType>
28 void BaseUnaryEdge<D, E, VertexXiType>::resize(size_t size)
29 {
30  if (size != 1) {
31  std::cerr << "WARNING, attempting to resize unary edge " << BaseEdge<D, E>::id() << " to " << size << std::endl;
32  assert(0 && "error resizing unary edge where size != 1");
33  }
34  BaseEdge<D, E>::resize(size);
35 }
36 
37 template <int D, typename E, typename VertexXiType>
38 bool BaseUnaryEdge<D, E, VertexXiType>::allVerticesFixed() const
39 {
40  return static_cast<const VertexXiType*> (_vertices[0])->fixed();
41 }
42 
43 template <int D, typename E, typename VertexXiType>
44 OptimizableGraph::Vertex* BaseUnaryEdge<D, E, VertexXiType>::createVertex(int i)
45 {
46  if (i!=0)
47  return 0;
48  return new VertexXiType();
49 }
50 
51 template <int D, typename E, typename VertexXiType>
52 void BaseUnaryEdge<D, E, VertexXiType>::constructQuadraticForm()
53 {
54  VertexXiType* from=static_cast<VertexXiType*>(_vertices[0]);
55 
56  // chain rule to get the Jacobian of the nodes in the manifold domain
57  const JacobianXiOplusType& A = jacobianOplusXi();
58  const InformationType& omega = _information;
59 
60  bool istatus = !from->fixed();
61  if (istatus) {
62 #ifdef G2O_OPENMP
63  from->lockQuadraticForm();
64 #endif
65  if (this->robustKernel()) {
66  double error = this->chi2();
67  Vector3D rho;
68  this->robustKernel()->robustify(error, rho);
69  InformationType weightedOmega = this->robustInformation(rho);
70 
71  from->b().noalias() -= rho[1] * A.transpose() * omega * _error;
72  from->A().noalias() += A.transpose() * weightedOmega * A;
73  } else {
74  from->b().noalias() -= A.transpose() * omega * _error;
75  from->A().noalias() += A.transpose() * omega * A;
76  }
77 #ifdef G2O_OPENMP
78  from->unlockQuadraticForm();
79 #endif
80  }
81 }
82 
83 template <int D, typename E, typename VertexXiType>
84 void BaseUnaryEdge<D, E, VertexXiType>::linearizeOplus(JacobianWorkspace& jacobianWorkspace)
85 {
86  new (&_jacobianOplusXi) JacobianXiOplusType(jacobianWorkspace.workspaceForVertex(0), D, VertexXiType::Dimension);
87  linearizeOplus();
88 }
89 
90 template <int D, typename E, typename VertexXiType>
91 void BaseUnaryEdge<D, E, VertexXiType>::linearizeOplus()
92 {
93  //Xi - estimate the jacobian numerically
94  VertexXiType* vi = static_cast<VertexXiType*>(_vertices[0]);
95 
96  if (vi->fixed())
97  return;
98 
99 #ifdef G2O_OPENMP
100  vi->lockQuadraticForm();
101 #endif
102 
103  const double delta = 1e-9;
104  const double scalar = 1.0 / (2*delta);
105  ErrorVector error1;
106  ErrorVector errorBeforeNumeric = _error;
107 
108  double add_vi[VertexXiType::Dimension];
109  std::fill(add_vi, add_vi + VertexXiType::Dimension, 0.0);
110  // add small step along the unit vector in each dimension
111  for (int d = 0; d < VertexXiType::Dimension; ++d) {
112  vi->push();
113  add_vi[d] = delta;
114  vi->oplus(add_vi);
115  computeError();
116  error1 = _error;
117  vi->pop();
118  vi->push();
119  add_vi[d] = -delta;
120  vi->oplus(add_vi);
121  computeError();
122  vi->pop();
123  add_vi[d] = 0.0;
124 
125  _jacobianOplusXi.col(d) = scalar * (error1 - _error);
126  } // end dimension
127 
128  _error = errorBeforeNumeric;
129 #ifdef G2O_OPENMP
130  vi->unlockQuadraticForm();
131 #endif
132 }
133 
134 template <int D, typename E, typename VertexXiType>
135 void BaseUnaryEdge<D, E, VertexXiType>::initialEstimate(const OptimizableGraph::VertexSet&, OptimizableGraph::Vertex*)
136 {
137  std::cerr << __PRETTY_FUNCTION__ << " is not implemented, please give implementation in your derived class" << std::endl;
138 }
#define __PRETTY_FUNCTION__
Definition: macros.h:89
Eigen::Matrix< double, 3, 1, Eigen::ColMajor > Vector3D
Definition: eigen_types.h:46