Go to the documentation of this file.00001 #include "node.h"
00002 #include "scoped_timer.h"
00003 #include "transformation_estimation.h"
00004
00005 #include "g2o/core/sparse_optimizer.h"
00006 #include "g2o/core/block_solver.h"
00007 #include "g2o/core/solver.h"
00008 #include "g2o/solvers/cholmod/linear_solver_cholmod.h"
00009 #include "g2o/types/icp/types_icp.h"
00010
00011 #include "g2o/types/slam3d/se3quat.h"
00012 #include "g2o/types/slam3d/edge_se3_pointxyz_depth.h"
00013 #include "g2o/types/slam3d/vertex_pointxyz.h"
00014 #include "misc2.h"
00015 #include <Eigen/SVD>
00016
00017 #include "g2o/core/estimate_propagator.h"
00018
00019
00020 #include "g2o/core/hyper_dijkstra.h"
00021 #include "g2o/core/optimization_algorithm_gauss_newton.h"
00022 #include "g2o/core/optimization_algorithm_levenberg.h"
00023 #include "g2o/core/robust_kernel_impl.h"
00024
00025 using namespace Eigen;
00026 using namespace std;
00027 using namespace g2o;
00028
00029 typedef g2o::VertexPointXYZ feature_vertex_type;
00030 typedef g2o::EdgeSE3PointXYZDepth feature_edge_type;
00031
00032
00033
00034
00035
00037 void optimizerSetup(g2o::SparseOptimizer& optimizer){
00038
00039
00040 optimizer.setVerbose(false);
00041
00042
00043 g2o::BlockSolverX::LinearSolverType * linearSolver
00044 = new g2o::LinearSolverCholmod<g2o ::BlockSolverX::PoseMatrixType>();
00045
00046
00047 g2o::BlockSolverX * solver_ptr
00048 = new g2o::BlockSolverX(linearSolver);
00049
00050 g2o::OptimizationAlgorithmGaussNewton* solver = new g2o::OptimizationAlgorithmGaussNewton(solver_ptr);
00051 optimizer.setAlgorithm(solver);
00052
00053
00054 g2o::ParameterCamera* cameraParams = new g2o::ParameterCamera();
00055
00056 cameraParams->setKcam(521,521,319.5,239.5);
00057 g2o::SE3Quat offset;
00058 cameraParams->setOffset(offset);
00059 cameraParams->setId(0);
00060 optimizer.addParameter(cameraParams);
00061 }
00062
00063
00064 std::pair<g2o::VertexSE3*, g2o::VertexSE3*> sensorVerticesSetup(g2o::SparseOptimizer& optimizer, Eigen::Matrix4f& tf_estimate){
00065 g2o::VertexSE3 *vc2 = new VertexSE3();
00066 {
00067 Eigen::Quaterniond q(1,0,0,0);
00068 Eigen::Vector3d t(0,0,0);
00069 q.setIdentity();
00070 g2o::SE3Quat cam2(q,t);
00071
00072 vc2->setEstimate(cam2);
00073 vc2->setId(1);
00074 vc2->setFixed(true);
00075 optimizer.addVertex(vc2);
00076 }
00077
00078 g2o::VertexSE3 *vc1 = new VertexSE3();
00079 {
00080 Eigen::Quaterniond q(tf_estimate.topLeftCorner<3,3>().cast<double>());
00081 Eigen::Vector3d t(tf_estimate.topRightCorner<3,1>().cast<double>());
00082 g2o::SE3Quat cam1(q,t);
00083 vc1->setEstimate(cam1);
00084 vc1->setId(0);
00085 optimizer.addVertex(vc1);
00086 }
00087
00088
00089 return std::make_pair(vc1, vc2);
00090 }
00091 feature_edge_type* edgeToFeature(const Node* node,
00092 unsigned int feature_id,
00093 g2o::VertexSE3* camera_vertex,
00094 g2o::VertexPointXYZ* feature_vertex)
00095 {
00096 feature_edge_type* edge = new feature_edge_type();
00097 cv::KeyPoint kp = node->feature_locations_2d_[feature_id];
00098 Vector4f position = node->feature_locations_3d_[feature_id];
00099 float depth = position(2);
00100 if(!isnan(depth))
00101 {
00102 Eigen::Vector3d pix_d(kp.pt.x,kp.pt.y,depth);
00103
00104 edge->setMeasurement(pix_d);
00105 Eigen::Matrix3d info_mat = point_information_matrix(depth);
00106 edge->setInformation(info_mat);
00107 feature_vertex->setEstimate(position.cast<double>().head<3>());
00108
00109 }
00110 else {
00111 Eigen::Vector3d pix_d(kp.pt.x,kp.pt.y,10.0);
00112
00113 edge->setMeasurement(pix_d);
00114 Eigen::Matrix3d info_mat = point_information_matrix(10);
00115 edge->setInformation(info_mat);
00116 feature_vertex->setEstimate(Eigen::Vector3d(position(0)*10, position(1)*10, 10.0));
00117 }
00118 edge->setParameterId(0,0);
00119
00120 edge->vertices()[0] = camera_vertex;
00121 edge->vertices()[1] = feature_vertex;
00122
00123 return edge;
00124 }
00126 void getTransformFromMatchesG2O(const Node* earlier_node,
00127 const Node* newer_node,
00128 const std::vector<cv::DMatch> & matches,
00129 Eigen::Matrix4f& transformation_estimate,
00130 int iterations)
00131 {
00132 ScopedTimer s(__FUNCTION__);
00133
00134 g2o::SparseOptimizer* optimizer = new g2o::SparseOptimizer();
00135
00136 optimizerSetup(*optimizer);
00137
00138
00139 std::pair<g2o::VertexSE3*, g2o::VertexSE3*> cams = sensorVerticesSetup(*optimizer, transformation_estimate);
00140
00141
00142 int v_id = optimizer->vertices().size();
00143
00144 BOOST_FOREACH(const cv::DMatch& m, matches)
00145 {
00146 feature_vertex_type* v = new feature_vertex_type();
00147 v->setId(v_id++);
00148 v->setFixed(false);
00149
00150 optimizer->addVertex(v);
00151
00152
00153 feature_edge_type* e1 = edgeToFeature(earlier_node, m.trainIdx, cams.first, v);
00154 optimizer->addEdge(e1);
00155
00156 feature_edge_type* e2 = edgeToFeature(newer_node, m.queryIdx, cams.second, v);
00157 optimizer->addEdge(e2);
00158
00159 }
00160 optimizer->initializeOptimization();
00161
00162 ROS_INFO("Optimizer Size: %zu", optimizer->vertices().size());
00163 optimizer->optimize(iterations);
00164 optimizer->computeActiveErrors();
00165
00166
00167
00168 transformation_estimate = cams.first->estimate().cast<float>().inverse().matrix();
00169 delete optimizer;
00170 }