types_sba.h
Go to the documentation of this file.
00001 // g2o - General Graph Optimization
00002 // Copyright (C) 2011 Kurt Konolige
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 #ifndef SBA_TYPES
00018 #define SBA_TYPES
00019 
00020 #include "g2o/core/base_vertex.h"
00021 #include "g2o/core/base_binary_edge.h"
00022 #include "g2o/core/base_multi_edge.h"
00023 #include "g2o/math_groups/sbacam.h"
00024 #include <Eigen/Geometry>
00025 #include <iostream>
00026 
00027 namespace g2o {
00028 
00029   using namespace Eigen;
00030 
00035 class VertexIntrinsics : public BaseVertex<4, Matrix<double, 5, 1> >
00036 {
00037   public:
00038     EIGEN_MAKE_ALIGNED_OPERATOR_NEW
00039     VertexIntrinsics();
00040     virtual bool read(std::istream& is);
00041     virtual bool write(std::ostream& os) const;
00042       
00043     virtual void setToOrigin() {
00044       _estimate << 1., 1., 0.5, 0.5, 0.1;
00045     }
00046       
00047     virtual void oplus(double* update)
00048     {
00049       _estimate.head<4>() += Vector4d(update);
00050     }
00051  };
00052 
00061   class VertexCam : public BaseVertex<6, SBACam>
00062 {
00063   public:
00064     EIGEN_MAKE_ALIGNED_OPERATOR_NEW
00065     VertexCam();
00066       
00067     virtual bool read(std::istream& is);
00068     virtual bool write(std::ostream& os) const;
00069 
00070     virtual void setToOrigin() {
00071       _estimate = SBACam();
00072     }
00073       
00074     virtual void oplus(double* update)
00075     {
00076       /* if (_intrinsics){ */
00077       /*        _estimate.setKcam(_intrinsics->estimate()[0], */
00078       /*                          _intrinsics->estimate()[1], */
00079       /*                          _intrinsics->estimate()[2], */
00080       /*                          _intrinsics->estimate()[3], */
00081       /*                          _intrinsics->estimate()[4]); */
00082       /* } */
00083       Vector6d v;
00084       for (int i=0; i<6; i++) 
00085         v[i]=update[i];
00086       _estimate.update(v);
00087     }
00088 
00089     VertexIntrinsics* _intrinsics;
00090  };
00091 
00095  class VertexPointXYZ : public BaseVertex<3, Vector3d>
00096 {
00097   public:
00098     EIGEN_MAKE_ALIGNED_OPERATOR_NEW    
00099     VertexPointXYZ();
00100     virtual bool read(std::istream& is);
00101     virtual bool write(std::ostream& os) const;
00102 
00103     virtual void setToOrigin() {
00104       _estimate.fill(0.);
00105     }
00106 
00107     virtual void oplus(double* update_)
00108     {
00109 
00110       Vector3d update;
00111       for (int i=0; i<3; i++)
00112         update[i]=update_[i];
00113 
00114       _estimate += update;
00115     }
00116 
00117 
00118  protected:
00119 };
00120 
00121 
00122 // monocular projection
00123 // first two args are the measurement type, second two the connection classes
00124  class EdgeProjectP2MC : public  BaseBinaryEdge<2, Vector2d, VertexPointXYZ, VertexCam> 
00125 {
00126   public:
00127     EIGEN_MAKE_ALIGNED_OPERATOR_NEW
00128     EdgeProjectP2MC();
00129     virtual bool read(std::istream& is);
00130     virtual bool write(std::ostream& os) const;
00131 
00132     // return the error estimate as a 2-vector
00133     void computeError()
00134     {
00135       // from <Point> to <Cam>
00136       const VertexPointXYZ *point = static_cast<const VertexPointXYZ*>(_vertices[0]);
00137       const VertexCam *cam = static_cast<const VertexCam*>(_vertices[1]);
00138 
00139       // calculate the projection
00140       const Vector3d &pt = point->estimate();
00141       Vector4d ppt(pt(0),pt(1),pt(2),1.0);
00142       Vector3d p = cam->estimate().w2i * ppt;
00143       Vector2d perr;
00144       perr = p.head<2>()/p(2);
00145       //      std::cout << std::endl << "CAM   " << cam->estimate() << std::endl;
00146       //      std::cout << "POINT " << pt.transpose() << std::endl;
00147       //      std::cout << "PROJ  " << p.transpose() << std::endl;
00148       //      std::cout << "CPROJ " << perr.transpose() << std::endl;
00149       //      std::cout << "MEAS  " << _measurement.transpose() << std::endl;
00150 
00151       // error, which is backwards from the normal observed - calculated
00152       // _measurement is the measured projection
00153       _error = perr - _measurement;
00154       // std::cerr << _error.x() << " " << _error.y() <<  " " << chi2() << std::endl;
00155     }
00156 
00157     // jacobian
00158     virtual void linearizeOplus();
00159 
00160 };
00161 
00162 // stereo projection
00163 // first two args are the measurement type, second two the connection classes
00164  class EdgeProjectP2SC : public  BaseBinaryEdge<3, Vector3d, VertexPointXYZ, VertexCam>
00165 {
00166   public:
00167     EIGEN_MAKE_ALIGNED_OPERATOR_NEW
00168     EdgeProjectP2SC();
00169     virtual bool read(std::istream& is);
00170     virtual bool write(std::ostream& os) const;
00171 
00172     // return the error estimate as a 2-vector
00173     void computeError()
00174     {
00175       // from <Point> to <Cam>
00176       const VertexPointXYZ *point = static_cast<const VertexPointXYZ*>(_vertices[0]);
00177       VertexCam *cam = static_cast<VertexCam*>(_vertices[1]);
00178 
00179       // calculate the projection
00180       Vector3d kp;
00181       Vector4d pt;
00182       pt.head<3>() = point->estimate();
00183       pt(3) = 1.0;
00184       SBACam &nd = cam->estimate();
00185       nd.setTransform();
00186       nd.setProjection();
00187       nd.setDr();
00188 
00189       Vector3d p1 = nd.w2i * pt; 
00190       Vector3d p2 = nd.w2n * pt; 
00191       Vector3d pb(nd.baseline,0,0);
00192 
00193       double invp1 = 1.0/p1(2);
00194       kp.head<2>() = p1.head<2>()*invp1;
00195 
00196       // right camera px
00197       p2 = nd.Kcam*(p2-pb);
00198       kp(2) = p2(0)/p2(2);
00199 
00200       // std::cout << std::endl << "CAM   " << cam->estimate() << std::endl; 
00201       // std::cout << "POINT " << pt.transpose() << std::endl; 
00202       // std::cout << "PROJ  " << p1.transpose() << std::endl; 
00203       // std::cout << "PROJ  " << p2.transpose() << std::endl; 
00204       // std::cout << "CPROJ " << kp.transpose() << std::endl; 
00205       // std::cout << "MEAS  " << _measurement.transpose() << std::endl; 
00206 
00207       // error, which is backwards from the normal observed - calculated
00208       // _measurement is the measured projection
00209       _error = kp - _measurement;
00210     }
00211 
00212     // jacobian
00213     virtual void linearizeOplus();
00214 
00215 };
00216 
00217 // monocular projection with parameter calibration
00218 // first two args are the measurement type, second two the connection classes
00219  class EdgeProjectP2MC_Intrinsics : public  BaseMultiEdge<2, Vector2d> 
00220 {
00221   public:
00222     EIGEN_MAKE_ALIGNED_OPERATOR_NEW
00223     EdgeProjectP2MC_Intrinsics();
00224     virtual bool read(std::istream& is);
00225     virtual bool write(std::ostream& os) const;
00226 
00227     // return the error estimate as a 2-vector
00228     void computeError()
00229     {
00230       // from <Point> to <Cam>, the intrinsics in KCam should be already set!
00231       const VertexPointXYZ *point = static_cast<const VertexPointXYZ*>(_vertices[0]);
00232       VertexCam *cam = static_cast<VertexCam*>(_vertices[1]);
00233       // calculate the projection
00234       const Vector3d &pt = point->estimate();
00235       Vector4d ppt(pt(0),pt(1),pt(2),1.0);
00236       Vector3d p = cam->estimate().w2i * ppt;
00237       Vector2d perr = p.head<2>()/p(2);
00238       _error = perr - _measurement;
00239     }
00240 
00241     // jacobian
00242     virtual void linearizeOplus();
00243 
00244 };
00245 
00246 
00250  class EdgeSBACam : public BaseBinaryEdge<6, SE3Quat, VertexCam, VertexCam>
00251 {
00252   public:
00253     EIGEN_MAKE_ALIGNED_OPERATOR_NEW
00254     EdgeSBACam();
00255     virtual bool read(std::istream& is);
00256     virtual bool write(std::ostream& os) const;
00257     void computeError()
00258     {
00259       const VertexCam* v1 = dynamic_cast<const VertexCam*>(_vertices[0]);
00260       const VertexCam* v2 = dynamic_cast<const VertexCam*>(_vertices[1]);
00261       SE3Quat delta = _inverseMeasurement * (v1->estimate().inverse()*v2->estimate());
00262       _error[0]=delta.translation().x();
00263       _error[1]=delta.translation().y();
00264       _error[2]=delta.translation().z();
00265       _error[3]=delta.rotation().x();
00266       _error[4]=delta.rotation().y();
00267       _error[5]=delta.rotation().z();
00268     }
00269 
00270     virtual double initialEstimatePossible(const OptimizableGraph::VertexSet& , OptimizableGraph::Vertex* ) { return 1.;}
00271     virtual void initialEstimate(const OptimizableGraph::VertexSet& from, OptimizableGraph::Vertex* to);
00272 };
00273 
00274 
00278  class EdgeSBAScale : public BaseBinaryEdge<1, double, VertexCam, VertexCam>
00279 {
00280   public:
00281     EIGEN_MAKE_ALIGNED_OPERATOR_NEW
00282     EdgeSBAScale();
00283     virtual bool read(std::istream& is);
00284     virtual bool write(std::ostream& os) const;
00285     void computeError()
00286     {
00287       const VertexCam* v1 = dynamic_cast<const VertexCam*>(_vertices[0]);
00288       const VertexCam* v2 = dynamic_cast<const VertexCam*>(_vertices[1]);
00289       Vector3d dt=v2->estimate().translation()-v1->estimate().translation();
00290       _error[0] = _measurement - dt.norm();
00291     }
00292     virtual double initialEstimatePossible(const OptimizableGraph::VertexSet& , OptimizableGraph::Vertex* ) { return 1.;}
00293     virtual void initialEstimate(const OptimizableGraph::VertexSet& from_, OptimizableGraph::Vertex* to_);
00294 };
00295 
00296 
00297 
00298 } // end namespace
00299 
00300 #endif // SBA_TYPES


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