g2o
Loading...
Searching...
No Matches
Functions
gicp_sba_demo.cpp File Reference
#include <stdint.h>
#include <iostream>
#include <random>
#include "g2o/core/block_solver.h"
#include "g2o/core/optimization_algorithm_levenberg.h"
#include "g2o/core/solver.h"
#include "g2o/core/sparse_optimizer.h"
#include "g2o/solvers/eigen/linear_solver_eigen.h"
#include "g2o/stuff/sampler.h"
#include "g2o/types/icp/types_icp.h"
Include dependency graph for gicp_sba_demo.cpp:

Go to the source code of this file.

Functions

int main (int argc, char **argv)
 

Function Documentation

◆ main()

int main ( int  argc,
char **  argv 
)

Definition at line 44 of file gicp_sba_demo.cpp.

44 {
45 int num_points = 0;
46
47 // check for arg, # of points to use in projection SBA
48 if (argc > 1) num_points = atoi(argv[1]);
49
50 double euc_noise = 0.1; // noise in position, m
51 double pix_noise = 1.0; // pixel noise
52 // double outlier_ratio = 0.1;
53
54 SparseOptimizer optimizer;
55 optimizer.setVerbose(false);
56
57 // variable-size block solver
59 new g2o::OptimizationAlgorithmLevenberg(std::make_unique<BlockSolverX>(
60 std::make_unique<
62
63 optimizer.setAlgorithm(solver);
64
65 vector<Vector3d> true_points;
66 for (size_t i = 0; i < 1000; ++i) {
67 true_points.push_back(
68 Vector3d((g2o::Sampler::uniformRand(0., 1.) - 0.5) * 3,
69 g2o::Sampler::uniformRand(0., 1.) - 0.5,
70 g2o::Sampler::uniformRand(0., 1.) + 10));
71 }
72
73 // set up camera params
74 Vector2d focal_length(500, 500); // pixels
75 Vector2d principal_point(320, 240); // 640x480 image
76 double baseline = 0.075; // 7.5 cm baseline
77
78 // set up camera params and projection matrices on vertices
79 g2o::VertexSCam::setKcam(focal_length[0], focal_length[1], principal_point[0],
80 principal_point[1], baseline);
81
82 // set up two poses
83 int vertex_id = 0;
84 for (size_t i = 0; i < 2; ++i) {
85 // set up rotation and translation for this node
86 Vector3d t(0, 0, i);
87 Quaterniond q;
88 q.setIdentity();
89
90 Eigen::Isometry3d cam; // camera pose
91 cam = q;
92 cam.translation() = t;
93
94 // set up node
95 VertexSCam* vc = new VertexSCam();
96 vc->setEstimate(cam);
97 vc->setId(vertex_id); // vertex id
98
99 cerr << t.transpose() << " | " << q.coeffs().transpose() << endl;
100
101 // set first cam pose fixed
102 if (i == 0) vc->setFixed(true);
103
104 // make sure projection matrices are set
105 vc->setAll();
106
107 // add to optimizer
108 optimizer.addVertex(vc);
109
110 vertex_id++;
111 }
112
113 // set up point matches for GICP
114 for (size_t i = 0; i < true_points.size(); ++i) {
115 // get two poses
116 VertexSE3* vp0 =
117 dynamic_cast<VertexSE3*>(optimizer.vertices().find(0)->second);
118 VertexSE3* vp1 =
119 dynamic_cast<VertexSE3*>(optimizer.vertices().find(1)->second);
120
121 // calculate the relative 3D position of the point
122 Vector3d pt0, pt1;
123 pt0 = vp0->estimate().inverse() * true_points[i];
124 pt1 = vp1->estimate().inverse() * true_points[i];
125
126 // add in noise
127 pt0 += Vector3d(g2o::Sampler::gaussRand(0., euc_noise),
128 g2o::Sampler::gaussRand(0., euc_noise),
129 g2o::Sampler::gaussRand(0., euc_noise));
130
131 pt1 += Vector3d(g2o::Sampler::gaussRand(0., euc_noise),
132 g2o::Sampler::gaussRand(0., euc_noise),
133 g2o::Sampler::gaussRand(0., euc_noise));
134
135 // form edge, with normals in varioius positions
136 Vector3d nm0, nm1;
137 nm0 << 0, i, 1;
138 nm1 << 0, i, 1;
139 nm0.normalize();
140 nm1.normalize();
141
142 Edge_V_V_GICP* e // new edge with correct cohort for caching
143 = new Edge_V_V_GICP();
144
145 e->vertices()[0] // first viewpoint
146 = dynamic_cast<OptimizableGraph::Vertex*>(vp0);
147
148 e->vertices()[1] // second viewpoint
149 = dynamic_cast<OptimizableGraph::Vertex*>(vp1);
150
151 EdgeGICP meas;
152
153 meas.pos0 = pt0;
154 meas.pos1 = pt1;
155 meas.normal0 = nm0;
156 meas.normal1 = nm1;
157 e->setMeasurement(meas);
158 meas = e->measurement();
159 // e->inverseMeasurement().pos() = -kp;
160
161 // use this for point-plane
162 e->information() = meas.prec0(0.01);
163
164 // use this for point-point
165 // e->information().setIdentity();
166
167 // e->setRobustKernel(true);
168 // e->setHuberWidth(0.01);
169
170 optimizer.addEdge(e);
171 }
172
173 // set up SBA projections with some number of points
174
175 true_points.clear();
176 for (int i = 0; i < num_points; ++i) {
177 true_points.push_back(
178 Vector3d((g2o::Sampler::uniformRand(0., 1.) - 0.5) * 3,
179 g2o::Sampler::uniformRand(0., 1.) - 0.5,
180 g2o::Sampler::uniformRand(0., 1.) + 10));
181 }
182
183 // add point projections to this vertex
184 for (size_t i = 0; i < true_points.size(); ++i) {
186
187 v_p->setId(vertex_id++);
188 v_p->setMarginalized(true);
189 v_p->setEstimate(true_points.at(i) +
190 Vector3d(g2o::Sampler::gaussRand(0., 1),
193
194 optimizer.addVertex(v_p);
195
196 for (size_t j = 0; j < 2; ++j) {
197 Vector3d z;
198 dynamic_cast<g2o::VertexSCam*>(optimizer.vertices().find(j)->second)
199 ->mapPoint(z, true_points.at(i));
200
201 if (z[0] >= 0 && z[1] >= 0 && z[0] < 640 && z[1] < 480) {
202 z += Vector3d(g2o::Sampler::gaussRand(0., pix_noise),
203 g2o::Sampler::gaussRand(0., pix_noise),
204 g2o::Sampler::gaussRand(0., pix_noise / 16.0));
205
207
208 e->vertices()[0] = dynamic_cast<g2o::OptimizableGraph::Vertex*>(v_p);
209
210 e->vertices()[1] = dynamic_cast<g2o::OptimizableGraph::Vertex*>(
211 optimizer.vertices().find(j)->second);
212
213 e->setMeasurement(z);
214 // e->inverseMeasurement() = -z;
215 e->information() = Matrix3d::Identity();
216
217 // e->setRobustKernel(false);
218 // e->setHuberWidth(1);
219
220 optimizer.addEdge(e);
221 }
222 }
223 } // done with adding projection points
224
225 // move second cam off of its true position
226 VertexSE3* vc =
227 dynamic_cast<VertexSE3*>(optimizer.vertices().find(1)->second);
228 Eigen::Isometry3d cam = vc->estimate();
229 cam.translation() = Vector3d(-0.1, 0.1, 0.2);
230 vc->setEstimate(cam);
231 optimizer.initializeOptimization();
232 optimizer.computeActiveErrors();
233 cout << "Initial chi2 = " << FIXED(optimizer.chi2()) << endl;
234
235 optimizer.setVerbose(true);
236
237 optimizer.optimize(20);
238
239 cout << endl << "Second vertex should be near 0,0,1" << endl;
240 cout << dynamic_cast<VertexSE3*>(optimizer.vertices().find(0)->second)
241 ->estimate()
242 .translation()
243 .transpose()
244 << endl;
245 cout << dynamic_cast<VertexSE3*>(optimizer.vertices().find(1)->second)
246 ->estimate()
247 .translation()
248 .transpose()
249 << endl;
250}
EIGEN_STRONG_INLINE const Measurement & measurement() const
accessor functions for the measurement represented by the edge
Definition base_edge.h:119
virtual void setMeasurement(const Measurement &m)
Definition base_edge.h:122
EIGEN_STRONG_INLINE const InformationType & information() const
information matrix of the constraint
Definition base_edge.h:107
const EstimateType & estimate() const
return the current estimate of the vertex
void setEstimate(const EstimateType &et)
set the estimate for the vertex also calls updateCache()
Vector3 pos1
Definition types_icp.h:62
Vector3 pos0
Definition types_icp.h:62
Matrix3 prec0(double e)
Definition types_icp.h:107
Vector3 normal1
Definition types_icp.h:65
Vector3 normal0
Definition types_icp.h:65
Point vertex, XYZ, is in types_sba.
Definition types_icp.h:342
const VertexContainer & vertices() const
const VertexIDMap & vertices() const
linear solver which uses the sparse Cholesky solver from Eigen
A general case Vertex for optimization.
void setFixed(bool fixed)
true => this node should be considered fixed during the optimization
void setMarginalized(bool marginalized)
true => this node should be marginalized out during the optimization
Implementation of the Levenberg Algorithm.
static double gaussRand(double mean, double sigma)
Definition sampler.h:89
static double uniformRand(double lowerBndr, double upperBndr)
Definition sampler.h:102
int optimize(int iterations, bool online=false)
void setVerbose(bool verbose)
virtual bool initializeOptimization(HyperGraph::EdgeSet &eset)
void setAlgorithm(OptimizationAlgorithm *algorithm)
Vertex for a tracked point in space.
Stereo camera vertex, derived from SE3 class. Note that we use the actual pose of the vertex as its p...
Definition types_icp.h:228
static void setKcam(double fx, double fy, double cx, double cy, double tx)
Definition types_icp.h:276
3D pose Vertex, represented as an Isometry3
Definition vertex_se3.h:50
virtual bool addEdge(HyperGraph::Edge *e)
virtual bool addVertex(HyperGraph::Vertex *v, Data *userData)
double chi2() const
returns the chi2 of the current configuration

References g2o::OptimizableGraph::addEdge(), g2o::OptimizableGraph::addVertex(), g2o::OptimizableGraph::chi2(), g2o::SparseOptimizer::computeActiveErrors(), g2o::BaseVertex< D, T >::estimate(), g2o::Sampler::gaussRand(), g2o::BaseEdge< D, E >::information(), g2o::SparseOptimizer::initializeOptimization(), g2o::BaseEdge< D, E >::measurement(), g2o::EdgeGICP::normal0, g2o::EdgeGICP::normal1, g2o::SparseOptimizer::optimize(), g2o::EdgeGICP::pos0, g2o::EdgeGICP::pos1, g2o::EdgeGICP::prec0(), g2o::SparseOptimizer::setAlgorithm(), g2o::VertexSCam::setAll(), g2o::BaseVertex< D, T >::setEstimate(), g2o::OptimizableGraph::Vertex::setFixed(), g2o::OptimizableGraph::Vertex::setId(), g2o::VertexSCam::setKcam(), g2o::OptimizableGraph::Vertex::setMarginalized(), g2o::BaseEdge< D, E >::setMeasurement(), g2o::SparseOptimizer::setVerbose(), g2o::Sampler::uniformRand(), g2o::HyperGraph::Edge::vertices(), and g2o::HyperGraph::vertices().