16 using namespace Eigen;
24 return lowerBndr + ((double) std::rand() / (RAND_MAX + 1.0)) * (upperBndr - lowerBndr);
34 }
while (r2 > 1.0 || r2 == 0.0);
35 return sigma * y * std::sqrt(-2.0 * log(r2) / r2);
47 AngleAxisd aa(AngleAxisd(nyaw, Vector3d::UnitZ())*
48 AngleAxisd(nroll, Vector3d::UnitX())*
49 AngleAxisd(npitch, Vector3d::UnitY()));
51 Eigen::Isometry3d retval=Isometry3d::Identity();
52 retval.matrix().block<3,3>(0,0)= aa.toRotationMatrix();
53 retval.translation()=Vector3d(nx,ny,nz);
98 _position = Isometry3d::Identity();
102 void move(
const Isometry3d& newPosition,
int&
id) {
103 Isometry3d delta = _position.inverse()*newPosition;
104 _position = newPosition;
108 graph()->addVertex(v);
118 graph()->addEdge(planeConstraint);
126 for (
int i=0; i<6; i++){
127 m(i,i)=1./(_nmovecov(i));
141 Isometry3d newPosition = _position*delta;
142 move(newPosition,
id);
146 for (
size_t i=0; i<_sensors.size(); i++){
148 s->
sense(wi, _position);
163 Robot* r=_robots[robotIndex];
164 for (WorldItemSet::iterator it=_world.begin(); it!=_world.end(); it++){
170 void move(
int robotIndex,
const Isometry3d& newRobotPose){
171 Robot* r=_robots[robotIndex];
172 r->
move(newRobotPose, _lastVertexId);
176 Robot* r=_robots[robotIndex];
189 graph()->addVertex(p);
197 _offsetVertex->setId(offsetId);
198 _offsetVertex->setEstimate(offset_);
199 robot()->graph()->addVertex(_offsetVertex);
225 const Isometry3d& robotPose=position;
226 Isometry3d sensorPose=robotPose*_offsetVertex->
estimate();
230 Plane3D measuredPlane=sensorPose.inverse()*worldPlane;
237 measuredPlane.
oplus(noise);
239 Matrix3d m=Matrix3d::Zero();
240 m(0,0)=1./(_nplane(0));
241 m(1,1)=1./(_nplane(1));
242 m(2,2)=1./(_nplane(2));
244 robot()->graph()->addEdge(e);
252 int main (
int argc ,
char ** argv){
265 cerr <<
"graph" << endl;
266 arg.
param(
"i", maxIterations, 5,
"perform n iterations");
267 arg.
param(
"v", verbose,
false,
"verbose output of the optimization process");
268 arg.
param(
"solver", strSolver,
"lm_var",
"select one specific solver");
269 arg.
param(
"lambdaInit", lambdaInit, 0,
"user specified lambda init for levenberg");
270 arg.
param(
"robustKernel", robustKernel,
false,
"use robust error functions");
271 arg.
param(
"fixSensor", fixSensor,
false,
"fix the sensor position on the robot");
272 arg.
param(
"fixTrajectory", fixTrajectory,
false,
"fix the trajectory");
273 arg.
param(
"fixFirstPose", fixFirstPose,
false,
"fix the first robot pose");
274 arg.
param(
"fixPlanes", fixPlanes,
false,
"fix the planes (do localization only)");
275 arg.
param(
"planarMotion", planarMotion,
false,
"robot moves on a plane");
276 arg.
param(
"listSolvers", listSolvers,
false,
"list the solvers");
283 odomOffset->
setId(0);
296 cerr <<
"Error allocating solver. Allocating \"" << strSolver <<
"\" failed!" << endl;
297 cerr <<
"available solvers: " << endl;
299 cerr <<
"--------------" << endl;
303 cerr <<
"sim" << endl;
306 cerr <<
"robot" << endl;
310 cerr <<
"planeSensor" << endl;
311 Matrix3d R=Matrix3d::Identity();
317 Isometry3d sensorPose=Isometry3d::Identity();
318 sensorPose.matrix().block<3,3>(0,0) = R;
319 sensorPose.translation()= Vector3d(.3 , 0.5 , 1.2);
321 ps->
_nplane << 0.03, 0.03, 0.005;
325 cerr <<
"p1" << endl;
328 plane.
fromVector(Eigen::Vector4d(0.,0.,1.,5.));
333 plane.
fromVector(Eigen::Vector4d(1.,0.,0.,5.));
339 cerr <<
"p2" << endl;
341 plane.
fromVector(Eigen::Vector4d(0.,1.,0.,5.));
349 r->_planarMotion =
true;
350 r->_nmovecov << 0.01, 0.0025, 1e-9, 0.001, 0.001, 0.025;
351 q = Quaterniond(AngleAxisd(0.2, Vector3d::UnitZ()).toRotationMatrix());
352 iq = Quaterniond(AngleAxisd(-0.2, Vector3d::UnitZ()).toRotationMatrix());
354 r->_planarMotion =
false;
356 r->_nmovecov << 0.1, 0.005, 1e-9, 0.001, 0.001, 0.05;
357 q = Quaterniond((AngleAxisd(
M_PI/10, Vector3d::UnitZ()) * AngleAxisd(0.1, Vector3d::UnitY())).toRotationMatrix());
358 iq = Quaterniond((AngleAxisd(-
M_PI/10, Vector3d::UnitZ()) * AngleAxisd(0.1, Vector3d::UnitY())).toRotationMatrix());
361 Isometry3d delta=Isometry3d::Identity();
364 Isometry3d startPose=Isometry3d::Identity();
365 startPose.matrix().block<3,3>(0,0) = AngleAxisd(-0.75*
M_PI, Vector3d::UnitZ()).toRotationMatrix();
366 sim->
move(0,startPose);
370 double delta_t = 0.2;
371 for (
int j=0; j<l; j++) {
372 Vector3d tr(1.,0.,0.);
373 delta.matrix().block<3,3>(0,0) = q.toRotationMatrix();
375 delta.matrix().block<3,3>(0,0) = Matrix3d::Identity();
377 delta.translation()=tr*(delta_t*j);
378 Isometry3d iDelta = delta.inverse();
379 for (
int a=0; a<2; a++){
380 for (
int i=0; i<k; i++){
392 for (
int j=0; j<l; j++) {
393 Vector3d tr(1.,0.,0.);
394 delta.matrix().block<3,3>(0,0) = iq.toRotationMatrix();
396 delta.matrix().block<3,3>(0,0) = Matrix3d::Identity();
398 delta.translation()=tr*(delta_t*j);
399 Isometry3d iDelta = delta.inverse();
400 for (
int a=0; a<2; a++){
401 for (
int i=0; i<k; i++){
413 ofstream os(
"test_gt.g2o");
420 noffcov << 0.1,0.1,0.1,0.5, 0.5, 0.5;
444 ofstream osp(
"test_preopt.g2o");
452 std::pair<int, int> indexParams;
455 std::vector<std::pair <int, int> > blockIndices;
456 blockIndices.push_back(indexParams);
458 cerr <<
"error in computing the covariance" << endl;
463 cerr <<
"Param covariance" << endl;
465 cerr <<
"OffsetVertex: " << endl;
468 cerr <<
"rotationDeterminant: " << m.block<3,3>(0,0).determinant() << endl;
469 cerr <<
"translationDeterminant: " << m.block<3,3>(3,3).determinant() << endl;
473 ofstream os1(
"test_postOpt.g2o");
void oplus(const Eigen::Vector3d &v)
Command line parsing of argc and argv.
OptimizableGraph::Vertex * _vertex
void setVertex(OptimizableGraph::Vertex *vertex_)
VertexSE3 * _offsetVertex
describe the properties of a solver
PlaneItem(OptimizableGraph *graph_, int id)
int optimize(int iterations, bool online=false)
SparseMatrixBlock * block(int r, int c, bool alloc=false)
returns the block at location r,c. if alloc=true he block is created if it does not exist ...
OptimizationAlgorithm * solver()
void move(int robotIndex, const Isometry3d &newRobotPose)
int hessianIndex() const
temporary index of this node in the parameter vector obtained from linearization
create solvers based on their short name
double uniform_rand(double lowerBndr, double upperBndr)
Vertex * vertex(int id)
returns the vertex number id appropriately casted
Edge between two 3D pose vertices.
virtual bool sense(WorldItem *, const Isometry3d &)
virtual bool write(std::ostream &os) const
write the vertex to a stream
virtual void setId(int id)
sets the id of the node in the graph be sure that the graph keeps consistent after changing the id ...
std::set< BaseSensor * > _sensors
Eigen::Matrix< double, 6, 6 > Matrix6d
bool setParameterId(int argNum, int paramId)
const VertexContainer & vertices() const
bool parseArgs(int argc, char **argv, bool exitOnError=true)
virtual bool save(std::ostream &os, int level=0) const
save the graph to a stream. Again uses the Factory system.
virtual bool isVisible(const WorldItem *wi) const
void setVerbose(bool verbose)
void sense(WorldItem *wi=0)
class G2O_CORE_API SparseOptimizer
virtual void setMeasurement(const Isometry3D &m)
void setAlgorithm(OptimizationAlgorithm *algorithm)
EIGEN_STRONG_INLINE void setInformation(const InformationType &information)
void relativeMove(const Isometry3d &delta, int &id)
plane measurement that also calibrates an offset for the sensor
Robot(OptimizableGraph *graph_)
SimulatorItem(OptimizableGraph *graph_)
void param(const std::string &name, bool &p, bool defValue, const std::string &desc)
void fromVector(const Eigen::Vector4d &coeffs_)
G2O_USE_OPTIMIZATION_LIBRARY(cholmod)
bool addParameter(Parameter *p)
void relativeMove(int robotIndex, const Isometry3d &delta)
PlaneSensor(Robot *r, int offsetId, const Isometry3d &offset_)
void setEstimate(const EstimateType &et)
set the estimate for the vertex also calls updateCache()
void listSolvers(std::ostream &os) const
list the known solvers into a stream
Simulator(OptimizableGraph *graph_)
A general case Vertex for optimization.
std::vector< Robot * > RobotVector
virtual void relativeMove(const PoseType &movement_)
static OptimizationAlgorithmFactory * instance()
return the instance
void setMeasurement(const Plane3D &m)
void sense(int robotIndex)
void move(const Isometry3d &newPosition, int &id)
Vector3d sample_noise_from_plane(const Vector3d &cov)
const EstimateType & estimate() const
return the current estimate of the vertex
Eigen::Matrix< double, 6, 1 > Vector6d
Eigen::Isometry3d sample_noise_from_se3(const Vector6d &cov)
3D pose Vertex, represented as an Isometry3D
void setFixed(bool fixed)
true => this node should be considered fixed during the optimization
virtual bool sense(WorldItem *wi, const Isometry3d &position)
virtual bool initializeOptimization(HyperGraph::EdgeSet &eset)
virtual void setMeasurement(const Isometry3D &m)
Generic interface for a non-linear solver operating on a graph.
OptimizableGraph::Vertex * vertex()
std::vector< Sensor * > SensorVector
bool computeMarginals(SparseBlockMatrix< MatrixXD > &spinv, const std::vector< std::pair< int, int > > &blockIndices)
virtual bool isVisible(const WorldItem *) const
OptimizableGraph * _graph
virtual void move(const PoseType &pose_)
std::set< WorldItem * > WorldItemSet
Sparse matrix which uses blocks.
OptimizationAlgorithm * construct(const std::string &tag, OptimizationAlgorithmProperty &solverProperty) const
WorldItem(OptimizableGraph *graph_, OptimizableGraph::Vertex *vertex_=0)
double gauss_rand(double sigma)
Protocol The SLAM executable accepts such as solving the and retrieving or vertices in the graph
EIGEN_STRONG_INLINE const Measurement & measurement() const
accessor functions for the measurement represented by the edge
int main(int argc, char **argv)
OptimizableGraph * graph()