G2oSolver.cpp
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         // Initialize the SparseOptimizer
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         // destroy all the singletons
00033         g2o::Factory::destroy();
00034         g2o::OptimizationAlgorithmFactory::destroy();
00035         g2o::HyperGraphActionLibrary::destroy();
00036 }
00037 
00038 void G2oSolver::Clear()
00039 {
00040         // freeing the graph memory
00041         ROS_INFO("[g2o] Clearing Optimizer..."); 
00042         mCorrections.Clear();
00043 }
00044 
00045 void G2oSolver::Compute()
00046 {
00047         // Fix the first node in the graph to hold the map in place
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         // Do the graph optimization
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         // Write the result so it can be used by the mapper
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         // Create a new edge
00097         g2o::EdgeSE2* odometry = new g2o::EdgeSE2;
00098         
00099         // Set source and target
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         // Set the measurement (odometry distance between vertices)
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         // Set the covariance of the measurement
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         // Add the constraint to the optimizer
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 }


nav2d_karto
Author(s): Sebastian Kasperski
autogenerated on Mon Oct 6 2014 02:44:17