SRBA: Sparser Relative Bundle Adjustment
srba/impl/define_new_keyframe.h
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends