25 #define VERBOSE_LEVEL(_LEVEL) if (m_verbose_level>=_LEVEL) std::cout
61 template <
class KF2KF_POSE_TYPE,
class LM_TYPE,
class OBS_TYPE,
class RBA_OPTIONS = RBA_OPTIONS_DEFAULT>
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;
89 typedef typename KF2KF_POSE_TYPE::pose_t
pose_t;
96 typedef typename kf2kf_pose_traits_t::pose_flag_t
pose_flag_t;
144 num_observations = 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();
170 created_edge_ids.clear();
171 optimize_results.
clear();
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
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 )
213 void optimize_local_area(
215 const unsigned int win_size,
216 TOptimizeExtraOutputInfo & out_info,
217 const TOptimizeLocalAreaParams ¶ms = TOptimizeLocalAreaParams(),
218 const std::vector<size_t> & observation_indices_to_optimize = std::vector<size_t>()
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)
245 void build_opengl_representation(
248 mrpt::opengl::CSetOfObjectsPtr out_scene,
249 mrpt::opengl::CSetOfObjectsPtr out_root_tree = mrpt::opengl::CSetOfObjectsPtr()
254 bool save_graph_as_dot(
255 const std::string &targetFileName,
256 const bool all_landmarks =
false
266 double eval_overall_squared_error()
const;
281 template <
class POSE_GRAPH>
282 void get_global_graphslam_problem(POSE_GRAPH &global_graph,
const ExportGraphSLAM_Params ¶ms = ExportGraphSLAM_Params() )
const;
308 size_t create_kf2kf_edge(
311 const typename traits_t::new_kf_observations_t & obs,
312 const pose_t &init_inv_pose_val = pose_t() );
324 void create_complete_spanning_tree(
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
343 std::vector<TKeyFrameID> & found_path)
const
345 return rba_state.find_path_bfs(src_kf,trg_kf,&found_path);
354 class K2K_EDGE_VISITOR,
355 class K2F_EDGE_VISITOR
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;
408 void (*feedback_user_iteration)(
unsigned int iter,
const double total_sq_err,
const double mean_sqroot_error);
423 typename OBS_TYPE::TObservationParams
sensor;
426 typename RBA_OPTIONS::sensor_pose_on_robot_t::parameters_t
sensor_pose;
429 typename RBA_OPTIONS::obs_noise_matrix_t::parameters_t
obs_noise;
440 const k2k_edges_deque_t &
get_k2k_edges()
const {
return rba_state.k2k_edges; }
442 const TRelativeLandmarkPosMap &
get_known_feats()
const {
return rba_state.known_lms; }
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(
462 const std::vector<JACOB_COLUMN_dh_dAp*> & dh_dAp,
463 const std::vector<JACOB_COLUMN_dh_df*> & dh_df);
470 template <
class SPARSEBLOCKHESSIAN>
471 size_t sparse_hessian_update_numeric( SPARSEBLOCKHESSIAN & H )
const;
483 void make_ordered_list_base_kfs(
485 base_sorted_lst_t & obs_for_each_base_sorted,
486 map<TKeyFrameID,size_t> *out_obs_for_each_base =NULL )
const;
489 void determine_kf2kf_edges_to_create(
492 std::vector<TNewEdgeInfo> &new_k2k_edge_ids );
496 virtual void edge_creation_policy(
499 std::vector<TNewEdgeInfo> &new_k2k_edge_ids );
506 const std::vector<size_t> & run_k2k_edges,
507 const std::vector<size_t> & run_feat_ids_in,
509 const std::vector<size_t> & observation_indices_to_optimize = std::vector<size_t>()
518 rba_state(rba_state_),
556 const k2k_edge_t* edge,
const topo_dist_t cur_dist)
564 const k2k_edge_t* edge,
const topo_dist_t cur_dist)
569 k2k_edges_to_optimize.push_back(edge->
id);
587 lm_IDs_to_optimize.push_back(lm_ID);
617 size_t add_observation(
620 const array_landmark_t * fixed_relative_position = NULL,
621 const array_landmark_t * unknown_relative_position_init_val = NULL
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 );
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 );
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;
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;
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
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),
705 is_inverse_dir(_is_inverse_dir),
706 k2k_edges(_k2k_edges),
707 sensor_params(_sensor_params),
708 sensor_pose(_sensor_pose)
719 const typename RBA_OPTIONS::sensor_pose_on_robot_t::parameters_t &
sensor_pose;
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
730 pose_base_wrt_obs(_pose_base_wrt_obs),
732 sensor_params(_sensor_params),
733 sensor_pose(_sensor_pose)
740 const typename RBA_OPTIONS::sensor_pose_on_robot_t::parameters_t &
sensor_pose;
746 static void numeric_dh_df(
const array_landmark_t &x,
const TNumeric_dh_df_params& params, array_obs_t &y);
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
765 TObsUsed(
const size_t obs_idx_, k2f_edge_t *
const k2f_) : obs_idx(obs_idx_),k2f(k2f_)
777 inline double reprojection_residuals(
778 vector_residuals_t & residuals,
779 const std::vector<TObsUsed> & observations
783 static inline double huber_kernel(
double delta,
const double kernel_param)
RBA_OPTIONS::obs_noise_matrix_t::parameters_t obs_noise
Parameters related to the sensor noise covariance matrix.
The main class for the mrpt-srba: it defines a Relative Bundle-Adjustment (RBA) problem with (optiona...
map< TLandmarkID, size_t > lm_times_seen
TAllParameters parameters
bool optimize_new_edges_alone
(Default:true) Before running a whole "local area" optimization, try to optimize new edges one by one...
Elemental observation data.
A STL-like container which looks and behaves (almost exactly) like a std::map<> but is implemented as...
obs_traits_t::observation_t obs
Observation data.
const rba_problem_state_t & rba_state
TLandmarkID feat_id
Observed what.
RBA_OPTIONS rba_options_type
KF2KF_POSE_TYPE kf2kf_pose_type
jacobian_traits< KF2KF_POSE_TYPE, LM_TYPE, OBS_TYPE > jacobian_traits_t
TObsUsed(const size_t obs_idx_, k2f_edge_t *const k2f_)
TKeyFrameID max_visitable_kf_id
While exploring around the root KF, stop the BFS when KF_ID>=this number (default:infinity) ...
observation_traits_t::vector_residuals_t vector_residuals_t
const rba_problem_state_t & get_rba_state() const
A set of object, which are referenced to the coordinates framework established in this object...
options::solver_LM_schur_dense_cholesky solver_t
Solver algorithm (Default: Lev-Marq, with Schur, with dense Cholesky)
double max_error_per_obs_to_stop
default: 1e-9
T square(const T x)
Inline function for the square of a number.
TKeyFrameID kf_id
The ID of the newly created KF.
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)
bool compute_condition_number
Compute and return to the user the Hessian condition number of k2k edges (default=false) ...
bool visit_filter_k2k(const TKeyFrameID current_kf, const TKeyFrameID next_kf, const k2k_edge_t *edge, const topo_dist_t cur_dist)
uint64_t TLandmarkID
Numeric IDs for landmarks.
const RBA_OPTIONS::sensor_pose_on_robot_t::parameters_t & sensor_pose
topo_dist_t max_tree_depth
Maximum depth for maintained spanning trees.
bool show_unknown_feats_ids
TEdgeCreationPolicy
For usage in RbaEngine.parameters.
const bool is_inverse_dir
hessian_traits< KF2KF_POSE_TYPE, LM_TYPE, OBS_TYPE > hessian_traits_t
RBA_OPTIONS::sensor_pose_on_robot_t::parameters_t sensor_pose
Parameters related to the relative pose of sensors wrt the robot (if applicable)
Different parameters for the SRBA methods.
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).
const array_landmark_t & xji_i
mrpt::utils::CTimeLogger m_profiler
Profiler for all SRBA operations Enabled by default, can be disabled with enable_time_profiler(false)...
size_t obs_idx
Global index in all_observations.
const k2k_edges_deque_t & get_k2k_edges() const
TOptimizeExtraOutputInfo optimize_results_stg1
Results from the least-squares optimization.
size_t id
0-based index of this edge, in the std::list "k2k_edges".
TSRBAParameters srba
Different parameters for the SRBA methods.
TOptimizeLocalAreaParams()
observation_traits< OBS_TYPE > observation_traits_t
Each of the observations used during the optimization.
bool draw_unknown_feats_ellipses
kf2kf_pose_traits_t::pose_flag_t pose_flag_t
KF2KF_POSE_TYPE::pose_t pose_t
The type of relative poses (e.g. mrpt::poses::CPose3D)
Keyframe-to-keyframe edge: an unknown of the problem.
TCovarianceRecoveryPolicy cov_recovery
Recover covariance? What method to use? (Default: crpLandmarksApprox)
double min_error_reduction_ratio_to_relinearize
default 0.01
uint64_t topo_dist_t
Unsigned integral type for topological distances in a graph/tree.
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.
const pose_t * pose_d1_wrt_obs
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)
kf2kf_pose_traits_t::TRelativePosesForEachTarget TRelativePosesForEachTarget
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)
This class allows loading and storing values and vectors of different types from a configuration text...
double max_rho
default: 1.0
kf2kf_pose_traits_t::array_pose_t array_pose_t
const OBS_TYPE::TObservationParams & sensor_params
observation_traits_t::residual_t residual_t
TOpenGLRepresentationOptions()
double draw_unknown_feats_ellipses_quantiles
traits_t::keyframe_info keyframe_info
TCovarianceRecoveryPolicy
Covariances recovery from Hessian matrix policy, for usage in RbaEngine.parameters.
Generic declaration, of which specializations are defined for each combination of LM+OBS type...
Useful data structures that depend of a combination of "OBSERVATION_TYPE"+"LANDMARK_PARAMETERIZATION_...
rba_joint_parameterization_traits_t< KF2KF_POSE_TYPE, LM_TYPE, OBS_TYPE > traits_t
Parameters for optimize_local_area()
#define MRPT_UNUSED_PARAM(a)
Can be used to avoid "not used parameters" warnings from the compiler.
const k2k_edges_deque_t & k2k_edges
KF2KF_POSE_TYPE::se_traits_t se_traits_t
The SE(2) or SE(3) traits struct (for Lie algebra log/exp maps, etc.)
Observations, as provided by the user.
std::map< TLandmarkID, TRelativeLandmarkPos > TRelativeLandmarkPosMap
An index of feature IDs and their relative locations.
Private aux structure for BFS searches.
rba_problem_state_t & get_rba_state()
landmark_traits_t::array_landmark_t array_landmark_t
double max_lambda
default: 1e20
TOptimizeExtraOutputInfo optimize_results
Results from the least-squares optimization.
const TRelativeLandmarkPosMap & get_known_feats() const
bool use_robust_kernel_stage1
TRBA_Problem_state< KF2KF_POSE_TYPE, LM_TYPE, OBS_TYPE, RBA_OPTIONS > rba_problem_state_t
void enable_time_profiler(bool enable=true)
Enable or disables time profiling of all operations (default=enabled), which will be reported upon de...
void visit_k2f(const TKeyFrameID current_kf, const k2f_edge_t *edge, const topo_dist_t cur_dist)
landmark_traits_t::TRelativeLandmarkPos TRelativeLandmarkPos
One landmark position (relative to its base KF)
TKeyFrameID root_kf_id
The KF to use as a root for the spanning tree to init global poses (default=0)
const pose_t & pose_base_wrt_d1
vector< size_t > lm_IDs_to_optimize
VisitorOptimizeLocalArea(const rba_problem_state_t &rba_state_, const TOptimizeLocalAreaParams ¶ms_)
mrpt::aligned_containers< k2k_edge_t >::deque_t k2k_edges_deque_t
jacobian_traits< KF2KF_POSE_TYPE, LM_TYPE, OBS_TYPE >::TSparseBlocksJacobians_dh_df TSparseBlocksJacobians_dh_df
All the important data of a RBA problem at any given instant of time Operations on this structure are...
size_t span_tree_max_depth
Maximum spanning tree depth for reconstructing relative poses (default=-1 : infinity) ...
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
traits_t::new_kf_observations_t new_kf_observations_t
size_t min_obs_to_loop_closure
Default:6, reduce to 1 for relative graph-slam.
bool draw_unknown_feats
Draw features with non-fixed rel.pos as well?
void visit_k2k(const TKeyFrameID current_kf, const TKeyFrameID next_kf, const k2k_edge_t *edge, const topo_dist_t cur_dist)
mrpt::utils::CTimeLogger & get_time_profiler()
Access to the time profiler.
topo_dist_t max_optimize_depth
The maximum topological distance of keyframes to be optimized around the most recent keyframe...
void visit_kf(const TKeyFrameID kf_ID, const topo_dist_t cur_dist)
bool visit_filter_kf(const TKeyFrameID kf_ID, const topo_dist_t cur_dist)
landmark_traits< LM_TYPE > landmark_traits_t
kf2kf_pose_traits_t::frameid2pose_map_t frameid2pose_map_t
const TRelativeLandmarkPosMap & get_unknown_feats() const
std::pair< TKeyFrameID, TKeyFrameID > TPairKeyFrameID
Used to represent the IDs of a directed edge (first –> second)
bool visit_filter_feat(const TLandmarkID lm_ID, const topo_dist_t cur_dist)
TEdgeCreationPolicy edge_creation_policy
Parameters for determine_kf2kf_edges_to_create(); custom user-defined policies can be also defined (s...
Aux visitor struct, used in optimize_local_area()
options::sensor_pose_on_robot_none sensor_pose_on_robot_t
The sensor pose coincides with the robot pose.
jacobian_traits< KF2KF_POSE_TYPE, LM_TYPE, OBS_TYPE >::TSparseBlocksJacobians_dh_dAp TSparseBlocksJacobians_dh_dAp
const pose_t * pose_base_wrt_obs
const TOptimizeLocalAreaParams & params
const RBA_OPTIONS::sensor_pose_on_robot_t::parameters_t & sensor_pose
std::vector< TNewEdgeInfo > created_edge_ids
The newly created edges (minimum: 1 edge)
A versatile "profiler" that logs the time spent within each pair of calls to enter(X)-leave(X), among other stats.
A partial specialization of CArrayNumeric for double numbers.
void setVerbosityLevel(int level)
Changes the verbosity level: 0=None (only critical msgs), 1=verbose, 2=so verbose you'll have to say ...
OBS_TYPE::TObservationParams sensor
Sensor-specific parameters (sensor calibration, etc.)
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...
std::multimap< size_t, TKeyFrameID, std::greater< size_t > > base_sorted_lst_t
Information per key-frame needed for RBA.
sensor_model< LM_TYPE, OBS_TYPE > sensor_model_t
The sensor model for the specified combination of LM parameterization + observation type...
landmark_traits_t::TRelativeLandmarkPosMap TRelativeLandmarkPosMap
An index of feature IDs and their relative locations.
mrpt::aligned_containers< residual_t >::vector_t vector_residuals_t
const OBS_TYPE::TObservationParams & sensor_params
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...
static void add_edge_ij_to_list_needed_roots(std::set< TKeyFrameID > &lst, const TKeyFrameID i, const TKeyFrameID j)
observation_traits_t::array_obs_t array_obs_t
rba_problem_state_t::k2k_edge_t k2k_edge_t
The set of default settings for RbaEngine.
int m_verbose_level
0: None (only critical msgs), 1: verbose, 2:even more verbose, 3: even more
Keyframe-to-feature edge: observation data stored for each keyframe.
const array_landmark_t & xji_i
The unique struct which hold all the parameters from the different SRBA modules (sensors, optional features, optimizers,...)
options::observation_noise_identity obs_noise_matrix_t
The sensor noise matrix is the same for all observations and equal to * I(identity) ...
std::vector< bool > m_complete_st_ws
Temporary working space used in create_complete_spanning_tree()
Usage: A possible type for RBA_OPTIONS::sensor_pose_on_robot_t.
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.
Information returned by RbaEngine::define_new_keyframe()
bool feat_has_known_rel_pos
whether it's a known or unknown relative position feature
kf2kf_pose_traits< KF2KF_POSE_TYPE > kf2kf_pose_traits_t
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:
bool numeric_jacobians
(Default:false) Use a numeric approximation of the Jacobians (very slow!) instead of analytical ones...
rba_problem_state_t rba_state
All the beef is here.
RbaEngine< KF2KF_POSE_TYPE, LM_TYPE, OBS_TYPE, RBA_OPTIONS > rba_engine_t
traits_t::new_kf_observation_t new_kf_observation_t
k2f_edge_t * k2f
Obs data.
void visit_feat(const TLandmarkID lm_ID, const topo_dist_t cur_dist)
rba_problem_state_t::k2f_edge_t k2f_edge_t
static double huber_kernel(double delta, const double kernel_param)
pseudo-huber cost function
uint64_t TKeyFrameID
Numeric IDs for key-frames (KFs)