Main MRPT website > C++ reference for MRPT 1.9.9
levmarq_impl.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-2017, 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 #ifndef GRAPH_SLAM_LEVMARQ_IMPL_H
10 #define GRAPH_SLAM_LEVMARQ_IMPL_H
11 
13 #include <mrpt/utils/CTimeLogger.h>
15 
16 #include <memory>
17 
18 namespace mrpt
19 {
20 namespace graphslam
21 {
22 /// Internal auxiliary classes
23 namespace detail
24 {
25 using namespace mrpt;
26 using namespace mrpt::poses;
27 using namespace mrpt::graphslam;
28 using namespace mrpt::math;
29 using namespace mrpt::utils;
30 using namespace std;
31 
32 // An auxiliary struct to compute the pseudo-ln of a pose error, possibly
33 // modified with an information matrix.
34 // Specializations are below.
35 template <class EDGE, class gst>
36 struct AuxErrorEval;
37 
38 // For graphs of 2D constraints (no information matrix)
39 template <class gst>
40 struct AuxErrorEval<CPose2D, gst>
41 {
42  template <class POSE, class VEC, class EDGE_ITERATOR>
43  static inline void computePseudoLnError(
44  const POSE& P1DP2inv, VEC& err, const EDGE_ITERATOR& edge)
45  {
46  MRPT_UNUSED_PARAM(edge);
47  gst::SE_TYPE::pseudo_ln(P1DP2inv, err);
48  }
49 
50  template <class MAT, class EDGE_ITERATOR>
51  static inline void multiplyJtLambdaJ(
52  const MAT& J1, MAT& JtJ, const EDGE_ITERATOR& edge)
53  {
54  MRPT_UNUSED_PARAM(edge);
55  JtJ.multiply_AtA(J1);
56  }
57 
58  template <class MAT, class EDGE_ITERATOR>
59  static inline void multiplyJ1tLambdaJ2(
60  const MAT& J1, const MAT& J2, MAT& JtJ, const EDGE_ITERATOR& edge)
61  {
62  MRPT_UNUSED_PARAM(edge);
63  JtJ.multiply_AtB(J1, J2);
64  }
65 
66  template <class JAC, class EDGE_ITERATOR, class VEC1, class VEC2>
67  static inline void multiply_Jt_W_err(
68  const JAC& J, const EDGE_ITERATOR& edge, const VEC1& ERR, VEC2& OUT)
69  {
70  MRPT_UNUSED_PARAM(edge);
71  J.multiply_Atb(ERR, OUT, true /* accumulate in output */);
72  }
73 };
74 
75 // For graphs of 3D constraints (no information matrix)
76 template <class gst>
77 struct AuxErrorEval<CPose3D, gst>
78 {
79  template <class POSE, class VEC, class EDGE_ITERATOR>
80  static inline void computePseudoLnError(
81  const POSE& P1DP2inv, VEC& err, const EDGE_ITERATOR& edge)
82  {
83  MRPT_UNUSED_PARAM(edge);
84  gst::SE_TYPE::pseudo_ln(P1DP2inv, err);
85  }
86 
87  template <class MAT, class EDGE_ITERATOR>
88  static inline void multiplyJtLambdaJ(
89  const MAT& J1, MAT& JtJ, const EDGE_ITERATOR& edge)
90  {
91  MRPT_UNUSED_PARAM(edge);
92  JtJ.multiply_AtA(J1);
93  }
94 
95  template <class MAT, class EDGE_ITERATOR>
96  static inline void multiplyJ1tLambdaJ2(
97  const MAT& J1, const MAT& J2, MAT& JtJ, const EDGE_ITERATOR& edge)
98  {
99  MRPT_UNUSED_PARAM(edge);
100  JtJ.multiply_AtB(J1, J2);
101  }
102 
103  template <class JAC, class EDGE_ITERATOR, class VEC1, class VEC2>
104  static inline void multiply_Jt_W_err(
105  const JAC& J, const EDGE_ITERATOR& edge, const VEC1& ERR, VEC2& OUT)
106  {
107  MRPT_UNUSED_PARAM(edge);
108  J.multiply_Atb(ERR, OUT, true /* accumulate in output */);
109  }
110 };
111 
112 // For graphs of 2D constraints (with information matrix)
113 template <class gst>
115 {
116  template <class POSE, class VEC, class EDGE_ITERATOR>
117  static inline void computePseudoLnError(
118  const POSE& P1DP2inv, VEC& err, const EDGE_ITERATOR& edge)
119  {
120  gst::SE_TYPE::pseudo_ln(P1DP2inv, err);
121  }
122 
123  template <class MAT, class EDGE_ITERATOR>
124  static inline void multiplyJtLambdaJ(
125  const MAT& J1, MAT& JtJ, const EDGE_ITERATOR& edge)
126  {
127  JtJ.multiply_AtBC(J1, edge->second.cov_inv, J1);
128  }
129  template <class MAT, class EDGE_ITERATOR>
130  static inline void multiplyJ1tLambdaJ2(
131  const MAT& J1, const MAT& J2, MAT& JtJ, const EDGE_ITERATOR& edge)
132  {
133  JtJ.multiply_AtBC(J1, edge->second.cov_inv, J2);
134  }
135 
136  template <class JAC, class EDGE_ITERATOR, class VEC1, class VEC2>
137  static inline void multiply_Jt_W_err(
138  const JAC& J, const EDGE_ITERATOR& edge, const VEC1& ERR, VEC2& OUT)
139  {
141  JtInf.multiply_AtB(J, edge->second.cov_inv);
142  JtInf.multiply_Ab(ERR, OUT, true /* accumulate in output */);
143  }
144 };
145 
146 // For graphs of 3D constraints (with information matrix)
147 template <class gst>
149 {
150  template <class POSE, class VEC, class EDGE_ITERATOR>
151  static inline void computePseudoLnError(
152  const POSE& P1DP2inv, VEC& err, const EDGE_ITERATOR& edge)
153  {
154  MRPT_UNUSED_PARAM(edge);
155  gst::SE_TYPE::pseudo_ln(P1DP2inv, err);
156  }
157 
158  template <class MAT, class EDGE_ITERATOR>
159  static inline void multiplyJtLambdaJ(
160  const MAT& J1, MAT& JtJ, const EDGE_ITERATOR& edge)
161  {
162  JtJ.multiply_AtBC(J1, edge->second.cov_inv, J1);
163  }
164 
165  template <class MAT, class EDGE_ITERATOR>
166  static inline void multiplyJ1tLambdaJ2(
167  const MAT& J1, const MAT& J2, MAT& JtJ, const EDGE_ITERATOR& edge)
168  {
169  JtJ.multiply_AtBC(J1, edge->second.cov_inv, J2);
170  }
171 
172  template <class JAC, class EDGE_ITERATOR, class VEC1, class VEC2>
173  static inline void multiply_Jt_W_err(
174  const JAC& J, const EDGE_ITERATOR& edge, const VEC1& ERR, VEC2& OUT)
175  {
177  JtInf.multiply_AtB(J, edge->second.cov_inv);
178  JtInf.multiply_Ab(ERR, OUT, true /* accumulate in output */);
179  }
180 };
181 
182 } // end NS detail
183 
184 // Compute, at once, jacobians and the error vectors for each constraint in
185 // "lstObservationData", returns the overall squared error.
186 template <class GRAPH_T>
188  const GRAPH_T& graph,
189  const std::vector<typename graphslam_traits<GRAPH_T>::observation_info_t>&
190  lstObservationData,
192  typename mrpt::aligned_containers<
193  typename graphslam_traits<GRAPH_T>::Array_O>::vector_t& errs)
194 {
195  MRPT_UNUSED_PARAM(graph);
196  typedef graphslam_traits<GRAPH_T> gst;
197 
198  lstJacobians.clear();
199  errs.clear();
200 
201  const size_t nObservations = lstObservationData.size();
202 
203  for (size_t i = 0; i < nObservations; i++)
204  {
205  const typename gst::observation_info_t& obs = lstObservationData[i];
206  typename gst::edge_const_iterator it = obs.edge;
207  const typename gst::graph_t::constraint_t::type_value* EDGE_POSE =
208  obs.edge_mean;
209  typename gst::graph_t::constraint_t::type_value* P1 = obs.P1;
210  typename gst::graph_t::constraint_t::type_value* P2 = obs.P2;
211 
212  const mrpt::utils::TPairNodeIDs& ids = it->first;
213  const typename gst::graph_t::edge_t& edge = it->second;
214 
215  // Compute the residual pose error of these pair of nodes + its
216  // constraint,
217  // that is: P1DP2inv = P1 * EDGE * inv(P2)
218  typename gst::graph_t::constraint_t::type_value P1DP2inv(
220  {
221  typename gst::graph_t::constraint_t::type_value P1D(
223  P1D.composeFrom(*P1, *EDGE_POSE);
224  const typename gst::graph_t::constraint_t::type_value P2inv =
225  -(*P2); // Pose inverse (NOT just switching signs!)
226  P1DP2inv.composeFrom(P1D, P2inv);
227  }
228 
229  // Add to vector of errors:
230  errs.resize(errs.size() + 1);
232  P1DP2inv, errs.back(), edge);
233 
234  // Compute the jacobians:
235  alignas(16)
236  std::pair<mrpt::utils::TPairNodeIDs, typename gst::TPairJacobs>
237  newMapEntry;
238  newMapEntry.first = ids;
239  gst::SE_TYPE::jacobian_dP1DP2inv_depsilon(
240  P1DP2inv, &newMapEntry.second.first, &newMapEntry.second.second);
241 
242  // And insert into map of jacobians:
243  lstJacobians.insert(lstJacobians.end(), newMapEntry);
244  }
245 
246  // return overall square error: (Was:
247  // std::accumulate(...,mrpt::math::squareNorm_accum<>), but led to GCC
248  // errors when enabling parallelization)
249  double ret_err = 0.0;
250  for (size_t i = 0; i < errs.size(); i++) ret_err += errs[i].squaredNorm();
251  return ret_err;
252 }
253 
254 } // end of NS
255 } // end of NS
256 
257 #endif
static void multiplyJtLambdaJ(const MAT &J1, MAT &JtJ, const EDGE_ITERATOR &edge)
Definition: levmarq_impl.h:88
static void multiplyJtLambdaJ(const MAT &J1, MAT &JtJ, const EDGE_ITERATOR &edge)
Definition: levmarq_impl.h:124
GLuint * ids
Definition: glext.h:3906
static void computePseudoLnError(const POSE &P1DP2inv, VEC &err, const EDGE_ITERATOR &edge)
Definition: levmarq_impl.h:117
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
std::pair< TNodeID, TNodeID > TPairNodeIDs
A pair of node IDs.
static void multiplyJ1tLambdaJ2(const MAT &J1, const MAT &J2, MAT &JtJ, const EDGE_ITERATOR &edge)
Definition: levmarq_impl.h:130
mrpt::aligned_containers< mrpt::utils::TPairNodeIDs, TPairJacobs >::multimap_t map_pairIDs_pairJacobs_t
static void multiplyJ1tLambdaJ2(const MAT &J1, const MAT &J2, MAT &JtJ, const EDGE_ITERATOR &edge)
Definition: levmarq_impl.h:166
STL namespace.
Helper types for STL containers with Eigen memory allocators.
static void computePseudoLnError(const POSE &P1DP2inv, VEC &err, const EDGE_ITERATOR &edge)
Definition: levmarq_impl.h:43
double computeJacobiansAndErrors(const GRAPH_T &graph, const std::vector< typename graphslam_traits< GRAPH_T >::observation_info_t > &lstObservationData, typename graphslam_traits< GRAPH_T >::map_pairIDs_pairJacobs_t &lstJacobians, typename mrpt::aligned_containers< typename graphslam_traits< GRAPH_T >::Array_O >::vector_t &errs)
Definition: levmarq_impl.h:187
Auxiliary struct used in graph-slam implementation: It holds the relevant information for each of the...
static void multiplyJ1tLambdaJ2(const MAT &J1, const MAT &J2, MAT &JtJ, const EDGE_ITERATOR &edge)
Definition: levmarq_impl.h:59
static void computePseudoLnError(const POSE &P1DP2inv, VEC &err, const EDGE_ITERATOR &edge)
Definition: levmarq_impl.h:80
SLAM methods related to graphs of pose constraints.
This base provides a set of functions for maths stuff.
Definition: CArrayNumeric.h:19
static void multiply_Jt_W_err(const JAC &J, const EDGE_ITERATOR &edge, const VEC1 &ERR, VEC2 &OUT)
Definition: levmarq_impl.h:67
#define MRPT_UNUSED_PARAM(a)
Can be used to avoid "not used parameters" warnings from the compiler.
static void multiply_Jt_W_err(const JAC &J, const EDGE_ITERATOR &edge, const VEC1 &ERR, VEC2 &OUT)
Definition: levmarq_impl.h:173
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
Definition: CPoint.h:17
Auxiliary traits template for use among graph-slam problems to make life easier with these complicate...
static void multiplyJtLambdaJ(const MAT &J1, MAT &JtJ, const EDGE_ITERATOR &edge)
Definition: levmarq_impl.h:159
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
A Probability Density function (PDF) of a 2D pose as a Gaussian with a mean and the inverse of the c...
A class used to store a 2D pose, including the 2D coordinate point and a heading (phi) angle...
Definition: CPose2D.h:40
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
Definition: CPose3D.h:88
static void multiplyJtLambdaJ(const MAT &J1, MAT &JtJ, const EDGE_ITERATOR &edge)
Definition: levmarq_impl.h:51
static void multiplyJ1tLambdaJ2(const MAT &J1, const MAT &J2, MAT &JtJ, const EDGE_ITERATOR &edge)
Definition: levmarq_impl.h:96
static void multiply_Jt_W_err(const JAC &J, const EDGE_ITERATOR &edge, const VEC1 &ERR, VEC2 &OUT)
Definition: levmarq_impl.h:137
Declares a class that represents a Probability Density function (PDF) of a 3D pose as a Gaussian des...
static void computePseudoLnError(const POSE &P1DP2inv, VEC &err, const EDGE_ITERATOR &edge)
Definition: levmarq_impl.h:151
static void multiply_Jt_W_err(const JAC &J, const EDGE_ITERATOR &edge, const VEC1 &ERR, VEC2 &OUT)
Definition: levmarq_impl.h:104



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: ae4571287 Thu Nov 23 00:06:53 2017 +0100 at dom oct 27 23:51:55 CET 2019