keyframe_graph_solver_g2o.cpp
Go to the documentation of this file.
00001 
00024 #include "rgbdtools/graph/keyframe_graph_solver_g2o.h"
00025 
00026 namespace rgbdtools {
00027 
00028 KeyframeGraphSolverG2O::KeyframeGraphSolverG2O():
00029   KeyframeGraphSolver(),
00030   vertexIdx(0)
00031 {
00032     typedef g2o::BlockSolver< g2o::BlockSolverTraits<-1, -1> >  SlamBlockSolver;
00033     typedef g2o::LinearSolverCSparse<SlamBlockSolver::PoseMatrixType> SlamLinearSolver;
00034     // allocating the optimizer
00035     linearSolver = new g2o::LinearSolverCSparse<g2o::BlockSolver_6_3::PoseMatrixType>();
00036     solver_ptr = new g2o::BlockSolver_6_3(linearSolver);
00037     g2o::OptimizationAlgorithmLevenberg* solver = new g2o::OptimizationAlgorithmLevenberg(solver_ptr);
00038 
00039     optimizer.setAlgorithm(solver);
00040     optimizer.setVerbose(true);
00041 }
00042 
00043 KeyframeGraphSolverG2O::~KeyframeGraphSolverG2O()
00044 {
00045 
00046 }
00047 
00048 void KeyframeGraphSolverG2O::solve(
00049   KeyframeVector& keyframes,
00050   const KeyframeAssociationVector& associations,
00051   AffineTransformVector& path)
00052 {
00053   // add vertices
00054   printf("Adding vertices...\n");
00055   for (unsigned int p_idx = 0; p_idx < path.size(); ++p_idx)
00056   {
00057     addVertex(path[p_idx], p_idx);
00058   }
00059 
00060   // add edges odometry edges
00061   printf("Adding VO edges...\n");
00062 
00063   if(path.size() > 1)
00064   {
00065     InformationMatrix path_inf = InformationMatrix::Identity();
00066 
00067     for (unsigned int p_idx = 0; p_idx < path.size()-1; ++p_idx)
00068     {
00069       int from_idx = p_idx;
00070       int to_idx   = p_idx+1;
00071 
00072       const AffineTransform& from_pose = path[from_idx];
00073       const AffineTransform& to_pose   = path[to_idx];
00074 
00075       AffineTransform tf = from_pose.inverse() * to_pose;
00076 
00077       InformationMatrix inf = path_inf * 100.0;
00078       addEdge(from_idx, to_idx, tf, inf);
00079     }
00080   }
00081 
00082   printf("Adding RANSAC edges...\n");
00083   InformationMatrix ransac_inf = InformationMatrix::Identity();
00084 
00085   for (unsigned int as_idx = 0; as_idx < associations.size(); ++as_idx)
00086   {
00087     const KeyframeAssociation& association = associations[as_idx];
00088 
00089     // skip non-ransac associations
00090     if (association.type != KeyframeAssociation::RANSAC) continue;
00091 
00092     // get the keyframe indices
00093     int kf_from_idx = association.kf_idx_a;
00094     int kf_to_idx   = association.kf_idx_b;
00095 
00096     // get the corresponding frame indices (also matches path index)
00097     int from_idx = keyframes[kf_from_idx].index;
00098     int to_idx   = keyframes[kf_to_idx].index;
00099 
00100     // calculate the information matrix
00101     int n_matches = association.matches.size();
00102     InformationMatrix inf = ransac_inf;
00103 
00104     // add the edge
00105     addEdge(from_idx, to_idx, association.a2b, inf);
00106   }
00107 
00108   // run the optimization
00109   printf("Optimizing...\n");
00110   optimizeGraph();
00111 
00112   // update the path poses
00113   printf("Updating path poses...\n");
00114   getOptimizedPoses(path);
00115 
00116   // update the keyframe poses
00117   printf("Updating keyframe poses...\n");
00118   for (unsigned int kf_idx = 0; kf_idx < keyframes.size(); ++kf_idx)
00119   {
00120     RGBDKeyframe& keyframe = keyframes[kf_idx];
00121     printf("keyframe.index: %d\n", keyframe.index);
00122     keyframe.pose = path[keyframe.index];
00123   }
00124 }
00125 
00126 void KeyframeGraphSolverG2O::solve(
00127   KeyframeVector& keyframes,
00128   const KeyframeAssociationVector& associations)
00129 {
00130   // add vertices
00131   printf("Adding vertices...\n");
00132   for (unsigned int kf_idx = 0; kf_idx < keyframes.size(); ++kf_idx)
00133   {
00134     const RGBDKeyframe& keyframe = keyframes[kf_idx];
00135     addVertex(keyframe.pose, kf_idx);
00136   }
00137 
00138     // add edges odometry edges
00139   printf("Adding VO edges...\n");
00140 
00141   InformationMatrix inf_identity = InformationMatrix::Identity();
00142 
00143   for (unsigned int kf_idx = 0; kf_idx < keyframes.size()-1; ++kf_idx)
00144   {
00145     int from_idx = kf_idx;
00146     int to_idx   = kf_idx+1;
00147 
00148     const AffineTransform& from_pose = keyframes[from_idx].pose;
00149     const AffineTransform& to_pose   = keyframes[to_idx].pose;
00150 
00151     AffineTransform tf = from_pose.inverse() * to_pose;
00152 
00153     InformationMatrix inf = inf_identity * 100.0;
00154     addEdge(from_idx, to_idx, tf, inf);
00155   }
00156 
00157   // add edges
00158   printf("Adding RANSAC edges...\n");
00159   for (unsigned int as_idx = 0; as_idx < associations.size(); ++as_idx)
00160   {
00161     const KeyframeAssociation& association = associations[as_idx];
00162     int from_idx = association.kf_idx_a;
00163     int to_idx   = association.kf_idx_b;
00164 
00165     int matches = association.matches.size();
00166     InformationMatrix inf = inf_identity * matches;
00167 
00168     addEdge(from_idx, to_idx, association.a2b, inf);
00169   }
00170 
00171   // run the optimization
00172   printf("Optimizing...\n");
00173   optimizeGraph();
00174 
00175   // update the keyframe poses
00176   printf("Updating keyframe poses...\n");
00177 
00178   AffineTransformVector optimized_poses;
00179   optimized_poses.resize(keyframes.size());
00180   getOptimizedPoses(optimized_poses);
00181 
00182   for (unsigned int kf_idx = 0; kf_idx < keyframes.size(); ++kf_idx)
00183   {
00184     RGBDKeyframe& keyframe = keyframes[kf_idx];
00185     keyframe.pose = optimized_poses[kf_idx];
00186   }
00187 }
00188 
00189 void KeyframeGraphSolverG2O::addVertex(
00190   const AffineTransform& vertex_pose,
00191   int vertex_idx)
00192 {
00193   // TODO: use eigen quaternion, not manual conversion
00194   //Transform Eigen::Matrix4f into 3D traslation and rotation for g2o
00195   double yaw,pitch,roll;
00196   yaw   = atan2f(vertex_pose(1,0),vertex_pose(0,0));
00197   pitch = asinf(-vertex_pose(2,0));
00198   roll  = atan2f(vertex_pose(2,1),vertex_pose(2,2));
00199 
00200   g2o::Vector3d t(vertex_pose(0,3),vertex_pose(1,3),vertex_pose(2,3));
00201   g2o::Quaterniond q;
00202   q.x()=sin(roll/2)*cos(pitch/2)*cos(yaw/2)-cos(roll/2)*sin(pitch/2)*sin(yaw/2);
00203   q.y()=cos(roll/2)*sin(pitch/2)*cos(yaw/2)+sin(roll/2)*cos(pitch/2)*sin(yaw/2);
00204   q.z()=cos(roll/2)*cos(pitch/2)*sin(yaw/2)-sin(roll/2)*sin(pitch/2)*cos(yaw/2);
00205   q.w()=cos(roll/2)*cos(pitch/2)*cos(yaw/2)+sin(roll/2)*sin(pitch/2)*sin(yaw/2);
00206 
00207   g2o::SE3Quat pose(q,t); // vertex pose
00208 
00209   // TODO: smart pointers
00210 
00211   // set up node
00212   g2o::VertexSE3 *vc = new g2o::VertexSE3();
00213   vc->setEstimate(pose);
00214 //  vc->estimate() = pose;
00215   vc->setId(vertex_idx);
00216 
00217   // set first pose fixed
00218   if (vertex_idx == 0)
00219     vc->setFixed(true);
00220 
00221   // add to optimizer
00222   optimizer.addVertex(vc);
00223 }
00224 
00225 void KeyframeGraphSolverG2O::addEdge(
00226   int from_idx,
00227   int to_idx,
00228   const AffineTransform& relative_pose,
00229   const Eigen::Matrix<double,6,6>& information_matrix)
00230 {
00231   // TODO: use eigen quaternion, not manual conversion
00232   //Transform Eigen::Matrix4f into 3D traslation and rotation for g2o
00233   double yaw,pitch,roll;
00234   yaw   = atan2f(relative_pose(1,0),relative_pose(0,0));
00235   pitch = asinf(-relative_pose(2,0));
00236   roll  = atan2f(relative_pose(2,1),relative_pose(2,2));
00237 
00238   g2o::Vector3d t(relative_pose(0,3),relative_pose(1,3),relative_pose(2,3));
00239   g2o::Quaterniond q;
00240   q.x()=sin(roll/2)*cos(pitch/2)*cos(yaw/2)-cos(roll/2)*sin(pitch/2)*sin(yaw/2);
00241   q.y()=cos(roll/2)*sin(pitch/2)*cos(yaw/2)+sin(roll/2)*cos(pitch/2)*sin(yaw/2);
00242   q.z()=cos(roll/2)*cos(pitch/2)*sin(yaw/2)-sin(roll/2)*sin(pitch/2)*cos(yaw/2);
00243   q.w()=cos(roll/2)*cos(pitch/2)*cos(yaw/2)+sin(roll/2)*sin(pitch/2)*sin(yaw/2);
00244 
00245   // relative transformation
00246   g2o::SE3Quat transf(q,t);
00247 
00248   // TODO: smart pointers
00249 
00250   g2o::EdgeSE3* edge = new g2o::EdgeSE3;
00251   edge->vertices()[0] = optimizer.vertex(from_idx);
00252   edge->vertices()[1] = optimizer.vertex(to_idx);
00253   edge->setMeasurement(transf);
00254 
00255   //Set the information matrix
00256   edge->setInformation(information_matrix);
00257 
00258   optimizer.addEdge(edge);
00259 }
00260 
00261 void KeyframeGraphSolverG2O::optimizeGraph()
00262 {
00263   //Prepare and run the optimization
00264   optimizer.initializeOptimization();
00265 
00266   //Set the initial Levenberg-Marquardt lambda
00267 //  optimizer.setUserLambdaInit(0.01);
00268 
00269   //Run optimization
00270   optimizer.optimize(20);
00271 }
00272 
00273 void KeyframeGraphSolverG2O::getOptimizedPoses(AffineTransformVector& poses)
00274 {
00275   for (unsigned int idx = 0; idx < poses.size(); ++idx)
00276   {
00277     //Transform the vertex pose from G2O quaternion to Eigen::Matrix4f
00278     g2o::VertexSE3* vertex = dynamic_cast<g2o::VertexSE3*>(optimizer.vertex(idx));
00279     double optimized_pose_quat[7];
00280     vertex->getEstimateData(optimized_pose_quat);
00281 
00282     AffineTransform optimized_pose;
00283     double qx,qy,qz,qr,qx2,qy2,qz2,qr2;
00284 
00285     qx=optimized_pose_quat[3];
00286     qy=optimized_pose_quat[4];
00287     qz=optimized_pose_quat[5];
00288     qr=optimized_pose_quat[6];
00289     qx2=qx*qx;
00290     qy2=qy*qy;
00291     qz2=qz*qz;
00292     qr2=qr*qr;
00293 
00294     optimized_pose(0,0)=qr2+qx2-qy2-qz2;
00295     optimized_pose(0,1)=2*(qx*qy-qr*qz);
00296     optimized_pose(0,2)=2*(qz*qx+qr*qy);
00297     optimized_pose(0,3)=optimized_pose_quat[0];
00298     optimized_pose(1,0)=2*(qx*qy+qr*qz);
00299     optimized_pose(1,1)=qr2-qx2+qy2-qz2;
00300     optimized_pose(1,2)=2*(qy*qz-qr*qx);
00301     optimized_pose(1,3)=optimized_pose_quat[1];
00302     optimized_pose(2,0)=2*(qz*qx-qr*qy);
00303     optimized_pose(2,1)=2*(qy*qz+qr*qx);
00304     optimized_pose(2,2)=qr2-qx2-qy2+qz2;
00305     optimized_pose(2,3)=optimized_pose_quat[2];
00306 
00307     //Set the optimized pose to the vector of poses
00308     poses[idx] = optimized_pose;
00309   }
00310 }
00311 
00312 } // namespace ccny_rgbd
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends


lib_rgbdtools
Author(s): Ivan Dryanovski
autogenerated on Tue Aug 27 2013 10:33:54