SRBA: Sparser Relative Bundle Adjustment
|
00001 /* +---------------------------------------------------------------------------+ 00002 | Mobile Robot Programming Toolkit (MRPT) | 00003 | http://www.mrpt.org/ | 00004 | | 00005 | Copyright (c) 2005-2015, Individual contributors, see AUTHORS file | 00006 | See: http://www.mrpt.org/Authors - All rights reserved. | 00007 | Released under BSD License. See details in http://www.mrpt.org/License | 00008 +---------------------------------------------------------------------------+ */ 00009 00010 #pragma once 00011 00012 namespace srba { 00013 00014 // The main entry point of SRBA. See .h and papers for docs. 00015 template <class KF2KF_POSE_TYPE,class LM_TYPE,class OBS_TYPE,class RBA_OPTIONS> 00016 void RbaEngine<KF2KF_POSE_TYPE,LM_TYPE,OBS_TYPE,RBA_OPTIONS>::define_new_keyframe( 00017 const typename traits_t::new_kf_observations_t & obs, 00018 TNewKeyFrameInfo & out_new_kf_info, 00019 const bool run_local_optimization ) 00020 { 00021 m_profiler.enter("define_new_keyframe"); 00022 00023 out_new_kf_info.clear(); 00024 00025 // Update KFs data structures ; O(1) 00026 // ------------------------------------ 00027 const TKeyFrameID new_kf_id = alloc_keyframe(); 00028 00029 // Apply edge-creation policy to decide how to handle loop closures, etc. 00030 // ----------------------------------------------------------------------------- 00031 // ==== Determine what edges to create: O(...) (See papers) ==== 00032 m_profiler.enter("define_new_keyframe.determine_edges"); 00033 00034 // Keep a list of the new kf2kf edges, whose initial values are indeterminate: 00035 std::vector<TNewEdgeInfo> new_k2k_edge_ids; 00036 determine_kf2kf_edges_to_create(new_kf_id,obs, new_k2k_edge_ids); // ***** here's the beef! ***** 00037 00038 m_profiler.leave("define_new_keyframe.determine_edges"); 00039 00040 // Expand symbolic Jacobians to accomodate new observations: O( No * (P+log C) ) 00041 // ----------------------------------------------------------------------------------- 00042 m_profiler.enter("define_new_keyframe.add_observations"); 00043 00044 for (typename new_kf_observations_t::const_iterator it_obs = obs.begin();it_obs != obs.end();++it_obs) 00045 { 00046 const typename landmark_traits_t::array_landmark_t *fixed_rel_pos = it_obs->is_fixed ? &it_obs->feat_rel_pos : NULL; 00047 const typename landmark_traits_t::array_landmark_t *unk_rel_pos_initval = it_obs->is_unknown_with_init_val ? &it_obs->feat_rel_pos : NULL; 00048 00049 this->add_observation( new_kf_id, it_obs->obs, fixed_rel_pos, unk_rel_pos_initval ); 00050 } 00051 00052 m_profiler.leave("define_new_keyframe.add_observations"); 00053 00054 // Update SLAM estimation: 00055 // ----------------------------------------------------------------------------- 00056 if (run_local_optimization) 00057 { 00058 // Try to initialize the new edges in separate optimizations? 00059 if (parameters.srba.optimize_new_edges_alone) 00060 { 00061 // Do it one by one so we can detect rank-deficient situations, etc. 00062 if (!new_k2k_edge_ids.empty()) 00063 { 00064 m_profiler.enter("define_new_keyframe.opt_new_edges"); 00065 00066 // temporarily disable robust kernel for initialization (faster) 00067 const bool old_kernel = parameters.srba.use_robust_kernel; 00068 parameters.srba.use_robust_kernel= parameters.srba.use_robust_kernel_stage1; 00069 00070 std::vector<size_t> k2f_edges_to_opt; // Empty: only initialize k2k edges. 00071 std::vector<size_t> k2k_edges_to_opt(1); 00072 00073 for (size_t i=0;i<new_k2k_edge_ids.size();i++) 00074 { 00075 if (new_k2k_edge_ids[i].has_approx_init_val) 00076 continue; // Already initialized, can skip it. 00077 k2k_edges_to_opt[0] = new_k2k_edge_ids[i].id ; 00078 00079 //TOptimizeExtraOutputInfo init_opt_info; 00080 this->optimize_edges( 00081 k2k_edges_to_opt, 00082 k2f_edges_to_opt, 00083 out_new_kf_info.optimize_results_stg1 /*init_opt_info*/ 00084 ); 00085 } 00086 00087 parameters.srba.use_robust_kernel = old_kernel; 00088 00089 m_profiler.leave("define_new_keyframe.opt_new_edges"); 00090 } 00091 } 00092 00093 m_profiler.enter("define_new_keyframe.optimize"); 00094 00095 TOptimizeLocalAreaParams opt_params; // Default values 00096 00097 this->optimize_local_area( 00098 new_kf_id, // root node 00099 parameters.srba.max_optimize_depth, // win size 00100 out_new_kf_info.optimize_results, 00101 opt_params 00102 ); 00103 00104 m_profiler.leave("define_new_keyframe.optimize"); 00105 } 00106 00107 00108 // Fill out_new_kf_info 00109 // ----------------------------------------- 00110 out_new_kf_info.kf_id = new_kf_id; 00111 out_new_kf_info.created_edge_ids.swap( new_k2k_edge_ids ); // swap, faster than copy 00112 00113 m_profiler.leave("define_new_keyframe"); 00114 00115 VERBOSE_LEVEL(1) << "[define_new_keyframe] Done. New KF #" << out_new_kf_info.kf_id << " with " << out_new_kf_info.created_edge_ids.size() << " new edges.\n"; 00116 } // end of RbaEngine::define_new_keyframe 00117 00118 00119 } // end NS