SRBA: Sparser Relative Bundle Adjustment
srba/ecps/classic_linear_rba.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 #include <mrpt/utils/CConfigFileBase.h> // MRPT_LOAD_CONFIG_VAR
00012 
00013 namespace srba {
00014 namespace ecps {
00015 
00022 struct classic_linear_rba
00023 {
00024     struct parameters_t
00025     {
00026         size_t              min_obs_to_loop_closure; 
00027 
00029         parameters_t() :
00030             min_obs_to_loop_closure ( 4 )
00031         { }
00032 
00034         void loadFromConfigFile(const mrpt::utils::CConfigFileBase & source,const std::string & section)
00035         {
00036             MRPT_LOAD_CONFIG_VAR(min_obs_to_loop_closure,uint64_t,source,section)
00037         }
00038 
00040         void saveToConfigFile(mrpt::utils::CConfigFileBase & out,const std::string & section) const
00041         {
00042             out.write(section,"min_obs_to_loop_closure",static_cast<uint64_t>(min_obs_to_loop_closure), /* text width */ 30, 30, "Min. num. of covisible observations to add a loop closure edge");
00043         }
00044     };
00045     
00049     template <class traits_t,class rba_engine_t>
00050     void eval(
00051         const TKeyFrameID               new_kf_id,
00052         const typename traits_t::new_kf_observations_t   & obs,
00053         std::vector<TNewEdgeInfo> &new_k2k_edge_ids,
00054         rba_engine_t       & rba_engine,
00055         const parameters_t &params)
00056     {
00057         using namespace std;
00058         ASSERT_(new_kf_id>=1)
00059 
00060         // (1/2) Always add an edge (n-1) => (n)
00061         // -------------------------------------------
00062         const typename traits_t::original_kf2kf_pose_t::pose_t   init_inv_pose;
00063 
00064         TNewEdgeInfo nei1;
00065         nei1.has_approx_init_val = true; // In a linear graph it's a reasonable approx. to make each KF start at the last KF pose, which is what means a null pose init val.
00066 
00067         nei1.id = rba_engine.create_kf2kf_edge(new_kf_id, TPairKeyFrameID( new_kf_id-1, new_kf_id), obs, init_inv_pose);
00068         new_k2k_edge_ids.push_back(nei1);
00069 
00070         // (2/2) Need to add loop closures?
00071         // -------------------------------------------
00072         const topo_dist_t min_dist_for_loop_closure = rba_engine.parameters.srba.max_tree_depth + 1; // By definition of loop closure in the SRBA framework
00073 
00074         // Go thru all observations and for those already-seen LMs, check the distance between their base KFs and (i_id):
00075         // Make a list of base KFs of my new observations, ordered in descending order by # of shared observations:
00076         base_sorted_lst_t         obs_for_each_base_sorted;
00077         srba::internal::make_ordered_list_base_kfs<traits_t,typename rba_engine_t::rba_problem_state_t>(obs, rba_engine.get_rba_state(), obs_for_each_base_sorted);
00078 
00079         for (base_sorted_lst_t::const_iterator it=obs_for_each_base_sorted.begin();it!=obs_for_each_base_sorted.end();++it)
00080         {
00081             const size_t      num_obs_this_base = it->first;
00082             
00083             // Find the distance between "central_kf_id" <=> "new_kf_id"
00084             const TKeyFrameID from_id = new_kf_id;
00085             const TKeyFrameID to_id = it->second;
00086 
00087             typename rba_engine_t::rba_problem_state_t::TSpanningTree::next_edge_maps_t::const_iterator it_from = rba_engine.get_rba_state().spanning_tree.sym.next_edge.find(from_id);
00088 
00089             topo_dist_t  found_distance = numeric_limits<topo_dist_t>::max();
00090 
00091             if (it_from != rba_engine.get_rba_state().spanning_tree.sym.next_edge.end()) {
00092                 const map<TKeyFrameID,TSpanTreeEntry> &from_Ds = it_from->second;
00093                 map<TKeyFrameID,TSpanTreeEntry>::const_iterator it_to_dist = from_Ds.find(to_id);
00094                 if (it_to_dist != from_Ds.end())
00095                     found_distance = it_to_dist->second.distance;
00096             }
00097             else {
00098                 // The new KF doesn't still have any edge created to it, that's why we didn't found any spanning tree for it.
00099                 // Since this means that the KF is aisolated from the rest of the world, leave the topological distance to infinity.
00100             }
00101 
00102             if ( found_distance>=min_dist_for_loop_closure && num_obs_this_base>=params.min_obs_to_loop_closure)
00103             {
00104                 // The KF is TOO FAR: We will need to create an additional edge:
00105                 TNewEdgeInfo nei;
00106 
00107                 nei.id = rba_engine.create_kf2kf_edge(new_kf_id, TPairKeyFrameID( to_id, new_kf_id), obs);
00108 
00109                 nei.has_approx_init_val = false; // By default: Will need to estimate this one
00110                 new_k2k_edge_ids.push_back(nei);
00111 
00112                 mrpt::system::setConsoleColor(mrpt::system::CONCOL_BLUE);
00113                 //VERBOSE_LEVEL(2) << "[edge_creation_policy] Created edge #"<< nei.id << ": "<< central_kf_id <<"->"<<new_kf_id << " with #obs: "<< num_obs_this_base<< endl;
00114                 mrpt::system::setConsoleColor(mrpt::system::CONCOL_NORMAL);
00115             }
00116         } // end for each base KF
00117 
00118     } // end of eval()
00119 
00120 };  // end of struct
00121 
00122 } } // End of namespaces
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends