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 #include <queue> 00013 00014 namespace srba { 00015 00016 // This is used mainly for 3D rendering 00017 template <class KF2KF_POSE_TYPE,class LM_TYPE,class OBS_TYPE,class RBA_OPTIONS> 00018 void RbaEngine<KF2KF_POSE_TYPE,LM_TYPE,OBS_TYPE,RBA_OPTIONS>::create_complete_spanning_tree( 00019 const TKeyFrameID root_id, 00020 frameid2pose_map_t & span_tree, 00021 const size_t max_depth, 00022 std::vector<bool> * aux_ws 00023 ) const 00024 { 00025 using namespace std; 00026 MRPT_UNUSED_PARAM(aux_ws); 00027 span_tree.clear(); 00028 00029 set<TKeyFrameID> visited; 00030 queue<TKeyFrameID> pending; 00031 map<TKeyFrameID,TBFSEntryEdges> preceding; 00032 00033 // ---------------------------------------------------------------------------------------------------------------- 00034 // (1) Do a BFS to build a spanning tree, storing the shortest path and its depth for each KF within max_depth: 00035 // ---------------------------------------------------------------------------------------------------------------- 00036 // Insert: 00037 pending.push(root_id); 00038 visited.insert(root_id); 00039 preceding[root_id].dist = 0; 00040 00041 while (!pending.empty()) 00042 { 00043 const TKeyFrameID next_kf = pending.front(); 00044 pending.pop(); 00045 00046 const topo_dist_t cur_dist = preceding[next_kf].dist; 00047 00048 if (cur_dist>=max_depth) 00049 continue; 00050 00051 // Get all connections of this node: 00052 ASSERTDEB_(next_kf < rba_state.keyframes.size()) 00053 const keyframe_info & kfi = rba_state.keyframes[next_kf]; 00054 00055 for (size_t i=0;i<kfi.adjacent_k2k_edges.size();i++) 00056 { 00057 const k2k_edge_t* ed = kfi.adjacent_k2k_edges[i]; 00058 const TKeyFrameID new_kf = getTheOtherFromPair2(next_kf, *ed); 00059 if (!visited.count(new_kf)) 00060 { 00061 pending.push(new_kf); 00062 visited.insert(new_kf); 00063 00064 TBFSEntryEdges & p = preceding[new_kf]; 00065 00066 if (p.dist>cur_dist+1) 00067 { 00068 p.dist = cur_dist+1; 00069 p.prev = next_kf; 00070 p.edge = ed; 00071 } 00072 } 00073 } 00074 } 00075 00076 // ---------------------------------------------------------------------------------------------------------------- 00077 // (2) Sort all KFs in range by hiearchy, i.e. by increasing depth: 00078 // ---------------------------------------------------------------------------------------------------------------- 00079 multimap<topo_dist_t,pair<TKeyFrameID,TBFSEntryEdges> > kfs_by_depth; 00080 00081 for (typename map<TKeyFrameID,TBFSEntryEdges>::const_iterator it=preceding.begin();it!=preceding.end();++it) 00082 kfs_by_depth.insert( make_pair( it->second.dist, *it ) ); 00083 00084 00085 // ---------------------------------------------------------------------------------------------------------------- 00086 // (3) Construct the pose of each KF by composing the poses along the tree, from the root to the leaves: 00087 // ---------------------------------------------------------------------------------------------------------------- 00088 for (typename multimap<topo_dist_t,pair<TKeyFrameID,TBFSEntryEdges> >::const_iterator it=kfs_by_depth.begin();it!=kfs_by_depth.end();++it) 00089 { 00090 const topo_dist_t kf_depth = it->first; 00091 const TKeyFrameID kf_id = it->second.first; 00092 const TBFSEntryEdges & bfs_data = it->second.second; 00093 00094 00095 if (kf_depth==0) 00096 { 00097 // Root: 00098 span_tree[ kf_id ].pose = pose_t(); // Default: origin. 00099 } 00100 else 00101 { 00102 // All leaves: 00103 ASSERT_(bfs_data.edge!=NULL) 00104 00105 // The pose of my parent KF: 00106 const pose_t & parent_pose = span_tree[ bfs_data.prev ].pose; 00107 00108 // A ref to the placeholder for my pose: 00109 pose_t & my_pose = span_tree[ kf_id ].pose; 00110 00111 // Is the edge direct or inverted? 00112 if (bfs_data.edge->to==kf_id) 00113 { 00114 // Edge: parent -> me 00115 // "inv_pose" in edge is really the inverse pose of me w.r.t. my parent: 00116 my_pose.composeFrom(parent_pose, -bfs_data.edge->inv_pose ); 00117 } 00118 else 00119 { 00120 // Edge: me -> parent 00121 // "inv_pose" in edge is directly the pose of me w.r.t. my parent: 00122 my_pose.composeFrom(parent_pose, bfs_data.edge->inv_pose ); 00123 } 00124 } 00125 } 00126 00127 } 00128 00129 00130 } // end NS