Main MRPT website > C++ reference for MRPT 1.9.9
CPose3DPDFSOG.cpp
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 
10 #include "base-precomp.h" // Precompiled headers
11 
13 #include <mrpt/system/os.h>
14 #include <mrpt/utils/CStream.h>
17 
18 using namespace mrpt;
19 using namespace mrpt::poses;
20 using namespace mrpt::math;
21 using namespace mrpt::utils;
22 using namespace mrpt::system;
23 using namespace std;
24 
26 
27 /*---------------------------------------------------------------
28  Constructor
29  ---------------------------------------------------------------*/
30 CPose3DPDFSOG::CPose3DPDFSOG(size_t nModes) : m_modes(nModes) {}
31 /*---------------------------------------------------------------
32  clear
33  ---------------------------------------------------------------*/
34 void CPose3DPDFSOG::clear() { m_modes.clear(); }
35 /*---------------------------------------------------------------
36  Resize
37  ---------------------------------------------------------------*/
38 void CPose3DPDFSOG::resize(const size_t N) { m_modes.resize(N); }
39 /*---------------------------------------------------------------
40  getMean
41  Returns an estimate of the pose, (the mean, or mathematical expectation of the
42  PDF)
43  ---------------------------------------------------------------*/
45 {
46  if (!m_modes.empty())
47  {
48  // Calc average on SE(3)
49  mrpt::poses::SE_average<3> se_averager;
50  for (const_iterator it = m_modes.begin(); it != m_modes.end(); ++it)
51  {
52  const double w = exp(it->log_w);
53  se_averager.append((it)->val.mean, w);
54  }
55  se_averager.get_average(p);
56  }
57  else
58  {
59  p.setFromValues(0, 0, 0, 0, 0, 0);
60  }
61 }
62 
63 /*---------------------------------------------------------------
64  getCovarianceAndMean
65  ---------------------------------------------------------------*/
67  mrpt::math::CMatrixDouble66& estCovOut, CPose3D& mean) const
68 {
69  size_t N = m_modes.size();
70 
71  getMean(mean);
73 
74  if (N)
75  {
76  // 1) Get the mean:
77  double sumW = 0;
79 
82  for (const_iterator it = m_modes.begin(); it != m_modes.end(); ++it)
83  {
84  double w;
85  sumW += w = exp((it)->log_w);
86  estMean_i = mrpt::math::CMatrixDouble61((it)->val.mean);
87  MMt.multiply_AAt(estMean_i);
88  MMt += (it)->val.cov;
89  MMt *= w;
90  estCov += MMt; // w * ( (it)->val.cov +
91  // ((estMean_i-estMean)*(~(estMean_i-estMean))) );
92  }
93 
94  if (sumW != 0) estCov *= (1.0 / sumW);
95  }
96 
97  estCovOut = estCov;
98 }
99 
100 /*---------------------------------------------------------------
101  writeToStream
102  ---------------------------------------------------------------*/
104 {
105  if (version)
106  *version = 2;
107  else
108  {
109  uint32_t N = m_modes.size();
110  out << N;
111  for (const_iterator it = m_modes.begin(); it != m_modes.end(); ++it)
112  {
113  out << (it)->log_w;
114  out << (it)->val.mean;
115  out << (it)->val.cov;
116  }
117  }
118 }
119 
120 /*---------------------------------------------------------------
121  readFromStream
122  ---------------------------------------------------------------*/
124 {
125  switch (version)
126  {
127  case 0:
128  case 1:
129  case 2:
130  {
131  uint32_t N;
132  in >> N;
133  this->resize(N);
134 
135  for (iterator it = m_modes.begin(); it != m_modes.end(); ++it)
136  {
137  in >> (it)->log_w;
138 
139  // In version 0, weights were linear!!
140  if (version == 0) (it)->log_w = log(max(1e-300, (it)->log_w));
141 
142  in >> (it)->val.mean;
143 
144  if (version == 1) // were floats
145  {
146  THROW_EXCEPTION("Unsupported serialized version: too old")
147  }
148  else
149  {
150  in >> (it)->val.cov;
151  }
152  }
153  }
154  break;
155  default:
157  };
158 }
159 
161 {
162  MRPT_START
163 
164  if (this == &o) return; // It may be used sometimes
165 
167  {
168  *this = *static_cast<const CPose3DPDFSOG*>(&o);
169  }
170  else
171  {
172  this->resize(1);
173  m_modes[0].log_w = 0;
175  o.getCovarianceAndMean(C, m_modes[0].val.mean);
176  m_modes[0].val.cov = C;
177  }
178 
179  MRPT_END
180 }
181 
182 /*---------------------------------------------------------------
183  saveToTextFile
184  ---------------------------------------------------------------*/
186 {
187  FILE* f = os::fopen(file.c_str(), "wt");
188  if (!f) return;
189 
190  for (const_iterator it = m_modes.begin(); it != m_modes.end(); ++it)
191  os::fprintf(
192  f, "%e %e %e %e %e %e %e %e %e %e\n", exp((it)->log_w),
193  (it)->val.mean.x(), (it)->val.mean.y(), (it)->val.mean.z(),
194  (it)->val.cov(0, 0), (it)->val.cov(1, 1), (it)->val.cov(2, 2),
195  (it)->val.cov(0, 1), (it)->val.cov(0, 2), (it)->val.cov(1, 2));
196  os::fclose(f);
197 }
198 
199 /*---------------------------------------------------------------
200  changeCoordinatesReference
201  ---------------------------------------------------------------*/
203 {
204  for (iterator it = m_modes.begin(); it != m_modes.end(); ++it)
205  (it)->val.changeCoordinatesReference(newReferenceBase);
206 }
207 
208 /*---------------------------------------------------------------
209  bayesianFusion
210  ---------------------------------------------------------------*/
212 {
213  MRPT_START
214 
215  // p1: CPose3DPDFSOG, p2: CPosePDFGaussian:
216 
219 
220  THROW_EXCEPTION("TODO!!!");
221 #if 0
222 /*
223  CPose3DPDFSOG *p1 = (CPose3DPDFSOG*)&p1_;
224  CPose3DPDFSOG *p2 = (CPose3DPDFSOG*)&p2_;
225 
226  // Compute the new kernel means, covariances, and weights after multiplying to the Gaussian "p2":
227  CPosePDFGaussian auxGaussianProduct,auxSOG_Kernel_i;
228  TGaussianMode newKernel;
229 
230 
231 
232  CMatrixD covInv( p2->cov.inv() );
233  CMatrixD eta(3,1);
234  eta(0,0) = p2->mean.x;
235  eta(1,0) = p2->mean.y;
236  eta(2,0) = p2->mean.phi;
237  eta = covInv * eta;
238 
239  // Normal distribution canonical form constant:
240  // See: http://www-static.cc.gatech.edu/~wujx/paper/Gaussian.pdf
241  double a = -0.5*( 3*log(M_2PI) - log( covInv.det() ) + (~eta * p2->cov * eta)(0,0) );
242 
243  this->m_modes.clear();
244  for (std::deque<TGaussianMode>::iterator it =p1->m_modes.begin();it!=p1->m_modes.end();++it)
245  {
246  auxSOG_Kernel_i.mean = it->mean;
247  auxSOG_Kernel_i.cov = it->cov;
248  auxGaussianProduct.bayesianFusion( auxSOG_Kernel_i, *p2 );
249 
250  // ----------------------------------------------------------------------
251  // The new weight is given by:
252  //
253  // w'_i = w_i * exp( a + a_i - a' )
254  //
255  // a = -1/2 ( dimensionality * log(2pi) - log(det(Cov^-1)) + (Cov^-1 * mu)^t * Cov^-1 * (Cov^-1 * mu) )
256  //
257  // ----------------------------------------------------------------------
258  newKernel.mean = auxGaussianProduct.mean;
259  newKernel.cov = auxGaussianProduct.cov;
260 
261  CMatrixD covInv_i( auxSOG_Kernel_i.cov.inv() );
262  CMatrixD eta_i(3,1);
263  eta_i(0,0) = auxSOG_Kernel_i.mean.x;
264  eta_i(1,0) = auxSOG_Kernel_i.mean.y;
265  eta_i(2,0) = auxSOG_Kernel_i.mean.phi;
266  eta_i = covInv_i * eta_i;
267 
268  CMatrixD new_covInv_i( newKernel.cov.inv() );
269  CMatrixD new_eta_i(3,1);
270  new_eta_i(0,0) = newKernel.mean.x;
271  new_eta_i(1,0) = newKernel.mean.y;
272  new_eta_i(2,0) = newKernel.mean.phi;
273  new_eta_i = new_covInv_i * new_eta_i;
274 
275  double a_i = -0.5*( 3*log(M_2PI) - log( new_covInv_i.det() ) + (~eta_i * auxSOG_Kernel_i.cov * eta_i)(0,0) );
276  double new_a_i = -0.5*( 3*log(M_2PI) - log( new_covInv_i.det() ) + (~new_eta_i * newKernel.cov * new_eta_i)(0,0) );
277 
278  newKernel.w = it->w * exp( a + a_i - new_a_i );
279 
280  // Add to the results (in "this") the new kernel:
281  this->m_modes.push_back( newKernel );
282  }
283 */
284  normalizeWeights();
285 #endif
286  MRPT_END
287 }
288 
289 /*---------------------------------------------------------------
290  assureSymmetry
291  ---------------------------------------------------------------*/
293 {
294  MRPT_START
295  // Differences, when they exist, appear in the ~15'th significant
296  // digit, so... just take one of them arbitrarily!
297  for (iterator it = m_modes.begin(); it != m_modes.end(); ++it)
298  {
299  for (size_t i = 0; i < 6; i++)
300  for (size_t j = i + 1; j < 6; j++)
301  (it)->val.cov.get_unsafe(i, j) = (it)->val.cov.get_unsafe(j, i);
302  }
303 
304  MRPT_END
305 }
306 
307 /*---------------------------------------------------------------
308  normalizeWeights
309  ---------------------------------------------------------------*/
311 {
312  MRPT_START
313 
314  if (m_modes.empty()) return;
315 
316  double maxW = m_modes[0].log_w;
317  for (iterator it = m_modes.begin(); it != m_modes.end(); ++it)
318  maxW = max(maxW, (it)->log_w);
319 
320  for (iterator it = m_modes.begin(); it != m_modes.end(); ++it)
321  (it)->log_w -= maxW;
322 
323  MRPT_END
324 }
325 
326 /*---------------------------------------------------------------
327  drawSingleSample
328  ---------------------------------------------------------------*/
330 {
331  MRPT_UNUSED_PARAM(outPart);
332  THROW_EXCEPTION("TO DO!");
333 }
334 
335 /*---------------------------------------------------------------
336  drawManySamples
337  ---------------------------------------------------------------*/
339  size_t N, std::vector<CVectorDouble>& outSamples) const
340 {
342  MRPT_UNUSED_PARAM(outSamples);
343  THROW_EXCEPTION("TO DO!");
344 }
345 
346 /*---------------------------------------------------------------
347  inverse
348  ---------------------------------------------------------------*/
350 {
351  MRPT_START
353  CPose3DPDFSOG* out = static_cast<CPose3DPDFSOG*>(&o);
354 
355  // Prepare the output SOG:
356  out->resize(m_modes.size());
357 
358  const_iterator it;
359  iterator outIt;
360 
361  for (it = m_modes.begin(), outIt = out->m_modes.begin();
362  it != m_modes.end(); it++, outIt++)
363  {
364  (it)->val.inverse((outIt)->val);
365  (outIt)->log_w = (it)->log_w;
366  }
367 
368  MRPT_END
369 }
370 
371 /*---------------------------------------------------------------
372  appendFrom
373  ---------------------------------------------------------------*/
375 {
376  MRPT_START
377 
378  ASSERT_(&o != this); // Don't be bad...
379  if (o.m_modes.empty()) return;
380 
381  // Make copies:
382  for (const_iterator it = o.m_modes.begin(); it != o.m_modes.end(); ++it)
383  m_modes.push_back(*it);
384 
385  normalizeWeights();
386  MRPT_END
387 }
388 
389 /*---------------------------------------------------------------
390  getMostLikelyMode
391  ---------------------------------------------------------------*/
393 {
394  if (this->empty())
395  {
396  outVal = CPose3DPDFGaussian();
397  }
398  else
399  {
400  const_iterator it_best = m_modes.end();
401  for (const_iterator it = m_modes.begin(); it != m_modes.end(); ++it)
402  if (it_best == m_modes.end() || it->log_w > it_best->log_w)
403  it_best = it;
404 
405  outVal = it_best->val;
406  }
407 }
EIGEN_STRONG_INLINE bool empty() const
void append(const mrpt::poses::CPose3D &p)
Adds a new pose to the computation.
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
This namespace provides a OS-independent interface to many useful functions: filenames manipulation...
Definition: math_frwds.h:30
void getCovarianceAndMean(mrpt::math::CMatrixDouble66 &cov, CPose3D &mean_point) const override
Returns an estimate of the pose covariance matrix (6x6 cov matrix) and the mean, both at once...
TModesList::iterator iterator
Definition: CPose3DPDFSOG.h:54
int void fclose(FILE *f)
An OS-independent version of fclose.
Definition: os.cpp:272
void getMostLikelyMode(CPose3DPDFGaussian &outVal) const
Return the Gaussian mode with the highest likelihood (or an empty Gaussian if there are no modes in t...
void appendFrom(const CPose3DPDFSOG &o)
Append the Gaussian modes from "o" to the current set of modes of "this" density. ...
#define IMPLEMENTS_SERIALIZABLE(class_name, base, NameSpace)
This must be inserted in all CSerializable classes implementation files.
#define THROW_EXCEPTION(msg)
Declares a class that represents a Probability Density function (PDF) of a 3D(6D) pose ...
Definition: CPose3DPDFSOG.h:35
void getMean(CPose3D &mean_pose) const override
Returns an estimate of the pose, (the mean, or mathematical expectation of the PDF), computed as a weighted average over all m_particles.
STL namespace.
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:4178
void normalizeWeights()
Normalize the weights in m_modes such as the maximum log-weight is 0.
void inverse(CPose3DPDF &o) const override
Returns a new PDF such as: NEW_PDF = (0,0,0) - THIS_PDF.
virtual const mrpt::utils::TRuntimeClassId * GetRuntimeClass() const override
Returns information about the class of an object in runtime.
This base class is used to provide a unified interface to files,memory buffers,..Please see the deriv...
Definition: CStream.h:41
A numeric matrix of compile-time fixed size.
This base provides a set of functions for maths stuff.
Definition: CArrayNumeric.h:19
#define CLASS_ID(T)
Access to runtime class ID for a defined class name.
Definition: CObject.h:85
void readFromStream(mrpt::utils::CStream &in, int version) override
Introduces a pure virtual method responsible for loading from a CStream This can not be used directly...
#define MRPT_END
#define MRPT_UNUSED_PARAM(a)
Can be used to avoid "not used parameters" warnings from the compiler.
void drawManySamples(size_t N, std::vector< mrpt::math::CVectorDouble > &outSamples) const override
Draws a number of samples from the distribution, and saves as a list of 1x6 vectors, where each row contains a (x,y,z,yaw,pitch,roll) datum.
#define MRPT_THROW_UNKNOWN_SERIALIZATION_VERSION(__V)
For use in CSerializable implementations.
TModesList m_modes
Access directly to this array for modify the modes as desired.
Definition: CPose3DPDFSOG.h:66
TModesList::const_iterator const_iterator
Definition: CPose3DPDFSOG.h:53
void changeCoordinatesReference(const CPose3D &newReferenceBase) override
this = p (+) this.
int val
Definition: mrpt_jpeglib.h:955
void drawSingleSample(CPose3D &outPart) const override
Draws a single sample from the distribution.
void saveToTextFile(const std::string &file) const override
Save the density to a text file, with the following format: There is one row per Gaussian "mode"...
GLsizei const GLchar ** string
Definition: glext.h:4101
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
Definition: CPoint.h:17
int fprintf(FILE *fil, const char *format,...) noexcept MRPT_printf_format_check(2
An OS-independent version of fprintf.
Definition: os.cpp:405
#define MRPT_START
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
Computes weighted and un-weighted averages of SE(3) poses.
void get_average(mrpt::poses::CPose3D &out_mean) const
Returns the average pose.
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
Definition: CPose3D.h:88
void clear()
Clear all the gaussian modes.
This file implements matrix/vector text and binary serialization.
GLuint in
Definition: glext.h:7274
#define ASSERT_(f)
Declares a class that represents a Probability Density function (PDF) of a 3D pose ...
void bayesianFusion(const CPose3DPDF &p1, const CPose3DPDF &p2) override
Bayesian fusion of two pose distributions, then save the result in this object (WARNING: Currently p1...
void assureSymmetry()
Assures the symmetry of the covariance matrix (eventually certain operations in the math-coprocessor ...
void writeToStream(mrpt::utils::CStream &out, int *getVersion) const override
Introduces a pure virtual method responsible for writing to a CStream.
FILE * fopen(const char *fileName, const char *mode) noexcept
An OS-independent version of fopen.
Definition: os.cpp:254
virtual void getCovarianceAndMean(mrpt::math::CMatrixFixedNumeric< double, STATE_LEN, STATE_LEN > &cov, TDATA &mean_point) const =0
Returns an estimate of the pose covariance matrix (STATE_LENxSTATE_LEN cov matrix) and the mean...
unsigned __int32 uint32_t
Definition: rptypes.h:47
GLfloat GLfloat p
Definition: glext.h:6305
Declares a class that represents a Probability Density Function (PDF) of a 3D pose (6D actually)...
Definition: CPose3DPDF.h:42
void copyFrom(const CPose3DPDF &o) override
Copy operator, translating if necesary (for example, between particles and gaussian representations) ...
EIGEN_STRONG_INLINE double mean() const
Computes the mean of the entire matrix.
CMatrixFixedNumeric< double, 6, 1 > CMatrixDouble61
Definition: eigen_frwds.h:63
void resize(const size_t N)
Set the number of SOG modes.



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