g2o
Loading...
Searching...
No Matches
Public Types | Public Member Functions | Protected Member Functions | Protected Attributes | List of all members
g2o::G2oSlamInterface Class Reference

#include <g2o_slam_interface.h>

Inheritance diagram for g2o::G2oSlamInterface:
Inheritance graph
[legend]
Collaboration diagram for g2o::G2oSlamInterface:
Collaboration graph
[legend]

Public Types

enum  SolveResult { SOLVED , SOLVED_BATCH , NOOP , ERROR }
 

Public Member Functions

 G2oSlamInterface (SparseOptimizerOnline *optimizer)
 
bool addNode (const std::string &tag, int id, int dimension, const std::vector< double > &values)
 
bool addEdge (const std::string &tag, int id, int dimension, int v1, int v2, const std::vector< double > &measurement, const std::vector< double > &information)
 
bool fixNode (const std::vector< int > &nodes)
 
bool queryState (const std::vector< int > &nodes)
 
bool solveState ()
 
SolveResult solve ()
 
int updatedGraphEachN () const
 
void setUpdateGraphEachN (int n)
 
int batchSolveEachN () const
 
void setBatchSolveEachN (int n)
 
SparseOptimizerOnlineoptimizer ()
 

Protected Member Functions

OptimizableGraph::VertexaddVertex (int dimension, int id)
 
bool printVertex (OptimizableGraph::Vertex *v)
 

Protected Attributes

SparseOptimizerOnline_optimizer
 
bool _firstOptimization
 
int _nodesAdded
 
int _incIterations
 
int _updateGraphEachN
 
int _batchEveryN
 
int _lastBatchStep
 
bool _initSolverDone
 
HyperGraph::VertexSet _verticesAdded
 
HyperGraph::EdgeSet _edgesAdded
 

Detailed Description

Definition at line 41 of file g2o_slam_interface.h.

Member Enumeration Documentation

◆ SolveResult

Enumerator
SOLVED 
SOLVED_BATCH 
NOOP 
ERROR 

Definition at line 44 of file g2o_slam_interface.h.

Constructor & Destructor Documentation

◆ G2oSlamInterface()

g2o::G2oSlamInterface::G2oSlamInterface ( SparseOptimizerOnline optimizer)

Member Function Documentation

◆ addEdge()

bool g2o::G2oSlamInterface::addEdge ( const std::string &  tag,
int  id,
int  dimension,
int  v1,
int  v2,
const std::vector< double > &  measurement,
const std::vector< double > &  information 
)
virtual

adding an edge to the SLAM engine.

Parameters
tagthe tag specifying the type of the vertex
idthe unique id of the edge.
dimensionthe dimension of the edge.
v1the unique id of the edge of the first vertex
v2the unique id of the edge of the second vertex
measurementthe measurement of the constraint
informationthe information matrix (inverse of the covariance) representing the uncertainty of the measurement (row-major upper triangular and diagonal)
Returns
true, if adding was successful

Implements SlamParser::AbstractSlamInterface.

Definition at line 133 of file g2o_slam_interface.cpp.

136 {
137 (void)tag;
138 (void)id;
139 size_t oldEdgesSize = _optimizer->edges().size();
140
141 if (dimension == 3) {
142 SE2 transf(measurement[0], measurement[1], measurement[2]);
143 Eigen::Matrix3d infMat;
144 int idx = 0;
145 for (int r = 0; r < 3; ++r)
146 for (int c = r; c < 3; ++c, ++idx) {
147 assert(idx < (int)information.size());
148 infMat(r, c) = infMat(c, r) = information[idx];
149 }
150 // cerr << PVAR(infMat) << endl;
151
152 int doInit = 0;
153 SparseOptimizer::Vertex* v1 = _optimizer->vertex(v1Id);
154 SparseOptimizer::Vertex* v2 = _optimizer->vertex(v2Id);
155 if (!v1) {
156 OptimizableGraph::Vertex* v = v1 = addVertex(dimension, v1Id);
157 _verticesAdded.insert(v);
158 doInit = 1;
159 ++_nodesAdded;
160 }
161
162 if (!v2) {
163 OptimizableGraph::Vertex* v = v2 = addVertex(dimension, v2Id);
164 _verticesAdded.insert(v);
165 doInit = 2;
166 ++_nodesAdded;
167 }
168
169 if (_optimizer->edges().size() == 0) {
170 cerr << "FIRST EDGE ";
171 if (v1->id() < v2->id()) {
172 cerr << "fixing " << v1->id() << endl;
173 v1->setFixed(true);
174 } else {
175 cerr << "fixing " << v2->id() << endl;
176 v2->setFixed(true);
177 }
178 }
179
180 OnlineEdgeSE2* e = new OnlineEdgeSE2;
181 e->vertices()[0] = v1;
182 e->vertices()[1] = v2;
183 e->setMeasurement(transf);
184 e->setInformation(infMat);
186 _edgesAdded.insert(e);
187
188 if (doInit) {
189 OptimizableGraph::Vertex* from =
190 static_cast<OptimizableGraph::Vertex*>(e->vertices()[0]);
191 OptimizableGraph::Vertex* to =
192 static_cast<OptimizableGraph::Vertex*>(e->vertices()[1]);
193 switch (doInit) {
194 case 1: // initialize v1 from v2
195 {
197 toSet.insert(to);
198 if (e->initialEstimatePossible(toSet, from) > 0.) {
199 e->initialEstimate(toSet, from);
200 }
201 break;
202 }
203 case 2: {
204 HyperGraph::VertexSet fromSet;
205 fromSet.insert(from);
206 if (e->initialEstimatePossible(fromSet, to) > 0.) {
207 e->initialEstimate(fromSet, to);
208 }
209 break;
210 }
211 default:
212 cerr << "doInit wrong value\n";
213 }
214 }
215
216 } else if (dimension == 6) {
217 Eigen::Isometry3d transf;
218 Matrix<double, 6, 6> infMat;
219
220 if (measurement.size() == 7) { // measurement is a Quaternion
221 Vector7 meas;
222 for (int i = 0; i < 7; ++i) meas(i) = measurement[i];
223 // normalize the quaternion to recover numerical precision lost by storing
224 // as human readable text
225 Vector4::MapType(meas.data() + 3).normalize();
226 transf = internal::fromVectorQT(meas);
227
228 for (int i = 0, idx = 0; i < infMat.rows(); ++i)
229 for (int j = i; j < infMat.cols(); ++j) {
230 infMat(i, j) = information[idx++];
231 if (i != j) infMat(j, i) = infMat(i, j);
232 }
233 } else { // measurement consists of Euler angles
234 Vector6 aux;
235 aux << measurement[0], measurement[1], measurement[2], measurement[3],
236 measurement[4], measurement[5];
237 transf = internal::fromVectorET(aux);
238 Matrix<double, 6, 6> infMatEuler;
239 int idx = 0;
240 for (int r = 0; r < 6; ++r)
241 for (int c = r; c < 6; ++c, ++idx) {
242 assert(idx < (int)information.size());
243 infMatEuler(r, c) = infMatEuler(c, r) = information[idx];
244 }
245 // convert information matrix to our internal representation
246 Matrix<double, 6, 6> J;
247 SE3Quat transfAsSe3(transf.matrix().topLeftCorner<3, 3>(),
248 transf.translation());
249 jac_quat3_euler3(J, transfAsSe3);
250 infMat.noalias() = J.transpose() * infMatEuler * J;
251 // cerr << PVAR(transf.matrix()) << endl;
252 // cerr << PVAR(infMat) << endl;
253 }
254
255 int doInit = 0;
256 SparseOptimizer::Vertex* v1 = _optimizer->vertex(v1Id);
257 SparseOptimizer::Vertex* v2 = _optimizer->vertex(v2Id);
258 if (!v1) {
259 OptimizableGraph::Vertex* v = v1 = addVertex(dimension, v1Id);
260 _verticesAdded.insert(v);
261 doInit = 1;
262 ++_nodesAdded;
263 }
264
265 if (!v2) {
266 OptimizableGraph::Vertex* v = v2 = addVertex(dimension, v2Id);
267 _verticesAdded.insert(v);
268 doInit = 2;
269 ++_nodesAdded;
270 }
271
272 if (_optimizer->edges().size() == 0) {
273 cerr << "FIRST EDGE ";
274 if (v1->id() < v2->id()) {
275 cerr << "fixing " << v1->id() << endl;
276 v1->setFixed(true);
277 } else {
278 cerr << "fixing " << v2->id() << endl;
279 v2->setFixed(true);
280 }
281 }
282
283 OnlineEdgeSE3* e = new OnlineEdgeSE3;
284 e->vertices()[0] = v1;
285 e->vertices()[1] = v2;
286 e->setMeasurement(transf);
287 e->setInformation(infMat);
289 _edgesAdded.insert(e);
290
291 if (doInit) {
292 OptimizableGraph::Vertex* from =
293 static_cast<OptimizableGraph::Vertex*>(e->vertices()[0]);
294 OptimizableGraph::Vertex* to =
295 static_cast<OptimizableGraph::Vertex*>(e->vertices()[1]);
296 switch (doInit) {
297 case 1: // initialize v1 from v2
298 {
300 toSet.insert(to);
301 if (e->initialEstimatePossible(toSet, from) > 0.) {
302 e->initialEstimate(toSet, from);
303 }
304 break;
305 }
306 case 2: {
307 HyperGraph::VertexSet fromSet;
308 fromSet.insert(from);
309 if (e->initialEstimatePossible(fromSet, to) > 0.) {
310 e->initialEstimate(fromSet, to);
311 }
312 break;
313 }
314 default:
315 cerr << "doInit wrong value\n";
316 }
317 }
318
319 } else {
320 cerr << __PRETTY_FUNCTION__ << " not implemented for this dimension"
321 << endl;
322 return false;
323 }
324
325 if (oldEdgesSize == 0) {
327 }
328
329 return true;
330}
HyperGraph::EdgeSet _edgesAdded
OptimizableGraph::Vertex * addVertex(int dimension, int id)
HyperGraph::VertexSet _verticesAdded
std::set< Vertex * > VertexSet
const EdgeSet & edges() const
#define __PRETTY_FUNCTION__
Definition macros.h:90
Isometry3 fromVectorQT(const Vector7 &v)
Isometry3 fromVectorET(const Vector6 &v)
VectorN< 7 > Vector7
Definition eigen_types.h:54
VectorN< 6 > Vector6
Definition eigen_types.h:53
static void jac_quat3_euler3(Eigen::Matrix< double, 6, 6, Eigen::ColMajor > &J, const Isometry3 &t)
JacobianWorkspace & jacobianWorkspace()
the workspace for storing the Jacobians of the graph
virtual bool addEdge(HyperGraph::Edge *e)
Vertex * vertex(int id)
returns the vertex number id appropriately casted

References __PRETTY_FUNCTION__, _edgesAdded, _nodesAdded, _optimizer, _verticesAdded, g2o::OptimizableGraph::addEdge(), addVertex(), g2o::JacobianWorkspace::allocate(), g2o::HyperGraph::edges(), g2o::internal::fromVectorET(), g2o::internal::fromVectorQT(), g2o::HyperGraph::Vertex::id(), g2o::OnlineEdgeSE2::initialEstimate(), g2o::OnlineEdgeSE3::initialEstimate(), g2o::EdgeSE2::initialEstimatePossible(), g2o::EdgeSE3::initialEstimatePossible(), g2o::jac_quat3_euler3(), g2o::OptimizableGraph::jacobianWorkspace(), g2o::BaseEdge< D, E >::setInformation(), g2o::EdgeSE3::setMeasurement(), g2o::EdgeSE2::setMeasurement(), g2o::OptimizableGraph::vertex(), and g2o::HyperGraph::Edge::vertices().

Referenced by main().

◆ addNode()

bool g2o::G2oSlamInterface::addNode ( const std::string &  tag,
int  id,
int  dimension,
const std::vector< double > &  values 
)
virtual

adding a node to the SLAM engine.

Parameters
tagthe tag specifying the type of the vertex
idthe unique id of the node.
dimensionthe dimension of the node.
valuesthe pose of the node, may be empty (i.e., the engine should initialize the node itself)
Returns
true, if adding was successful

Implements SlamParser::AbstractSlamInterface.

Definition at line 117 of file g2o_slam_interface.cpp.

118 {
119 // allocating the desired solver + testing whether the solver is okay
120 if (!_initSolverDone) {
121 _initSolverDone = true;
123 }
124
125 // we add the node when we are asked to add the according edge
126 (void)tag;
127 (void)id;
128 (void)dimension;
129 (void)values;
130 return true;
131}
virtual bool initSolver(int dimension, int batchEveryN)

References _batchEveryN, _initSolverDone, _optimizer, and g2o::SparseOptimizerOnline::initSolver().

Referenced by main().

◆ addVertex()

OptimizableGraph::Vertex * g2o::G2oSlamInterface::addVertex ( int  dimension,
int  id 
)
protected

Definition at line 369 of file g2o_slam_interface.cpp.

369 {
370 if (dimension == 3) {
371 OnlineVertexSE2* v = new OnlineVertexSE2;
372 v->setId(id); // estimate will be set later when the edge is added
374 return v;
375 } else if (dimension == 6) {
376 OnlineVertexSE3* v = new OnlineVertexSE3;
377 v->setId(id); // estimate will be set later when the edge is added
379 return v;
380 } else {
381 return 0;
382 }
383}
virtual bool addVertex(HyperGraph::Vertex *v, Data *userData)

References _optimizer, g2o::OptimizableGraph::addVertex(), and g2o::OptimizableGraph::Vertex::setId().

Referenced by addEdge().

◆ batchSolveEachN()

int g2o::G2oSlamInterface::batchSolveEachN ( ) const
inline

Definition at line 67 of file g2o_slam_interface.h.

67{ return _batchEveryN; }

◆ fixNode()

bool g2o::G2oSlamInterface::fixNode ( const std::vector< int > &  nodes)
virtual

set some nodes to a fixed position

Parameters
nodesthe list of vertex IDs to fix
Returns
true, if successful

Implements SlamParser::AbstractSlamInterface.

Definition at line 332 of file g2o_slam_interface.cpp.

332 {
333 for (size_t i = 0; i < nodes.size(); ++i) {
334 OptimizableGraph::Vertex* v = _optimizer->vertex(nodes[i]);
335 if (v) v->setFixed(true);
336 }
337 return true;
338}
void setFixed(bool fixed)
true => this node should be considered fixed during the optimization

References _optimizer, g2o::OptimizableGraph::Vertex::setFixed(), and g2o::OptimizableGraph::vertex().

◆ optimizer()

SparseOptimizerOnline * g2o::G2oSlamInterface::optimizer ( )
inline

Definition at line 70 of file g2o_slam_interface.h.

70{ return _optimizer; }

Referenced by solveAndPrint().

◆ printVertex()

bool g2o::G2oSlamInterface::printVertex ( OptimizableGraph::Vertex v)
protected

Definition at line 385 of file g2o_slam_interface.cpp.

385 {
386 static char buffer[10000]; // that should be more than enough
387 int vdim = v->dimension();
388 if (vdim == 3) {
389 char* s = buffer;
390 OnlineVertexSE2* v2 = static_cast<OnlineVertexSE2*>(v);
391 memcpy(s, "VERTEX_XYT ", 11);
392 s += 11;
393 s += modp_itoa10(v->id(), s);
394 *s++ = ' ';
395 s += modp_dtoa(v2->updatedEstimate.translation().x(), s, 6);
396 *s++ = ' ';
397 s += modp_dtoa(v2->updatedEstimate.translation().y(), s, 6);
398 *s++ = ' ';
399 s += modp_dtoa(v2->updatedEstimate.rotation().angle(), s, 6);
400 *s++ = '\n';
401 cout.write(buffer, s - buffer);
402 return true;
403 } else if (vdim == 6) {
404 char* s = buffer;
405 OnlineVertexSE3* v3 = static_cast<OnlineVertexSE3*>(v);
406 Vector3d eulerAngles =
407 internal::toEuler(v3->updatedEstimate.matrix().topLeftCorner<3, 3>());
408 const double& roll = eulerAngles(0);
409 const double& pitch = eulerAngles(1);
410 const double& yaw = eulerAngles(2);
411 memcpy(s, "VERTEX_XYZRPY ", 14);
412 s += 14;
413 s += modp_itoa10(v->id(), s);
414 *s++ = ' ';
415 s += modp_dtoa(v3->updatedEstimate.translation().x(), s, 6);
416 *s++ = ' ';
417 s += modp_dtoa(v3->updatedEstimate.translation().y(), s, 6);
418 *s++ = ' ';
419 s += modp_dtoa(v3->updatedEstimate.translation().z(), s, 6);
420 *s++ = ' ';
421 s += modp_dtoa(roll, s, 6);
422 *s++ = ' ';
423 s += modp_dtoa(pitch, s, 6);
424 *s++ = ' ';
425 s += modp_dtoa(yaw, s, 6);
426 *s++ = '\n';
427 cout.write(buffer, s - buffer);
428 return true;
429 }
430 return false;
431}
int modp_itoa10(int32_t value, char *str)
int modp_dtoa(double value, char *str, int prec)
Definition fast_output.h:56
Vector3 toEuler(const Matrix3 &R)

References g2o::OptimizableGraph::Vertex::dimension(), g2o::HyperGraph::Vertex::id(), modp_dtoa(), modp_itoa10(), g2o::SE2::rotation(), g2o::internal::toEuler(), g2o::SE2::translation(), g2o::OnlineVertexSE2::updatedEstimate, and g2o::OnlineVertexSE3::updatedEstimate.

Referenced by queryState().

◆ queryState()

bool g2o::G2oSlamInterface::queryState ( const std::vector< int > &  nodes)
virtual

Ask the SLAM engine to print the current estimate of the variables

Parameters
nodesthe list of vertex IDs to print, if empty print all variables
Returns
true, if successful

Implements SlamParser::AbstractSlamInterface.

Definition at line 340 of file g2o_slam_interface.cpp.

340 {
341 // return true;
342 cout << "BEGIN" << endl;
343#if 1
344 if (nodes.size() == 0) {
345 for (OptimizableGraph::VertexIDMap::const_iterator it =
346 _optimizer->vertices().begin();
347 it != _optimizer->vertices().end(); ++it) {
348 OptimizableGraph::Vertex* v =
349 static_cast<OptimizableGraph::Vertex*>(it->second);
350 printVertex(v);
351 }
352 } else {
353 for (size_t i = 0; i < nodes.size(); ++i) {
354 OptimizableGraph::Vertex* v = _optimizer->vertex(nodes[i]);
355 if (v) printVertex(v);
356 }
357 }
358#endif
359 cout << "END" << endl << flush;
360
361 return true;
362}
bool printVertex(OptimizableGraph::Vertex *v)
const VertexIDMap & vertices() const

References _optimizer, printVertex(), g2o::OptimizableGraph::vertex(), and g2o::HyperGraph::vertices().

◆ setBatchSolveEachN()

void g2o::G2oSlamInterface::setBatchSolveEachN ( int  n)

Definition at line 469 of file g2o_slam_interface.cpp.

469{ _batchEveryN = n; }

References _batchEveryN.

Referenced by main().

◆ setUpdateGraphEachN()

void g2o::G2oSlamInterface::setUpdateGraphEachN ( int  n)

Definition at line 433 of file g2o_slam_interface.cpp.

433{ _updateGraphEachN = n; }

References _updateGraphEachN.

Referenced by main().

◆ solve()

G2oSlamInterface::SolveResult g2o::G2oSlamInterface::solve ( )

Definition at line 435 of file g2o_slam_interface.cpp.

435 {
437 // decide on batch step or normal step
438 _optimizer->batchStep = false;
439 if ((int)_optimizer->vertices().size() - _lastBatchStep >= _batchEveryN) {
441 _optimizer->batchStep = true;
442 }
443
444 if (_firstOptimization) {
446 cerr << "initialization failed" << endl;
447 return ERROR;
448 }
449 } else {
451 cerr << "updating initialization failed" << endl;
452 return ERROR;
453 }
454 }
455
457 (void)currentIt;
458 _firstOptimization = false;
459 _nodesAdded = 0;
460 _verticesAdded.clear();
461 _edgesAdded.clear();
462 if (_optimizer->batchStep) return SOLVED_BATCH;
463 return SOLVED;
464 }
465
466 return NOOP;
467}
int optimize(int iterations, bool online=false)
virtual bool updateInitialization(HyperGraph::VertexSet &vset, HyperGraph::EdgeSet &eset)
virtual bool initializeOptimization(HyperGraph::EdgeSet &eset)

References _batchEveryN, _edgesAdded, _firstOptimization, _incIterations, _lastBatchStep, _nodesAdded, _optimizer, _updateGraphEachN, _verticesAdded, g2o::SparseOptimizerOnline::batchStep, ERROR, g2o::SparseOptimizer::initializeOptimization(), NOOP, g2o::SparseOptimizerOnline::optimize(), SOLVED, SOLVED_BATCH, g2o::SparseOptimizerOnline::updateInitialization(), and g2o::HyperGraph::vertices().

Referenced by solveAndPrint(), and solveState().

◆ solveState()

bool g2o::G2oSlamInterface::solveState ( )
virtual

ask the engine to solve

Returns
true, if successful

Implements SlamParser::AbstractSlamInterface.

Definition at line 364 of file g2o_slam_interface.cpp.

364 {
365 SolveResult state = solve();
366 return state != ERROR;
367}

References ERROR, and solve().

◆ updatedGraphEachN()

int g2o::G2oSlamInterface::updatedGraphEachN ( ) const
inline

Definition at line 64 of file g2o_slam_interface.h.

64{ return _updateGraphEachN; }

Member Data Documentation

◆ _batchEveryN

int g2o::G2oSlamInterface::_batchEveryN
protected

Definition at line 78 of file g2o_slam_interface.h.

Referenced by addNode(), setBatchSolveEachN(), and solve().

◆ _edgesAdded

HyperGraph::EdgeSet g2o::G2oSlamInterface::_edgesAdded
protected

Definition at line 83 of file g2o_slam_interface.h.

Referenced by addEdge(), and solve().

◆ _firstOptimization

bool g2o::G2oSlamInterface::_firstOptimization
protected

Definition at line 74 of file g2o_slam_interface.h.

Referenced by solve().

◆ _incIterations

int g2o::G2oSlamInterface::_incIterations
protected

Definition at line 76 of file g2o_slam_interface.h.

Referenced by solve().

◆ _initSolverDone

bool g2o::G2oSlamInterface::_initSolverDone
protected

Definition at line 80 of file g2o_slam_interface.h.

Referenced by addNode().

◆ _lastBatchStep

int g2o::G2oSlamInterface::_lastBatchStep
protected

Definition at line 79 of file g2o_slam_interface.h.

Referenced by solve().

◆ _nodesAdded

int g2o::G2oSlamInterface::_nodesAdded
protected

Definition at line 75 of file g2o_slam_interface.h.

Referenced by addEdge(), and solve().

◆ _optimizer

SparseOptimizerOnline* g2o::G2oSlamInterface::_optimizer
protected

Definition at line 73 of file g2o_slam_interface.h.

Referenced by addEdge(), addNode(), addVertex(), fixNode(), queryState(), and solve().

◆ _updateGraphEachN

int g2o::G2oSlamInterface::_updateGraphEachN
protected

Definition at line 77 of file g2o_slam_interface.h.

Referenced by setUpdateGraphEachN(), and solve().

◆ _verticesAdded

HyperGraph::VertexSet g2o::G2oSlamInterface::_verticesAdded
protected

Definition at line 82 of file g2o_slam_interface.h.

Referenced by addEdge(), and solve().


The documentation for this class was generated from the following files: