SRBA: Sparser Relative Bundle Adjustment
srba/srba_types.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 <mrpt/math/lightweight_geom_data.h>
00013 #include <mrpt/math/MatrixBlockSparseCols.h>
00014 #include <mrpt/math/CArrayNumeric.h>
00015 #include <mrpt/utils/TEnumType.h>
00016 #include <mrpt/system/memory.h> // for MRPT_MAKE_ALIGNED_OPERATOR_NEW
00017 #include <set>
00018 
00019 namespace srba
00020 {
00021     typedef uint64_t  TKeyFrameID; 
00022     typedef uint64_t  TLandmarkID; 
00023     typedef uint64_t  topo_dist_t;  
00024     typedef std::pair<TKeyFrameID,TKeyFrameID> TPairKeyFrameID;  
00025     typedef std::multimap<size_t,TKeyFrameID,std::greater<size_t> > base_sorted_lst_t;  
00026 
00027     #define VERBOSE_LEVEL(_LEVEL) if (m_verbose_level>=_LEVEL) std::cout
00028 
00029     #define VERBOSE_LEVEL_COLOR(_LEVEL,_TEXT_COLOR) if (m_verbose_level>=_LEVEL) { mrpt::system::setConsoleColor(_TEXT_COLOR); std::cout
00030     #define VERBOSE_LEVEL_COLOR_POST() mrpt::system::setConsoleColor(mrpt::system::CONCOL_NORMAL); }
00031 
00032 
00033     #define SRBA_INVALID_KEYFRAMEID  static_cast<TKeyFrameID>(-1)
00034     #define SRBA_INVALID_INDEX       static_cast<size_t>(-1)
00035 
00036     // -------------------------------------------------------------------------------
00043     template <class landmark_t,class obs_t>
00044     struct sensor_model;
00045 
00049     template <class POSE_TRAITS>
00050     struct kf2kf_pose_traits: public POSE_TRAITS
00051     {
00052         typedef kf2kf_pose_traits<POSE_TRAITS> me_t;
00053         typedef typename POSE_TRAITS::pose_t  pose_t;  
00054         typedef typename mrpt::math::CArrayDouble<POSE_TRAITS::REL_POSE_DIMS>  array_pose_t;  
00055 
00057         struct pose_flag_t
00058         {
00059             pose_t        pose;
00060             mutable bool  updated;
00061 
00062             pose_flag_t() : updated(false) { }
00063             pose_flag_t(const pose_t &pose_, const bool updated_) : pose(pose_),updated(updated_) { }
00064 
00065             inline void mark_outdated() const { updated=false; }
00066 
00067             MRPT_MAKE_ALIGNED_OPERATOR_NEW  // Needed because we have fixed-length Eigen matrices (within CPose3D)
00068         };
00069 
00071         typedef typename mrpt::aligned_containers<TKeyFrameID, pose_flag_t>::map_t  frameid2pose_map_t;
00072 
00073         // Use special map-like container with an underlying planar deque container, which avoid reallocations
00074         // and still provides map-like [] access at O(1).
00075         typedef mrpt::utils::map_as_vector<
00076             TKeyFrameID,
00077             frameid2pose_map_t,
00078             typename std::deque<std::pair<TKeyFrameID,frameid2pose_map_t> >
00079             >  TRelativePosesForEachTarget;
00080 
00082         struct k2k_edge_t
00083         {
00084             TKeyFrameID  from;
00085             TKeyFrameID  to;
00086             pose_t       inv_pose; 
00087 
00088             size_t       id; 
00089 
00090             MRPT_MAKE_ALIGNED_OPERATOR_NEW    // Needed because we have fixed-length Eigen matrices (within CPose3D)
00091         };
00092 
00093         typedef std::deque<k2k_edge_t*>  k2k_edge_vector_t; 
00094     }; // end of kf2kf_pose_traits
00095 
00099     template <class LM_TRAITS>
00100     struct landmark_traits: public LM_TRAITS
00101     {
00102         typedef landmark_traits<LM_TRAITS> me_t;
00103         typedef typename mrpt::math::CArrayDouble<LM_TRAITS::LM_DIMS>        array_landmark_t;  
00104 
00106         struct TRelativeLandmarkPos
00107         {
00108             inline TRelativeLandmarkPos() { }
00112             template <typename LANDMARK_POS>
00113             inline TRelativeLandmarkPos(const TKeyFrameID  _id_frame_base, const LANDMARK_POS &_pos) : id_frame_base(_id_frame_base) {
00114                 for (size_t i=0;i<LM_TRAITS::LM_DIMS;i++) pos[i]=_pos[i];
00115             }
00116 
00117             TKeyFrameID  id_frame_base; 
00118             array_landmark_t   pos;  
00119 
00120             MRPT_MAKE_ALIGNED_OPERATOR_NEW  // Needed because we have fixed-length Eigen matrices ("array_landmark_t")
00121         };
00122 
00124         typedef std::map<TLandmarkID, TRelativeLandmarkPos>  TRelativeLandmarkPosMap;
00125 
00127         struct TLandmarkEntry
00128         {
00129             bool                 has_known_pos; 
00130             TRelativeLandmarkPos *rfp;           
00131 
00132             TLandmarkEntry() : has_known_pos(true), rfp(NULL) {}
00133             TLandmarkEntry(bool has_known_pos_, TRelativeLandmarkPos *rfp_) : has_known_pos(has_known_pos_), rfp(rfp_)
00134             {}
00135         };
00136 
00137     }; // end of landmark_traits
00138 
00139     template <class OBS_TRAITS>
00140     struct observation_traits : public OBS_TRAITS
00141     {
00142         typedef typename mrpt::math::CArrayDouble<OBS_TRAITS::OBS_DIMS>  array_obs_t;  
00143         typedef typename mrpt::math::CArrayDouble<OBS_TRAITS::OBS_DIMS>  residual_t;   
00144 
00145         typedef typename mrpt::aligned_containers<residual_t>::vector_t  vector_residuals_t;
00146 
00148         struct observation_t
00149         {
00150             TLandmarkID   feat_id;  
00151             typename OBS_TRAITS::obs_data_t  obs_data; 
00152         };
00153 
00154         MRPT_MAKE_ALIGNED_OPERATOR_NEW
00155 
00156     }; // end of "observation_traits"
00157 
00159     // --------------------------------------------------------------
00160 
00164     enum TCovarianceRecoveryPolicy {
00166         crpNone = 0,
00168         crpLandmarksApprox
00169     };
00170 
00172     template <typename PAIR,typename V>
00173     V getTheOtherFromPair(const V one, const PAIR &p) {
00174         return p.first==one ? p.second : p.first;
00175     }
00176 
00178     template <typename K2K_EDGE,typename V>
00179     V getTheOtherFromPair2(const V one, const K2K_EDGE &p) {
00180         return p.from==one ? p.to: p.from;
00181     }
00182 
00184     struct TNewEdgeInfo
00185     {
00186         size_t  id; 
00187         bool    has_approx_init_val; 
00188 
00192         TKeyFrameID loopclosure_observer_kf, loopclosure_base_kf;
00193 
00194         TNewEdgeInfo() :
00195             id                      (SRBA_INVALID_INDEX),
00196             has_approx_init_val     (false),
00197             loopclosure_observer_kf (SRBA_INVALID_KEYFRAMEID),
00198             loopclosure_base_kf     (SRBA_INVALID_KEYFRAMEID)
00199         {}
00200     };
00201 
00204     template <class kf2kf_pose_t, class LANDMARK_TYPE>
00205     struct TJacobianSymbolicInfo_dh_dAp
00206     {
00207         typedef kf2kf_pose_traits<kf2kf_pose_t> kf2kf_traits_t;
00208         typedef landmark_traits<LANDMARK_TYPE>     lm_traits_t;
00209 
00212         const typename kf2kf_traits_t::pose_flag_t * rel_pose_d1_from_obs, * rel_pose_base_from_d1;
00213 
00216         bool  edge_normal_dir;
00217 
00219         const typename lm_traits_t::TRelativeLandmarkPos * feat_rel_pos;
00220 
00223         TKeyFrameID  kf_d;
00224         TKeyFrameID  kf_base;  
00225         size_t       k2k_edge_id; 
00226         size_t       obs_idx; 
00227         char       * is_valid; 
00228 
00229         TJacobianSymbolicInfo_dh_dAp() : 
00230             rel_pose_d1_from_obs(NULL),
00231             rel_pose_base_from_d1(NULL),
00232             edge_normal_dir(true),
00233             feat_rel_pos(NULL),
00234             kf_d(SRBA_INVALID_KEYFRAMEID),
00235             kf_base(SRBA_INVALID_KEYFRAMEID),
00236             k2k_edge_id(SRBA_INVALID_INDEX),
00237             obs_idx(SRBA_INVALID_INDEX),
00238             is_valid(NULL)
00239         {}
00240     };
00241 
00242 
00245     template <class kf2kf_pose_t, class LANDMARK_TYPE>
00246     struct TJacobianSymbolicInfo_dh_df
00247     {
00248         typedef kf2kf_pose_traits<kf2kf_pose_t> kf2kf_traits_t;
00249         typedef landmark_traits<LANDMARK_TYPE>     lm_traits_t;
00250 
00251         typename lm_traits_t::TRelativeLandmarkPos  *feat_rel_pos;  
00252 
00255         const typename kf2kf_traits_t::pose_flag_t * rel_pose_base_from_obs;
00256 
00257         size_t   obs_idx;  
00258         char   * is_valid; 
00259 
00260         TJacobianSymbolicInfo_dh_df() :
00261             feat_rel_pos(NULL),
00262             rel_pose_base_from_obs(NULL),
00263             obs_idx(SRBA_INVALID_INDEX),
00264             is_valid(NULL)
00265         {}
00266     };
00267 
00274     template <typename Scalar,int N,int M1,int M2>
00275     struct THessianSymbolicInfo
00276     {
00277         typedef Eigen::Matrix<Scalar,N,M1> matrix1_t;
00278         typedef Eigen::Matrix<Scalar,N,M2> matrix2_t;
00279 
00284         struct THessianSymbolicInfoEntry
00285         {
00286             const matrix1_t * J1; 
00287             const matrix2_t * J2; 
00288             const char *      J1_valid;
00289             const char *      J2_valid;
00290             size_t            obs_idx; 
00291 
00292             THessianSymbolicInfoEntry(const matrix1_t * const J1_, const matrix2_t * const J2_, const char * const J1_valid_, const char * const J2_valid_, const size_t obs_idx_ ) :
00293                 J1(J1_), J2(J2_),J1_valid(J1_valid_),J2_valid(J2_valid_),obs_idx(obs_idx_) 
00294             { }
00295 
00296             // Default ctor: should not be invoked under normal usage, but just in case:
00297             THessianSymbolicInfoEntry() : J1(NULL),J2(NULL),J1_valid(NULL),J2_valid(NULL),obs_idx(static_cast<size_t>(-1)) {}
00298         };
00299 
00300         typedef std::vector<THessianSymbolicInfoEntry> list_jacob_blocks_t;
00301 
00302         list_jacob_blocks_t lst_jacob_blocks; 
00303     };
00304 
00305 
00311     template <
00312         typename Scalar,
00313         int NROWS,
00314         int NCOLS,
00315         typename INFO,
00316         bool HAS_REMAP,
00317         typename INDEX_REMAP_MAP_IMPL = mrpt::utils::map_as_vector<size_t,size_t>
00318     >
00319     struct SparseBlockMatrix : public mrpt::math::MatrixBlockSparseCols<Scalar,NROWS,NCOLS,INFO,HAS_REMAP,INDEX_REMAP_MAP_IMPL>
00320     {
00321         typedef mrpt::math::MatrixBlockSparseCols<Scalar,NROWS,NCOLS,INFO,HAS_REMAP,INDEX_REMAP_MAP_IMPL> base_t;
00322 
00324         size_t findRowSpan(size_t *row_min_idx=NULL, size_t *row_max_idx=NULL) const
00325         {
00326             size_t row_min=std::numeric_limits<size_t>::max();
00327             size_t row_max=0;
00328             const size_t nCols = base_t::getColCount();
00329             for (size_t j=0;j<nCols;j++)
00330                 for (typename base_t::col_t::const_iterator itRow=base_t::getCol(j).begin();itRow!=base_t::getCol(j).end();++itRow) {
00331                     mrpt::utils::keep_max(row_max, itRow->first);
00332                     mrpt::utils::keep_min(row_min, itRow->first);
00333                 }
00334             if (row_min==std::numeric_limits<size_t>::max())
00335                 row_min=0;
00336             if (row_min_idx) *row_min_idx = row_min;
00337             if (row_max_idx) *row_max_idx = row_max;
00338             return (row_max-row_min)+1;
00339         }
00340 
00342         static size_t findRowSpan(const std::vector<typename base_t::col_t*> &lstColumns, size_t *row_min_idx=NULL, size_t *row_max_idx=NULL)
00343         {
00344             size_t row_min=std::numeric_limits<size_t>::max();
00345             size_t row_max=0;
00346             for (size_t i=0;i<lstColumns.size();++i)
00347                 for (typename base_t::col_t::const_iterator itRow=lstColumns[i]->begin();itRow!=lstColumns[i]->end();++itRow) {
00348                     mrpt::utils::keep_max(row_max, itRow->first);
00349                     mrpt::utils::keep_min(row_min, itRow->first);
00350                 }
00351             if (row_min==std::numeric_limits<size_t>::max())
00352                 row_min=0;
00353             if (row_min_idx) *row_min_idx = row_min;
00354             if (row_max_idx) *row_max_idx = row_max;
00355             return (row_max-row_min)+1;
00356         }
00357 
00362         void getSparsityStats(size_t &nMaxBlocks, size_t &nNonZeroBlocks  ) const {
00363             const size_t nCols = base_t::getColCount();
00364             const size_t nRows = findRowSpan();
00365             nMaxBlocks = nCols * nRows;
00366             nNonZeroBlocks = 0;
00367             for (size_t j=0;j<nCols;j++)
00368                 nNonZeroBlocks+= base_t::getCol(j).size();
00369         }
00370 
00372         static void getSparsityStats(const std::vector<typename base_t::col_t*> &lstColumns, size_t &nMaxBlocks, size_t &nNonZeroBlocks  )
00373         {
00374             const size_t nCols = lstColumns.size();
00375             const size_t nRows = findRowSpan(lstColumns);
00376             nMaxBlocks = nCols * nRows;
00377             nNonZeroBlocks = 0;
00378             for (size_t j=0;j<nCols;j++)
00379                 nNonZeroBlocks+=lstColumns[j]->size();
00380         }
00381 
00382     }; // end SparseBlockMatrix()
00383 
00384 
00390     template <class kf2kf_pose_t, class LANDMARK_TYPE,class obs_t>
00391     struct jacobian_traits
00392     {
00393         static const size_t OBS_DIMS      = obs_t::OBS_DIMS;
00394         static const size_t REL_POSE_DIMS = kf2kf_pose_t::REL_POSE_DIMS;
00395         static const size_t LM_DIMS       = LANDMARK_TYPE::LM_DIMS;
00396 
00397         typedef TJacobianSymbolicInfo_dh_dAp<kf2kf_pose_t,LANDMARK_TYPE> jacob_dh_dAp_info_t;
00398         typedef TJacobianSymbolicInfo_dh_df<kf2kf_pose_t,LANDMARK_TYPE>  jacob_dh_df_info_t;
00399 
00400         typedef SparseBlockMatrix<double,OBS_DIMS,REL_POSE_DIMS,jacob_dh_dAp_info_t, false>  TSparseBlocksJacobians_dh_dAp;  
00401         typedef SparseBlockMatrix<double,OBS_DIMS,LM_DIMS,jacob_dh_df_info_t,  true >   TSparseBlocksJacobians_dh_df;  // The "true" is to "remap" indices
00402     };
00403 
00411     template <class kf2kf_pose_t, class LANDMARK_TYPE,class obs_t>
00412     struct hessian_traits
00413     {
00414         static const size_t OBS_DIMS      = obs_t::OBS_DIMS;
00415         static const size_t REL_POSE_DIMS = kf2kf_pose_t::REL_POSE_DIMS;
00416         static const size_t LM_DIMS       = LANDMARK_TYPE::LM_DIMS;
00417 
00418         typedef THessianSymbolicInfo<double,OBS_DIMS,REL_POSE_DIMS,REL_POSE_DIMS> hessian_Ap_info_t;
00419         typedef THessianSymbolicInfo<double,OBS_DIMS,LM_DIMS,LM_DIMS>             hessian_f_info_t;
00420         typedef THessianSymbolicInfo<double,OBS_DIMS,REL_POSE_DIMS,LM_DIMS>       hessian_Apf_info_t;
00421 
00422         // (the final "false" in all types is because we don't need remapping of indices in hessians)
00423         typedef SparseBlockMatrix<double,REL_POSE_DIMS , REL_POSE_DIMS , hessian_Ap_info_t , false> TSparseBlocksHessian_Ap;
00424         typedef SparseBlockMatrix<double,LM_DIMS       , LM_DIMS       , hessian_f_info_t  , false> TSparseBlocksHessian_f;
00425         typedef SparseBlockMatrix<double,REL_POSE_DIMS , LM_DIMS       , hessian_Apf_info_t, false> TSparseBlocksHessian_Apf;
00426 
00428         typedef mrpt::utils::map_as_vector<
00429             TLandmarkID,
00430             typename TSparseBlocksHessian_f::matrix_t,
00431             typename mrpt::aligned_containers<std::pair<TLandmarkID,typename TSparseBlocksHessian_f::matrix_t > >::deque_t> landmarks2infmatrix_t;
00432     };
00433 
00434 
00437     template <class kf2kf_pose_t,class landmark_t,class obs_t>
00438     struct rba_joint_parameterization_traits_t
00439     {
00440         typedef landmark_t   original_landmark_t;
00441         typedef kf2kf_pose_t original_kf2kf_pose_t;
00442 
00443         typedef kf2kf_pose_traits<kf2kf_pose_t> kf2kf_traits_t;
00444         typedef observation_traits<obs_t>       obs_traits_t;
00445         typedef landmark_traits<landmark_t>           lm_traits_t;
00446 
00447         typedef typename kf2kf_traits_t::k2k_edge_t k2k_edge_t;
00448 
00473         struct new_kf_observation_t
00474         {
00476             new_kf_observation_t() : is_fixed(false), is_unknown_with_init_val(false) { feat_rel_pos.setZero(); }
00477 
00478             typename obs_traits_t::observation_t  obs;
00479 
00482             bool is_fixed;
00483 
00487             bool is_unknown_with_init_val;
00488 
00489             typename lm_traits_t::array_landmark_t feat_rel_pos; 
00490 
00492             template <class REL_POS> inline void setRelPos(const REL_POS &pos) {
00493                 for (size_t i=0;i<landmark_t::LM_DIMS;i++) feat_rel_pos[i]=pos[i];
00494             }
00495         };
00496 
00498         typedef std::deque<new_kf_observation_t> new_kf_observations_t;
00499 
00501         struct kf_observation_t
00502         {
00503             inline kf_observation_t() {}
00504             inline kf_observation_t(const typename obs_traits_t::observation_t &obs_, const TKeyFrameID kf_id_) : obs(obs_), kf_id(kf_id_) {}
00505 
00506             typename obs_traits_t::observation_t obs;      
00507             typename obs_traits_t::array_obs_t   obs_arr;  
00508             TKeyFrameID   kf_id;    
00509 
00510             MRPT_MAKE_ALIGNED_OPERATOR_NEW  // This forces aligned mem allocation
00511         };
00512 
00513 
00515         struct k2f_edge_t
00516         {
00517             kf_observation_t  obs;
00518             bool              feat_has_known_rel_pos;   
00519             bool              is_first_obs_of_unknown;  
00520             typename lm_traits_t::TRelativeLandmarkPos *feat_rel_pos; 
00521 
00522             inline const TLandmarkID get_observed_feature_id() const { return obs.obs.feat_id; }
00523 
00524             MRPT_MAKE_ALIGNED_OPERATOR_NEW  // This forces aligned mem allocation
00525         };
00526 
00528         struct keyframe_info
00529         {
00530             std::deque<k2k_edge_t*>  adjacent_k2k_edges;
00531             std::deque<k2f_edge_t*>  adjacent_k2f_edges;
00532         };
00533 
00534     }; // end of "rba_joint_parameterization_traits_t"
00535 
00536 
00538     struct TSpanTreeEntry
00539     {
00540         TKeyFrameID next;     
00541         topo_dist_t distance; 
00542     };
00543 
00548     template <class kf2kf_pose_t,class landmark_t,class obs_t,class RBA_OPTIONS>
00549     struct TRBA_Problem_state
00550     {
00551         typedef typename kf2kf_pose_t::pose_t pose_t;
00552         typedef typename kf2kf_pose_traits<kf2kf_pose_t>::k2k_edge_t         k2k_edge_t;
00553         typedef typename kf2kf_pose_traits<kf2kf_pose_t>::k2k_edge_vector_t  k2k_edge_vector_t;
00554         typedef typename kf2kf_pose_traits<kf2kf_pose_t>::frameid2pose_map_t frameid2pose_map_t;
00555         typedef typename kf2kf_pose_traits<kf2kf_pose_t>::pose_flag_t        pose_flag_t;
00556         typedef typename landmark_traits<landmark_t>::TRelativeLandmarkPosMap TRelativeLandmarkPosMap;
00557         typedef typename landmark_traits<landmark_t>::TLandmarkEntry          TLandmarkEntry;
00558         typedef typename hessian_traits<kf2kf_pose_t,landmark_t,obs_t>::landmarks2infmatrix_t   landmarks2infmatrix_t;
00559         typedef typename rba_joint_parameterization_traits_t<kf2kf_pose_t,landmark_t,obs_t>::keyframe_info          keyframe_info;
00560         typedef typename rba_joint_parameterization_traits_t<kf2kf_pose_t,landmark_t,obs_t>::k2f_edge_t             k2f_edge_t;
00561         typedef typename rba_joint_parameterization_traits_t<kf2kf_pose_t,landmark_t,obs_t>::new_kf_observations_t  new_kf_observations_t;
00562         typedef typename rba_joint_parameterization_traits_t<kf2kf_pose_t,landmark_t,obs_t>::new_kf_observation_t   new_kf_observation_t;
00563 
00564         typedef typename mrpt::aligned_containers<k2k_edge_t>::deque_t  k2k_edges_deque_t;  // Note: A std::deque() does not invalidate pointers/references, as we always insert elements at the end; we'll exploit this...
00565         typedef typename mrpt::aligned_containers<k2f_edge_t>::deque_t  all_observations_deque_t;
00566 
00567         typedef std::deque<keyframe_info>  keyframe_vector_t;  
00568 
00569         struct TSpanningTree
00570         {
00572             typedef mrpt::utils::map_as_vector<
00573                 TKeyFrameID,
00574                 std::map<TKeyFrameID,TSpanTreeEntry>,
00575                 std::deque<std::pair<TKeyFrameID,std::map<TKeyFrameID,TSpanTreeEntry> > >
00576                 > next_edge_maps_t;
00577 
00579             typedef mrpt::utils::map_as_vector<
00580                 TKeyFrameID,
00581                 std::map<TKeyFrameID, k2k_edge_vector_t>,
00582                 std::deque<std::pair<TKeyFrameID,std::map<TKeyFrameID, k2k_edge_vector_t > > >
00583                 > all_edges_maps_t;
00584 
00585             const TRBA_Problem_state<kf2kf_pose_t,landmark_t,obs_t,RBA_OPTIONS> *m_parent;
00586 
00591             struct TSpanningTreeSym
00592             {
00599                 next_edge_maps_t  next_edge;
00600 
00607                 all_edges_maps_t all_edges;
00608             }
00609             sym;
00610 
00620             typename kf2kf_pose_traits<kf2kf_pose_t>::TRelativePosesForEachTarget num;
00621 
00629             void clear();
00630 
00634             void update_symbolic_new_node(
00635                 const TKeyFrameID                    new_node_id,
00636                 const TPairKeyFrameID & new_edge,
00637                 const topo_dist_t                    max_depth
00638                 );
00639 
00643             size_t update_numeric(bool skip_marked_as_uptodate = false);
00644 
00646             size_t update_numeric(const std::set<TKeyFrameID> & kfs_to_update,bool skip_marked_as_uptodate = false);
00647 
00651             size_t update_numeric_only_all_from_node( const typename all_edges_maps_t::const_iterator & it,bool skip_marked_as_uptodate = false);
00652 
00659             void dump_as_text(std::string &s) const;
00660 
00662             bool dump_as_text_to_file(const std::string &sFileName) const;
00663 
00668             bool save_as_dot_file(const std::string &sFileName, const std::vector<TKeyFrameID> &kf_roots_to_save = std::vector<TKeyFrameID>() ) const;
00669 
00671             void get_stats(
00672                 size_t &num_nodes_min,
00673                 size_t &num_nodes_max,
00674                 double &num_nodes_mean,
00675                 double &num_nodes_std) const;
00676 
00679         }; // end of TSpanningTree
00680 
00681 
00682         struct TLinearSystem
00683         {
00684             TLinearSystem() :
00685                 dh_dAp(),
00686                 dh_df()
00687             {
00688             }
00689 
00690             typename jacobian_traits<kf2kf_pose_t,landmark_t,obs_t>::TSparseBlocksJacobians_dh_dAp dh_dAp;   
00691             typename jacobian_traits<kf2kf_pose_t,landmark_t,obs_t>::TSparseBlocksJacobians_dh_df  dh_df;    
00692 
00693             void clear() {
00694                 dh_dAp.clearAll();
00695                 dh_df.clearAll();
00696             }
00697 
00698         }; // end of TLinearSystem
00699 
00703         keyframe_vector_t       keyframes;   
00704         k2k_edges_deque_t       k2k_edges;   
00705         TRelativeLandmarkPosMap unknown_lms; 
00706         landmarks2infmatrix_t   unknown_lms_inf_matrices; 
00707         TRelativeLandmarkPosMap known_lms;   
00708 
00711         typename mrpt::aligned_containers<TLandmarkEntry>::deque_t   all_lms;
00712 
00713         TSpanningTree            spanning_tree;
00714         all_observations_deque_t all_observations;  
00715         TLinearSystem            lin_system;        
00716 
00722         std::deque<char>       all_observations_Jacob_validity;
00723 
00725         std::set<size_t>       last_timestep_touched_kfs;  
00729         void clear() {
00730             keyframes.clear();
00731             k2k_edges.clear();
00732             unknown_lms.clear();
00733             unknown_lms_inf_matrices.clear();
00734             known_lms.clear();
00735             all_lms.clear();
00736             spanning_tree.clear();
00737             all_observations.clear();
00738             lin_system.clear();
00739             last_timestep_touched_kfs.clear();
00740         }
00741 
00743         TRBA_Problem_state() {
00744             spanning_tree.m_parent=this; // Not passed as ctor argument to avoid compiler warnings...
00745         }
00746 
00753         bool find_path_bfs(
00754             const TKeyFrameID           from,
00755             const TKeyFrameID           to,
00756             std::vector<TKeyFrameID>  * out_path_IDs,
00757             typename kf2kf_pose_traits<kf2kf_pose_t>::k2k_edge_vector_t * out_path_edges = NULL) const;
00758 
00759 
00761         void compute_all_node_degrees(
00762             double &out_mean_degree,
00763             double &out_std_degree,
00764             double &out_max_degree) const;
00765 
00767         bool are_keyframes_connected(const TKeyFrameID id1, const TKeyFrameID id2) const;
00768 
00776         size_t alloc_kf2kf_edge(
00777             const TPairKeyFrameID &ids,
00778             const pose_t &init_inv_pose_val = pose_t() );
00779 
00780     private:
00781         // Forbid making copies of this object, since it heavily relies on internal lists of pointers:
00782         TRBA_Problem_state(const TRBA_Problem_state &);
00783         TRBA_Problem_state & operator =(const TRBA_Problem_state &);
00784 
00785     }; // end of TRBA_Problem_state
00786 
00787 } // end of namespace "srba"
00788 
00789 // Specializations MUST occur at the same namespace:
00790 namespace mrpt { namespace utils
00791 {
00792     template <>
00793     struct TEnumTypeFiller<srba::TCovarianceRecoveryPolicy>
00794     {
00795         typedef srba::TCovarianceRecoveryPolicy enum_t;
00796         static void fill(bimap<enum_t,std::string>  &m_map)
00797         {
00798             m_map.insert(srba::crpNone,      "crpNone");
00799             m_map.insert(srba::crpLandmarksApprox,   "crpLandmarksApprox");
00800         }
00801     };
00802 } } // End of namespace
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends