keyframe_graph_solver_isam.cpp
Go to the documentation of this file.
00001 
00024 #include "isam/isam.h"
00025 #include "rgbdtools/graph/keyframe_graph_solver_isam.h"
00026 #include "rgbdtools/map_util.h"
00027 #include "rgbdtools/rgbd_util.h"
00028 #include "Eigen/Geometry"
00029 
00030 namespace rgbdtools {
00031 
00032 KeyframeGraphSolverISAM::KeyframeGraphSolverISAM()
00033 {
00034 //    isam::Properties prop;
00035 //    prop.method = isam::DOG_LEG;
00036 //    slam.set_properties(prop);
00037     n_original_poses = 0;
00038 
00039 }
00040 
00041 KeyframeGraphSolverISAM::~KeyframeGraphSolverISAM()
00042 {
00043 
00044 }
00045 void KeyframeGraphSolverISAM::giveMarkers( std::vector<aruco::Marker> markers)
00046 {
00047     markers_ = markers;
00048 }
00049 
00050 void KeyframeGraphSolverISAM::save_graph(std::string filepath)
00051 {
00052     slam.save(filepath+"/out.graph");
00053     save_landmarks(filepath);
00054 }
00055 
00056 void KeyframeGraphSolverISAM::save_landmarks(std::string filepath)
00057 {
00058     std::ofstream ldmrk_file;
00059     ldmrk_file.open ((filepath+"/out.lnd").c_str());
00060     if(!ldmrk_file.is_open())
00061     {
00062         std::cout << "Landmark file wasnt saved." << std::endl;
00063         return;
00064     }
00065     ldmrk_file << "# Keyframe Match Landmark" << std::endl;
00066     for(std::map<Observation,isam::Point3d_Node*>::iterator it = landmarks.begin(); it != landmarks.end(); ++it)
00067     {
00068         ldmrk_file << it->first.first << " " << it->first.second << " " << it->second->unique_id() << std::endl;
00069     }
00070     ldmrk_file.close();
00071     return;
00072 }
00073 void KeyframeGraphSolverISAM::load_landmarks(std::string filepath)
00074 {
00075     FILE* file = fopen(filepath.c_str(), "r");
00076     if(file == NULL)
00077     {
00078         std::cout << "Landmark file wasnt read." << std::endl;
00079         return;
00080     }
00081 
00082     while (!feof(file)) {
00083        char str[2000];
00084        if (fgets(str, 2000, file)) {
00085            if(str[0] == '#') //commnent
00086                continue;
00087            int kf,match,land;
00088            int res = 0;
00089            res = sscanf(str, "%i %i %i",&kf,&match,&land);
00090            if(res != 3)
00091            {
00092                std::cout << "Syntax error in landmark file" << std::endl;
00093                continue;
00094            }
00095            Observation o;
00096            o.first = kf;
00097            o.second = match;
00098            landmarks[o] = landmarks_explicit[land-poses.size()];
00099        }
00100      }
00101     return;
00102 }
00103 
00104 Pose tfFromMeans(const Eigen::Vector3f& t)
00105 {
00106     Pose pose = Eigen::Affine3f(Eigen::Translation3f(t));
00107     return pose;
00108 }
00109 Eigen::Matrix<double,3,1> XYZfromPose(const Pose& t)
00110 {
00111     Eigen::Matrix<double,3,1> pos;
00112     pos[0]=t(0,3);
00113     pos[1]=t(1,3);
00114     pos[2]=t(2,3);
00115     return pos;
00116 }
00117 
00118 
00119 
00120 void KeyframeGraphSolverISAM::add_edge(isam::Pose3d_Node* from, isam::Pose3d_Node* to, const AffineTransform& pose, isam::Noise noise)
00121 {
00122     // TODO: use eigen quaternion, not manual conversion
00123     //Transform Eigen::Matrix4f into 3D traslation and rotation for g2o
00124     Eigen::Matrix4d pose_ = m4dfromPose(pose);
00125     isam::Pose3d transf(pose_);
00126     isam::Pose3d_Pose3d_Factor *edge = new isam::Pose3d_Pose3d_Factor(from,to,transf,noise);
00127     slam.add_factor(edge);
00128     vodom.push_back(edge);
00129 }
00130 void KeyframeGraphSolverISAM::add_edges(u_int kf_idx,KeyframeVector& keyframes,
00131                                         const KeyframeAssociationVector& associations)
00132 {
00133     isam::Noise inf_pose = isam::SqrtInformation(1*isam::eye(6));
00134     isam::Noise inf_ransac = isam::SqrtInformation(60*isam::eye(6));
00135 
00136     bool hit = false;
00137     add_pose(keyframes[kf_idx].pose,inf_pose);
00138     valid_poses.resize(keyframes.size());
00139     for(int  i = associations.size()-1; i>=0; i--)
00140     {
00141         KeyframeAssociation association = associations[i];
00142         if(association.kf_idx_a != kf_idx && association.kf_idx_b != kf_idx)
00143         {
00144             break;
00145         }
00146         hit = true;
00147         add_edge(poses[association.kf_idx_a],poses[association.kf_idx_b],association.a2b,inf_ransac);
00148     }
00149     if(hit)
00150         valid_poses[kf_idx] = true;
00151     else
00152         valid_poses[kf_idx] = false;
00153     int old_size=valid_markers.size();
00154     valid_markers.resize(valid_markers.size()+markers_.size());
00155     for(u_int i = 0; i < markers_.size(); i++)
00156     {
00157         if(hit)
00158             valid_markers[old_size+i]=true;
00159         else
00160             valid_markers[old_size+i]=false;
00161         const aruco::Marker marker = markers_[i];
00162         isam::Noise info = isam::SqrtInformation(6*isam::eye(3));
00163         marker_kf.push_back(kf_idx);
00164         add_aruco(marker,poses[kf_idx],info);
00165 //        isam::Point3d measure1(marker.Tvec.ptr<float>(0)[0],marker.Tvec.ptr<float>(0)[1],marker.Tvec.ptr<float>(0)[2]);
00166 //        RGBDFrame keyframe = keyframes[kf_idx];
00167 //        aruco::Marker m=marker;
00168 //        std::vector<std::vector<float> > points;
00169 //        std::vector<float> point;
00170 //        point.push_back(m[0].x);
00171 //        point.push_back(m[0].y);
00172 //        points.push_back(point);
00173 //        point.clear();
00174 //        point.push_back(m[1].x);
00175 //        point.push_back(m[1].y);
00176 //        points.push_back(point);
00177 //        point.clear();
00178 //        point.push_back(m[2].x);
00179 //        point.push_back(m[2].y);
00180 //        points.push_back(point);
00181 //        point.clear();
00182 //        point.push_back(m[3].x);
00183 //        point.push_back(m[3].y);
00184 //        points.push_back(point);
00185 //        std::vector<std::vector<double> > dists;
00186 //        keyframe.getPointsDist(points,&dists);
00187 //        std::cout << " " <<std::endl;
00188 //        std::vector<double> mean;
00189 //        mean.push_back(0.0);
00190 //        mean.push_back(0.0);
00191 //        mean.push_back(0.0);
00192 //        for (u_int k = 0; k < dists.size(); k++)
00193 //        {
00194 //            mean[0]+=(dists[k][0]);
00195 //            mean[1]+=(dists[k][1]);
00196 //            mean[2]+=(dists[k][2]);
00197 //        }
00198 //        mean[0]/=dists.size();
00199 //        mean[1]/=dists.size();
00200 //        mean[2]/=dists.size();
00201 //        std::cout << measure1 << std::endl;
00202 //        std::cout << mean[0] << " " << mean[1] << " "<< mean[2] << std::endl;
00203     }
00204 }
00205 void KeyframeGraphSolverISAM::add_edge(isam::Pose3d_Node* from, isam::Pose3d_Node* to,double x, double y, double z, double roll, double pitch, double yaw, isam::Noise noise)
00206 {
00207 
00208     isam::Rot3d r(yaw,pitch,roll);
00209     isam::Point3d p(x,y,z);
00210     isam::Pose3d transf(p,r);
00211     isam::Pose3d_Pose3d_Factor *edge = new isam::Pose3d_Pose3d_Factor(from,to,transf,noise);
00212     slam.add_factor(edge);
00213     vodom.push_back(edge);
00214 }
00215 std::vector<std::string> factors;
00216 std::vector<std::string> nodes;
00217 void KeyframeGraphSolverISAM::parse_nodes()
00218 {
00219     for (u_int i = 0; i< nodes.size() ; i++)
00220     {
00221         char str[2000];
00222         strcpy(str,nodes[i].c_str());
00223         char keyword_c[2000];
00224         int key_length;
00225         sscanf(str, "%s%n", keyword_c, &key_length);
00226         const char* arguments = &str[key_length];
00227         std::string keyword(keyword_c);
00228 
00229         if (keyword == "Pose3d_Node"  )
00230         {
00231             int idx;
00232             double x,y,z,roll,pitch,yaw;
00233             int res = sscanf(arguments, "%i (%lg, %lg, %lg; %lg, %lg, %lg)",
00234                              &idx, &x, &y, &z, &yaw, &pitch,&roll);
00235             isam::Noise inf = isam::SqrtInformation(100*isam::eye(6));
00236             add_pose(x,y,z,roll,pitch,yaw,inf);
00237         }
00238         else
00239         {
00240             std::cout << "Error: I shouldnt find a " << keyword << " here." << std::endl;
00241         }
00242 
00243     }
00244 }
00245 
00246 void KeyframeGraphSolverISAM::parse_factors()
00247 {
00248     for (u_int i = 0; i< factors.size() ; i++)
00249     {
00250         char str[2000];
00251         strcpy(str,factors[i].c_str());
00252         char keyword_c[2000];
00253         int key_length;
00254         sscanf(str, "%s%n", keyword_c, &key_length);
00255         const char* arguments = &str[key_length];
00256         std::string keyword(keyword_c);
00257 //        if (keyword == "Pose3d_Factor"  )
00258 //        {
00259 //            continue;
00260 //            int idx;
00261 //            double x,y,z,roll,pitch,yaw,i11,i12,i13,i14,i15,i16,i22,i23,i24,i25,i26,i33, i34, i35, i36, i44, i45, i46, i55, i56, i66;
00262 //            int res = sscanf(arguments, "%i (%lg, %lg, %lg; %lg, %lg, %lg) {%lg,%lg,%lg,%lg,%lg,%lg,%lg,%lg,%lg,%lg,%lg,%lg,%lg,%lg,%lg,%lg,%lg,%lg,%lg,%lg,%lg}",
00263 //                             &idx, &x, &y, &z, &yaw, &pitch,&roll,
00264 //                             &i11, &i12, &i13, &i14, &i15, &i16, &i22, &i23, &i24, &i25, &i26,
00265 //                             &i33, &i34, &i35, &i36, &i44, &i45, &i46, &i55, &i56, &i66);
00266 //            if(res != 28)
00267 //            {
00268 //                std::cout << "Error on input graph file: ->" << std::endl << str << std::endl;
00269 //                continue;
00270 //            }
00271 //            Eigen::MatrixXd sqrtinf(6,6);
00272 //            sqrtinf <<
00273 //                       i11, i12, i13, i14, i15, i16,
00274 //                    0., i22, i23, i24, i25, i26,
00275 //                    0.,  0., i33, i34, i35, i36,
00276 //                    0.,  0.,  0., i44, i45, i46,
00277 //                    0.,  0.,  0.,  0., i55, i56,
00278 //                    0.,  0.,  0.,  0.,  0., i66;
00279 
00280 //            isam::Noise inf = isam::SqrtInformation (sqrtinf);
00281 //            add_prior(poses[idx],x,y,z,roll,pitch,yaw,inf);
00282 //            continue;
00283 //        }
00284         if(keyword == "Pose3d_Pose3d_Factor" )
00285         {
00286             int idx_0,idx_1;
00287             double x,y,z,roll,pitch,yaw,i11,i12,i13,i14,i15,i16,i22,i23,i24,i25,i26,i33, i34, i35, i36, i44, i45, i46, i55, i56, i66;
00288             int res = sscanf(arguments, "%i %i (%lg, %lg, %lg; %lg, %lg, %lg) {%lg,%lg,%lg,%lg,%lg,%lg,%lg,%lg,%lg,%lg,%lg,%lg,%lg,%lg,%lg,%lg,%lg,%lg,%lg,%lg,%lg}",
00289                              &idx_0,&idx_1, &x, &y, &z ,&yaw, &pitch, &roll,
00290                              &i11, &i12, &i13, &i14, &i15, &i16, &i22, &i23, &i24, &i25, &i26,
00291                              &i33, &i34, &i35, &i36, &i44, &i45, &i46, &i55, &i56, &i66);
00292             if(res != 29)
00293             {
00294                 std::cout << "Error on input graph file: ->" << std::endl << str << std::endl;
00295                 continue;
00296             }
00297             Eigen::MatrixXd sqrtinf(6,6);
00298             sqrtinf <<
00299                        i11, i12, i13, i14, i15, i16,
00300                     0., i22, i23, i24, i25, i26,
00301                     0.,  0., i33, i34, i35, i36,
00302                     0.,  0.,  0., i44, i45, i46,
00303                     0.,  0.,  0.,  0., i55, i56,
00304                     0.,  0.,  0.,  0.,  0., i66;
00305 
00306             isam::Noise inf = isam::SqrtInformation (sqrtinf);
00307             add_edge(poses[idx_0],poses[idx_1],x,y,z,roll,pitch,yaw,inf);
00308             continue;
00309         }
00310 //        if(keyword == "Pose3d_Point3d_Factor" )
00311 //        {
00312 //            int idx_0,idx_1;
00313 //            double x,y,z,i11,i12,i13,i22,i23,i33;
00314 //            int res = sscanf(arguments, "%i %i (%lg, %lg, %lg) {%lg,%lg,%lg,%lg,%lg,%lg}",
00315 //                             &idx_0,&idx_1, &x, &y, &z,
00316 //                             &i11, &i12, &i13,
00317 //                             &i22, &i23,
00318 //                             &i33);
00319 //            if(res != 11)
00320 //            {
00321 //                std::cout << "Error on input graph file: ->" << std::endl << str << std::endl;
00322 //                continue;
00323 //            }
00324 //            Eigen::MatrixXd sqrtinf(3,3);
00325 //            sqrtinf <<
00326 //                       i11, i12, i13,
00327 //                    0., i22, i23,
00328 //                    0.,  0., i33;
00329 
00330 
00331 //            isam::Noise inf = isam::SqrtInformation (sqrtinf);
00332 
00333 //            add_landmark_from_file(idx_0,idx_1-poses.size(),x,y,z,inf);
00334 //            continue;
00335 //        }
00336     }
00337 }
00338 
00339 int counter = 0;
00340 void KeyframeGraphSolverISAM::parse_line(char* str)
00341 {
00342 
00343     char keyword_c[2000];
00344     sscanf(str, "%s", keyword_c);
00345     std::string keyword(keyword_c);
00346     if (keyword == "Pose3d_Factor" || keyword == "Pose3d_Point3d_Factor" || keyword == "Pose3d_Pose3d_Factor" )
00347     {
00348         std::string k(str);
00349         factors.push_back(k);
00350         return;
00351     }
00352     if(keyword == "Pose3d_Node" )
00353     {
00354         std::string k(str);
00355         nodes.push_back(k);
00356         return;
00357     }
00358     if(keyword == "Point3d_Node")
00359     {
00360 //        isam::Point3d_Node* node = new isam::Point3d_Node;
00361 //        slam.add_node(node);
00362 //        landmarks_explicit.push_back(node);
00363 //        counter++;
00364         return;
00365     }
00366     std::cout << str << std::endl;
00367 }
00368 
00369 void KeyframeGraphSolverISAM::parse (std::string fname, KeyframeVector keyframes)
00370 {
00371     FILE* file = fopen((fname+"/out.graph").c_str(), "r");
00372     if(file == NULL)
00373         return;
00374     while (!feof(file)) {
00375        char str[2000];
00376        if (fgets(str, 2000, file)) {
00377          parse_line(str);
00378        }
00379      }
00380      fclose(file);
00381      parse_nodes();
00382 //     for (u_int i = 0; i< counter ; i++)
00383 //     {
00384 //         isam::Point3d_Node* node = new isam::Point3d_Node;
00385 //         slam.add_node(node);
00386 //         landmarks_explicit.push_back(node);
00387 //     }
00388      parse_factors();
00389      //we still need to load landmark observations
00390 //     load_landmarks(fname+"/out.lnd");
00391 //     save_graph(fname+"/teste");
00392      std::cout << "Solving Graph" << std::endl;
00393      optimizeGraph();
00394      AffineTransformVector optimized_poses;
00395      optimized_poses.resize(keyframes.size());
00396 
00397      getOptimizedPoses(optimized_poses);
00398      valid_poses.resize(keyframes.size());
00399      for (unsigned int kf_idx = 0; kf_idx < keyframes.size(); ++kf_idx)
00400      {
00401          valid_poses[kf_idx] = true;
00402          RGBDKeyframe& keyframe = keyframes[kf_idx];
00403          keyframe.pose = optimized_poses[kf_idx];
00404          keyframe.used = true;
00405      }
00406      n_original_poses = keyframes.size();
00407 }
00408 
00409 
00410 
00411 void KeyframeGraphSolverISAM::add_pose(Pose pose,isam::Noise noise)
00412 {
00413 
00414     isam::Pose3d_Node* pose_node = new isam::Pose3d_Node();
00415     slam.add_node(pose_node);
00416     poses.push_back(pose_node);
00417 
00418     Eigen::Matrix4d pose_ = m4dfromPose(pose);
00419 
00420     isam::Pose3d vo(pose_);
00421     isam::Factor* prior;
00422 
00423     prior = new isam::Pose3d_Factor(pose_node,vo,noise);
00424     slam.add_factor(prior);
00425     priors.push_back(prior);
00426 
00427 }
00428 void KeyframeGraphSolverISAM::add_pose(double x, double y, double z, double roll, double pitch, double yaw,isam::Noise noise)
00429 {
00430 
00431     isam::Pose3d_Node* pose_node = new isam::Pose3d_Node();
00432     slam.add_node(pose_node);
00433     poses.push_back(pose_node);
00434     isam::Point3d p(x,y,z);
00435     isam::Rot3d r(yaw,pitch,roll);
00436     isam::Pose3d vo(p,r);
00437     isam::Factor* prior;
00438 
00439     prior = new isam::Pose3d_Factor(pose_node,vo,noise);
00440 
00441     slam.add_factor(prior);
00442     priors.push_back(prior);
00443 
00444 }
00445 void KeyframeGraphSolverISAM::add_prior(isam::Pose3d_Node* pose_node, double x, double y, double z, double roll, double pitch, double yaw,isam::Noise noise)
00446 {
00447 
00448     isam::Point3d p(x,y,z);
00449     isam::Rot3d r(yaw,pitch,roll);
00450     isam::Pose3d vo(p,r);
00451     isam::Factor* prior;
00452 
00453     prior = new isam::Pose3d_Factor(pose_node,vo,noise);
00454 
00455     slam.add_factor(prior);
00456     priors.push_back(prior);
00457 
00458 }
00459 void KeyframeGraphSolverISAM::add_landmark_from_file(int from_idx,int to_idx,double x, double y, double z,isam::Noise noise3)
00460 {
00461     // this is only from file because we dont load landmark_observations here
00462     isam::Point3d measure1(x,y,z);
00463     isam::Point3d c_landmark1(measure1);
00464     isam::Pose3d_Point3d_Factor* factor1 = new isam::Pose3d_Point3d_Factor(poses[from_idx],landmarks_explicit[to_idx],c_landmark1,noise3);
00465     landmark_observations.push_back(factor1);
00466     slam.add_factor(factor1);
00467 }
00468 
00469 void KeyframeGraphSolverISAM::add_landmark(KeyframeVector& keyframes,KeyframeAssociation association, int from_idx,int to_idx,int j, isam::Noise noise3)
00470 {
00471     const RGBDKeyframe keyframe1 = keyframes[from_idx];
00472     const RGBDKeyframe keyframe2 = keyframes[to_idx];
00473     const cv::DMatch match = association.matches[j];
00474     Observation land1, land2;
00475     land1.first = from_idx;
00476     land2.first = to_idx;
00477     land1.second = match.trainIdx; // these ones are switched on purpose (because on graph detector it a = train, b = query)
00478     land2.second = match.queryIdx; // these ones are switched on purpose (because on graph detector it a = train, b = query)
00479 
00480     assert(keyframe1.kp_valid[land1.second] == true && keyframe2.kp_valid[land2.second] == true);
00481 
00482     //we have to check if it exists already
00483     if(landmarks.find(land1)==landmarks.end() && landmarks.find(land2)==landmarks.end())//not added yet
00484     {
00485         isam::Point3d_Node* landmark = new isam::Point3d_Node();
00486         slam.add_node(landmark);
00487         landmarks_explicit.push_back(landmark);
00488         landmarks[land1] = landmark;
00489         landmarks[land2] = landmark;
00490 
00491     }
00492     else if (landmarks.find(land1)!=landmarks.end() && landmarks.find(land2)==landmarks.end())//seen in keyframe1
00493     {
00494         landmarks[land2] = landmarks[land1];
00495     }
00496     else if(landmarks.find(land1)==landmarks.end() && landmarks.find(land2)!=landmarks.end()) //seen in keyframe2
00497     {
00498         landmarks[land1] = landmarks[land2];
00499     }
00500     isam::Point3d measure1(keyframe1.kp_means[land1.second][0],keyframe1.kp_means[land1.second][1],keyframe1.kp_means[land1.second][2]);
00501     isam::Point3d c_landmark1(measure1);
00502     isam::Pose3d_Point3d_Factor* factor1 = new isam::Pose3d_Point3d_Factor(poses[land1.first],landmarks[land1],c_landmark1,noise3);
00503     slam.add_factor(factor1);
00504     landmark_observations.push_back(factor1);
00505     isam::Point3d measure2(keyframe2.kp_means[land2.second][0],keyframe2.kp_means[land2.second][1],keyframe2.kp_means[land2.second][2]);
00506     isam::Point3d c_landmark2(measure2);
00507     isam::Pose3d_Point3d_Factor* factor2 = new isam::Pose3d_Point3d_Factor(poses[land2.first],landmarks[land2],c_landmark2,noise3);
00508     slam.add_factor(factor2);
00509     landmark_observations.push_back(factor2);
00510 }
00511 
00512 void KeyframeGraphSolverISAM::add_aruco(aruco::Marker marker, isam::Pose3d_Node* from, isam::Noise noise3)
00513 {
00514     isam::Point3d_Node* aruco = new isam::Point3d_Node();
00515     slam.add_node(aruco);
00516     marker_poses.push_back(aruco);
00517     isam::Point3d measure1(marker.Tvec.ptr<float>(0)[0],marker.Tvec.ptr<float>(0)[1],marker.Tvec.ptr<float>(0)[2]);
00518     isam::Point3d aruco_measure(measure1);
00519     isam::Pose3d_Point3d_Factor* factor = new isam::Pose3d_Point3d_Factor(from,aruco,aruco_measure,noise3);
00520     slam.add_factor(factor);
00521     marker_observations.push_back(factor);
00522 }
00523 
00524 void KeyframeGraphSolverISAM::solve(
00525         KeyframeVector& keyframes,
00526         const KeyframeAssociationVector& associations)
00527 {
00528     isam::Noise noise3 = isam::Information(1. * isam::eye(3));
00529     isam::Noise noise6 = isam::Information(10. * isam::eye(6));
00530     bool train = false;
00531 
00532     if(keyframes.size() > 0 && train == true)
00533     {
00534         train = false;
00535         std::cout << "Can't use training data because there are already keyframes loaded" << std::endl;
00536     }
00537     KeyframeAssociationVector local_associations = associations;
00538 
00539     //Sample data
00540     if(train)
00541     {
00542         RGBDKeyframe sample;
00543         sample.pose = AffineFromTRPY(0,0,0,0,0,0);
00544 
00545         sample.kp_valid.push_back(true);
00546         sample.kp_valid.push_back(true);
00547         sample.kp_valid.push_back(true);
00548         sample.kp_means.push_back(Eigen::Vector3f(1,0,0));
00549         sample.kp_means.push_back(Eigen::Vector3f(0,1,0));
00550         sample.kp_means.push_back(Eigen::Vector3f(0,0,1));
00551         RGBDKeyframe sample2;
00552         sample2.pose = AffineFromTRPY(1,1,1,0,0,M_PI/2);
00553         sample2.kp_valid.push_back(true);
00554         sample2.kp_valid.push_back(true);
00555         sample2.kp_valid.push_back(true);
00556         sample2.kp_means.push_back(sample.pose*sample2.pose.inverse()*sample.kp_means[0]);
00557         sample2.kp_means.push_back(sample.pose*sample2.pose.inverse()*sample.kp_means[1]);
00558         sample2.kp_means.push_back(sample.pose*sample2.pose.inverse()*sample.kp_means[2]);
00559         keyframes.push_back(sample);
00560         keyframes.push_back(sample2);
00561         KeyframeAssociation a;
00562         a.a2b = sample.pose.inverse()*sample2.pose;
00563         a.kf_idx_a=0;
00564         a.kf_idx_b=1;
00565         cv::DMatch b0;
00566         b0.distance =0;
00567         b0.imgIdx = 0;
00568         b0.queryIdx = 0;
00569         b0.trainIdx = 0;
00570         cv::DMatch c0;
00571         c0.distance =0;
00572         c0.imgIdx = 0;
00573         c0.queryIdx = 1;
00574         c0.trainIdx = 1;
00575         cv::DMatch d0;
00576         d0.distance =0;
00577         d0.imgIdx = 0;
00578         d0.queryIdx = 2;
00579         d0.trainIdx = 2;
00580         a.matches.push_back(b0);
00581         a.matches.push_back(c0);
00582         a.matches.push_back(d0);
00583         local_associations.push_back(a);
00584     }
00585 
00586     if (!train)
00587         local_associations = associations;
00588     // add vertices
00589     n_original_poses = keyframes.size();
00590     std::cout << "Adding vertices..." << std::flush;
00591     for (unsigned int kf_idx = 0; kf_idx < keyframes.size(); ++kf_idx)
00592     {
00593         Pose pose = keyframes[kf_idx].pose;
00594         if (kf_idx == 0)
00595         {
00596             isam::Noise noise_prior = isam::Information(99999. * isam::eye(6));
00597             add_pose(pose,noise_prior);
00598 
00599         }
00600         else
00601         {
00602             add_pose(pose,noise6);
00603         }
00604     }
00605     std::cout << " done." << std::endl;
00606 
00607     // add visual odometry
00608     std::cout << "Adding Visual Odometry..." << std::flush;
00609     for (unsigned int kf_idx = 0; kf_idx < keyframes.size(); ++kf_idx)
00610     {
00611         Pose pose;
00612         if (kf_idx != 0)
00613         {
00614             pose = keyframes[kf_idx-1].pose.inverse()*keyframes[kf_idx].pose;
00615             add_edge(poses[kf_idx-1],poses[kf_idx],pose,noise6);
00616 
00617         }
00618     }
00619     std::cout << " done." << std::endl;
00620     std::cout << "Adding RANSAC vertices..." << std::flush;
00621 
00622     for (unsigned int as_idx = 0; as_idx < local_associations.size(); ++as_idx)
00623     {
00624         const KeyframeAssociation& association = local_associations[as_idx];
00625         if (!(association.type == KeyframeAssociation::RANSAC))
00626             continue;
00627         int from_idx = association.kf_idx_a;
00628         int to_idx   = association.kf_idx_b;
00629 
00630         add_edge(poses[from_idx], poses[to_idx], association.a2b, noise6);
00631     }
00632 
00633 
00634     std::cout << " done." << std::endl;
00635 
00636     std::cout << "Adding Landmark Observations...     " << std::flush;
00637 
00638     for (size_t i = 0; i < local_associations.size(); ++i) {
00639         //        std::cout << '\b'<<'\b'<<'\b'<<'\b' << std::flush;
00640         //        std::cout << boost::format("%.2f") % ((float)(i)/local_associations.size()) << std::flush;
00641         const KeyframeAssociation& association = local_associations[i];
00642         bool cont = false;
00643         int from_idx = association.kf_idx_a;
00644         int to_idx   = association.kf_idx_b;
00645         if (association.type == KeyframeAssociation::RANSAC && association.matches.size() < 30) //we already have a good estimate with ransac
00646             cont = true;
00647         if (association.type == KeyframeAssociation::LANDMARKS || cont)
00648             for (u_int j = 0; j < association.matches.size(); j++)
00649             {
00650                 add_landmark(keyframes,association,from_idx,to_idx,j,noise3);
00651             }
00652     }
00653     std::cout << " done." << std::endl;
00654 
00655 //    std::cout << "Searching for ArUco markers..." << std::endl;
00656 //    assert(markers_.size() == keyframes.size());
00657 //    for(u_int i = 0; i< markers_.size(); i++)
00658 //    {
00659 //        const std::vector<aruco::Marker> marker_vec;
00660 //        for (u_int j = 0; j < marker_vec.size(); j++)
00661 //        {
00662 //            add_aruco(marker_vec[j],i,noise3);
00663 //        }
00664 //    }
00665 
00666     std::cout << "Graph has " << slam.num_nodes() << " nodes and " << slam.num_factors() << " factors." << std::endl;
00667 
00668     slam.save("~/before.txt");
00669     // run the optimization
00670     printf("Optimizing...\n");
00671     optimizeGraph();
00672 
00673     // update the keyframe poses
00674     printf("Updating keyframe poses...\n");
00675 
00676     AffineTransformVector optimized_poses;
00677     optimized_poses.resize(keyframes.size());
00678     getOptimizedPoses(optimized_poses);
00679     slam.save("~/after.txt");
00680     for (unsigned int kf_idx = 0; kf_idx < keyframes.size(); ++kf_idx)
00681     {
00682         RGBDKeyframe& keyframe = keyframes[kf_idx];
00683         keyframe.pose = optimized_poses[kf_idx];
00684     }
00685     PointCloudT c;
00686     concatenate_clouds(c,keyframes);
00687 }
00688 
00689 void KeyframeGraphSolverISAM::solve(
00690         KeyframeVector& keyframes,
00691         const KeyframeAssociationVector& associations,
00692         AffineTransformVector& path)
00693 {
00694     return;
00695 }
00696 void KeyframeGraphSolverISAM::solve_Iterative(
00697         KeyframeVector& keyframes)
00698 {
00699     slam.update();
00700     AffineTransformVector optimized_poses;
00701     optimized_poses.resize(keyframes.size());
00702 
00703     getOptimizedPoses(optimized_poses);
00704     for (unsigned int kf_idx = n_original_poses; kf_idx < keyframes.size(); ++kf_idx)
00705     {
00706         RGBDKeyframe& keyframe = keyframes[kf_idx];
00707         keyframe.pose = optimized_poses[kf_idx];
00708         isam::Pose3d_Node* pose = poses[kf_idx];
00709         bool hit = false;
00710 
00711         for (std::list<isam::Factor*>::const_iterator it=pose->factors().begin(); it != pose->factors().end(); ++it)
00712         {
00713             if(dynamic_cast<isam::Pose3d_Pose3d_Factor*>(*it) == *it)
00714                 hit = true;
00715         }
00716         if(hit) //robustness
00717             keyframe.used = true;
00718     }
00719 //    for (u_int i = 0; i<marker_poses.size(); i++)
00720 //    {
00721 //        if(!valid_markers[i])
00722 //            continue;
00723 //        const isam::Point3d_Node* pose = marker_poses[i];
00724 //        std::cout << pose->value().x() << " " <<pose->value().y() << " " << pose->value().z() << std::endl;
00725 //    }
00726 
00727 }
00728 void KeyframeGraphSolverISAM::solve_rgb_Iterative(
00729         KeyframeVector& keyframes)
00730 {
00731     slam.update();
00732     AffineTransformVector optimized_poses;
00733     optimized_poses.resize(keyframes.size());
00734 
00735     getOptimizedPoses(optimized_poses);
00736     for (unsigned int kf_idx = n_original_poses; kf_idx < keyframes.size(); ++kf_idx)
00737     {
00738         RGBDKeyframe& keyframe = keyframes[kf_idx];
00739         keyframe.pose = optimized_poses[kf_idx];
00740         isam::Pose3d_Node* pose = poses[kf_idx];
00741         if(pose->factors().size() > 1)
00742             keyframe.used = true;
00743     }
00744 
00745 }
00746 void KeyframeGraphSolverISAM::getArucoPos(std::vector<std::vector<double> >* positions,std::vector<int> *marker_kfs,KeyframeVector& keyframes)
00747 {
00748 
00749     positions->clear();
00750     for (u_int i = 0; i<marker_poses.size(); i++)
00751     {
00752         if(!valid_markers[i])
00753             continue;
00754         isam::Point3d_Node* pose = marker_poses[i];
00755         std::vector<double> values;
00756         values.push_back(pose->value().x());
00757         values.push_back(pose->value().y());
00758         values.push_back(pose->value().z());
00759         positions->push_back(values);
00760     }
00761     for(u_int i = 0; i< marker_kf.size(); i++)
00762     {
00763         marker_kfs->push_back(marker_kf[i]);
00764     }
00765 }
00766 
00767 void KeyframeGraphSolverISAM::optimizeGraph()
00768 {
00769     //  //Prepare and run the optimization
00770     slam.batch_optimization();
00771 }
00772 
00773 void KeyframeGraphSolverISAM::getOptimizedPoses(AffineTransformVector& poses_)
00774 {
00775     for (unsigned int idx = 0; idx < poses_.size(); ++idx)
00776     {
00777         isam::Pose3d_Node* pose = poses[idx];
00778         Pose optimized_pose = AffineFromTRPY(pose->value().x(),pose->value().y(),pose->value().z(),pose->value().roll(),pose->value().pitch(),pose->value().yaw());
00779         //    //Set the optimized pose to the vector of poses
00780 
00781         poses_[idx] = optimized_pose;
00782     }
00783 }
00784 
00785 } // namespace ccny_rgbd
00786 
 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