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 #define UPDATE_NUM_ST_VERBOSE 0 00015 #define DEBUG_GARBAGE_FILL_ALL_NUMS 0 00016 00018 template <class KF2KF_POSE_TYPE,class LM_TYPE,class OBS_TYPE,class RBA_OPTIONS> 00019 size_t TRBA_Problem_state<KF2KF_POSE_TYPE,LM_TYPE,OBS_TYPE,RBA_OPTIONS>::TSpanningTree::update_numeric_only_all_from_node( 00020 const typename all_edges_maps_t::const_iterator & it, 00021 bool skip_marked_as_uptodate) 00022 { 00023 // num[SOURCE] |--> map[TARGET] = CPose3D of TARGET as seen from SOURCE 00024 const TKeyFrameID id_from = it->first; 00025 frameid2pose_map_t &frameid2pose_map = num[id_from]; // O(1) with map_as_vector 00026 00027 for (typename std::map<TKeyFrameID, k2k_edge_vector_t >::const_iterator itE = it->second.begin();itE != it->second.end();++itE) 00028 { 00029 const TKeyFrameID id_to = itE->first; 00030 00031 pose_flag_t & i2j = frameid2pose_map[id_to]; 00032 pose_flag_t & j2i = num[id_to][id_from]; // O(1) with map_as_vector 00033 00034 if (skip_marked_as_uptodate && i2j.updated && j2i.updated) 00035 continue; 00036 00037 // Go recompute this pose: 00038 const k2k_edge_vector_t &ev = itE->second; 00039 00040 // Accumulate inverse poses in the order established by the path: 00041 pose_t accum; 00042 TKeyFrameID curKF = id_from; 00043 00044 #if UPDATE_NUM_ST_VERBOSE 00045 std::cout << "ST.NUM["<<id_from<<"]["<<id_to<<"] : "; 00046 #endif 00047 for (size_t k=0;k<ev.size();k++) 00048 { 00049 if(ev[k]->to==curKF) // Inverse poses means we should face all arcs by the "head" (arrow) side 00050 { 00051 accum.composeFrom(accum, ev[k]->inv_pose ); 00052 curKF = ev[k]->from; 00053 #if UPDATE_NUM_ST_VERBOSE 00054 std::cout << "->"<<curKF; 00055 #endif 00056 } 00057 else 00058 { 00059 accum.composeFrom(accum, -ev[k]->inv_pose ); // unary "-" operator inverts SE(3) poses 00060 curKF = ev[k]->to; 00061 #if UPDATE_NUM_ST_VERBOSE 00062 std::cout << "<-"<<curKF; 00063 #endif 00064 } 00065 } 00066 00067 // Save in map: 00068 i2j.pose = accum; 00069 i2j.updated = true; 00070 00071 // And also symmetric (inverse) pose: 00072 j2i.pose = -accum; 00073 j2i.updated = true; 00074 00075 #if UPDATE_NUM_ST_VERBOSE 00076 std::cout << " "<< accum.asString() << std::endl; 00077 #endif 00078 } 00079 00080 return it->second.size(); 00081 } 00082 00083 #if DEBUG_GARBAGE_FILL_ALL_NUMS 00084 00085 template <class KF2KF_POSE_TYPE,class LM_TYPE,class OBS_TYPE,class RBA_OPTIONS> 00086 void setAllNumericToGarbage(typename TRBA_Problem_state<KF2KF_POSE_TYPE,LM_TYPE,OBS_TYPE,RBA_OPTIONS>::TSpanningTree &st) 00087 { 00088 // Mark all numeric values to trash so we detect if some goes un-initialized. 00089 for (typename kf2kf_pose_traits<kf2kf_pose_t>::TRelativePosesForEachTarget::iterator it=st.num.begin();it!=st.num.end();++it) 00090 { 00091 typename kf2kf_pose_traits<kf2kf_pose_t>::frameid2pose_map_t & m = it->second; 00092 for (typename kf2kf_pose_traits<kf2kf_pose_t>::frameid2pose_map_t::iterator it2=m.begin();it2!=m.end();++it2) 00093 it2->second.pose.setToNaN(); 00094 } 00095 } 00096 #endif 00097 00098 template <class KF2KF_POSE_TYPE,class LM_TYPE,class OBS_TYPE,class RBA_OPTIONS> 00099 size_t TRBA_Problem_state<KF2KF_POSE_TYPE,LM_TYPE,OBS_TYPE,RBA_OPTIONS>::TSpanningTree::update_numeric(bool skip_marked_as_uptodate) 00100 { 00101 #if DEBUG_GARBAGE_FILL_ALL_NUMS 00102 setAllNumericToGarbage<RBA_SETTINGS_T>(*this); 00103 #endif 00104 size_t pose_count = 0; 00105 for (typename all_edges_maps_t::const_iterator it=sym.all_edges.begin();it!=sym.all_edges.end();++it) 00106 pose_count += update_numeric_only_all_from_node(it, skip_marked_as_uptodate); 00107 return pose_count; 00108 } 00109 00110 template <class KF2KF_POSE_TYPE,class LM_TYPE,class OBS_TYPE,class RBA_OPTIONS> 00111 size_t TRBA_Problem_state<KF2KF_POSE_TYPE,LM_TYPE,OBS_TYPE,RBA_OPTIONS>::TSpanningTree::update_numeric(const std::set<TKeyFrameID> & kfs_to_update,bool skip_marked_as_uptodate) 00112 { 00113 #if DEBUG_GARBAGE_FILL_ALL_NUMS 00114 setAllNumericToGarbage<RBA_SETTINGS_T>(*this); 00115 #endif 00116 00117 size_t pose_count = 0; 00118 for (std::set<TKeyFrameID>::const_iterator it=kfs_to_update.begin();it!=kfs_to_update.end();++it) 00119 { 00120 typename all_edges_maps_t::const_iterator it_edge=sym.all_edges.find( *it ); 00121 if (it_edge!=sym.all_edges.end()) 00122 { 00123 pose_count += update_numeric_only_all_from_node(it_edge, skip_marked_as_uptodate); 00124 } 00125 } 00126 return pose_count; 00127 } 00128 00129 } // end NS