SRBA: Sparser Relative Bundle Adjustment
|
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 00015 template <class KF2KF_POSE_TYPE,class LM_TYPE,class OBS_TYPE,class RBA_OPTIONS> 00016 double RbaEngine<KF2KF_POSE_TYPE,LM_TYPE,OBS_TYPE,RBA_OPTIONS>::reprojection_residuals( 00017 vector_residuals_t & residuals, // Out: 00018 const std::vector<TObsUsed> & observations // In: 00019 ) const 00020 { 00021 const size_t nObs = observations.size(); 00022 if (residuals.size()!=nObs) residuals.resize(nObs); 00023 00024 double total_sqr_err = 0; 00025 00026 for (size_t i=0;i<nObs;i++) 00027 { 00028 // Actually measured pixel coords: observations[i]->obs.px 00029 const TKeyFrameID obs_frame_id = observations[i].k2f->obs.kf_id; // Observed from here. 00030 const TRelativeLandmarkPos *feat_rel_pos = observations[i].k2f->feat_rel_pos; 00031 00032 ASSERTDEB_(feat_rel_pos!=NULL) 00033 00034 const TKeyFrameID base_id = feat_rel_pos->id_frame_base; 00035 00036 pose_t const * base_pose_wrt_observer=NULL; 00037 00038 // This case can occur with feats with unknown rel.pos: 00039 if (base_id==obs_frame_id) 00040 { 00041 base_pose_wrt_observer = &aux_null_pose; 00042 } 00043 else 00044 { 00045 // num[SOURCE] |--> map[TARGET] = CPose3D of TARGET as seen from SOURCE 00046 const typename TRelativePosesForEachTarget::const_iterator itPoseMap_for_base_id = rba_state.spanning_tree.num.find(obs_frame_id); 00047 ASSERT_( itPoseMap_for_base_id != rba_state.spanning_tree.num.end() ) 00048 00049 const typename frameid2pose_map_t::const_iterator itRelPose = itPoseMap_for_base_id->second.find(base_id); 00050 ASSERT_( itRelPose != itPoseMap_for_base_id->second.end() ) 00051 00052 base_pose_wrt_observer = &itRelPose->second.pose; 00053 } 00054 00055 // pose_robot2sensor(): pose wrt sensor = pose_wrt_robot (-) sensor_pose_on_the_robot 00056 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); 00057 RBA_OPTIONS::sensor_pose_on_robot_t::pose_robot2sensor( *base_pose_wrt_observer, base_pose_wrt_sensor, this->parameters.sensor_pose ); 00058 00059 const array_obs_t & real_obs = observations[i].k2f->obs.obs_arr; 00060 residual_t &delta = residuals[i]; 00061 00062 // Generate observation and compare to real obs: 00063 sensor_model_t::observe_error(delta,real_obs, base_pose_wrt_sensor,feat_rel_pos->pos, this->parameters.sensor); 00064 00065 const double sum_2 = delta.squaredNorm(); 00066 if (this->parameters.srba.use_robust_kernel) 00067 { 00068 const double nrm = std::max(1e-11,std::sqrt(sum_2)); 00069 const double w = std::sqrt(huber_kernel(nrm,parameters.srba.kernel_param))/nrm; 00070 delta *= w; 00071 total_sqr_err += (w*w)*sum_2; 00072 } 00073 else 00074 { 00075 // nothing else to do: 00076 total_sqr_err += sum_2; 00077 } 00078 } // end for i 00079 00080 return total_sqr_err; 00081 } 00082 00083 } // End of namespaces