base_binary_edge.hpp
Go to the documentation of this file.
00001 // g2o - General Graph Optimization
00002 // Copyright (C) 2011 R. Kuemmerle, G. Grisetti, H. Strasdat, W. Burgard
00003 // 
00004 // g2o is free software: you can redistribute it and/or modify
00005 // it under the terms of the GNU Lesser General Public License as published
00006 // by the Free Software Foundation, either version 3 of the License, or
00007 // (at your option) any later version.
00008 // 
00009 // g2o is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 // GNU Lesser General Public License for more details.
00013 // 
00014 // You should have received a copy of the GNU Lesser General Public License
00015 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
00016 
00017 template <int D, typename E, typename VertexXiType, typename VertexXjType>
00018 OptimizableGraph::Vertex* BaseBinaryEdge<D, E, VertexXiType, VertexXjType>::createFrom(){
00019   return new VertexXiType();
00020 }
00021 
00022 template <int D, typename E, typename VertexXiType, typename VertexXjType>
00023 OptimizableGraph::Vertex* BaseBinaryEdge<D, E, VertexXiType, VertexXjType>::createTo(){
00024   return new VertexXjType();
00025 }
00026 
00027 
00028 template <int D, typename E, typename VertexXiType, typename VertexXjType>
00029 void BaseBinaryEdge<D, E, VertexXiType, VertexXjType>::constructQuadraticForm()
00030 {
00031   VertexXiType* from = static_cast<VertexXiType*>(_vertices[0]);
00032   VertexXjType* to   = static_cast<VertexXjType*>(_vertices[1]);
00033 
00034   // get the Jacobian of the nodes in the manifold domain
00035   const JacobianXiOplusType& A = jacobianOplusXi();
00036   const JacobianXjOplusType& B = jacobianOplusXj();
00037 
00038   const InformationType& omega = _information;
00039 
00040   bool fromNotFixed = !(from->fixed());
00041   bool toNotFixed = !(to->fixed());
00042 
00043   if (fromNotFixed || toNotFixed) {
00044 #ifdef G2O_OPENMP
00045     from->lockQuadraticForm();
00046     to->lockQuadraticForm();
00047 #endif
00048     Matrix<double, D, 1> omega_r = - omega * _error;
00049     if (fromNotFixed) {
00050       Matrix<double, VertexXiType::Dimension, D> AtO = A.transpose() * omega;
00051       from->b().noalias() += A.transpose() * omega_r;
00052       from->A().noalias() += AtO*A;
00053       if (toNotFixed ) {
00054         if (_hessianRowMajor) // we have to write to the block as transposed
00055           _hessianTransposed.noalias() += B.transpose() * AtO.transpose();
00056         else
00057           _hessian.noalias() += AtO * B;
00058       }
00059     } 
00060     if (toNotFixed ) {
00061       to->b().noalias() += B.transpose() * omega_r;
00062       to->A().noalias() += B.transpose() * omega * B;
00063     }
00064 #ifdef G2O_OPENMP
00065     to->unlockQuadraticForm();
00066     from->unlockQuadraticForm();
00067 #endif
00068   }
00069 }
00070 
00071 template <int D, typename E, typename VertexXiType, typename VertexXjType>
00072 void BaseBinaryEdge<D, E, VertexXiType, VertexXjType>::linearizeOplus()
00073 {
00074   VertexXiType* vi = static_cast<VertexXiType*>(_vertices[0]);
00075   VertexXjType* vj = static_cast<VertexXjType*>(_vertices[1]);
00076 
00077   bool iNotFixed = !(vi->fixed());
00078   bool jNotFixed = !(vj->fixed());
00079 
00080   if (!iNotFixed && !jNotFixed)
00081     return;
00082 
00083 #ifdef G2O_OPENMP
00084   vi->lockQuadraticForm();
00085   vj->lockQuadraticForm();
00086 #endif
00087 
00088   const double delta = 1e-9;
00089   const double scalar = 1.0 / (2*delta);
00090   ErrorVector errorBak;
00091   ErrorVector errorBeforeNumeric = _error;
00092 
00093   if (iNotFixed) {
00094     //Xi - estimate the jacobian numerically
00095     double add_vi[VertexXiType::Dimension];
00096     std::fill(add_vi, add_vi + VertexXiType::Dimension, 0.0);
00097     // add small step along the unit vector in each dimension
00098     for (int d = 0; d < VertexXiType::Dimension; ++d) {
00099       vi->push();
00100       add_vi[d] = delta;
00101       vi->oplus(add_vi);
00102       computeError();
00103       errorBak = _error;
00104       vi->pop();
00105       vi->push();
00106       add_vi[d] = -delta;
00107       vi->oplus(add_vi);
00108       computeError();
00109       errorBak -= _error;
00110       vi->pop();
00111       add_vi[d] = 0.0;
00112 
00113       _jacobianOplusXi.col(d) = scalar * errorBak;
00114     } // end dimension
00115   }
00116 
00117   if (jNotFixed) {
00118     //Xj - estimate the jacobian numerically
00119     double add_vj[VertexXjType::Dimension];
00120     std::fill(add_vj, add_vj + VertexXjType::Dimension, 0.0);
00121     // add small step along the unit vector in each dimension
00122     for (int d = 0; d < VertexXjType::Dimension; ++d) {
00123       vj->push();
00124       add_vj[d] = delta;
00125       vj->oplus(add_vj);
00126       computeError();
00127       errorBak = _error;
00128       vj->pop();
00129       vj->push();
00130       add_vj[d] = -delta;
00131       vj->oplus(add_vj);
00132       computeError();
00133       errorBak -= _error;
00134       vj->pop();
00135       add_vj[d] = 0.0;
00136 
00137       _jacobianOplusXj.col(d) = scalar * errorBak;
00138     }
00139   } // end dimension
00140 
00141   _error = errorBeforeNumeric;
00142 #ifdef G2O_OPENMP
00143   vj->unlockQuadraticForm();
00144   vi->unlockQuadraticForm();
00145 #endif
00146 }
00147 
00148 template <int D, typename E, typename VertexXiType, typename VertexXjType>
00149 void BaseBinaryEdge<D, E, VertexXiType, VertexXjType>::mapHessianMemory(double* d, int i, int j, bool rowMajor)
00150 {
00151   (void) i; (void) j;
00152   //assert(i == 0 && j == 1);
00153   if (rowMajor) {
00154     new (&_hessianTransposed) HessianBlockTransposedType(d, VertexXjType::Dimension, VertexXiType::Dimension);
00155   } else {
00156     new (&_hessian) HessianBlockType(d, VertexXiType::Dimension, VertexXjType::Dimension);
00157   }
00158   _hessianRowMajor = rowMajor;
00159 }


re_vision
Author(s): Dorian Galvez-Lopez
autogenerated on Sun Jan 5 2014 11:30:47