Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <Eigen/StdVector>
00018 #include <tr1/random>
00019 #include <iostream>
00020 #include <stdint.h>
00021
00022 #include "g2o/core/graph_optimizer_sparse.h"
00023 #include "g2o/core/block_solver.h"
00024 #include "g2o/core/solver.h"
00025 #include "g2o/solvers/cholmod/linear_solver_cholmod.h"
00026 #include "g2o/types/icp/types_icp.h"
00027
00028 using namespace Eigen;
00029 using namespace std;
00030 using namespace g2o;
00031
00032
00033 class Sample
00034 {
00035
00036 static tr1::ranlux_base_01 gen_real;
00037 static tr1::mt19937 gen_int;
00038 public:
00039 static int uniform(int from, int to);
00040
00041 static double uniform();
00042
00043 static double gaussian(double sigma);
00044 };
00045
00046
00047 tr1::ranlux_base_01 Sample::gen_real;
00048 tr1::mt19937 Sample::gen_int;
00049
00050 int Sample::uniform(int from, int to)
00051 {
00052 tr1::uniform_int<int> unif(from, to);
00053 int sam = unif(gen_int);
00054 return sam;
00055 }
00056
00057 double Sample::uniform()
00058 {
00059 std::tr1::uniform_real<double> unif(0.0, 1.0);
00060 double sam = unif(gen_real);
00061 return sam;
00062 }
00063
00064 double Sample::gaussian(double sigma)
00065 {
00066 std::tr1::normal_distribution<double> gauss(0.0, sigma);
00067 double sam = gauss(gen_real);
00068 return sam;
00069 }
00070
00071
00072
00073
00074
00075
00076 int main(int argc, char **argv)
00077 {
00078 int num_points = 0;
00079
00080
00081 if (argc > 1)
00082 num_points = atoi(argv[1]);
00083
00084 double euc_noise = 0.1;
00085 double pix_noise = 1.0;
00086
00087
00088
00089 SparseOptimizer optimizer;
00090 optimizer.setMethod(SparseOptimizer::LevenbergMarquardt);
00091 optimizer.setVerbose(false);
00092
00093
00094 BlockSolverX::LinearSolverType * linearSolver
00095 = new LinearSolverCholmod<g2o
00096 ::BlockSolverX::PoseMatrixType>();
00097
00098
00099 BlockSolverX * solver_ptr
00100 = new BlockSolverX(&optimizer,linearSolver);
00101
00102
00103 optimizer.setSolver(solver_ptr);
00104
00105
00106 vector<Vector3d> true_points;
00107 for (size_t i=0;i<1000; ++i)
00108 {
00109 true_points.push_back(Vector3d((Sample::uniform()-0.5)*3,
00110 Sample::uniform()-0.5,
00111 Sample::uniform()+10));
00112 }
00113
00114
00115
00116 Vector2d focal_length(500,500);
00117 Vector2d principal_point(320,240);
00118 double baseline = 0.075;
00119
00120
00121 g2o::VertexSCam::setKcam(focal_length[0],focal_length[1],
00122 principal_point[0],principal_point[1],
00123 baseline);
00124
00125
00126
00127 int vertex_id = 0;
00128 for (size_t i=0; i<2; ++i)
00129 {
00130
00131 Vector3d t(0,0,i);
00132 Quaterniond q;
00133 q.setIdentity();
00134
00135 SE3Quat cam(q,t);
00136
00137
00138 VertexSCam *vc = new VertexSCam();
00139 vc->estimate() = cam;
00140 vc->setId(vertex_id);
00141
00142 cerr << t.transpose() << " | " << q.coeffs().transpose() << endl;
00143
00144
00145 if (i==0)
00146 vc->setFixed(true);
00147
00148
00149 vc->setAll();
00150
00151
00152 optimizer.addVertex(vc);
00153
00154 vertex_id++;
00155 }
00156
00157
00158 for (size_t i=0; i<true_points.size(); ++i)
00159 {
00160
00161 VertexSE3* vp0 =
00162 dynamic_cast<VertexSE3*>(optimizer.vertices().find(0)->second);
00163 VertexSE3* vp1 =
00164 dynamic_cast<VertexSE3*>(optimizer.vertices().find(1)->second);
00165
00166
00167 Vector3d pt0,pt1;
00168 pt0 = vp0->estimate().inverse().map(true_points[i]);
00169 pt1 = vp1->estimate().inverse().map(true_points[i]);
00170
00171
00172 pt0 += Vector3d(Sample::gaussian(euc_noise ),
00173 Sample::gaussian(euc_noise ),
00174 Sample::gaussian(euc_noise ));
00175
00176 pt1 += Vector3d(Sample::gaussian(euc_noise ),
00177 Sample::gaussian(euc_noise ),
00178 Sample::gaussian(euc_noise ));
00179
00180
00181 Vector3d nm0, nm1;
00182 nm0 << 0, i, 1;
00183 nm1 << 0, i, 1;
00184 nm0.normalize();
00185 nm1.normalize();
00186
00187 Edge_V_V_GICP * e
00188 = new Edge_V_V_GICP();
00189
00190 e->vertices()[0]
00191 = dynamic_cast<OptimizableGraph::Vertex*>(vp0);
00192
00193 e->vertices()[1]
00194 = dynamic_cast<OptimizableGraph::Vertex*>(vp1);
00195
00196 e->measurement().pos0 = pt0;
00197 e->measurement().pos1 = pt1;
00198 e->measurement().normal0 = nm0;
00199 e->measurement().normal1 = nm1;
00200
00201
00202
00203 e->information() = e->measurement().prec0(0.01);
00204
00205
00206
00207
00208
00209 e->setHuberWidth(0.01);
00210
00211 optimizer.addEdge(e);
00212 }
00213
00214
00215
00216 true_points.clear();
00217 for (int i=0;i<num_points; ++i)
00218 {
00219 true_points.push_back(Vector3d((Sample::uniform()-0.5)*3,
00220 Sample::uniform()-0.5,
00221 Sample::uniform()+10));
00222 }
00223
00224
00225
00226 for (size_t i=0; i<true_points.size(); ++i)
00227 {
00228 g2o::VertexPointXYZ * v_p
00229 = new g2o::VertexPointXYZ();
00230
00231
00232 v_p->setId(vertex_id++);
00233 v_p->setMarginalized(true);
00234 v_p->estimate() = true_points.at(i)
00235 + Vector3d(Sample::gaussian(1),
00236 Sample::gaussian(1),
00237 Sample::gaussian(1));
00238
00239 optimizer.addVertex(v_p);
00240
00241 for (size_t j=0; j<2; ++j)
00242 {
00243 Vector3d z;
00244 dynamic_cast<g2o::VertexSCam*>
00245 (optimizer.vertices().find(j)->second)
00246 ->mapPoint(z,true_points.at(i));
00247
00248 if (z[0]>=0 && z[1]>=0 && z[0]<640 && z[1]<480)
00249 {
00250 z += Vector3d(Sample::gaussian(pix_noise),
00251 Sample::gaussian(pix_noise),
00252 Sample::gaussian(pix_noise/16.0));
00253
00254 g2o::Edge_XYZ_VSC * e
00255 = new g2o::Edge_XYZ_VSC();
00256
00257 e->vertices()[0]
00258 = dynamic_cast<g2o::OptimizableGraph::Vertex*>(v_p);
00259
00260 e->vertices()[1]
00261 = dynamic_cast<g2o::OptimizableGraph::Vertex*>
00262 (optimizer.vertices().find(j)->second);
00263
00264 e->measurement() = z;
00265 e->inverseMeasurement() = -z;
00266 e->information() = Matrix3d::Identity();
00267
00268 e->setRobustKernel(false);
00269 e->setHuberWidth(1);
00270
00271 optimizer.addEdge(e);
00272 }
00273
00274 }
00275 }
00276
00277
00278
00279
00280 VertexSE3* vc =
00281 dynamic_cast<VertexSE3*>(optimizer.vertices().find(1)->second);
00282 SE3Quat &cam = vc->estimate();
00283 cam.translation() = Vector3d(-0.1,0.1,0.2);
00284
00285 optimizer.initializeOptimization();
00286 optimizer.computeActiveErrors();
00287 cout << "Initial chi2 = " << FIXED(optimizer.chi2()) << endl;
00288
00289 optimizer.setVerbose(true);
00290
00291 optimizer.optimize(20);
00292
00293 cout << endl << "Second vertex should be near 0,0,1" << endl;
00294 cout << dynamic_cast<VertexSE3*>(optimizer.vertices().find(0)->second)
00295 ->estimate().translation().transpose() << endl;
00296 cout << dynamic_cast<VertexSE3*>(optimizer.vertices().find(1)->second)
00297 ->estimate().translation().transpose() << endl;
00298 }