Main MRPT website > C++ reference
MRPT logo
RbaEngine.h
Go to the documentation of this file.
1 /* +---------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2014, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +---------------------------------------------------------------------------+ */
9 
10 #pragma once
11 
12 /** \file RbaEngine.h
13  * \brief This file exposes the public API and data types of libmrpt-srba (it requires also including srba/models/{*.h} to have a complete SLAM/RBA system)
14  */
15 
16 #include <mrpt/utils/CTimeLogger.h>
20 
21 #include "srba_types.h"
22 #include "srba_options.h"
24 
25 #define VERBOSE_LEVEL(_LEVEL) if (m_verbose_level>=_LEVEL) std::cout
26 
27 namespace mrpt
28 {
29 /** An heavily template-based implementation of Relative Bundle Adjustment (RBA) - See \ref mrpt_srba_grp */
30 namespace srba
31 {
32  using namespace std;
33 
34  /** The set of default settings for RbaEngine */
36  {
37  typedef options::sensor_pose_on_robot_none sensor_pose_on_robot_t; //!< The sensor pose coincides with the robot pose
38  typedef options::observation_noise_identity obs_noise_matrix_t; //!< The sensor noise matrix is the same for all observations and equal to \sigma * I(identity)
39  typedef options::solver_LM_schur_dense_cholesky solver_t; //!< Solver algorithm (Default: Lev-Marq, with Schur, with dense Cholesky)
40  };
41 
42  /** The main class for the mrpt-srba: it defines a Relative Bundle-Adjustment (RBA) problem with (optionally, partially known) landmarks,
43  * the methods to update it with new observations and to optimize the relative poses with least squares optimizers.
44  *
45  * The unknowns to be solved are:
46  * - Relative poses among keyframes.
47  * - Relative positions of landmarks wrt to their base frame (or no landmarks for graph-SLAM-like problems)
48  *
49  * The set of known data used to run the optimization comprises:
50  * - Sequence of all observations.
51  * - Optional sensor parameters (e.g. camera calibration)
52  * - Optionally, the relative positions of a subset of landmarks wrt to their base frame (these are the "fixed" or "known" landmarks).
53  *
54  * See http://www.mrpt.org/srba and the <a href="srba-guide.pdf" >library guide</a> for a list of possible template arguments, code examples, etc.
55  *
56  * \tparam KF2KF_POSE_TYPE The parameterization of keyframe-to-keyframe relative poses (edges, problem unknowns).
57  * \tparam LM_TYPE The parameterization of relative positions of landmarks relative poses (edges).
58  * \tparam OBS_TYPE The type of observations.
59  * \tparam RBA_OPTIONS A struct with nested typedefs which can be used to tune and customize the behavior of this class.
60  */
61  template <class KF2KF_POSE_TYPE,class LM_TYPE,class OBS_TYPE, class RBA_OPTIONS = RBA_OPTIONS_DEFAULT>
62  class RbaEngine
63  {
64  public:
65  /** @name Templatized typedef's
66  @{ */
68 
69  typedef KF2KF_POSE_TYPE kf2kf_pose_type;
70  typedef LM_TYPE lm_type;
71  typedef OBS_TYPE obs_type;
72  typedef RBA_OPTIONS rba_options_type;
73 
74  static const size_t REL_POSE_DIMS = KF2KF_POSE_TYPE::REL_POSE_DIMS;
75  static const size_t LM_DIMS = LM_TYPE::LM_DIMS;
76  static const size_t OBS_DIMS = OBS_TYPE::OBS_DIMS;
77 
78  typedef typename KF2KF_POSE_TYPE::se_traits_t se_traits_t; //!< The SE(2) or SE(3) traits struct (for Lie algebra log/exp maps, etc.)
79 
86 
87  typedef sensor_model<LM_TYPE,OBS_TYPE> sensor_model_t; //!< The sensor model for the specified combination of LM parameterization + observation type.
88 
89  typedef typename KF2KF_POSE_TYPE::pose_t pose_t; //!< The type of relative poses (e.g. mrpt::poses::CPose3D)
91 
94  typedef typename rba_problem_state_t::k2k_edges_deque_t k2k_edges_deque_t; //!< A list (deque) of KF-to-KF edges (unknown relative poses).
95 
96  typedef typename kf2kf_pose_traits_t::pose_flag_t pose_flag_t;
99  typedef typename landmark_traits_t::TRelativeLandmarkPosMap TRelativeLandmarkPosMap; //!< An index of feature IDs and their relative locations
100  typedef typename landmark_traits_t::TRelativeLandmarkPos TRelativeLandmarkPos; //!< One landmark position (relative to its base KF)
104 
110 
113  /** @} */
114 
115  /** Default constructor */
116  RbaEngine();
117 
118  /** All the information returned by the local area optimizer \sa define_new_keyframe() */
120  {
122  {
123  clear();
124  }
125 
126  size_t num_observations; //!< Number of individual feature observations taken into account in the optimization
127  size_t num_jacobians; //!< Number of Jacobian blocks which had been to be evaluated for each relinearization step.
128  size_t num_kf2kf_edges_optimized; //!< Number of solved unknowns of type "kf-to-kf edge".
129  size_t num_kf2lm_edges_optimized; //!< Number of solved unknowns of type "kf-to-landmark".
130  size_t num_total_scalar_optimized; //!< The total number of dimensions (scalar values) in all the optimized unknowns.
131  size_t num_span_tree_numeric_updates; //!< Number of poses updated in the spanning tree numeric-update stage.
132  double obs_rmse; //!< RMSE for each observation after optimization
133  double total_sqr_error_init, total_sqr_error_final; //!< Initial and final total squared error for all the observations
134  double HAp_condition_number; //!< To be computed only if enabled in parameters.compute_condition_number
135 
136  std::vector<size_t> optimized_k2k_edge_indices; //!< The 0-based indices of all kf-to-kf edges which were considered in the optimization
137  std::vector<size_t> optimized_landmark_indices; //!< The 0-based indices of all landmarks whose relative positions were considered as unknowns in the optimization
138 
139  /** Other solver-specific output information */
140  typename RBA_OPTIONS::solver_t::extra_results_t extra_results;
141 
142  void clear()
143  {
144  num_observations = 0;
145  num_jacobians = 0;
146  num_kf2kf_edges_optimized = 0;
147  num_kf2lm_edges_optimized = 0;
148  num_total_scalar_optimized = 0;
149  num_span_tree_numeric_updates=0;
150  total_sqr_error_init=0.;
151  total_sqr_error_final=0.;
152  HAp_condition_number=0.;
153  optimized_k2k_edge_indices.clear();
154  optimized_landmark_indices.clear();
155  extra_results.clear();
156  }
157  };
158 
159  /** Information returned by RbaEngine::define_new_keyframe() */
161  {
162  TKeyFrameID kf_id; //!< The ID of the newly created KF.
163  std::vector<TNewEdgeInfo> created_edge_ids; //!< The newly created edges (minimum: 1 edge)
164  TOptimizeExtraOutputInfo optimize_results; //!< Results from the least-squares optimization
165  TOptimizeExtraOutputInfo optimize_results_stg1; //!< Results from the least-squares optimization
166 
167  void clear()
168  {
169  kf_id = static_cast<TKeyFrameID>(-1);
170  created_edge_ids.clear();
171  optimize_results.clear();
172  }
173  };
174 
175  /** @name Main API methods
176  @{ */
177 
178  /** The most common entry point for SRBA: append a new keyframe (KF) to the map, automatically creates the required edges
179  * and optimize the local area around this new KF.
180  *
181  * \param[in] obs All the landmark observations gathered from this new KF (with data association already solved).
182  * \param[out] out_new_kf_info Returned information about the newly created KF.
183  * \param[in] run_local_optimization If set to true (default), the local map around the new KF will be optimized (i.e. optimize_local_area() will be called automatically).
184  */
185  void define_new_keyframe(
186  const typename traits_t::new_kf_observations_t & obs,
187  TNewKeyFrameInfo & out_new_kf_info,
188  const bool run_local_optimization = true
189  );
190 
191  /** Parameters for optimize_local_area() */
193  {
196  TKeyFrameID max_visitable_kf_id; //!< While exploring around the root KF, stop the BFS when KF_ID>=this number (default:infinity)
197  size_t dont_optimize_landmarks_seen_less_than_n_times; //!< Set to 1 to try to optimize all landmarks even if they're just observed once, which may makes sense depending on the sensor type (default: 2)
198 
200  optimize_k2k_edges(true),
201  optimize_landmarks(true),
202  max_visitable_kf_id( static_cast<TKeyFrameID>(-1) ),
203  dont_optimize_landmarks_seen_less_than_n_times( 2 )
204  {}
205  };
206 
207  /** Runs least-squares optimization for all the unknowns within a given topological distance to a given KeyFrame.
208  *
209  * \param[in] observation_indices_to_optimize Indices wrt \a rba_state.all_observations. An empty vector means use ALL the observations involving the selected unknowns.
210  * \note Extra options are available in \a parameters
211  * \sa define_new_keyframe, add_observation, optimize_edges
212  */
213  void optimize_local_area(
214  const TKeyFrameID root_id,
215  const unsigned int win_size,
216  TOptimizeExtraOutputInfo & out_info,
217  const TOptimizeLocalAreaParams &params = TOptimizeLocalAreaParams(),
218  const std::vector<size_t> & observation_indices_to_optimize = std::vector<size_t>()
219  );
220 
221 
222  struct TOpenGLRepresentationOptions : public LM_TYPE::render_mode_t::TOpenGLRepresentationOptionsExtra
223  {
225  span_tree_max_depth(static_cast<size_t>(-1)),
226  draw_unknown_feats(true),
227  draw_unknown_feats_ellipses(true),
228  draw_unknown_feats_ellipses_quantiles(1),
229  show_unknown_feats_ids(true)
230  {
231  }
232 
233  size_t span_tree_max_depth; //!< Maximum spanning tree depth for reconstructing relative poses (default=-1 : infinity)
234  bool draw_unknown_feats; //!< Draw features with non-fixed rel.pos as well?
238  };
239 
240  /** Build an opengl representation of the current state of this RBA problem
241  * One of different representations can be generated: those opengl objects passed as NULL smart pointers will not be generated.
242  * \param[out] out_scene If not a NULL smart pointer, at return will hold a 3D view of the current KF, neighbor KFs and landmarks.
243  * \param[out] out_root_tree If not a NULL smart pointer, at return will hold a schematic 2D view of the current KF and its spanning tree.
244  */
245  void build_opengl_representation(
246  const srba::TKeyFrameID root_keyframe,
247  const TOpenGLRepresentationOptions &options,
248  mrpt::opengl::CSetOfObjectsPtr out_scene,
249  mrpt::opengl::CSetOfObjectsPtr out_root_tree = mrpt::opengl::CSetOfObjectsPtr()
250  ) const;
251 
252  /** Exports all the keyframes (and optionally all landmarks) as a directed graph in DOT (graphviz) format.
253  * \return false on any error writing to target file */
254  bool save_graph_as_dot(
255  const std::string &targetFileName,
256  const bool all_landmarks = false
257  ) const;
258 
259  /** Evaluates the quality of the overall map/landmark estimations, by computing the sum of the squared
260  * error contributions for all observations. For this, this method may have to compute *very long* shortest paths
261  * between distant keyframes if no loop-closure edges exist in order to evaluate the best approximation of relative
262  * coordinates between observing KFs and features' reference KFs.
263  *
264  * The worst-case time consumed by this method is O(M*log(N) + N^2 + N E), N=# of KFs, E=# of edges, M=# of observations.
265  */
266  double eval_overall_squared_error() const;
267 
269  {
270  TKeyFrameID root_kf_id; //!< The KF to use as a root for the spanning tree to init global poses (default=0)
271 
272  ExportGraphSLAM_Params() : root_kf_id(0) {}
273  };
274  /** Build a graph-slam problem suitable for recovering the (consistent) global pose (vs. relative ones as are handled in SRBA) of each keyframe.
275  * \note This version of the method doesn't account for the covariances of relative pose estimations in RBA.
276  * \sa mrpt::graphslam (for methods capable of optimizing the output graph of pose constraints)
277  * \param[out] global_graph Previous contents will be erased. The output global graph will be returned here, initialized with poses from a Dijkstra/Spanning-tree from the first KF.
278  * \tparam POSE_GRAPH Must be an instance of mrpt::graphs::CNetworkOfPoses<>, e.g. CNetworkOfPoses2D (for 2D poses) or CNetworkOfPoses3D (for 3D).
279  * \note This method is NOT O(1)
280  */
281  template <class POSE_GRAPH>
282  void get_global_graphslam_problem(POSE_GRAPH &global_graph, const ExportGraphSLAM_Params &params = ExportGraphSLAM_Params() ) const;
283 
284 
285  /** @} */ // End of main API methods
286 
287 
288  /** @name Extra API methods (for debugging, etc.)
289  @{ */
290 
291  /** Reset the entire problem to an empty state (automatically called at construction) */
292  void clear();
293 
294  /** Users normally won't need to call this directly. Use define_new_keyframe() instead.
295  * This method appends an empty new keyframe to the data structures
296  * \return The ID of the new KF.
297  * \note Runs in O(1)
298  */
299  TKeyFrameID alloc_keyframe();
300 
301  /** Users normally won't need to call this directly. Use define_new_keyframe() instead.
302  * This method calls:
303  * 1) alloc_kf2kf_edge() for creating the data structures
304  * 2) spanning_tree.update_symbolic_new_node() for updating the spanning trees.
305  *
306  * \note obs is passed just for fixing missing spanning trees when using the policy of pure linear graph.
307  */
308  size_t create_kf2kf_edge(
309  const TKeyFrameID new_kf_id,
310  const TPairKeyFrameID & new_edge,
311  const typename traits_t::new_kf_observations_t & obs,
312  const pose_t &init_inv_pose_val = pose_t() );
313 
314 
315  /** Creates a numeric spanning tree between a given root keyframe and the entire graph, returning it into a user-supplied data structure
316  * Note that this method does NOT use the depth-limited spanning trees which are built incrementally with the graph. So, it takes an extra cost to
317  * call this method. For the other trees, see get_rba_state()
318  * \param[in] root_id The root keyframe
319  * \param[out] span_tree The output with all found relative poses. Its previous contents are cleared.
320  * \param[in] max_depth Defaults to std::numeric_limits<size_t>::max() for infinity depth, can be set to a maximum desired depth from the root.
321  * \param[in] aux_ws Auxiliary working space: Set to an uninitialized vector<bool> (it'll automatically initialized) if you want to call this method simultaneously from several threads. Otherwise, setting to NULL will automatically use one working space, reusable between succesive calls.
322  * \sa find_path_bfs
323  */
324  void create_complete_spanning_tree(
325  const TKeyFrameID root_id,
326  frameid2pose_map_t & span_tree,
327  const size_t max_depth = std::numeric_limits<size_t>::max(),
328  std::vector<bool> * aux_ws = NULL
329  ) const;
330 
331  /** An unconstrained breadth-first search (BFS) for the shortest path between two keyframes.
332  * Note that this method does NOT use the depth-limited spanning trees which are built incrementally with the graph. So, it takes the extra cost of
333  * really running a BFS algorithm. For the other precomputed trees, see get_rba_state()
334  * Edge direction is ignored during the search, i.e. as if we had an undirected graph of Keyframes.
335  * If both source and target KF coincide, an empty path is returned.
336  * \return true if a path was found.
337  * \note Worst-case computational complexity is that of a BFS over the entire graph: O(V+E), V=number of nodes, E=number of edges.
338  * \sa create_complete_spanning_tree
339  */
341  const TKeyFrameID src_kf,
342  const TKeyFrameID trg_kf,
343  std::vector<TKeyFrameID> & found_path) const
344  {
345  return rba_state.find_path_bfs(src_kf,trg_kf,&found_path);
346  }
347 
348  /** Visits all k2k & k2f edges following a BFS starting at a given starting node and up to a given maximum depth.
349  * Only k2k edges are considered for BFS paths.
350  */
351  template <
352  class KF_VISITOR,
353  class FEAT_VISITOR,
354  class K2K_EDGE_VISITOR,
355  class K2F_EDGE_VISITOR
356  >
357  void bfs_visitor(
358  const TKeyFrameID root_id,
359  const topo_dist_t max_distance,
360  const bool rely_on_prebuilt_spanning_trees,
361  KF_VISITOR & kf_visitor,
362  FEAT_VISITOR & feat_visitor,
363  K2K_EDGE_VISITOR & k2k_edge_visitor,
364  K2F_EDGE_VISITOR & k2f_edge_visitor ) const;
365 
366  /** @} */ // End of Extra API methods
367 
368 
369  /** @name Public data fields
370  @{ */
371 
372  /** Different parameters for the SRBA methods */
374  {
375  TSRBAParameters();
376 
377  /** See docs of mrpt::utils::CLoadableOptions */
378  virtual void loadFromConfigFile(const mrpt::utils::CConfigFileBase & source,const std::string & section);
379  /** See docs of mrpt::utils::CLoadableOptions */
380  virtual void saveToConfigFile(mrpt::utils::CConfigFileBase &out,const std::string & section) const;
381 
382 
383  /** Parameters for determine_kf2kf_edges_to_create(); custom user-defined policies can be also defined (see tutorials) */
385 
386  /** Maximum depth for maintained spanning trees. */
388 
389  /** The maximum topological distance of keyframes to be optimized around the most recent keyframe. */
391 
392  size_t submap_size;
393  size_t min_obs_to_loop_closure; //!< Default:6, reduce to 1 for relative graph-slam
394  // -------------------------------------------------------
395 
396  // Parameters for optimize_*()
397  // -------------------------------------
398  bool optimize_new_edges_alone; //!< (Default:true) Before running a whole "local area" optimization, try to optimize new edges one by one to have a better starting point.
401  double kernel_param;
402  size_t max_iters;
403  double max_error_per_obs_to_stop; //!< default: 1e-9
404  double max_rho; //!< default: 1.0
405  double max_lambda; //!< default: 1e20
407  bool numeric_jacobians; //!< (Default:false) Use a numeric approximation of the Jacobians (very slow!) instead of analytical ones.
408  void (*feedback_user_iteration)(unsigned int iter, const double total_sq_err, const double mean_sqroot_error);
409  bool compute_condition_number; //!< Compute and return to the user the Hessian condition number of k2k edges (default=false)
410 
411  TCovarianceRecoveryPolicy cov_recovery; //!< Recover covariance? What method to use? (Default: crpLandmarksApprox)
412  // -------------------------------------
413 
414  };
415 
416  /** The unique struct which hold all the parameters from the different SRBA modules (sensors, optional features, optimizers,...) */
418  {
419  /** Different parameters for the SRBA methods \sa sensor_params */
421 
422  /** Sensor-specific parameters (sensor calibration, etc.) \sa parameters */
423  typename OBS_TYPE::TObservationParams sensor;
424 
425  /** Parameters related to the relative pose of sensors wrt the robot (if applicable) */
426  typename RBA_OPTIONS::sensor_pose_on_robot_t::parameters_t sensor_pose;
427 
428  /** Parameters related to the sensor noise covariance matrix */
429  typename RBA_OPTIONS::obs_noise_matrix_t::parameters_t obs_noise;
430  };
431 
433 
434  /** @} */ // End of data fields
435 
436 
437  /** Enable or disables time profiling of all operations (default=enabled), which will be reported upon destruction */
438  void inline enable_time_profiler(bool enable=true) { m_profiler.enable(enable); }
439 
440  const k2k_edges_deque_t & get_k2k_edges() const { return rba_state.k2k_edges; }
441 
442  const TRelativeLandmarkPosMap & get_known_feats() const { return rba_state.known_lms; }
443  const TRelativeLandmarkPosMap & get_unknown_feats() const { return rba_state.unknown_lms; }
444 
445  const rba_problem_state_t & get_rba_state() const { return rba_state; }
446  rba_problem_state_t & get_rba_state() { return rba_state; }
447 
448  /** Access to the time profiler */
449  inline mrpt::utils::CTimeLogger & get_time_profiler() { return m_profiler; }
450 
451  /** Changes the verbosity level: 0=None (only critical msgs), 1=verbose, 2=so verbose you'll have to say "Stop!" */
452  inline void setVerbosityLevel(int level) { m_verbose_level = level; }
453 
454  /** Rebuild the Hessian symbolic information from the given Jacobians.
455  * \param[out] H Output hessian (must be empty at input)
456  */
457  template <class HESS_Ap, class HESS_f,class HESS_Apf, class JACOB_COLUMN_dh_dAp,class JACOB_COLUMN_dh_df>
458  static void sparse_hessian_build_symbolic(
459  HESS_Ap & HAp,
460  HESS_f & Hf,
461  HESS_Apf & HApf,
462  const std::vector<JACOB_COLUMN_dh_dAp*> & dh_dAp,
463  const std::vector<JACOB_COLUMN_dh_df*> & dh_df);
464 
465  /** Rebuild the Hessian symbolic information from the internal pointers to blocks of Jacobians.
466  * Only the upper triangle is filled-in (all what is needed for Cholesky) for square Hessians, in whole for rectangular ones (it depends on the symbolic decomposition, done elsewhere).
467  * \tparam SPARSEBLOCKHESSIAN can be: TSparseBlocksHessian_6x6, TSparseBlocksHessian_3x3 or TSparseBlocksHessian_6x3
468  * \return The number of Jacobian multiplications skipped due to its observation being marked as "invalid"
469  */
470  template <class SPARSEBLOCKHESSIAN>
471  size_t sparse_hessian_update_numeric( SPARSEBLOCKHESSIAN & H ) const;
472 
473 
474  protected:
475  int m_verbose_level; //!< 0: None (only critical msgs), 1: verbose, 2:even more verbose, 3: even more
476 
477  typedef std::multimap<size_t,TKeyFrameID,std::greater<size_t> > base_sorted_lst_t;
478 
479  /** @name (Protected) Sub-algorithms
480  @{ */
481 
482  /** Make a list of base KFs of my new observations, ordered in descending order by # of shared observations: */
483  void make_ordered_list_base_kfs(
484  const typename traits_t::new_kf_observations_t & obs,
485  base_sorted_lst_t & obs_for_each_base_sorted,
486  map<TKeyFrameID,size_t> *out_obs_for_each_base =NULL ) const;
487 
488  /** This method will call edge_creation_policy(), which has predefined algorithms but could be re-defined by the user in a derived class */
489  void determine_kf2kf_edges_to_create(
490  const TKeyFrameID new_kf_id,
491  const typename traits_t::new_kf_observations_t & obs,
492  std::vector<TNewEdgeInfo> &new_k2k_edge_ids );
493 
494  /** Implements the edge-creation policy, by default depending on "parameters.edge_creation_policy" if the user doesn't re-implement this virtual method.
495  * See tutorials for examples of how to implement custom policies. */
496  virtual void edge_creation_policy(
497  const TKeyFrameID new_kf_id,
498  const typename traits_t::new_kf_observations_t & obs,
499  std::vector<TNewEdgeInfo> &new_k2k_edge_ids );
500 
501  /**
502  * \param observation_indices_to_optimize Indices wrt \a rba_state.all_observations. An empty vector means use ALL the observations involving the selected unknowns.
503  * \sa optimize_local_area
504  */
505  void optimize_edges(
506  const std::vector<size_t> & run_k2k_edges,
507  const std::vector<size_t> & run_feat_ids_in,
508  TOptimizeExtraOutputInfo & out_info,
509  const std::vector<size_t> & observation_indices_to_optimize = std::vector<size_t>()
510  );
511 
512  /** @} */
513 
514  /** Aux visitor struct, used in optimize_local_area() */
516  {
517  VisitorOptimizeLocalArea(const rba_problem_state_t & rba_state_, const TOptimizeLocalAreaParams &params_) :
518  rba_state(rba_state_),
519  params(params_)
520  { }
521 
522  const rba_problem_state_t & rba_state;
524 
525  vector<size_t> k2k_edges_to_optimize, lm_IDs_to_optimize;
526  map<TLandmarkID,size_t> lm_times_seen;
527 
528  /* Implementation of FEAT_VISITOR */
529  inline bool visit_filter_feat(const TLandmarkID lm_ID,const topo_dist_t cur_dist)
530  {
531  MRPT_UNUSED_PARAM(lm_ID); MRPT_UNUSED_PARAM(cur_dist);
532  return false; // Don't need to visit landmark nodes.
533  }
534 
535  inline void visit_feat(const TLandmarkID lm_ID,const topo_dist_t cur_dist)
536  {
537  MRPT_UNUSED_PARAM(lm_ID); MRPT_UNUSED_PARAM(cur_dist);
538  // Nothing to do
539  }
540 
541  /* Implementation of KF_VISITOR */
542  inline bool visit_filter_kf(const TKeyFrameID kf_ID,const topo_dist_t cur_dist)
543  {
544  MRPT_UNUSED_PARAM(cur_dist);
545  return (kf_ID<=params.max_visitable_kf_id);
546  }
547 
548  inline void visit_kf(const TKeyFrameID kf_ID,const topo_dist_t cur_dist)
549  {
550  MRPT_UNUSED_PARAM(kf_ID); MRPT_UNUSED_PARAM(cur_dist);
551  // Nothing to do.
552  }
553 
554  /* Implementation of K2K_EDGE_VISITOR */
555  inline bool visit_filter_k2k(const TKeyFrameID current_kf, const TKeyFrameID next_kf,
556  const k2k_edge_t* edge, const topo_dist_t cur_dist)
557  {
558  MRPT_UNUSED_PARAM(current_kf); MRPT_UNUSED_PARAM(next_kf);
559  MRPT_UNUSED_PARAM(edge); MRPT_UNUSED_PARAM(cur_dist);
560  return true; // Visit all k2k edges
561  }
562 
563  inline void visit_k2k(const TKeyFrameID current_kf, const TKeyFrameID next_kf,
564  const k2k_edge_t* edge, const topo_dist_t cur_dist)
565  {
566  MRPT_UNUSED_PARAM(current_kf); MRPT_UNUSED_PARAM(next_kf);
567  MRPT_UNUSED_PARAM(cur_dist);
568  if (params.optimize_k2k_edges)
569  k2k_edges_to_optimize.push_back(edge->id);
570  }
571 
572  /* Implementation of K2F_EDGE_VISITOR */
573  inline bool visit_filter_k2f(const TKeyFrameID current_kf, const k2f_edge_t* edge,
574  const topo_dist_t cur_dist)
575  {
576  MRPT_UNUSED_PARAM(current_kf); MRPT_UNUSED_PARAM(edge); MRPT_UNUSED_PARAM(cur_dist);
577  return params.optimize_landmarks; // Yes: visit all feature nodes if we're asked to
578  }
579  inline void visit_k2f(const TKeyFrameID current_kf, const k2f_edge_t* edge, const topo_dist_t cur_dist)
580  {
581  MRPT_UNUSED_PARAM(current_kf); MRPT_UNUSED_PARAM(cur_dist);
582  if (!edge->feat_has_known_rel_pos)
583  {
584  const TLandmarkID lm_ID = edge->obs.obs.feat_id;
585  // Use an "==" so we only add the LM_ID to the list ONCE, just when it passes the threshold
586  if (++lm_times_seen[lm_ID] == params.dont_optimize_landmarks_seen_less_than_n_times)
587  lm_IDs_to_optimize.push_back(lm_ID);
588  }
589  }
590  };
591 
592  private:
593  rba_problem_state_t rba_state; //!< All the beef is here.
594 
595  mutable std::vector<bool> m_complete_st_ws; //!< Temporary working space used in \a create_complete_spanning_tree()
596 
597  /** Profiler for all SRBA operations
598  * Enabled by default, can be disabled with \a enable_time_profiler(false)
599  */
601 
602  /** Creates a new known/unknown position landmark (upon first LM observation ), and expands Jacobians with new observation
603  * \param[in] new_obs The basic data on the observed landmark: landmark ID, keyframe from which it's observed and parameters ("z" vector) of the observation itself (e.g. pixel coordinates).
604  * \param[in] fixed_relative_position If not NULL, this is the first observation of a landmark with a fixed, known position. Each such feature can be created only once, next observations MUST have this field set to NULL as with normal ("unfixed") landmarks.
605  * \param[in] unknown_relative_position_init_val Can be set to not-NULL only upon the first observation of a landmark with an unknown relative position. The feature will be created with this initial value for its relative position wrt the KF (further optimization will refine that value).
606  *
607  * \return The 0-based index of the new observation
608  *
609  * \note Both \a fixed_relative_position and \a unknown_relative_position_init_val CAN'T be set to !=NULL at once.
610  *
611  * \note If new edges had been introduced before this observation, make sure the symbolic spanning trees are up-to-date!
612  *
613  * \note Runs in O(P+log C), with:
614  * - C=typical amount of KFs which all see the same landmark,
615  * - P=typical number of kf2kf edges between observing and the base KF of the observed landmark.
616  */
617  size_t add_observation(
618  const TKeyFrameID observing_kf_id,
619  const typename observation_traits_t::observation_t & new_obs,
620  const array_landmark_t * fixed_relative_position = NULL,
621  const array_landmark_t * unknown_relative_position_init_val = NULL
622  );
623 
624  /** Prepare the list of all required KF roots whose spanning trees need numeric updates with each optimization iteration */
625  void prepare_Jacobians_required_tree_roots(
626  std::set<TKeyFrameID> & kfs_num_spantrees_to_update,
627  const std::vector<typename TSparseBlocksJacobians_dh_dAp::col_t*> &lst_JacobCols_dAp,
628  const std::vector<typename TSparseBlocksJacobians_dh_df::col_t*> &lst_JacobCols_df );
629 
630 
631  /** Re-evaluate all Jacobians numerically using their symbolic info. Return overall number of block Jacobians */
632  size_t recompute_all_Jacobians(
633  std::vector<typename TSparseBlocksJacobians_dh_dAp::col_t*> &lst_JacobCols_dAp,
634  std::vector<typename TSparseBlocksJacobians_dh_df::col_t*> &lst_JacobCols_df,
635  std::vector<const pose_flag_t*> * out_list_of_required_num_poses = NULL );
636 
637  public:
638 
639  /** Private aux structure for BFS searches. */
641  {
642  TBFSEntryEdges() : dist( numeric_limits<topo_dist_t>::max() ), edge(NULL)
643  {}
644 
647  const k2k_edge_t* edge;
648  };
649 
650 
651  /** ====================================================================
652  j,i lm_id,base_id
653  \partial h \partial h
654  l obs_frame_id
655  dh_dp = ------------------ = ---------------------------------
656  d+1 cur_id
657  \partial p \partial p
658  d stp.next_node
659 
660  See tech report:
661  "A tutorial on SE(3) transformation parameterizations and
662  on-manifold optimization", Jose-Luis Blanco, 2010.
663  ==================================================================== */
664  void compute_jacobian_dh_dp(
665  typename TSparseBlocksJacobians_dh_dAp::TEntry &jacob,
666  const k2f_edge_t & observation,
667  const k2k_edges_deque_t &k2k_edges,
668  std::vector<const pose_flag_t*> *out_list_of_required_num_poses) const;
669 
670  /** ====================================================================
671  j,i lm_id,base_id
672  \partial h \partial h
673  l obs_frame_id
674  dh_df = ------------------ = ---------------------------------
675 
676  \partial f \partial f
677 
678  Note: f=relative position of landmark with respect to its base kf
679  ==================================================================== */
680  void compute_jacobian_dh_df(
681  typename TSparseBlocksJacobians_dh_df::TEntry &jacob,
682  const k2f_edge_t & observation,
683  std::vector<const pose_flag_t*> *out_list_of_required_num_poses) const;
684 
685  void gl_aux_draw_node(mrpt::opengl::CSetOfObjects &soo, const std::string &label, const float x, const float y) const;
686 
687  const pose_t aux_null_pose; //!< A fixed SE(3) pose at the origin (used when we need a pointer or a reference to a "null transformation").
688 
690  {
692  const size_t _k2k_edge_id,
693  const pose_t * _pose_d1_wrt_obs,
694  const pose_t & _pose_base_wrt_d1,
695  const array_landmark_t & _xji_i,
696  const bool _is_inverse_dir,
697  const k2k_edges_deque_t &_k2k_edges,
698  const typename OBS_TYPE::TObservationParams & _sensor_params,
699  const typename RBA_OPTIONS::sensor_pose_on_robot_t::parameters_t & _sensor_pose
700  ) :
701  k2k_edge_id(_k2k_edge_id),
702  pose_d1_wrt_obs(_pose_d1_wrt_obs),
703  pose_base_wrt_d1(_pose_base_wrt_d1),
704  xji_i(_xji_i),
705  is_inverse_dir(_is_inverse_dir),
706  k2k_edges(_k2k_edges),
707  sensor_params(_sensor_params),
708  sensor_pose(_sensor_pose)
709  {
710  }
711 
712  const size_t k2k_edge_id;
713  const pose_t * pose_d1_wrt_obs;
714  const pose_t & pose_base_wrt_d1;
715  const array_landmark_t & xji_i;
716  const bool is_inverse_dir;
717  const k2k_edges_deque_t &k2k_edges;
718  const typename OBS_TYPE::TObservationParams & sensor_params;
719  const typename RBA_OPTIONS::sensor_pose_on_robot_t::parameters_t & sensor_pose;
720  };
721 
723  {
725  const pose_t * _pose_base_wrt_obs,
726  const array_landmark_t & _xji_i,
727  const typename OBS_TYPE::TObservationParams & _sensor_params,
728  const typename RBA_OPTIONS::sensor_pose_on_robot_t::parameters_t & _sensor_pose
729  ) :
730  pose_base_wrt_obs(_pose_base_wrt_obs),
731  xji_i(_xji_i),
732  sensor_params(_sensor_params),
733  sensor_pose(_sensor_pose)
734  {
735  }
736 
737  const pose_t * pose_base_wrt_obs;
738  const array_landmark_t & xji_i;
739  const typename OBS_TYPE::TObservationParams & sensor_params;
740  const typename RBA_OPTIONS::sensor_pose_on_robot_t::parameters_t & sensor_pose;
741  };
742 
743  /** Auxiliary method for numeric Jacobian: numerically evaluates the new observation "y" for a small increment "x" in a relative KF-to-KF pose */
744  static void numeric_dh_dAp(const array_pose_t &x, const TNumeric_dh_dAp_params& params, array_obs_t &y);
745  /** Auxiliary method for numeric Jacobian: numerically evaluates the new observation "y" for a small increment "x" in a landmark position */
746  static void numeric_dh_df(const array_landmark_t &x, const TNumeric_dh_df_params& params, array_obs_t &y);
747 
748  static inline void add_edge_ij_to_list_needed_roots(std::set<TKeyFrameID> & lst, const TKeyFrameID i, const TKeyFrameID j)
749  {
750  lst.insert(i);
751  lst.insert(j);
752  }
753 
754  void compute_minus_gradient(
755  Eigen::VectorXd & minus_grad,
756  const std::vector<typename TSparseBlocksJacobians_dh_dAp::col_t*> & sparse_jacobs_Ap,
757  const std::vector<typename TSparseBlocksJacobians_dh_df::col_t*> & sparse_jacobs_f,
758  const vector_residuals_t & residuals,
759  const std::map<size_t,size_t> &obs_global_idx2residual_idx
760  ) const;
761 
762  /** Each of the observations used during the optimization */
763  struct TObsUsed
764  {
765  TObsUsed(const size_t obs_idx_, k2f_edge_t * const k2f_) : obs_idx(obs_idx_),k2f(k2f_)
766  { }
767 
768  size_t obs_idx; //!< Global index in all_observations
769  k2f_edge_t* k2f; //!< Obs data
770 
771  private:
772  // Don't use this constructor
773  TObsUsed() : obs_idx(0), k2f(NULL) {}
774  }; // end of TObsUsed
775 
776 
777  inline double reprojection_residuals(
778  vector_residuals_t & residuals, // Out:
779  const std::vector<TObsUsed> & observations // In:
780  ) const;
781 
782  /** pseudo-huber cost function */
783  static inline double huber_kernel(double delta, const double kernel_param)
784  {
785  return std::abs(2*mrpt::utils::square(kernel_param)*(std::sqrt(1+mrpt::utils::square(delta/kernel_param))-1));
786  }
787 
788  }; // end of class "RbaEngine"
789 
790 
791 } // end of namespace "srba"
792 } // end of namespace "mrpt"
793 
794 // -----------------------------------------------------------------
795 // Include all template implementation files
796 // -----------------------------------------------------------------
797 #include "impl/add-observations.h"
798 #include "impl/alloc_keyframe.h"
799 #include "impl/alloc_kf2kf_edge.h"
800 #include "impl/create_kf2kf_edge.h"
802 #include "impl/jacobians.h"
803 #include "impl/rba_problem_common.h"
804 #include "impl/schur.h"
807 
811 #include "impl/spantree_misc.h"
812 
813 #include "impl/jacobians.h"
814 
815 #include "impl/export_opengl.h"
816 #include "impl/export_dot.h"
818 
819 #include "impl/eval_overall_error.h"
820 
823 
826 #include "impl/optimize_edges.h"
827 #include "impl/lev-marq_solvers.h"
828 
829 #include "impl/bfs_visitor.h"
831 // -----------------------------------------------------------------
832 // ^^ End of implementation files ^^
833 // -----------------------------------------------------------------
834 
835 // Undefine temporary macro for verbose output
836 #undef VERBOSE_LEVEL
837 
RBA_OPTIONS::obs_noise_matrix_t::parameters_t obs_noise
Parameters related to the sensor noise covariance matrix.
Definition: RbaEngine.h:429
size_t num_observations
Number of individual feature observations taken into account in the optimization. ...
Definition: RbaEngine.h:126
The main class for the mrpt-srba: it defines a Relative Bundle-Adjustment (RBA) problem with (optiona...
Definition: RbaEngine.h:62
map< TLandmarkID, size_t > lm_times_seen
Definition: RbaEngine.h:526
TAllParameters parameters
Definition: RbaEngine.h:432
bool optimize_new_edges_alone
(Default:true) Before running a whole "local area" optimization, try to optimize new edges one by one...
Definition: RbaEngine.h:398
A STL-like container which looks and behaves (almost exactly) like a std::map<> but is implemented as...
Definition: map_as_vector.h:46
obs_traits_t::observation_t obs
Observation data.
Definition: srba_types.h:433
const rba_problem_state_t & rba_state
Definition: RbaEngine.h:522
RBA_OPTIONS rba_options_type
Definition: RbaEngine.h:72
KF2KF_POSE_TYPE kf2kf_pose_type
Definition: RbaEngine.h:69
jacobian_traits< KF2KF_POSE_TYPE, LM_TYPE, OBS_TYPE > jacobian_traits_t
Definition: RbaEngine.h:81
TObsUsed(const size_t obs_idx_, k2f_edge_t *const k2f_)
Definition: RbaEngine.h:765
TKeyFrameID max_visitable_kf_id
While exploring around the root KF, stop the BFS when KF_ID>=this number (default:infinity) ...
Definition: RbaEngine.h:196
observation_traits_t::vector_residuals_t vector_residuals_t
Definition: RbaEngine.h:109
const rba_problem_state_t & get_rba_state() const
Definition: RbaEngine.h:445
size_t num_span_tree_numeric_updates
Number of poses updated in the spanning tree numeric-update stage.
Definition: RbaEngine.h:131
double obs_rmse
RMSE for each observation after optimization.
Definition: RbaEngine.h:132
A set of object, which are referenced to the coordinates framework established in this object...
Definition: CSetOfObjects.h:32
options::solver_LM_schur_dense_cholesky solver_t
Solver algorithm (Default: Lev-Marq, with Schur, with dense Cholesky)
Definition: RbaEngine.h:39
double max_error_per_obs_to_stop
default: 1e-9
Definition: RbaEngine.h:403
T square(const T x)
Inline function for the square of a number.
TKeyFrameID kf_id
The ID of the newly created KF.
Definition: RbaEngine.h:162
TNumeric_dh_df_params(const pose_t *_pose_base_wrt_obs, const array_landmark_t &_xji_i, const typename OBS_TYPE::TObservationParams &_sensor_params, const typename RBA_OPTIONS::sensor_pose_on_robot_t::parameters_t &_sensor_pose)
Definition: RbaEngine.h:724
bool compute_condition_number
Compute and return to the user the Hessian condition number of k2k edges (default=false) ...
Definition: RbaEngine.h:409
bool visit_filter_k2k(const TKeyFrameID current_kf, const TKeyFrameID next_kf, const k2k_edge_t *edge, const topo_dist_t cur_dist)
Definition: RbaEngine.h:555
uint64_t TLandmarkID
Numeric IDs for landmarks.
Definition: srba_types.h:32
const RBA_OPTIONS::sensor_pose_on_robot_t::parameters_t & sensor_pose
Definition: RbaEngine.h:719
topo_dist_t max_tree_depth
Maximum depth for maintained spanning trees.
Definition: RbaEngine.h:387
TEdgeCreationPolicy
For usage in RbaEngine.parameters.
Definition: srba_types.h:164
hessian_traits< KF2KF_POSE_TYPE, LM_TYPE, OBS_TYPE > hessian_traits_t
Definition: RbaEngine.h:82
RBA_OPTIONS::sensor_pose_on_robot_t::parameters_t sensor_pose
Parameters related to the relative pose of sensors wrt the robot (if applicable)
Definition: RbaEngine.h:426
Different parameters for the SRBA methods.
Definition: RbaEngine.h:373
Usage: A possible type for RBA_OPTIONS::solver_t.
rba_problem_state_t::k2k_edges_deque_t k2k_edges_deque_t
A list (deque) of KF-to-KF edges (unknown relative poses).
Definition: RbaEngine.h:94
mrpt::utils::CTimeLogger m_profiler
Profiler for all SRBA operations Enabled by default, can be disabled with enable_time_profiler(false)...
Definition: RbaEngine.h:600
size_t obs_idx
Global index in all_observations.
Definition: RbaEngine.h:768
const k2k_edges_deque_t & get_k2k_edges() const
Definition: RbaEngine.h:440
TOptimizeExtraOutputInfo optimize_results_stg1
Results from the least-squares optimization.
Definition: RbaEngine.h:165
size_t id
0-based index of this edge, in the std::list "k2k_edges".
Definition: srba_types.h:88
STL namespace.
TSRBAParameters srba
Different parameters for the SRBA methods.
Definition: RbaEngine.h:420
observation_traits< OBS_TYPE > observation_traits_t
Definition: RbaEngine.h:85
Each of the observations used during the optimization.
Definition: RbaEngine.h:763
std::vector< size_t > optimized_k2k_edge_indices
The 0-based indices of all kf-to-kf edges which were considered in the optimization.
Definition: RbaEngine.h:136
kf2kf_pose_traits_t::pose_flag_t pose_flag_t
Definition: RbaEngine.h:96
KF2KF_POSE_TYPE::pose_t pose_t
The type of relative poses (e.g. mrpt::poses::CPose3D)
Definition: RbaEngine.h:89
Keyframe-to-keyframe edge: an unknown of the problem.
Definition: srba_types.h:82
TCovarianceRecoveryPolicy cov_recovery
Recover covariance? What method to use? (Default: crpLandmarksApprox)
Definition: RbaEngine.h:411
double min_error_reduction_ratio_to_relinearize
default 0.01
Definition: RbaEngine.h:406
double HAp_condition_number
To be computed only if enabled in parameters.compute_condition_number.
Definition: RbaEngine.h:134
uint64_t topo_dist_t
Unsigned integral type for topological distances in a graph/tree.
Definition: srba_types.h:33
std::deque< new_kf_observation_t > new_kf_observations_t
A set of all the observations made from a new KF, as provided by the user.
Definition: srba_types.h:422
Usage: A possible type for RBA_OPTIONS::obs_noise_matrix_t.
bool visit_filter_k2f(const TKeyFrameID current_kf, const k2f_edge_t *edge, const topo_dist_t cur_dist)
Definition: RbaEngine.h:573
kf2kf_pose_traits_t::TRelativePosesForEachTarget TRelativePosesForEachTarget
Definition: RbaEngine.h:98
TNumeric_dh_dAp_params(const size_t _k2k_edge_id, const pose_t *_pose_d1_wrt_obs, const pose_t &_pose_base_wrt_d1, const array_landmark_t &_xji_i, const bool _is_inverse_dir, const k2k_edges_deque_t &_k2k_edges, const typename OBS_TYPE::TObservationParams &_sensor_params, const typename RBA_OPTIONS::sensor_pose_on_robot_t::parameters_t &_sensor_pose)
Definition: RbaEngine.h:691
This class allows loading and storing values and vectors of different types from a configuration text...
kf2kf_pose_traits_t::array_pose_t array_pose_t
Definition: RbaEngine.h:105
const OBS_TYPE::TObservationParams & sensor_params
Definition: RbaEngine.h:739
observation_traits_t::residual_t residual_t
Definition: RbaEngine.h:108
size_t num_jacobians
Number of Jacobian blocks which had been to be evaluated for each relinearization step...
Definition: RbaEngine.h:127
traits_t::keyframe_info keyframe_info
Definition: RbaEngine.h:101
TCovarianceRecoveryPolicy
Covariances recovery from Hessian matrix policy, for usage in RbaEngine.parameters.
Definition: srba_types.h:176
TKeyFrameID prev
Definition: RbaEngine.h:645
Generic declaration, of which specializations are defined for each combination of LM+OBS type...
Definition: srba_types.h:44
Useful data structures that depend of a combination of "OBSERVATION_TYPE"+"LANDMARK_PARAMETERIZATION_...
Definition: srba_types.h:362
rba_joint_parameterization_traits_t< KF2KF_POSE_TYPE, LM_TYPE, OBS_TYPE > traits_t
Definition: RbaEngine.h:80
Parameters for optimize_local_area()
Definition: RbaEngine.h:192
#define MRPT_UNUSED_PARAM(a)
Can be used to avoid "not used parameters" warnings from the compiler.
size_t num_total_scalar_optimized
The total number of dimensions (scalar values) in all the optimized unknowns.
Definition: RbaEngine.h:130
KF2KF_POSE_TYPE::se_traits_t se_traits_t
The SE(2) or SE(3) traits struct (for Lie algebra log/exp maps, etc.)
Definition: RbaEngine.h:78
std::map< TLandmarkID, TRelativeLandmarkPos > TRelativeLandmarkPosMap
An index of feature IDs and their relative locations.
Definition: srba_types.h:124
Private aux structure for BFS searches.
Definition: RbaEngine.h:640
rba_problem_state_t & get_rba_state()
Definition: RbaEngine.h:446
landmark_traits_t::array_landmark_t array_landmark_t
Definition: RbaEngine.h:106
TOptimizeExtraOutputInfo optimize_results
Results from the least-squares optimization.
Definition: RbaEngine.h:164
const TRelativeLandmarkPosMap & get_known_feats() const
Definition: RbaEngine.h:442
TRBA_Problem_state< KF2KF_POSE_TYPE, LM_TYPE, OBS_TYPE, RBA_OPTIONS > rba_problem_state_t
Definition: RbaEngine.h:90
topo_dist_t dist
Definition: RbaEngine.h:646
void enable_time_profiler(bool enable=true)
Enable or disables time profiling of all operations (default=enabled), which will be reported upon de...
Definition: RbaEngine.h:438
const k2k_edge_t * edge
Definition: RbaEngine.h:647
RBA_OPTIONS::solver_t::extra_results_t extra_results
Other solver-specific output information.
Definition: RbaEngine.h:140
void visit_k2f(const TKeyFrameID current_kf, const k2f_edge_t *edge, const topo_dist_t cur_dist)
Definition: RbaEngine.h:579
landmark_traits_t::TRelativeLandmarkPos TRelativeLandmarkPos
One landmark position (relative to its base KF)
Definition: RbaEngine.h:100
T abs(T x)
Definition: nanoflann.hpp:237
std::vector< size_t > optimized_landmark_indices
The 0-based indices of all landmarks whose relative positions were considered as unknowns in the opti...
Definition: RbaEngine.h:137
TKeyFrameID root_kf_id
The KF to use as a root for the spanning tree to init global poses (default=0)
Definition: RbaEngine.h:270
VisitorOptimizeLocalArea(const rba_problem_state_t &rba_state_, const TOptimizeLocalAreaParams &params_)
Definition: RbaEngine.h:517
mrpt::aligned_containers< k2k_edge_t >::deque_t k2k_edges_deque_t
Definition: srba_types.h:493
jacobian_traits< KF2KF_POSE_TYPE, LM_TYPE, OBS_TYPE >::TSparseBlocksJacobians_dh_df TSparseBlocksJacobians_dh_df
Definition: RbaEngine.h:112
All the important data of a RBA problem at any given instant of time Operations on this structure are...
Definition: srba_types.h:474
size_t span_tree_max_depth
Maximum spanning tree depth for reconstructing relative poses (default=-1 : infinity) ...
Definition: RbaEngine.h:233
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
traits_t::new_kf_observations_t new_kf_observations_t
Definition: RbaEngine.h:103
size_t min_obs_to_loop_closure
Default:6, reduce to 1 for relative graph-slam.
Definition: RbaEngine.h:393
bool draw_unknown_feats
Draw features with non-fixed rel.pos as well?
Definition: RbaEngine.h:234
void visit_k2k(const TKeyFrameID current_kf, const TKeyFrameID next_kf, const k2k_edge_t *edge, const topo_dist_t cur_dist)
Definition: RbaEngine.h:563
mrpt::utils::CTimeLogger & get_time_profiler()
Access to the time profiler.
Definition: RbaEngine.h:449
topo_dist_t max_optimize_depth
The maximum topological distance of keyframes to be optimized around the most recent keyframe...
Definition: RbaEngine.h:390
void visit_kf(const TKeyFrameID kf_ID, const topo_dist_t cur_dist)
Definition: RbaEngine.h:548
TBFSEntryEdges()
Definition: RbaEngine.h:642
bool visit_filter_kf(const TKeyFrameID kf_ID, const topo_dist_t cur_dist)
Definition: RbaEngine.h:542
landmark_traits< LM_TYPE > landmark_traits_t
Definition: RbaEngine.h:84
kf2kf_pose_traits_t::frameid2pose_map_t frameid2pose_map_t
Definition: RbaEngine.h:97
const TRelativeLandmarkPosMap & get_unknown_feats() const
Definition: RbaEngine.h:443
std::pair< TKeyFrameID, TKeyFrameID > TPairKeyFrameID
Used to represent the IDs of a directed edge (first –> second)
Definition: srba_types.h:34
bool visit_filter_feat(const TLandmarkID lm_ID, const topo_dist_t cur_dist)
Definition: RbaEngine.h:529
TEdgeCreationPolicy edge_creation_policy
Parameters for determine_kf2kf_edges_to_create(); custom user-defined policies can be also defined (s...
Definition: RbaEngine.h:384
Aux visitor struct, used in optimize_local_area()
Definition: RbaEngine.h:515
options::sensor_pose_on_robot_none sensor_pose_on_robot_t
The sensor pose coincides with the robot pose.
Definition: RbaEngine.h:37
jacobian_traits< KF2KF_POSE_TYPE, LM_TYPE, OBS_TYPE >::TSparseBlocksJacobians_dh_dAp TSparseBlocksJacobians_dh_dAp
Definition: RbaEngine.h:111
const TOptimizeLocalAreaParams & params
Definition: RbaEngine.h:523
const RBA_OPTIONS::sensor_pose_on_robot_t::parameters_t & sensor_pose
Definition: RbaEngine.h:740
std::vector< TNewEdgeInfo > created_edge_ids
The newly created edges (minimum: 1 edge)
Definition: RbaEngine.h:163
All the information returned by the local area optimizer.
Definition: RbaEngine.h:119
A versatile "profiler" that logs the time spent within each pair of calls to enter(X)-leave(X), among other stats.
Definition: CTimeLogger.h:35
A partial specialization of CArrayNumeric for double numbers.
Definition: CArrayNumeric.h:74
void setVerbosityLevel(int level)
Changes the verbosity level: 0=None (only critical msgs), 1=verbose, 2=so verbose you'll have to say ...
Definition: RbaEngine.h:452
OBS_TYPE::TObservationParams sensor
Sensor-specific parameters (sensor calibration, etc.)
Definition: RbaEngine.h:423
size_t num_kf2kf_edges_optimized
Number of solved unknowns of type "kf-to-kf edge".
Definition: RbaEngine.h:128
const pose_t aux_null_pose
A fixed SE(3) pose at the origin (used when we need a pointer or a reference to a "null transformatio...
Definition: RbaEngine.h:687
std::multimap< size_t, TKeyFrameID, std::greater< size_t > > base_sorted_lst_t
Definition: RbaEngine.h:477
Information per key-frame needed for RBA.
Definition: srba_types.h:453
sensor_model< LM_TYPE, OBS_TYPE > sensor_model_t
The sensor model for the specified combination of LM parameterization + observation type...
Definition: RbaEngine.h:87
landmark_traits_t::TRelativeLandmarkPosMap TRelativeLandmarkPosMap
An index of feature IDs and their relative locations.
Definition: RbaEngine.h:99
mrpt::aligned_containers< residual_t >::vector_t vector_residuals_t
Definition: srba_types.h:145
const OBS_TYPE::TObservationParams & sensor_params
Definition: RbaEngine.h:718
size_t dont_optimize_landmarks_seen_less_than_n_times
Set to 1 to try to optimize all landmarks even if they're just observed once, which may makes sense d...
Definition: RbaEngine.h:197
static void add_edge_ij_to_list_needed_roots(std::set< TKeyFrameID > &lst, const TKeyFrameID i, const TKeyFrameID j)
Definition: RbaEngine.h:748
observation_traits_t::array_obs_t array_obs_t
Definition: RbaEngine.h:107
rba_problem_state_t::k2k_edge_t k2k_edge_t
Definition: RbaEngine.h:93
The set of default settings for RbaEngine.
Definition: RbaEngine.h:35
int m_verbose_level
0: None (only critical msgs), 1: verbose, 2:even more verbose, 3: even more
Definition: RbaEngine.h:475
Keyframe-to-feature edge: observation data stored for each keyframe.
Definition: srba_types.h:442
The unique struct which hold all the parameters from the different SRBA modules (sensors, optional features, optimizers,...)
Definition: RbaEngine.h:417
options::observation_noise_identity obs_noise_matrix_t
The sensor noise matrix is the same for all observations and equal to * I(identity) ...
Definition: RbaEngine.h:38
std::vector< bool > m_complete_st_ws
Temporary working space used in create_complete_spanning_tree()
Definition: RbaEngine.h:595
Usage: A possible type for RBA_OPTIONS::sensor_pose_on_robot_t.
size_t num_kf2lm_edges_optimized
Number of solved unknowns of type "kf-to-landmark".
Definition: RbaEngine.h:129
bool find_path_bfs(const TKeyFrameID src_kf, const TKeyFrameID trg_kf, std::vector< TKeyFrameID > &found_path) const
An unconstrained breadth-first search (BFS) for the shortest path between two keyframes.
Definition: RbaEngine.h:340
Information returned by RbaEngine::define_new_keyframe()
Definition: RbaEngine.h:160
bool feat_has_known_rel_pos
whether it's a known or unknown relative position feature
Definition: srba_types.h:445
kf2kf_pose_traits< KF2KF_POSE_TYPE > kf2kf_pose_traits_t
Definition: RbaEngine.h:83
This is a virtual base class for sets of options than can be loaded from and/or saved to configuratio...
mrpt::aligned_containers< TKeyFrameID, pose_flag_t >::map_t frameid2pose_map_t
"numeric" values of spanning tree poses:
Definition: srba_types.h:71
bool numeric_jacobians
(Default:false) Use a numeric approximation of the Jacobians (very slow!) instead of analytical ones...
Definition: RbaEngine.h:407
rba_problem_state_t rba_state
All the beef is here.
Definition: RbaEngine.h:593
RbaEngine< KF2KF_POSE_TYPE, LM_TYPE, OBS_TYPE, RBA_OPTIONS > rba_engine_t
Definition: RbaEngine.h:67
traits_t::new_kf_observation_t new_kf_observation_t
Definition: RbaEngine.h:102
k2f_edge_t * k2f
Obs data.
Definition: RbaEngine.h:769
void visit_feat(const TLandmarkID lm_ID, const topo_dist_t cur_dist)
Definition: RbaEngine.h:535
rba_problem_state_t::k2f_edge_t k2f_edge_t
Definition: RbaEngine.h:92
static double huber_kernel(double delta, const double kernel_param)
pseudo-huber cost function
Definition: RbaEngine.h:783
uint64_t TKeyFrameID
Numeric IDs for key-frames (KFs)
Definition: srba_types.h:31



Page generated by Doxygen 1.8.8 for MRPT 1.2.2 SVN:Unversioned directory at Tue Oct 14 02:14:08 UTC 2014