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