edge_se2Switchable.cpp
Go to the documentation of this file.
00001 /*
00002  * edge_se2Switchable.cpp
00003  *
00004  *  Created on: 13.07.2011
00005  *      Author: niko
00006  *
00007  *  Updated on: 14.01.2013
00008  *      Author: Christian Kerl <christian.kerl@in.tum.de>
00009  */
00010 
00011 #include "vertigo/g2o/edge_se2Switchable.h"
00012 #include "vertigo/g2o/vertex_switchLinear.h"
00013 
00014 using namespace std;
00015 using namespace Eigen;
00016 
00017 
00018 // ================================================
00019 EdgeSE2Switchable::EdgeSE2Switchable() : g2o::BaseMultiEdge<3, g2o::SE2>()
00020 {
00021   resize(3);
00022   _jacobianOplus[0].resize(3,3);    
00023   _jacobianOplus[1].resize(3,3);
00024   _jacobianOplus[2].resize(3,1); 
00025 
00026 }
00027 // ================================================
00028 bool EdgeSE2Switchable::read(std::istream& is)
00029   {
00030     Vector3d p;
00031     is >> p[0] >> p[1] >> p[2];
00032     setMeasurement(g2o::SE2(p));
00033     _inverseMeasurement = measurement().inverse();
00034 
00035     for (int i = 0; i < 3; ++i)
00036       for (int j = i; j < 3; ++j) {
00037         is >> information()(i, j);
00038         if (i != j)
00039           information()(j, i) = information()(i, j);
00040       }
00041     return true;
00042   }
00043 // ================================================
00044 bool EdgeSE2Switchable::write(std::ostream& os) const
00045 {
00046     Vector3d p = measurement().toVector();
00047     os << p.x() << " " << p.y() << " " << p.z();
00048     for (int i = 0; i < 3; ++i)
00049       for (int j = i; j < 3; ++j)
00050         os << " " << information()(i, j);
00051     return os.good();
00052 }
00053 
00054 // ================================================
00055 void EdgeSE2Switchable::linearizeOplus()
00056 {
00057    
00058     const g2o::VertexSE2* vi = static_cast<const g2o::VertexSE2*>(_vertices[0]);
00059     const g2o::VertexSE2* vj = static_cast<const g2o::VertexSE2*>(_vertices[1]);
00060     const VertexSwitchLinear* vSwitch = static_cast<const VertexSwitchLinear*>(_vertices[2]);
00061 
00062     double thetai = vi->estimate().rotation().angle();
00063 
00064     Vector2d dt = vj->estimate().translation() - vi->estimate().translation();
00065     double si=sin(thetai), ci=cos(thetai);
00066 
00067     _jacobianOplus[0](0, 0) = -ci; _jacobianOplus[0](0, 1) = -si; _jacobianOplus[0](0, 2) = -si*dt.x()+ci*dt.y();
00068     _jacobianOplus[0](1, 0) =  si; _jacobianOplus[0](1, 1) = -ci; _jacobianOplus[0](1, 2) = -ci*dt.x()-si*dt.y();
00069     _jacobianOplus[0](2, 0) =  0;  _jacobianOplus[0](2, 1) = 0;   _jacobianOplus[0](2, 2) = -1;
00070 
00071     _jacobianOplus[1](0, 0) = ci; _jacobianOplus[1](0, 1)= si; _jacobianOplus[1](0, 2)= 0;
00072     _jacobianOplus[1](1, 0) =-si; _jacobianOplus[1](1, 1)= ci; _jacobianOplus[1](1, 2)= 0;
00073     _jacobianOplus[1](2, 0) = 0;  _jacobianOplus[1](2, 1)= 0;  _jacobianOplus[1](2, 2)= 1;
00074 
00075     const g2o::SE2& rmean = _inverseMeasurement;
00076     Matrix3d z = Matrix3d::Zero();
00077     z.block<2, 2>(0, 0) = rmean.rotation().toRotationMatrix();
00078     z(2, 2) = 1.;
00079     _jacobianOplus[0] = z * _jacobianOplus[0];
00080     _jacobianOplus[1] = z * _jacobianOplus[1];
00081 
00082 
00083     _jacobianOplus[0]*=vSwitch->estimate();
00084     _jacobianOplus[1]*=vSwitch->estimate();
00085 
00086 
00087     // derivative w.r.t switch vertex
00088     _jacobianOplus[2].setZero();
00089     g2o::SE2 delta = _inverseMeasurement * (vi->estimate().inverse()*vj->estimate());
00090     _jacobianOplus[2] = delta.toVector() * vSwitch->gradient();  
00091 }
00092 
00093 // ================================================
00094 void EdgeSE2Switchable::computeError()
00095 {
00096     const g2o::VertexSE2* v1 = static_cast<const g2o::VertexSE2*>(_vertices[0]);
00097     const g2o::VertexSE2* v2 = static_cast<const g2o::VertexSE2*>(_vertices[1]);
00098     const VertexSwitchLinear* v3 = static_cast<const VertexSwitchLinear*>(_vertices[2]);
00099   
00100     g2o::SE2 delta = _inverseMeasurement * (v1->estimate().inverse()*v2->estimate());
00101     _error = delta.toVector() * v3->estimate();
00102 }
00103 
00104 /*
00105 #include <GL/gl.h>
00106 #ifdef G2O_HAVE_OPENGL
00107   EdgeSE2SwitchableDrawAction::EdgeSE2SwitchableDrawAction(): DrawAction(typeid(EdgeSE2Switchable).name()){}
00108 
00109   g2o::HyperGraphElementAction* EdgeSE2SwitchableDrawAction::operator()(g2o::HyperGraph::HyperGraphElement* element,
00110                g2o::HyperGraphElementAction::Parameters* ){
00111     if (typeid(*element).name()!=_typeName)
00112       return 0;
00113     EdgeSE2Switchable* e =  static_cast<EdgeSE2Switchable*>(element);
00114 
00115 
00116     g2o::VertexSE2* fromEdge = static_cast<g2o::VertexSE2*>(e->vertices()[0]);
00117     g2o::VertexSE2* toEdge   = static_cast<g2o::VertexSE2*>(e->vertices()[1]);
00118     VertexSwitchLinear* s   = static_cast<VertexSwitchLinear*>(e->vertices()[2]);
00119 
00120     glColor3f(s->estimate()*1.0,s->estimate()*0.1,s->estimate()*0.1);
00121     glPushAttrib(GL_ENABLE_BIT);
00122     glDisable(GL_LIGHTING);
00123     glBegin(GL_LINES);
00124     glVertex3f(fromEdge->estimate().translation().x(),fromEdge->estimate().translation().y(),0.);
00125     glVertex3f(toEdge->estimate().translation().x(),toEdge->estimate().translation().y(),0.);
00126     glEnd();
00127     glPopAttrib();
00128     return this;
00129   }
00130 #endif
00131 */


rtabmap
Author(s): Mathieu Labbe
autogenerated on Sat Jul 23 2016 11:44:16