Main MRPT website > C++ reference for MRPT 1.9.9
CPose3DPDFParticles.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 
14 #include <mrpt/poses/CPose3D.h>
15 #include <mrpt/math/wrap2pi.h>
16 #include <mrpt/utils/CStream.h>
18 #include <mrpt/system/os.h>
19 
20 using namespace mrpt;
21 using namespace mrpt::poses;
22 using namespace mrpt::math;
23 using namespace mrpt::utils;
24 
26 
27 /*---------------------------------------------------------------
28  Constructor
29  ---------------------------------------------------------------*/
31 {
32  m_particles.resize(M);
33 
34  for (auto& it : m_particles)
35  {
36  it.log_w = .0;
37  it.d.reset(new CPose3D());
38  }
39 
40  CPose3D nullPose(0, 0, 0);
41  resetDeterministic(nullPose);
42 }
43 
45 {
47 
50 
51  if (this == &o) return; // It may be used sometimes
52 
54  {
55  const CPose3DPDFParticles* pdf =
56  dynamic_cast<const CPose3DPDFParticles*>(&o);
57  ASSERT_(pdf);
58 
59  m_particles = pdf->m_particles;
60  }
62  {
63  THROW_EXCEPTION("TO DO!!");
64  }
65 
66  MRPT_END
67 }
68 
69 /*---------------------------------------------------------------
70  getMean
71  Returns an estimate of the pose, (the mean, or mathematical expectation of the
72  PDF), computed
73  as a weighted average over all m_particles.
74  ---------------------------------------------------------------*/
76 {
78 
79  // Default to (0,..,0)
80  p = CPose3D();
81  if (m_particles.empty()) return;
82 
83  // Calc average on SE(3)
84  mrpt::poses::SE_average<3> se_averager;
86  m_particles.begin();
87  it != m_particles.end(); ++it)
88  {
89  const double w = exp(it->log_w);
90  se_averager.append(*it->d, w);
91  }
92  se_averager.get_average(p);
93 
94  MRPT_END
95 }
96 
97 /*---------------------------------------------------------------
98  getCovarianceAndMean
99  ---------------------------------------------------------------*/
101  CMatrixDouble66& cov, CPose3D& mean) const
102 {
103  MRPT_START
104 
105  getMean(mean); // First! the mean value:
106 
107  // Now the covariance:
108  cov.zeros();
109  CVectorDouble vars;
110  vars.assign(6, 0.0); // The diagonal of the final covariance matrix
111 
112  // Elements off the diagonal of the covariance matrix:
113  double std_xy = 0, std_xz = 0, std_xya = 0, std_xp = 0, std_xr = 0;
114  double std_yz = 0, std_yya = 0, std_yp = 0, std_yr = 0;
115  double std_zya = 0, std_zp = 0, std_zr = 0;
116  double std_yap = 0, std_yar = 0;
117  double std_pr = 0;
118 
119  // Mean values in [0, 2pi] range:
120  double mean_yaw = mean.yaw();
121  double mean_pitch = mean.pitch();
122  double mean_roll = mean.roll();
123  if (mean_yaw < 0) mean_yaw += M_2PI;
124  if (mean_pitch < 0) mean_pitch += M_2PI;
125  if (mean_roll < 0) mean_roll += M_2PI;
126 
127  // Enought information to estimate the covariance?
128  if (m_particles.size() < 2) return;
129 
130  // Sum all weight values:
131  double W = 0;
133  m_particles.begin();
134  it != m_particles.end(); ++it)
135  W += exp(it->log_w);
136 
137  ASSERT_(W > 0);
138 
139  // Compute covariance:
141  m_particles.begin();
142  it != m_particles.end(); ++it)
143  {
144  double w = exp(it->log_w) / W;
145 
146  // Manage 1 PI range:
147  double err_yaw = wrapToPi(fabs(it->d->yaw() - mean_yaw));
148  double err_pitch = wrapToPi(fabs(it->d->pitch() - mean_pitch));
149  double err_roll = wrapToPi(fabs(it->d->roll() - mean_roll));
150 
151  double err_x = it->d->x() - mean.x();
152  double err_y = it->d->y() - mean.y();
153  double err_z = it->d->z() - mean.z();
154 
155  vars[0] += square(err_x) * w;
156  vars[1] += square(err_y) * w;
157  vars[2] += square(err_z) * w;
158  vars[3] += square(err_yaw) * w;
159  vars[4] += square(err_pitch) * w;
160  vars[5] += square(err_roll) * w;
161 
162  std_xy += err_x * err_y * w;
163  std_xz += err_x * err_z * w;
164  std_xya += err_x * err_yaw * w;
165  std_xp += err_x * err_pitch * w;
166  std_xr += err_x * err_roll * w;
167 
168  std_yz += err_y * err_z * w;
169  std_yya += err_y * err_yaw * w;
170  std_yp += err_y * err_pitch * w;
171  std_yr += err_y * err_roll * w;
172 
173  std_zya += err_z * err_yaw * w;
174  std_zp += err_z * err_pitch * w;
175  std_zr += err_z * err_roll * w;
176 
177  std_yap += err_yaw * err_pitch * w;
178  std_yar += err_yaw * err_roll * w;
179 
180  std_pr += err_pitch * err_roll * w;
181  } // end for it
182 
183  // Unbiased estimation of variance:
184  cov(0, 0) = vars[0];
185  cov(1, 1) = vars[1];
186  cov(2, 2) = vars[2];
187  cov(3, 3) = vars[3];
188  cov(4, 4) = vars[4];
189  cov(5, 5) = vars[5];
190 
191  cov(1, 0) = cov(0, 1) = std_xy;
192  cov(2, 0) = cov(0, 2) = std_xz;
193  cov(3, 0) = cov(0, 3) = std_xya;
194  cov(4, 0) = cov(0, 4) = std_xp;
195  cov(5, 0) = cov(0, 5) = std_xr;
196 
197  cov(2, 1) = cov(1, 2) = std_yz;
198  cov(3, 1) = cov(1, 3) = std_yya;
199  cov(4, 1) = cov(1, 4) = std_yp;
200  cov(5, 1) = cov(1, 5) = std_yr;
201 
202  cov(3, 2) = cov(2, 3) = std_zya;
203  cov(4, 2) = cov(2, 4) = std_zp;
204  cov(5, 2) = cov(2, 5) = std_zr;
205 
206  cov(4, 3) = cov(3, 4) = std_yap;
207  cov(5, 3) = cov(3, 5) = std_yar;
208 
209  cov(5, 4) = cov(4, 5) = std_pr;
210 
211  MRPT_END
212 }
213 
214 /*---------------------------------------------------------------
215  writeToStream
216  ---------------------------------------------------------------*/
218  mrpt::utils::CStream& out, int* version) const
219 {
220  if (version)
221  *version = 0;
222  else
223  {
224  writeParticlesToStream(out);
225  }
226 }
227 
228 /*---------------------------------------------------------------
229  readFromStream
230  ---------------------------------------------------------------*/
232 {
233  switch (version)
234  {
235  case 0:
236  {
237  readParticlesFromStream(in);
238  }
239  break;
240  default:
242  };
243 }
244 
245 /*---------------------------------------------------------------
246  saveToTextFile
247  Save PDF's m_particles to a text file. In each line it
248  will go: "x y phi weight"
249  ---------------------------------------------------------------*/
251 {
252  using namespace mrpt::system;
253 
254  FILE* f = os::fopen(file.c_str(), "wt");
255  if (!f) return;
256 
257  os::fprintf(f, "%% x y z yaw[rad] pitch[rad] roll[rad] log_weight\n");
258 
259  for (const auto& p : m_particles)
260  os::fprintf(
261  f, "%f %f %f %f %f %f %e\n", p.d->x(), p.d->y(), p.d->z(),
262  p.d->yaw(), p.d->pitch(), p.d->roll(), p.log_w);
263 
264  os::fclose(f);
265 }
266 
267 /*---------------------------------------------------------------
268  getParticlePose
269  ---------------------------------------------------------------*/
271 {
272  return *m_particles[i].d;
273 }
274 
275 /*---------------------------------------------------------------
276  changeCoordinatesReference
277  ---------------------------------------------------------------*/
279  const CPose3D& newReferenceBase)
280 {
281  for (CParticleList::iterator it = m_particles.begin();
282  it != m_particles.end(); ++it)
283  it->d->composeFrom(newReferenceBase, *it->d);
284 }
285 
286 /*---------------------------------------------------------------
287  drawSingleSample
288  ---------------------------------------------------------------*/
290 {
291  MRPT_UNUSED_PARAM(outPart);
292  THROW_EXCEPTION("TO DO!");
293 }
294 
295 /*---------------------------------------------------------------
296  drawManySamples
297  ---------------------------------------------------------------*/
299  size_t N, std::vector<CVectorDouble>& outSamples) const
300 {
302  MRPT_UNUSED_PARAM(outSamples);
303  THROW_EXCEPTION("TO DO!");
304 }
305 
306 /*---------------------------------------------------------------
307  +=
308  ---------------------------------------------------------------*/
310 {
311  MRPT_UNUSED_PARAM(Ap);
312  THROW_EXCEPTION("TO DO!");
313 }
314 
315 /*---------------------------------------------------------------
316  append
317  ---------------------------------------------------------------*/
319 {
321  THROW_EXCEPTION("TO DO!");
322 }
323 
324 /*---------------------------------------------------------------
325  inverse
326  ---------------------------------------------------------------*/
328 {
329  MRPT_START
331  CPose3DPDFParticles* out = static_cast<CPose3DPDFParticles*>(&o);
332 
333  // Prepare the output:
334  out->copyFrom(*this);
335 
337  CPose3D zero(0, 0, 0);
338 
339  for (it = out->m_particles.begin(); it != out->m_particles.end(); ++it)
340  *it->d = zero - *it->d;
341 
342  MRPT_END
343 }
344 
345 /*---------------------------------------------------------------
346  getMostLikelyParticle
347  ---------------------------------------------------------------*/
349 {
351  itMax = m_particles.begin();
352  double max_w = -1e300;
353 
354  for (it = m_particles.begin(); it != m_particles.end(); ++it)
355  {
356  if (it->log_w > max_w)
357  {
358  itMax = it;
359  max_w = it->log_w;
360  }
361  }
362 
363  return *itMax->d;
364 }
365 
366 /*---------------------------------------------------------------
367  bayesianFusion
368  ---------------------------------------------------------------*/
370  const CPose3DPDF& p1, const CPose3DPDF& p2)
371 {
372  MRPT_UNUSED_PARAM(p1);
373  MRPT_UNUSED_PARAM(p2);
374  THROW_EXCEPTION("Not implemented yet!");
375 }
376 
377 /*---------------------------------------------------------------
378  resetDeterministic
379  Reset PDF to a single point and set the number of m_particles
380  ---------------------------------------------------------------*/
382  const CPose3D& location, size_t particlesCount)
383 {
385 
386  if (particlesCount > 0)
387  {
388  clearParticles();
389  m_particles.resize(particlesCount);
390  for (it = m_particles.begin(); it != m_particles.end(); ++it)
391  it->d.reset(new CPose3D());
392  }
393 
394  for (it = m_particles.begin(); it != m_particles.end(); ++it)
395  {
396  *it->d = location;
397  it->log_w = 0;
398  }
399 }
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.
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...
This namespace provides a OS-independent interface to many useful functions: filenames manipulation...
Definition: math_frwds.h:30
int void fclose(FILE *f)
An OS-independent version of fclose.
Definition: os.cpp:272
GLint location
Definition: glext.h:4086
#define IMPLEMENTS_SERIALIZABLE(class_name, base, NameSpace)
This must be inserted in all CSerializable classes implementation files.
#define THROW_EXCEPTION(msg)
Scalar * iterator
Definition: eigen_plugins.h:26
Column vector, like Eigen::MatrixX*, but automatically initialized to zeros since construction...
Definition: eigen_frwds.h:42
const Scalar * const_iterator
Definition: eigen_plugins.h:27
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,phi) datum.
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:4178
#define M_2PI
Definition: mrpt_macros.h:437
T square(const T x)
Inline function for the square of a number.
Definition: bits.h:55
void append(CPose3DPDFParticles &o)
Appends (add to the list) a set of m_particles to the existing ones, and then normalize weights...
virtual const mrpt::utils::TRuntimeClassId * GetRuntimeClass() const override
Returns information about the class of an object in runtime.
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.
This base class is used to provide a unified interface to files,memory buffers,..Please see the deriv...
Definition: CStream.h:41
CParticleList m_particles
The array of particles.
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
#define MRPT_END
#define MRPT_UNUSED_PARAM(a)
Can be used to avoid "not used parameters" warnings from the compiler.
void operator+=(const CPose3D &Ap)
Appends (pose-composition) a given pose "p" to each particle.
#define MRPT_THROW_UNKNOWN_SERIALIZATION_VERSION(__V)
For use in CSerializable implementations.
CPose3D getParticlePose(int i) const
Returns the pose of the i&#39;th particle.
CPose3D getMostLikelyParticle() const
Returns the particle with the highest weight.
GLsizei const GLchar ** string
Definition: glext.h:4101
T wrapToPi(T a)
Modifies the given angle to translate it into the ]-pi,pi] range.
Definition: wrap2pi.h:53
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
Definition: CPoint.h:17
void copyFrom(const CPose3DPDF &o) override
Copy operator, translating if necesary (for example, between m_particles and gaussian representations...
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 drawSingleSample(CPose3D &outPart) const override
Draws a single sample from the distribution (WARNING: weights are assumed to be normalized!) ...
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 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 resetDeterministic(const CPose3D &location, size_t particlesCount=0)
Reset the PDF to a single point: All m_particles will be set exactly to the supplied pose...
void bayesianFusion(const CPose3DPDF &p1, const CPose3DPDF &p2) override
Bayesian fusion.
GLuint in
Definition: glext.h:7274
void changeCoordinatesReference(const CPose3D &newReferenceBase) override
this = p (+) this.
#define ASSERT_(f)
Declares a class that represents a Probability Density function (PDF) of a 3D pose ...
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 inverse(CPose3DPDF &o) const override
Returns a new PDF such as: NEW_PDF = (0,0,0) - THIS_PDF.
GLfloat GLfloat p
Definition: glext.h:6305
void saveToTextFile(const std::string &file) const override
Save PDF&#39;s m_particles to a text file.
Declares a class that represents a Probability Density Function (PDF) of a 3D pose (6D actually)...
Definition: CPose3DPDF.h:42
EIGEN_STRONG_INLINE double mean() const
Computes the mean of the entire matrix.
Declares a class that represents a Probability Density function (PDF) of a 3D pose.
void writeToStream(mrpt::utils::CStream &out, int *getVersion) const override
Introduces a pure virtual method responsible for writing to a CStream.



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