Go to the documentation of this file.00001 #include "G2oSolver.h"
00002
00003 #include "g2o/core/block_solver.h"
00004 #include "g2o/core/factory.h"
00005 #include "g2o/core/optimization_algorithm_factory.h"
00006 #include "g2o/core/optimization_algorithm_gauss_newton.h"
00007 #include "g2o/types/slam2d/types_slam2d.h"
00008
00009 #include <ros/console.h>
00010
00011 typedef g2o::BlockSolver< g2o::BlockSolverTraits<-1, -1> > SlamBlockSolver;
00012
00013 #ifdef SBA_CHOLMOD
00014 #include "g2o/solvers/cholmod/linear_solver_cholmod.h"
00015 typedef g2o::LinearSolverCholmod<SlamBlockSolver::PoseMatrixType> SlamLinearSolver;
00016 #else
00017 #include "g2o/solvers/csparse/linear_solver_csparse.h"
00018 typedef g2o::LinearSolverCSparse<SlamBlockSolver::PoseMatrixType> SlamLinearSolver;
00019 #endif
00020
00021 G2oSolver::G2oSolver()
00022 {
00023
00024 SlamLinearSolver* linearSolver = new SlamLinearSolver();
00025 linearSolver->setBlockOrdering(false);
00026 SlamBlockSolver* blockSolver = new SlamBlockSolver(linearSolver);
00027 mOptimizer.setAlgorithm(new g2o::OptimizationAlgorithmGaussNewton(blockSolver));
00028 }
00029
00030 G2oSolver::~G2oSolver()
00031 {
00032
00033 g2o::Factory::destroy();
00034 g2o::OptimizationAlgorithmFactory::destroy();
00035 g2o::HyperGraphActionLibrary::destroy();
00036 }
00037
00038 void G2oSolver::Clear()
00039 {
00040
00041 ROS_INFO("[g2o] Clearing Optimizer...");
00042 mCorrections.Clear();
00043 }
00044
00045 void G2oSolver::Compute()
00046 {
00047
00048 g2o::OptimizableGraph::Vertex* first = mOptimizer.vertex(0);
00049 if(!first)
00050 {
00051 ROS_ERROR("[g2o] No Node with ID 0 found!");
00052 return;
00053 }
00054 first->setFixed(true);
00055
00056
00057 mOptimizer.initializeOptimization();
00058 int iter = mOptimizer.optimize(500);
00059 if (iter > 0)
00060 {
00061 ROS_INFO("[g2o] Optimization finished after %d iterations.", iter);
00062 }else
00063 {
00064 ROS_ERROR("[g2o] Optimization failed, result might be invalid!");
00065 return;
00066 }
00067
00068
00069 g2o::SparseOptimizer::VertexContainer nodes = mOptimizer.activeVertices();
00070 for (g2o::SparseOptimizer::VertexContainer::const_iterator n = nodes.begin(); n != nodes.end(); n++)
00071 {
00072 double estimate[3];
00073 if((*n)->getEstimateData(estimate))
00074 {
00075 karto::Pose2 pose(estimate[0], estimate[1], estimate[2]);
00076 mCorrections.Add(karto::Pair<int, karto::Pose2>((*n)->id(), pose));
00077 }else
00078 {
00079 ROS_ERROR("[g2o] Could not get estimated pose from Optimizer!");
00080 }
00081 }
00082 }
00083
00084 void G2oSolver::AddNode(karto::Vertex<karto::LocalizedObjectPtr>* pVertex)
00085 {
00086 karto::Pose2 odom = pVertex->GetVertexObject()->GetCorrectedPose();
00087 g2o::VertexSE2* poseVertex = new g2o::VertexSE2;
00088 poseVertex->setEstimate(g2o::SE2(odom.GetX(), odom.GetY(), odom.GetHeading()));
00089 poseVertex->setId(pVertex->GetVertexObject()->GetUniqueId());
00090 mOptimizer.addVertex(poseVertex);
00091 ROS_DEBUG("[g2o] Adding node %d.", pVertex->GetVertexObject()->GetUniqueId());
00092 }
00093
00094 void G2oSolver::AddConstraint(karto::Edge<karto::LocalizedObjectPtr>* pEdge)
00095 {
00096
00097 g2o::EdgeSE2* odometry = new g2o::EdgeSE2;
00098
00099
00100 int sourceID = pEdge->GetSource()->GetVertexObject()->GetUniqueId();
00101 int targetID = pEdge->GetTarget()->GetVertexObject()->GetUniqueId();
00102 odometry->vertices()[0] = mOptimizer.vertex(sourceID);
00103 odometry->vertices()[1] = mOptimizer.vertex(targetID);
00104 if(odometry->vertices()[0] == NULL)
00105 {
00106 ROS_ERROR("[g2o] Source vertex with id %d does not exist!", sourceID);
00107 delete odometry;
00108 return;
00109 }
00110 if(odometry->vertices()[0] == NULL)
00111 {
00112 ROS_ERROR("[g2o] Target vertex with id %d does not exist!", targetID);
00113 delete odometry;
00114 return;
00115 }
00116
00117
00118 karto::LinkInfo* pLinkInfo = (karto::LinkInfo*)(pEdge->GetLabel());
00119 karto::Pose2 diff = pLinkInfo->GetPoseDifference();
00120 g2o::SE2 measurement(diff.GetX(), diff.GetY(), diff.GetHeading());
00121 odometry->setMeasurement(measurement);
00122
00123
00124 karto::Matrix3 precisionMatrix = pLinkInfo->GetCovariance().Inverse();
00125 Eigen::Matrix<double,3,3> info;
00126 info(0,0) = precisionMatrix(0,0);
00127 info(0,1) = info(1,0) = precisionMatrix(0,1);
00128 info(0,2) = info(2,0) = precisionMatrix(0,2);
00129 info(1,1) = precisionMatrix(1,1);
00130 info(1,2) = info(2,1) = precisionMatrix(1,2);
00131 info(2,2) = precisionMatrix(2,2);
00132 odometry->setInformation(info);
00133
00134
00135 ROS_DEBUG("[g2o] Adding Edge from node %d to node %d.", sourceID, targetID);
00136 mOptimizer.addEdge(odometry);
00137 }
00138
00139 const karto::ScanSolver::IdPoseVector& G2oSolver::GetCorrections() const
00140 {
00141 return mCorrections;
00142 }