SRBA: Sparser Relative Bundle Adjustment
srba/impl/eval_overall_error.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 namespace srba {
00013 
00014 template <class KF2KF_POSE_TYPE,class LM_TYPE,class OBS_TYPE,class RBA_OPTIONS>
00015 double RbaEngine<KF2KF_POSE_TYPE,LM_TYPE,OBS_TYPE,RBA_OPTIONS>::eval_overall_squared_error() const
00016 {
00017     using namespace std;
00018     using namespace mrpt::utils;
00019 
00020     m_profiler.enter("eval_overall_squared_error");
00021 
00022     double sqerr = 0;
00023 
00024     // ---------------------------------------------------------------------------
00025     // Make a list of all the observing & base KFs needed by all observations:
00026     // ---------------------------------------------------------------------------
00027     vector<bool>                         base_ids(rba_state.keyframes.size(), false);
00028     map<TKeyFrameID, set<TKeyFrameID> >  ob_pairs; // Minimum ID first index.
00029 
00030     for (typename rba_problem_state_t::all_observations_deque_t::const_iterator itO=rba_state.all_observations.begin();itO!=rba_state.all_observations.end();++itO)
00031     {
00032         const TKeyFrameID obs_id = itO->obs.kf_id;
00033         const TKeyFrameID base_id = itO->feat_rel_pos->id_frame_base;
00034 
00035         base_ids[base_id] = true;
00036         ob_pairs[ std::min(obs_id,base_id) ].insert( std::max(obs_id,base_id) );
00037     }
00038 
00039     // ---------------------------------------------------------------------------
00040     // Build all the needed shortest paths:
00041     // ---------------------------------------------------------------------------
00042     // all_rel_poses[SOURCE] |--> map[TARGET] = CPose3D of TARGET as seen from SOURCE
00043     TRelativePosesForEachTarget  all_rel_poses;
00044     for (map<TKeyFrameID, set<TKeyFrameID> >::const_iterator it1=ob_pairs.begin();it1!=ob_pairs.end();++it1)
00045     {
00046         const TKeyFrameID root = it1->first;
00047 
00048         // Build S.T. from this root:
00049         m_profiler.enter("eval_overall_squared_error.complete_ST");
00050 
00051         frameid2pose_map_t span_tree;
00052         this->create_complete_spanning_tree(root,span_tree);
00053 
00054         m_profiler.leave("eval_overall_squared_error.complete_ST");
00055 
00056         // Look for the "set_intersection":
00057         typename frameid2pose_map_t::const_iterator       it_have     = span_tree.begin();
00058         const typename frameid2pose_map_t::const_iterator it_have_end = span_tree.end();
00059 
00060         set<TKeyFrameID>::const_iterator         it_want     = it1->second.begin();
00061         const set<TKeyFrameID>::const_iterator   it_want_end = it1->second.end();
00062 
00063         while (it_have!=it_have_end && it_want!=it_want_end)
00064         {
00065             if (it_have->first<*it_want)
00066                 ++it_have;
00067             else if (*it_want<it_have->first)
00068                 ++it_want;
00069             else
00070             {
00071                 // This means we need 1 or both of the poses:
00072                 //   root -> *it_want
00073                 //   *it_want -> root
00074                 all_rel_poses[root][*it_want] =  it_have->second;
00075                 all_rel_poses[*it_want][root] = pose_flag_t(-it_have->second.pose, it_have->second.updated);
00076 
00077                 ++it_have;
00078                 ++it_want;
00079             }
00080         }
00081     }
00082 
00083     // ---------------------------------------------------------------------------
00084     // Evaluate errors:
00085     // ---------------------------------------------------------------------------
00086     for (typename rba_problem_state_t::all_observations_deque_t::const_iterator itO=rba_state.all_observations.begin();itO!=rba_state.all_observations.end();++itO)
00087     {
00088         // Actually measured pixel coords: observations[i]->obs.px
00089 
00090         const TKeyFrameID obs_frame_id = itO->obs.kf_id;
00091         const TKeyFrameID base_id = itO->feat_rel_pos->id_frame_base;
00092         const TRelativeLandmarkPos *feat_rel_pos = itO->feat_rel_pos;
00093         ASSERTDEB_(feat_rel_pos!=NULL)
00094 
00095         pose_t const * base_pose_wrt_observer=NULL;
00096 
00097         // This case can occur with feats with unknown rel.pos:
00098         if (base_id==obs_frame_id)
00099         {
00100             base_pose_wrt_observer = &aux_null_pose;
00101         }
00102         else
00103         {
00104             // num[SOURCE] |--> map[TARGET] = CPose3D of TARGET as seen from SOURCE
00105             const typename TRelativePosesForEachTarget::const_iterator itPoseMap_for_base_id = all_rel_poses.find(obs_frame_id);
00106             ASSERT_( itPoseMap_for_base_id != all_rel_poses.end() )
00107 
00108             const typename frameid2pose_map_t::const_iterator itRelPose = itPoseMap_for_base_id->second.find(base_id);
00109             ASSERT_( itRelPose != itPoseMap_for_base_id->second.end() )
00110 
00111             base_pose_wrt_observer = &itRelPose->second.pose;
00112         }
00113 
00114         // Sensor pose: base_pose_wrt_sensor = robot_pose (+) sensor_pose_on_the_robot
00115         typename options::internal::resulting_pose_t<typename RBA_OPTIONS::sensor_pose_on_robot_t,REL_POSE_DIMS>::pose_t base_pose_wrt_sensor(mrpt::poses::UNINITIALIZED_POSE);
00116         RBA_OPTIONS::sensor_pose_on_robot_t::robot2sensor( *base_pose_wrt_observer, base_pose_wrt_sensor, this->parameters.sensor_pose );
00117 
00118         // Stored observation:
00119         const array_obs_t & z_real = itO->obs.obs_arr;
00120 
00121         // Predict observation and compare to real obs:
00122         residual_t delta;
00123         sensor_model_t::observe_error(
00124             delta,
00125             z_real,
00126             base_pose_wrt_sensor,
00127             feat_rel_pos->pos, // Position of LM wrt its base_id
00128             this->parameters.sensor
00129             );
00130 
00131         sqerr+= delta.squaredNorm();
00132     }
00133 
00134     m_profiler.leave("eval_overall_squared_error");
00135 
00136     return sqerr;
00137 }
00138 
00139 } // end namespaces
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends