28 #ifndef GRAPH_SLAM_LEVMARQ_IMPL_H
29 #define GRAPH_SLAM_LEVMARQ_IMPL_H
42 using namespace mrpt::poses;
43 using namespace mrpt::graphslam;
44 using namespace mrpt::math;
45 using namespace mrpt::utils;
57 template <
class POSE,
class VEC,
class EDGE_ITERATOR>
58 static inline void computePseudoLnError(
const POSE &P1DP2inv, VEC &err,
const EDGE_ITERATOR &edge) { gst::SE_TYPE::pseudo_ln(P1DP2inv, err); }
60 template <
class MAT,
class EDGE_ITERATOR>
61 static inline void multiplyJtLambdaJ(
const MAT &J1, MAT &JtJ,
const EDGE_ITERATOR &edge) { JtJ.multiply_AtA(J1); }
63 template <
class MAT,
class EDGE_ITERATOR>
64 static inline void multiplyJ1tLambdaJ2(
const MAT &J1,
const MAT &J2, MAT &JtJ,
const EDGE_ITERATOR &edge) { JtJ.multiply_AtB(J1,J2); }
66 template <
class JAC,
class EDGE_ITERATOR,
class VEC1,
class VEC2>
67 static inline void multiply_Jt_W_err(
const JAC &J,
const EDGE_ITERATOR &edge,
const VEC1 & ERR,VEC2 &OUT) { J.multiply_Atb(ERR,OUT,
true ); }
72 template <
class POSE,
class VEC,
class EDGE_ITERATOR>
73 static inline void computePseudoLnError(
const POSE &P1DP2inv, VEC &err,
const EDGE_ITERATOR &edge) { gst::SE_TYPE::pseudo_ln(P1DP2inv, err); }
75 template <
class MAT,
class EDGE_ITERATOR>
76 static inline void multiplyJtLambdaJ(
const MAT &J1, MAT &JtJ,
const EDGE_ITERATOR &edge) { JtJ.multiply_AtA(J1); }
78 template <
class MAT,
class EDGE_ITERATOR>
79 static inline void multiplyJ1tLambdaJ2(
const MAT &J1,
const MAT &J2, MAT &JtJ,
const EDGE_ITERATOR &edge) { JtJ.multiply_AtB(J1,J2); }
81 template <
class JAC,
class EDGE_ITERATOR,
class VEC1,
class VEC2>
82 static inline void multiply_Jt_W_err(
const JAC &J,
const EDGE_ITERATOR &edge,
const VEC1 & ERR,VEC2 &OUT) { J.multiply_Atb(ERR,OUT,
true ); }
87 template <
class POSE,
class VEC,
class EDGE_ITERATOR>
88 static inline void computePseudoLnError(
const POSE &P1DP2inv, VEC &err,
const EDGE_ITERATOR &edge)
90 gst::SE_TYPE::pseudo_ln(P1DP2inv, err);
93 template <
class MAT,
class EDGE_ITERATOR>
94 static inline void multiplyJtLambdaJ(
const MAT &J1, MAT &JtJ,
const EDGE_ITERATOR &edge) { JtJ.multiply_AtBC(J1,edge->second.cov_inv,J1); }
95 template <
class MAT,
class EDGE_ITERATOR>
96 static inline void multiplyJ1tLambdaJ2(
const MAT &J1,
const MAT &J2, MAT &JtJ,
const EDGE_ITERATOR &edge) { JtJ.multiply_AtBC(J1,edge->second.cov_inv,J2); }
98 template <
class JAC,
class EDGE_ITERATOR,
class VEC1,
class VEC2>
99 static inline void multiply_Jt_W_err(
const JAC &J,
const EDGE_ITERATOR &edge,
const VEC1 & ERR,VEC2 &OUT)
102 JtInf.multiply_AtB(J,edge->second.cov_inv);
103 JtInf.multiply_Ab(ERR,OUT,
true );
109 template <
class POSE,
class VEC,
class EDGE_ITERATOR>
110 static inline void computePseudoLnError(
const POSE &P1DP2inv, VEC &err,
const EDGE_ITERATOR &edge) { gst::SE_TYPE::pseudo_ln(P1DP2inv, err); }
112 template <
class MAT,
class EDGE_ITERATOR>
113 static inline void multiplyJtLambdaJ(
const MAT &J1, MAT &JtJ,
const EDGE_ITERATOR &edge) { JtJ.multiply_AtBC(J1,edge->second.cov_inv,J1); }
115 template <
class MAT,
class EDGE_ITERATOR>
116 static inline void multiplyJ1tLambdaJ2(
const MAT &J1,
const MAT &J2, MAT &JtJ,
const EDGE_ITERATOR &edge) { JtJ.multiply_AtBC(J1,edge->second.cov_inv,J2); }
118 template <
class JAC,
class EDGE_ITERATOR,
class VEC1,
class VEC2>
119 static inline void multiply_Jt_W_err(
const JAC &J,
const EDGE_ITERATOR &edge,
const VEC1 & ERR,VEC2 &OUT)
122 JtInf.multiply_AtB(J,edge->second.cov_inv);
123 JtInf.multiply_Ab(ERR,OUT,
true );
130 template <
class GRAPH_T>
132 const GRAPH_T &graph,
140 lstJacobians.clear();
143 const size_t nObservations = lstObservationData.size();
145 for (
size_t i=0;i<nObservations;i++)
147 const typename gst::observation_info_t & obs = lstObservationData[i];
148 typename gst::edge_const_iterator it = obs.edge;
149 const typename gst::graph_t::constraint_t::type_value* EDGE_POSE = obs.edge_mean;
150 typename gst::graph_t::constraint_t::type_value* P1 = obs.P1;
151 typename gst::graph_t::constraint_t::type_value* P2 = obs.P2;
154 const typename gst::graph_t::edge_t &edge = it->second;
161 P1D.composeFrom(*P1,*EDGE_POSE);
162 const typename gst::graph_t::constraint_t::type_value P2inv = -(*P2);
163 P1DP2inv.composeFrom(P1D,P2inv);
167 errs.resize(errs.size()+1);
168 detail::AuxErrorEval<typename gst::edge_t,gst>::computePseudoLnError(P1DP2inv, errs.back(),edge);
171 EIGEN_ALIGN16 std::pair<TPairNodeIDs,typename gst::TPairJacobs> newMapEntry;
172 newMapEntry.first = ids;
173 gst::SE_TYPE::jacobian_dP1DP2inv_depsilon(P1DP2inv, &newMapEntry.second.first,&newMapEntry.second.second);
176 lstJacobians.insert(lstJacobians.end(),newMapEntry );
180 return std::accumulate( errs.begin(), errs.end(),0.0, mrpt::math::squareNorm_accum<typename gst::Array_O> );