g2o
Loading...
Searching...
No Matches
Classes | Typedefs | Functions
simulator_3d_plane.cpp File Reference
#include <fstream>
#include <iostream>
#include "g2o/core/optimization_algorithm_factory.h"
#include "g2o/core/sparse_optimizer.h"
#include "g2o/stuff/command_args.h"
#include "g2o/stuff/macros.h"
#include "g2o/stuff/sampler.h"
#include "g2o/types/slam3d/types_slam3d.h"
#include "g2o/types/slam3d_addons/types_slam3d_addons.h"
Include dependency graph for simulator_3d_plane.cpp:

Go to the source code of this file.

Classes

struct  SimulatorItem
 
struct  WorldItem
 
struct  Sensor
 
struct  Robot
 
struct  Simulator
 
struct  PlaneItem
 
struct  PlaneSensor
 

Typedefs

typedef std::set< WorldItem * > WorldItemSet
 
typedef std::vector< Sensor * > SensorVector
 
typedef std::vector< Robot * > RobotVector
 

Functions

Eigen::Isometry3d sample_noise_from_se3 (const Vector6 &cov)
 
Vector3d sample_noise_from_plane (const Vector3d &cov)
 
int main (int argc, char **argv)
 

Typedef Documentation

◆ RobotVector

typedef std::vector<Robot*> RobotVector

Definition at line 170 of file simulator_3d_plane.cpp.

◆ SensorVector

typedef std::vector<Sensor*> SensorVector

Definition at line 103 of file simulator_3d_plane.cpp.

◆ WorldItemSet

typedef std::set<WorldItem*> WorldItemSet

Definition at line 88 of file simulator_3d_plane.cpp.

Function Documentation

◆ main()

int main ( int  argc,
char **  argv 
)

Definition at line 263 of file simulator_3d_plane.cpp.

263 {
264 int maxIterations;
265 bool verbose;
266 bool robustKernel;
267 double lambdaInit;
268 CommandArgs arg;
269 bool fixSensor;
270 bool fixPlanes;
271 bool fixFirstPose;
272 bool fixTrajectory;
273 bool planarMotion;
274 bool listSolvers;
275 string strSolver;
276 cerr << "graph" << endl;
277 arg.param("i", maxIterations, 5, "perform n iterations");
278 arg.param("v", verbose, false, "verbose output of the optimization process");
279 arg.param("solver", strSolver, "lm_var", "select one specific solver");
280 arg.param("lambdaInit", lambdaInit, 0,
281 "user specified lambda init for levenberg");
282 arg.param("robustKernel", robustKernel, false, "use robust error functions");
283 arg.param("fixSensor", fixSensor, false,
284 "fix the sensor position on the robot");
285 arg.param("fixTrajectory", fixTrajectory, false, "fix the trajectory");
286 arg.param("fixFirstPose", fixFirstPose, false, "fix the first robot pose");
287 arg.param("fixPlanes", fixPlanes, false,
288 "fix the planes (do localization only)");
289 arg.param("planarMotion", planarMotion, false, "robot moves on a plane");
290 arg.param("listSolvers", listSolvers, false, "list the solvers");
291 arg.parseArgs(argc, argv);
292
294 ParameterSE3Offset* odomOffset = new ParameterSE3Offset();
295 odomOffset->setId(0);
296 g->addParameter(odomOffset);
297
298 OptimizationAlgorithmFactory* solverFactory =
300 OptimizationAlgorithmProperty solverProperty;
301 OptimizationAlgorithm* solver =
302 solverFactory->construct(strSolver, solverProperty);
303 g->setAlgorithm(solver);
304 if (listSolvers) {
305 solverFactory->listSolvers(cerr);
306 return 0;
307 }
308
309 if (!g->solver()) {
310 cerr << "Error allocating solver. Allocating \"" << strSolver
311 << "\" failed!" << endl;
312 cerr << "available solvers: " << endl;
313 solverFactory->listSolvers(cerr);
314 cerr << "--------------" << endl;
315 return 0;
316 }
317
318 cerr << "sim" << endl;
319 Simulator* sim = new Simulator(g);
320
321 cerr << "robot" << endl;
322 Robot* r = new Robot(g);
323
324 cerr << "planeSensor" << endl;
325 Matrix3d R = Matrix3d::Identity();
326 R << 0, 0, 1, -1, 0, 0, 0, -1, 0;
327
328 Isometry3d sensorPose = Isometry3d::Identity();
329 sensorPose.matrix().block<3, 3>(0, 0) = R;
330 sensorPose.translation() = Vector3d(.3, 0.5, 1.2);
331 PlaneSensor* ps = new PlaneSensor(r, 0, sensorPose);
332 ps->_nplane << 0.03, 0.03, 0.005;
333 r->_sensors.push_back(ps);
334 sim->_robots.push_back(r);
335
336 cerr << "p1" << endl;
337 Plane3D plane;
338 PlaneItem* pi = new PlaneItem(g, 1);
339 plane.fromVector(Eigen::Vector4d(0., 0., 1., 5.));
340 static_cast<VertexPlane*>(pi->vertex())->setEstimate(plane);
341 pi->vertex()->setFixed(fixPlanes);
342 sim->_world.insert(pi);
343
344 plane.fromVector(Eigen::Vector4d(1., 0., 0., 5.));
345 pi = new PlaneItem(g, 2);
346 static_cast<VertexPlane*>(pi->vertex())->setEstimate(plane);
347 pi->vertex()->setFixed(fixPlanes);
348 sim->_world.insert(pi);
349
350 cerr << "p2" << endl;
351 pi = new PlaneItem(g, 3);
352 plane.fromVector(Eigen::Vector4d(0., 1., 0., 5.));
353 static_cast<VertexPlane*>(pi->vertex())->setEstimate(plane);
354 pi->vertex()->setFixed(fixPlanes);
355 sim->_world.insert(pi);
356
357 Quaterniond q, iq;
358 if (planarMotion) {
359 r->_planarMotion = true;
360 r->_nmovecov << 0.01, 0.0025, 1e-9, 0.001, 0.001, 0.025;
361 q = Quaterniond(AngleAxisd(0.2, Vector3d::UnitZ()).toRotationMatrix());
362 iq = Quaterniond(AngleAxisd(-0.2, Vector3d::UnitZ()).toRotationMatrix());
363 } else {
364 r->_planarMotion = false;
365 // r->_nmovecov << 0.1, 0.005, 1e-9, 0.05, 0.001, 0.001;
366 r->_nmovecov << 0.1, 0.005, 1e-9, 0.001, 0.001, 0.05;
367 q = Quaterniond((AngleAxisd(M_PI / 10, Vector3d::UnitZ()) *
368 AngleAxisd(0.1, Vector3d::UnitY()))
369 .toRotationMatrix());
370 iq = Quaterniond((AngleAxisd(-M_PI / 10, Vector3d::UnitZ()) *
371 AngleAxisd(0.1, Vector3d::UnitY()))
372 .toRotationMatrix());
373 }
374
375 Isometry3d delta = Isometry3d::Identity();
376 sim->_lastVertexId = 4;
377
378 Isometry3d startPose = Isometry3d::Identity();
379 startPose.matrix().block<3, 3>(0, 0) =
380 AngleAxisd(-0.75 * M_PI, Vector3d::UnitZ()).toRotationMatrix();
381 sim->move(0, startPose);
382
383 int k = 20;
384 int l = 2;
385 double delta_t = 0.2;
386 for (int j = 0; j < l; j++) {
387 Vector3d tr(1., 0., 0.);
388 delta.matrix().block<3, 3>(0, 0) = q.toRotationMatrix();
389 if (j == (l - 1)) {
390 delta.matrix().block<3, 3>(0, 0) = Matrix3d::Identity();
391 }
392 delta.translation() = tr * (delta_t * j);
393 Isometry3d iDelta = delta.inverse();
394 for (int a = 0; a < 2; a++) {
395 for (int i = 0; i < k; i++) {
396 cerr << "m";
397 if (a == 0)
398 sim->relativeMove(0, delta);
399 else
400 sim->relativeMove(0, iDelta);
401 cerr << "s";
402 sim->sense(0);
403 }
404 }
405 }
406
407 for (int j = 0; j < l; j++) {
408 Vector3d tr(1., 0., 0.);
409 delta.matrix().block<3, 3>(0, 0) = iq.toRotationMatrix();
410 if (j == l - 1) {
411 delta.matrix().block<3, 3>(0, 0) = Matrix3d::Identity();
412 }
413 delta.translation() = tr * (delta_t * j);
414 Isometry3d iDelta = delta.inverse();
415 for (int a = 0; a < 2; a++) {
416 for (int i = 0; i < k; i++) {
417 cerr << "m";
418 if (a == 0)
419 sim->relativeMove(0, delta);
420 else
421 sim->relativeMove(0, iDelta);
422 cerr << "s";
423 sim->sense(0);
424 }
425 }
426 }
427
428 ofstream os("test_gt.g2o");
429 g->save(os);
430
431 if (fixSensor) {
432 ps->_offsetVertex->setFixed(true);
433 } else {
434 Vector6 noffcov;
435 noffcov << 0.1, 0.1, 0.1, 0.5, 0.5, 0.5;
437 sample_noise_from_se3(noffcov));
438 ps->_offsetVertex->setFixed(false);
439 }
440
441 if (fixFirstPose) {
442 OptimizableGraph::Vertex* gauge = g->vertex(4);
443 if (gauge) gauge->setFixed(true);
444 } // else {
445 // // multiply all vertices of the robot by this standard quantity
446 // Quaterniond q(AngleAxisd(1, Vector3d::UnitZ()).toRotationMatrix());
447 // Vector3d tr(1,0,0);
448 // Isometry3d delta;
449 // delta.matrix().block<3,3>(0,0)=q.toRotationMatrix();
450 // delta.translation()=tr;
451 // for (size_t i=0; i< g->vertices().size(); i++){
452 // VertexSE3 *v = dynamic_cast<VertexSE3 *>(g->vertex(i));
453 // if (v && v->id()>0){
454 // v->setEstimate (v->estimate()*delta);
455 // }
456 // }
457 // }
458
459 ofstream osp("test_preopt.g2o");
460 g->save(osp);
461 // g->setMethod(SparseOptimizer::LevenbergMarquardt);
463 g->setVerbose(verbose);
464 g->optimize(maxIterations);
465 if (!fixSensor) {
467 std::pair<int, int> indexParams;
468 indexParams.first = ps->_offsetVertex->hessianIndex();
469 indexParams.second = ps->_offsetVertex->hessianIndex();
470 std::vector<std::pair<int, int> > blockIndices;
471 blockIndices.push_back(indexParams);
472 if (!g->computeMarginals(spinv, blockIndices)) {
473 cerr << "error in computing the covariance" << endl;
474 } else {
475 MatrixXd m = *spinv.block(ps->_offsetVertex->hessianIndex(),
477
478 cerr << "Param covariance" << endl;
479 cerr << m << endl;
480 cerr << "OffsetVertex: " << endl;
481 ps->_offsetVertex->write(cerr);
482 cerr << endl;
483 cerr << "rotationDeterminant: " << m.block<3, 3>(0, 0).determinant()
484 << endl;
485 cerr << "translationDeterminant: " << m.block<3, 3>(3, 3).determinant()
486 << endl;
487 cerr << endl;
488 }
489 }
490 ofstream os1("test_postOpt.g2o");
491 g->save(os1);
492}
std::set< BaseSensor * > _sensors
Definition simulator.h:99
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()
Command line parsing of argc and argv.
bool parseArgs(int argc, char **argv, bool exitOnError=true)
void param(const std::string &name, bool &p, bool defValue, const std::string &desc)
A general case Vertex for optimization.
void setFixed(bool fixed)
true => this node should be considered fixed during the optimization
create solvers based on their short name
OptimizationAlgorithm * construct(const std::string &tag, OptimizationAlgorithmProperty &solverProperty) const
static OptimizationAlgorithmFactory * instance()
return the instance
void listSolvers(std::ostream &os) const
list the known solvers into a stream
Generic interface for a non-linear solver operating on a graph.
void setId(int id_)
Definition parameter.cpp:33
void fromVector(const Vector4 &coeffs_)
Definition plane3d.h:52
Sparse matrix which uses blocks.
SparseMatrixBlock * block(int r, int c, bool alloc=false)
int optimize(int iterations, bool online=false)
void setVerbose(bool verbose)
virtual bool initializeOptimization(HyperGraph::EdgeSet &eset)
void setAlgorithm(OptimizationAlgorithm *algorithm)
OptimizationAlgorithm * solver()
bool computeMarginals(SparseBlockMatrix< MatrixX > &spinv, const std::vector< std::pair< int, int > > &blockIndices)
virtual bool write(std::ostream &os) const
write the vertex to a stream
VectorN< 6 > Vector6
Definition eigen_types.h:53
Eigen::Isometry3d sample_noise_from_se3(const Vector6 &cov)
VertexSE3 * _offsetVertex
void sense(int robotIndex)
WorldItemSet _world
void relativeMove(int robotIndex, const Isometry3d &delta)
RobotVector _robots
void move(int robotIndex, const Isometry3d &newRobotPose)
OptimizableGraph::Vertex * vertex()
virtual bool save(std::ostream &os, int level=0) const
save the graph to a stream. Again uses the Factory system.
bool addParameter(Parameter *p)
Vertex * vertex(int id)
returns the vertex number id appropriately casted

References Simulator::_lastVertexId, PlaneSensor::_nplane, PlaneSensor::_offsetVertex, Simulator::_robots, g2o::BaseRobot::_sensors, Simulator::_world, g2o::OptimizableGraph::addParameter(), g2o::SparseBlockMatrix< MatrixType >::block(), g2o::SparseOptimizer::computeMarginals(), g2o::OptimizationAlgorithmFactory::construct(), g2o::BaseVertex< D, T >::estimate(), g2o::Plane3D::fromVector(), g2o::OptimizableGraph::Vertex::hessianIndex(), g2o::SparseOptimizer::initializeOptimization(), g2o::OptimizationAlgorithmFactory::instance(), g2o::OptimizationAlgorithmFactory::listSolvers(), Simulator::move(), g2o::SparseOptimizer::optimize(), g2o::CommandArgs::param(), g2o::CommandArgs::parseArgs(), Simulator::relativeMove(), sample_noise_from_se3(), g2o::OptimizableGraph::save(), Simulator::sense(), g2o::SparseOptimizer::setAlgorithm(), g2o::BaseVertex< D, T >::setEstimate(), g2o::OptimizableGraph::Vertex::setFixed(), g2o::Parameter::setId(), g2o::SparseOptimizer::setVerbose(), g2o::SparseOptimizer::solver(), WorldItem::vertex(), g2o::OptimizableGraph::vertex(), and g2o::VertexSE3::write().

◆ sample_noise_from_plane()

Vector3d sample_noise_from_plane ( const Vector3d &  cov)

Definition at line 63 of file simulator_3d_plane.cpp.

63 {
64 return Vector3d(g2o::Sampler::gaussRand(0., cov(0)),
65 g2o::Sampler::gaussRand(0., cov(1)),
66 g2o::Sampler::gaussRand(0., cov(2)));
67}
static double gaussRand(double mean, double sigma)
Definition sampler.h:89

References g2o::Sampler::gaussRand().

Referenced by PlaneSensor::sense().

◆ sample_noise_from_se3()

Eigen::Isometry3d sample_noise_from_se3 ( const Vector6 cov)

Definition at line 44 of file simulator_3d_plane.cpp.

44 {
45 double nx = g2o::Sampler::gaussRand(0., cov(0));
46 double ny = g2o::Sampler::gaussRand(0., cov(1));
47 double nz = g2o::Sampler::gaussRand(0., cov(2));
48
49 double nroll = g2o::Sampler::gaussRand(0., cov(3));
50 double npitch = g2o::Sampler::gaussRand(0., cov(4));
51 double nyaw = g2o::Sampler::gaussRand(0., cov(5));
52
53 AngleAxisd aa(AngleAxisd(nyaw, Vector3d::UnitZ()) *
54 AngleAxisd(nroll, Vector3d::UnitX()) *
55 AngleAxisd(npitch, Vector3d::UnitY()));
56
57 Eigen::Isometry3d retval = Isometry3d::Identity();
58 retval.matrix().block<3, 3>(0, 0) = aa.toRotationMatrix();
59 retval.translation() = Vector3d(nx, ny, nz);
60 return retval;
61}

References g2o::Sampler::gaussRand().

Referenced by main().