Main MRPT website > C++ reference for MRPT 1.9.9
CPosePDFSOG.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 
12 #include <mrpt/poses/CPosePDFSOG.h>
15 #include <mrpt/system/os.h>
17 #include <mrpt/math/CMatrixD.h>
18 #include <mrpt/math/wrap2pi.h>
19 #include <mrpt/utils/CStream.h>
21 
22 using namespace mrpt;
23 using namespace mrpt::poses;
24 using namespace mrpt::math;
25 using namespace mrpt::utils;
26 using namespace mrpt::system;
27 using namespace std;
28 
30 
31 /*---------------------------------------------------------------
32  Constructor
33  ---------------------------------------------------------------*/
34 CPosePDFSOG::CPosePDFSOG(size_t nModes) : m_modes(nModes) {}
35 /*---------------------------------------------------------------
36  clear
37  ---------------------------------------------------------------*/
38 void CPosePDFSOG::clear() { m_modes.clear(); }
39 /*---------------------------------------------------------------
40  Resize
41  ---------------------------------------------------------------*/
42 void CPosePDFSOG::resize(const size_t N) { m_modes.resize(N); }
43 /*---------------------------------------------------------------
44  getMean
45  Returns an estimate of the pose, (the mean, or mathematical expectation of the
46  PDF)
47  ---------------------------------------------------------------*/
49 {
50  if (!m_modes.empty())
51  {
52  mrpt::poses::SE_average<2> se_averager;
53  for (const_iterator it = m_modes.begin(); it != m_modes.end(); ++it)
54  {
55  const double w = exp((it)->log_w);
56  se_averager.append((it)->mean, w);
57  }
58  se_averager.get_average(p);
59  }
60  else
61  {
62  p = CPose2D();
63  }
64 }
65 
66 /*---------------------------------------------------------------
67  getEstimatedCovariance
68  ---------------------------------------------------------------*/
70  CMatrixDouble33& estCov, CPose2D& estMean2D) const
71 {
72  size_t N = m_modes.size();
73 
74  this->getMean(estMean2D);
75  estCov.zeros();
76 
77  if (N)
78  {
79  // 1) Get the mean:
80  double sumW = 0;
81  CMatrixDouble31 estMeanMat = CMatrixDouble31(estMean2D);
82  CMatrixDouble33 temp;
83  CMatrixDouble31 estMean_i;
84 
85  for (const_iterator it = m_modes.begin(); it != m_modes.end(); ++it)
86  {
87  double w;
88  sumW += w = exp((it)->log_w);
89 
90  estMean_i = CMatrixDouble31((it)->mean);
91  estMean_i -= estMeanMat;
92 
93  temp.multiply_AAt(estMean_i);
94  temp += (it)->cov;
95  temp *= w;
96 
97  estCov += temp;
98  }
99 
100  if (sumW != 0) estCov *= (1.0 / sumW);
101  }
102 }
103 
104 /*---------------------------------------------------------------
105  writeToStream
106  ---------------------------------------------------------------*/
107 void CPosePDFSOG::writeToStream(mrpt::utils::CStream& out, int* version) const
108 {
109  if (version)
110  *version = 2;
111  else
112  {
113  uint32_t N = m_modes.size();
114  out << N;
115 
116  for (const_iterator it = m_modes.begin(); it != m_modes.end(); ++it)
117  {
118  out << (it)->log_w;
119  out << (it)->mean;
120  out << (it)->cov(0, 0) << (it)->cov(1, 1) << (it)->cov(2, 2);
121  out << (it)->cov(0, 1) << (it)->cov(0, 2) << (it)->cov(1, 2);
122  }
123  }
124 }
125 
126 /*---------------------------------------------------------------
127  readFromStream
128  ---------------------------------------------------------------*/
130 {
131  switch (version)
132  {
133  case 0:
134  case 1:
135  case 2:
136  {
137  uint32_t N;
138  float x;
139  double x0;
140 
141  in >> N;
142 
143  resize(N);
144 
145  for (iterator it = m_modes.begin(); it != m_modes.end(); ++it)
146  {
147  in >> (it)->log_w;
148 
149  // In version 0, weights were linear!!
150  if (version == 0) (it)->log_w = log(max(1e-300, (it)->log_w));
151 
152  in >> (it)->mean;
153 
154  if (version == 1) // float's
155  {
156  in >> x;
157  (it)->cov(0, 0) = x;
158  in >> x;
159  (it)->cov(1, 1) = x;
160  in >> x;
161  (it)->cov(2, 2) = x;
162 
163  in >> x;
164  (it)->cov(1, 0) = x;
165  (it)->cov(0, 1) = x;
166  in >> x;
167  (it)->cov(2, 0) = x;
168  (it)->cov(0, 2) = x;
169  in >> x;
170  (it)->cov(1, 2) = x;
171  (it)->cov(2, 1) = x;
172  }
173  else
174  {
175  in >> x0;
176  (it)->cov(0, 0) = x0;
177  in >> x0;
178  (it)->cov(1, 1) = x0;
179  in >> x0;
180  (it)->cov(2, 2) = x0;
181 
182  in >> x0;
183  (it)->cov(1, 0) = x0;
184  (it)->cov(0, 1) = x0;
185  in >> x0;
186  (it)->cov(2, 0) = x0;
187  (it)->cov(0, 2) = x0;
188  in >> x0;
189  (it)->cov(1, 2) = x0;
190  (it)->cov(2, 1) = x0;
191  }
192  }
193  }
194  break;
195  default:
197  };
198 }
199 
201 {
202  MRPT_START
203 
204  if (this == &o) return; // It may be used sometimes
205 
207  {
208  m_modes = static_cast<const CPosePDFSOG*>(&o)->m_modes;
209  }
210  else
211  {
212  // Approximate as a mono-modal gaussian pdf:
213  m_modes.resize(1);
214  m_modes[0].log_w = 0;
215  o.getMean(m_modes[0].mean);
216  o.getCovariance(m_modes[0].cov);
217  }
218 
219  MRPT_END
220 }
221 
222 /*---------------------------------------------------------------
223  saveToTextFile
224  ---------------------------------------------------------------*/
226 {
227  FILE* f = os::fopen(file.c_str(), "wt");
228  if (!f) return;
229 
230  for (const_iterator it = m_modes.begin(); it != m_modes.end(); ++it)
231  os::fprintf(
232  f, "%e %e %e %e %e %e %e %e %e %e\n", exp((it)->log_w),
233  (it)->mean.x(), (it)->mean.y(), (it)->mean.phi(), (it)->cov(0, 0),
234  (it)->cov(1, 1), (it)->cov(2, 2), (it)->cov(0, 1), (it)->cov(0, 2),
235  (it)->cov(1, 2));
236  os::fclose(f);
237 }
238 
239 /*---------------------------------------------------------------
240  changeCoordinatesReference
241  ---------------------------------------------------------------*/
242 void CPosePDFSOG::changeCoordinatesReference(const CPose3D& newReferenceBase_)
243 {
244  const CPose2D newReferenceBase = CPose2D(newReferenceBase_);
245 
246  CMatrixDouble44 HM;
247  newReferenceBase.getHomogeneousMatrix(HM);
248 
249  // Clip the 4x4 matrix
250  CMatrixDouble33 M = HM.block(0, 0, 3, 3).eval();
251 
252  // The variance in phi is unmodified:
253  M(0, 2) = 0;
254  M(1, 2) = 0;
255  M(2, 0) = 0;
256  M(2, 1) = 0;
257  M(2, 2) = 1;
258 
259  for (iterator it = m_modes.begin(); it != m_modes.end(); ++it)
260  {
261  // The mean:
262  (it)->mean.composeFrom(newReferenceBase, (it)->mean);
263 
264  // The covariance:
265  // NOTE: The CMatrixDouble33() is NEEDED to create a temporary copy of
266  // (it)->cov
267  M.multiply_HCHt(
268  CMatrixDouble33((it)->cov), (it)->cov); // * (it)->cov * (~M);
269  }
270 
271  assureSymmetry();
272 }
273 
274 /*---------------------------------------------------------------
275  rotateAllCovariances
276  ---------------------------------------------------------------*/
277 void CPosePDFSOG::rotateAllCovariances(const double& ang)
278 {
279  CMatrixDouble33 rot;
280  rot(0, 0) = rot(1, 1) = cos(ang);
281  rot(0, 1) = -sin(ang);
282  rot(1, 0) = sin(ang);
283  rot(2, 2) = 1;
284 
285  for (iterator it = m_modes.begin(); it != m_modes.end(); ++it)
286  rot.multiply_HCHt(CMatrixDouble33((it)->cov), (it)->cov);
287 }
288 
289 /*---------------------------------------------------------------
290  drawSingleSample
291  ---------------------------------------------------------------*/
293 {
294  MRPT_START
295  MRPT_UNUSED_PARAM(outPart);
296 
297  THROW_EXCEPTION("Not implemented yet!!");
298 
299  MRPT_END
300 }
301 
302 /*---------------------------------------------------------------
303  drawManySamples
304  ---------------------------------------------------------------*/
306  size_t N, std::vector<CVectorDouble>& outSamples) const
307 {
308  MRPT_START
310  MRPT_UNUSED_PARAM(outSamples);
311 
312  THROW_EXCEPTION("Not implemented yet!!");
313 
314  MRPT_END
315 }
316 
317 /*---------------------------------------------------------------
318  bayesianFusion
319  ---------------------------------------------------------------*/
321  const CPosePDF& p1_, const CPosePDF& p2_,
322  const double& minMahalanobisDistToDrop)
323 {
324  MRPT_START
325 
326  MRPT_UNUSED_PARAM(minMahalanobisDistToDrop);
327 
328  // p1: CPosePDFSOG, p2: CPosePDFGaussian:
329 
332 
333  const CPosePDFSOG* p1 = static_cast<const CPosePDFSOG*>(&p1_);
334  const CPosePDFGaussian* p2 = static_cast<const CPosePDFGaussian*>(&p2_);
335 
336  // Compute the new kernel means, covariances, and weights after multiplying
337  // to the Gaussian "p2":
338  CPosePDFGaussian auxGaussianProduct, auxSOG_Kernel_i;
339 
340  CMatrixDouble33 covInv;
341  p2->cov.inv(covInv);
342 
344  eta = covInv * eta;
345 
346  // Normal distribution canonical form constant:
347  // See: http://www-static.cc.gatech.edu/~wujx/paper/Gaussian.pdf
348  double a = -0.5 * (3 * log(M_2PI) - log(covInv.det()) +
349  (eta.adjoint() * p2->cov * eta)(0, 0));
350 
351  this->m_modes.clear();
352  for (const_iterator it = p1->m_modes.begin(); it != p1->m_modes.end(); ++it)
353  {
354  auxSOG_Kernel_i.mean = (it)->mean;
355  auxSOG_Kernel_i.cov = CMatrixDouble((it)->cov);
356  auxGaussianProduct.bayesianFusion(auxSOG_Kernel_i, *p2);
357 
358  // ----------------------------------------------------------------------
359  // The new weight is given by:
360  //
361  // w'_i = w_i * exp( a + a_i - a' )
362  //
363  // a = -1/2 ( dimensionality * log(2pi) - log(det(Cov^-1)) +
364  // (Cov^-1 * mu)^t * Cov^-1 * (Cov^-1 * mu) )
365  //
366  // ----------------------------------------------------------------------
367  TGaussianMode newKernel;
368  newKernel.mean = auxGaussianProduct.mean;
369  newKernel.cov = auxGaussianProduct.cov;
370 
371  CMatrixDouble33 covInv_i;
372  auxSOG_Kernel_i.cov.inv(covInv_i);
373 
374  CMatrixDouble31 eta_i = CMatrixDouble31(auxSOG_Kernel_i.mean);
375  eta_i = covInv_i * eta_i;
376 
377  CMatrixDouble33 new_covInv_i;
378  newKernel.cov.inv(new_covInv_i);
379 
380  CMatrixDouble31 new_eta_i = CMatrixDouble31(newKernel.mean);
381  new_eta_i = new_covInv_i * new_eta_i;
382 
383  double a_i =
384  -0.5 * (3 * log(M_2PI) - log(new_covInv_i.det()) +
385  (eta_i.adjoint() * auxSOG_Kernel_i.cov * eta_i)(0, 0));
386  double new_a_i =
387  -0.5 * (3 * log(M_2PI) - log(new_covInv_i.det()) +
388  (new_eta_i.adjoint() * newKernel.cov * new_eta_i)(0, 0));
389 
390  // newKernel.w = (it)->w * exp( a + a_i - new_a_i );
391  newKernel.log_w = (it)->log_w + a + a_i - new_a_i;
392 
393  // Add to the results (in "this") the new kernel:
394  this->m_modes.push_back(newKernel);
395  }
396 
397  normalizeWeights();
398 
399  MRPT_END
400 }
401 
402 /*---------------------------------------------------------------
403  inverse
404  ---------------------------------------------------------------*/
406 {
408  CPosePDFSOG* out = static_cast<CPosePDFSOG*>(&o);
409 
410  const_iterator itSrc;
411  iterator itDest;
412 
413  out->m_modes.resize(m_modes.size());
414 
415  for (itSrc = m_modes.begin(), itDest = out->m_modes.begin();
416  itSrc != m_modes.end(); ++itSrc, ++itDest)
417  {
418  // The mean:
419  (itDest)->mean = -(itSrc)->mean;
420 
421  // The covariance: Is the same:
422  (itDest)->cov = (itSrc)->cov;
423  }
424 }
425 
426 /*---------------------------------------------------------------
427  +=
428  ---------------------------------------------------------------*/
430 {
431  for (iterator it = m_modes.begin(); it != m_modes.end(); ++it)
432  (it)->mean = (it)->mean + Ap;
433 
434  this->rotateAllCovariances(Ap.phi());
435 }
436 
437 /*---------------------------------------------------------------
438  evaluatePDF
439  ---------------------------------------------------------------*/
440 double CPosePDFSOG::evaluatePDF(const CPose2D& x, bool sumOverAllPhis) const
441 {
442  if (!sumOverAllPhis)
443  {
444  // Normal evaluation:
446  CMatrixDouble31 MU;
447  double ret = 0;
448 
449  for (const_iterator it = m_modes.begin(); it != m_modes.end(); ++it)
450  {
451  MU = CMatrixDouble31((it)->mean);
452  ret += exp((it)->log_w) * math::normalPDF(X, MU, (it)->cov);
453  }
454 
455  return ret;
456  }
457  else
458  {
459  // Only X,Y:
460  CMatrixDouble X(2, 1), MU(2, 1), COV(2, 2);
461  double ret = 0;
462 
463  X(0, 0) = x.x();
464  X(1, 0) = x.y();
465 
466  for (const_iterator it = m_modes.begin(); it != m_modes.end(); ++it)
467  {
468  MU(0, 0) = (it)->mean.x();
469  MU(1, 0) = (it)->mean.y();
470 
471  COV(0, 0) = (it)->cov(0, 0);
472  COV(1, 1) = (it)->cov(1, 1);
473  COV(0, 1) = COV(1, 0) = (it)->cov(0, 1);
474 
475  ret += exp((it)->log_w) * math::normalPDF(X, MU, COV);
476  }
477 
478  return ret;
479  }
480 }
481 
482 /*---------------------------------------------------------------
483  evaluateNormalizedPDF
484  ---------------------------------------------------------------*/
486 {
488  CMatrixDouble31 MU;
489  double ret = 0;
490 
491  for (const_iterator it = m_modes.begin(); it != m_modes.end(); ++it)
492  {
493  MU = CMatrixDouble31((it)->mean);
494  ret += exp((it)->log_w) * math::normalPDF(X, MU, (it)->cov) /
495  math::normalPDF(MU, MU, (it)->cov);
496  }
497 
498  return ret;
499 }
500 
501 /*---------------------------------------------------------------
502  assureSymmetry
503  ---------------------------------------------------------------*/
505 {
506  // Differences, when they exist, appear in the ~15'th significant
507  // digit, so... just take one of them arbitrarily!
508  for (iterator it = m_modes.begin(); it != m_modes.end(); ++it)
509  {
510  (it)->cov(0, 1) = (it)->cov(1, 0);
511  (it)->cov(0, 2) = (it)->cov(2, 0);
512  (it)->cov(1, 2) = (it)->cov(2, 1);
513  }
514 }
515 
516 /*---------------------------------------------------------------
517  normalizeWeights
518  ---------------------------------------------------------------*/
520 {
521  MRPT_START
522 
523  if (!m_modes.size()) return;
524 
525  double maxW = m_modes[0].log_w;
526  for (iterator it = m_modes.begin(); it != m_modes.end(); ++it)
527  maxW = max(maxW, (it)->log_w);
528 
529  for (iterator it = m_modes.begin(); it != m_modes.end(); ++it)
530  (it)->log_w -= maxW;
531 
532  MRPT_END
533 }
534 
535 /*---------------------------------------------------------------
536  normalizeWeights
537  ---------------------------------------------------------------*/
539  const double& x_min, const double& x_max, const double& y_min,
540  const double& y_max, const double& resolutionXY, const double& phi,
541  CMatrixD& outMatrix, bool sumOverAllPhis)
542 {
543  MRPT_START
544 
545  ASSERT_(x_max > x_min);
546  ASSERT_(y_max > y_min);
547  ASSERT_(resolutionXY > 0);
548 
549  const size_t Nx = (size_t)ceil((x_max - x_min) / resolutionXY);
550  const size_t Ny = (size_t)ceil((y_max - y_min) / resolutionXY);
551 
552  outMatrix.setSize(Ny, Nx);
553 
554  for (size_t i = 0; i < Ny; i++)
555  {
556  double y = y_min + i * resolutionXY;
557  for (size_t j = 0; j < Nx; j++)
558  {
559  double x = x_min + j * resolutionXY;
560  outMatrix(i, j) = evaluatePDF(CPose2D(x, y, phi), sumOverAllPhis);
561  }
562  }
563 
564  MRPT_END
565 }
566 
567 /*---------------------------------------------------------------
568  mergeModes
569  ---------------------------------------------------------------*/
570 void CPosePDFSOG::mergeModes(double max_KLd, bool verbose)
571 {
572  MRPT_START
573 
574  normalizeWeights();
575 
576  size_t N = m_modes.size();
577  if (N < 2) return; // Nothing to do
578 
579  // Method described in:
580  // "Kullback-Leibler Approach to Gaussian Mixture Reduction", A.R. Runnalls.
581  // IEEE Transactions on Aerospace and Electronic Systems, 2007.
582  // See Eq.(21) for Bij !!
583 
584  for (size_t i = 0; i < (N - 1);)
585  {
586  N = m_modes.size(); // It might have changed.
587  double sumW = 0;
588 
589  // For getting linear weights:
590  sumW = 0;
591  for (size_t j = 0; j < N; j++) sumW += exp(m_modes[j].log_w);
592  ASSERT_(sumW);
593 
594  const double Wi = exp(m_modes[i].log_w) / sumW;
595 
596  double min_Bij = std::numeric_limits<double>::max();
597 
598  CMatrixDouble33 min_Bij_COV;
599  size_t best_j = 0;
600 
601  CMatrixDouble31 MUi = CMatrixDouble31(m_modes[i].mean);
602 
603  // Compute B(i,j), j=[i+1,N-1] (the discriminant)
604  for (size_t j = 0; j < N; j++)
605  if (i != j)
606  {
607  const double Wj = exp(m_modes[j].log_w) / sumW;
608  const double Wij_ = 1.0 / (Wi + Wj);
609 
610  CMatrixDouble33 Pij = m_modes[i].cov * (Wi * Wij_);
611  Pij.add_Ac(m_modes[j].cov, Wj * Wij_);
612 
613  CMatrixDouble31 MUij = CMatrixDouble31(m_modes[j].mean);
614  MUij -= MUi;
615  // Account for circular dimensions:
616  mrpt::math::wrapToPiInPlace(MUij(2, 0));
617 
618  CMatrixDouble33 AUX;
619  AUX.multiply_AAt(MUij); // AUX = MUij * MUij^T
620 
621  AUX *= Wi * Wj * Wij_ * Wij_;
622  Pij += AUX;
623 
624  double Bij = (Wi + Wj) * log(Pij.det()) -
625  Wi * log(m_modes[i].cov.det()) -
626  Wj * log(m_modes[j].cov.det());
627  if (verbose)
628  {
629  cout << "try merge[" << i << ", " << j
630  << "] -> Bij: " << Bij << endl;
631  // cout << "AUX: " << endl << AUX;
632  // cout << "Wi: " << Wi << " Wj:" << Wj << " Wij_: " << Wij_
633  // << endl;
634  cout << "Pij: " << Pij << endl
635  << " Pi: " << m_modes[i].cov << endl
636  << " Pj: " << m_modes[j].cov << endl;
637  }
638 
639  if (Bij < min_Bij)
640  {
641  min_Bij = Bij;
642  best_j = j;
643  min_Bij_COV = Pij;
644  }
645  }
646 
647  // Is a good move to merge (i,j)??
648  if (verbose)
649  cout << "merge[" << i << ", " << best_j
650  << "] Tempting merge: KLd = " << min_Bij;
651 
652  if (min_Bij < max_KLd)
653  {
654  if (verbose) cout << " Accepted." << endl;
655 
656  // Do the merge (i,j):
657  TGaussianMode Mij;
658  TGaussianMode& Mi = m_modes[i];
659  TGaussianMode& Mj = m_modes[best_j];
660 
661  // Weight:
662  Mij.log_w = log(exp(Mi.log_w) + exp(Mj.log_w));
663 
664  // Mean:
665  const double Wj = exp(Mj.log_w) / sumW;
666  const double Wij_ = 1.0 / (Wi + Wj);
667  const double Wi_ = Wi * Wij_;
668  const double Wj_ = Wj * Wij_;
669 
670  Mij.mean = CPose2D(
671  Wi_ * Mi.mean.x() + Wj_ * Mj.mean.x(),
672  Wi_ * Mi.mean.y() + Wj_ * Mj.mean.y(),
673  Wi_ * Mi.mean.phi() + Wj_ * Mj.mean.phi());
674 
675  // Cov:
676  Mij.cov = min_Bij_COV;
677 
678  // Replace Mi <- Mij:
679  m_modes[i] = Mij;
680  m_modes.erase(m_modes.begin() + best_j); // erase Mj
681  } // end merge
682  else
683  {
684  if (verbose) cout << " Nope." << endl;
685 
686  i++;
687  }
688  } // for i
689 
690  normalizeWeights();
691 
692  MRPT_END
693 }
694 
695 /*---------------------------------------------------------------
696  getMostLikelyCovarianceAndMean
697  ---------------------------------------------------------------*/
699  CMatrixDouble33& cov, CPose2D& mean_point) const
700 {
701  const_iterator it_best = end();
702  double best_log_w = -std::numeric_limits<double>::max();
703 
704  for (const_iterator i = begin(); i != end(); ++i)
705  {
706  if (i->log_w > best_log_w)
707  {
708  best_log_w = i->log_w;
709  it_best = i;
710  }
711  }
712 
713  if (it_best != end())
714  {
715  mean_point = it_best->mean;
716  cov = it_best->cov;
717  }
718  else
719  {
720  cov.unit(3, 1.0);
721  cov *= 1e20;
722  mean_point = CPose2D(0, 0, 0);
723  }
724 }
725 
726 /*---------------------------------------------------------------
727  getAs3DObject
728  ---------------------------------------------------------------*/
729 // void CPosePDFSOG::getAs3DObject( mrpt::opengl::CSetOfObjects::Ptr &outObj
730 // )
731 // const
732 //{
733 // outObj->clear();
734 //
735 // for (const_iterator it=m_modes.begin();it!=m_modes.end();++it)
736 // {
737 // opengl::CEllipsoid::Ptr ellip =
738 // mrpt::make_aligned_shared<opengl::CEllipsoid>();
739 //
740 // ellip->setPose( CPose3D((it)->mean.x(), (it)->mean.y(),
741 //(it)->mean.phi())
742 //);
743 // ellip->setCovMatrix((it)->cov);
744 // ellip->setColor(0,0,1,0.6);
745 //
746 // outObj->insert(ellip);
747 // }
748 //
749 //}
Computes weighted and un-weighted averages of SE(2) poses.
void normalizeWeights()
Normalize the weights in m_modes such as the maximum log-weight is 0.
void writeToStream(mrpt::utils::CStream &out, int *getVersion) const override
Introduces a pure virtual method responsible for writing to a CStream.
double x() const
Common members of all points & poses classes.
Definition: CPoseOrPoint.h:135
void clear()
Clear the list of modes.
Definition: CPosePDFSOG.cpp:38
void inverse(CPosePDF &o) const override
Returns a new PDF such as: NEW_PDF = (0,0,0) - THIS_PDF.
void mergeModes(double max_KLd=0.5, bool verbose=false)
Merge very close modes so the overall number of modes is reduced while preserving the total distribut...
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
CPose2D mean
The mean value.
This class is a "CSerializable" wrapper for "CMatrixTemplateNumeric<double>".
Definition: CMatrixD.h:25
The struct for each mode:
Definition: CPosePDFSOG.h:43
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"...
This namespace provides a OS-independent interface to many useful functions: filenames manipulation...
Definition: math_frwds.h:30
Declares a class that represents a Probability Density function (PDF) of a 2D pose ...
Definition: CPosePDFSOG.h:36
int void fclose(FILE *f)
An OS-independent version of fclose.
Definition: os.cpp:272
#define IMPLEMENTS_SERIALIZABLE(class_name, base, NameSpace)
This must be inserted in all CSerializable classes implementation files.
double evaluatePDF(const mrpt::poses::CPose2D &x, bool sumOverAllPhis=false) const
Evaluates the PDF at a given point.
#define THROW_EXCEPTION(msg)
void getMean(CPose2D &mean_pose) const override
Returns an estimate of the pose, (the mean, or mathematical expectation of the PDF) ...
Definition: CPosePDFSOG.cpp:48
EIGEN_STRONG_INLINE iterator begin()
Definition: eigen_plugins.h:29
void getCovariance(mrpt::math::CMatrixDouble &cov) const
Returns the estimate of the covariance matrix (STATE_LEN x STATE_LEN covariance matrix) ...
STL namespace.
void append(const mrpt::poses::CPose2D &p)
Adds a new pose to the computation.
CMatrixFixedNumeric< double, 3, 3 > CMatrixDouble33
Definition: eigen_frwds.h:55
mrpt::math::CMatrixDouble33 cov
The 3x3 covariance matrix.
void rotateAllCovariances(const double &ang)
Rotate all the covariance matrixes by replacing them by , where .
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:4178
#define M_2PI
Definition: mrpt_macros.h:437
This base class is used to provide a unified interface to files,memory buffers,..Please see the deriv...
Definition: CStream.h:41
void wrapToPiInPlace(T &a)
Modifies the given angle to translate it into the ]-pi,pi] range.
Definition: wrap2pi.h:64
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
Declares a class that represents a Probability Density function (PDF) of a 2D pose ...
#define MRPT_END
#define MRPT_UNUSED_PARAM(a)
Can be used to avoid "not used parameters" warnings from the compiler.
void evaluatePDFInArea(const double &x_min, const double &x_max, const double &y_min, const double &y_max, const double &resolutionXY, const double &phi, mrpt::math::CMatrixD &outMatrix, bool sumOverAllPhis=false)
Evaluates the PDF within a rectangular grid (and a fixed orientation) and saves the result in a matri...
#define MRPT_THROW_UNKNOWN_SERIALIZATION_VERSION(__V)
For use in CSerializable implementations.
CMatrixTemplateNumeric< double > CMatrixDouble
Declares a matrix of double numbers (non serializable).
GLuint GLuint end
Definition: glext.h:3528
mrpt::math::CMatrixDouble33 cov
Definition: CPosePDFSOG.h:47
virtual void getMean(TDATA &mean_point) const =0
Returns the mean, or mathematical expectation of the probability density distribution (PDF)...
GLsizei const GLchar ** string
Definition: glext.h:4101
Declares a class that represents a probability density function (pdf) of a 2D pose (x...
Definition: CPosePDF.h:41
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
Definition: CPoint.h:17
double evaluateNormalizedPDF(const mrpt::poses::CPose2D &x) const
Evaluates the ratio PDF(x) / max_PDF(x*), that is, the normalized PDF in the range [0...
void getCovarianceAndMean(mrpt::math::CMatrixDouble33 &cov, CPose2D &mean_point) const override
Returns an estimate of the pose covariance matrix (3x3 cov matrix) and the mean, both at once...
Definition: CPosePDFSOG.cpp:69
void assureSymmetry()
Ensures the symmetry of the covariance matrix (eventually certain operations in the math-coprocessor ...
int fprintf(FILE *fil, const char *format,...) noexcept MRPT_printf_format_check(2
An OS-independent version of fprintf.
Definition: os.cpp:405
virtual const mrpt::utils::TRuntimeClassId * GetRuntimeClass() const override
Returns information about the class of an object in runtime.
#define MRPT_START
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
void getMostLikelyCovarianceAndMean(mrpt::math::CMatrixDouble33 &cov, CPose2D &mean_point) const
For the most likely Gaussian mode in the SOG, returns the pose covariance matrix (3x3 cov matrix) and...
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
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 1x3 vectors, where each row contains a (x,y,phi) datum.
const double & phi() const
Get the phi angle of the 2D pose (in radians)
Definition: CPose2D.h:91
void getHomogeneousMatrix(mrpt::math::CMatrixDouble44 &out_HM) const
Returns the corresponding 4x4 homogeneous transformation matrix for the point(translation) or pose (t...
Definition: CPose2D.cpp:288
GLuint in
Definition: glext.h:7274
void changeCoordinatesReference(const CPose3D &newReferenceBase) override
this = p (+) this.
#define ASSERT_(f)
void copyFrom(const CPosePDF &o) override
Copy operator, translating if necesary (for example, between particles and gaussian representations) ...
GLenum GLint GLint y
Definition: glext.h:3538
FILE * fopen(const char *fileName, const char *mode) noexcept
An OS-independent version of fopen.
Definition: os.cpp:254
Eigen::Matrix< typename MATRIX::Scalar, MATRIX::ColsAtCompileTime, MATRIX::ColsAtCompileTime > cov(const MATRIX &v)
Computes the covariance matrix from a list of samples in an NxM matrix, where each row is a sample...
Definition: ops_matrices.h:148
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...
void bayesianFusion(const CPosePDF &p1, const CPosePDF &p2, const double &minMahalanobisDistToDrop=0) override
Bayesian fusion of two pose distributions, then save the result in this object (WARNING: Currently p1...
CListGaussianModes::iterator iterator
Definition: CPosePDFSOG.h:70
GLenum GLint x
Definition: glext.h:3538
void operator+=(const mrpt::poses::CPose2D &Ap)
Makes: thisPDF = thisPDF + Ap, where "+" is pose composition (both the mean, and the covariance matri...
unsigned __int32 uint32_t
Definition: rptypes.h:47
double normalPDF(double x, double mu, double std)
Evaluates the univariate normal (Gaussian) distribution at a given point "x".
Definition: math.cpp:989
GLubyte GLubyte GLubyte a
Definition: glext.h:6279
GLfloat GLfloat p
Definition: glext.h:6305
CListGaussianModes::const_iterator const_iterator
Definition: CPosePDFSOG.h:69
void resize(const size_t N)
Resize the number of SOG modes.
Definition: CPosePDFSOG.cpp:42
EIGEN_STRONG_INLINE double mean() const
Computes the mean of the entire matrix.
CMatrixFixedNumeric< double, 3, 1 > CMatrixDouble31
Definition: eigen_frwds.h:60
void drawSingleSample(CPose2D &outPart) const override
Draws a single sample from the distribution.
CListGaussianModes m_modes
The list of SOG modes.
Definition: CPosePDFSOG.h:79
void bayesianFusion(const CPosePDF &p1, const CPosePDF &p2, const double &minMahalanobisDistToDrop=0) override
Bayesian fusion of two points gauss.
void get_average(mrpt::poses::CPose2D &out_mean) const
Returns the average pose.



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