MRPT  1.9.9
SO_SE_average.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-2018, 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 "poses-precomp.h" // Precompiled headers
11 
13 
14 using namespace mrpt;
15 using namespace mrpt::math;
16 
17 using namespace mrpt::poses;
18 
19 // ----------- SO_average<2> --------------------
21  : enable_exception_on_undeterminate(false),
22  m_count(0),
23  m_accum_x(0),
24  m_accum_y(0)
25 {
26 }
28 {
29  m_count = .0;
30  m_accum_x = m_accum_y = .0;
31 }
32 void SO_average<2>::append(const double orientation_rad)
33 {
34  append(orientation_rad, 1.0);
35 }
36 void SO_average<2>::append(const double orientation_rad, const double weight)
37 {
38  m_count += weight;
39  m_accum_x += cos(orientation_rad) * weight;
40  m_accum_y += sin(orientation_rad) * weight;
41 }
42 double SO_average<2>::get_average() const
43 {
44  ASSERT_ABOVE_(m_count, 0);
45  const double x = m_accum_x / m_count;
46  const double y = m_accum_y / m_count;
47  errno = 0;
48  double ang = atan2(y, x);
49  if (errno == EDOM)
50  {
51  if (enable_exception_on_undeterminate)
52  throw std::runtime_error(
53  "[SO_average<2>::get_average()] Undetermined average value");
54  else
55  ang = 0;
56  }
57  return ang;
58 }
59 
60 // ----------- SO_average<3> --------------------
62  : enable_exception_on_undeterminate(false), m_count(0), m_accum_rot()
63 {
64  clear();
65 }
67 {
68  m_count = .0;
69  m_accum_rot.setZero();
70 }
71 void SO_average<3>::append(const Eigen::Matrix3d& M) { append(M, 1.0); }
72 void SO_average<3>::append(const Eigen::Matrix3d& M, const double weight)
73 {
74  m_count += weight;
75  m_accum_rot += weight * M;
76 }
77 // See: eq. (3.7) in "MEANS AND AVERAGING IN THE GROUP OF ROTATIONS", MAHER
78 // MOAKHER, 2002.
79 Eigen::Matrix3d SO_average<3>::get_average() const
80 {
81  ASSERT_ABOVE_(m_count, 0);
82  const Eigen::Matrix3d MtM = m_accum_rot.transpose() * m_accum_rot;
83 
84  Eigen::JacobiSVD<Eigen::Matrix3d> svd(MtM, Eigen::ComputeFullU);
85  const Eigen::Vector3d vs = svd.singularValues();
86 
87  errno = 0;
88  const double d1 = 1.0 / sqrt(vs[0]);
89  const double d2 = 1.0 / sqrt(vs[1]);
90  const double d3 = mrpt::sign(m_accum_rot.determinant()) / sqrt(vs[2]);
91  if (errno != 0)
92  {
93  if (enable_exception_on_undeterminate)
94  throw std::runtime_error(
95  "[SO_average<3>::get_average()] Undetermined average value");
96  else
97  return Eigen::Matrix3d::Identity();
98  }
99 
100  Eigen::Matrix3d D = Eigen::Matrix3d::Zero();
101  D(0, 0) = d1;
102  D(1, 1) = d2;
103  D(2, 2) = d3;
104  Eigen::Matrix3d ret =
105  m_accum_rot * svd.matrixU() * D * svd.matrixU().transpose();
106  return ret;
107 }
108 
109 // ----------- SE_average<2> --------------------
111  : enable_exception_on_undeterminate(false),
112  m_count(0),
113  m_accum_x(0),
114  m_accum_y(0),
115  m_rot_part()
116 {
117  clear();
118 }
120 {
121  m_count = .0;
122  m_accum_x = m_accum_y = .0;
123  m_rot_part.clear();
124 }
125 void SE_average<2>::append(const mrpt::poses::CPose2D& p) { append(p, 1.0); }
126 void SE_average<2>::append(const mrpt::poses::CPose2D& p, const double weight)
127 {
128  m_count += weight;
129  m_accum_x += weight * p.x();
130  m_accum_y += weight * p.y();
131  m_rot_part.append(p.phi(), weight);
132 }
133 void SE_average<2>::append(const mrpt::math::TPose2D& p, const double weight)
134 {
135  m_count += weight;
136  m_accum_x += weight * p.x;
137  m_accum_y += weight * p.y;
138  m_rot_part.append(p.phi, weight);
139 }
141 {
142  ASSERT_ABOVE_(m_count, 0);
143  ret_mean.x(m_accum_x / m_count);
144  ret_mean.y(m_accum_y / m_count);
145  const_cast<SO_average<2>*>(&m_rot_part)->enable_exception_on_undeterminate =
146  this->enable_exception_on_undeterminate;
147  ret_mean.phi(m_rot_part.get_average());
148 }
149 
150 // ----------- SE_average<3> --------------------
152  : enable_exception_on_undeterminate(false),
153  m_count(0),
154  m_accum_x(0),
155  m_accum_y(0),
156  m_accum_z(0),
157  m_rot_part()
158 {
159  clear();
160 }
162 {
163  m_count = .0;
164  m_accum_x = m_accum_y = m_accum_z = .0;
165  m_rot_part.clear();
166 }
167 void SE_average<3>::append(const mrpt::poses::CPose3D& p) { append(p, 1.0); }
168 void SE_average<3>::append(const mrpt::poses::CPose3D& p, const double weight)
169 {
170  m_count += weight;
171  m_accum_x += weight * p.x();
172  m_accum_y += weight * p.y();
173  m_accum_z += weight * p.z();
174  m_rot_part.append(p.getRotationMatrix(), weight);
175 }
176 void SE_average<3>::append(const mrpt::math::TPose3D& p, const double weight)
177 {
178  append(CPose3D(p),weight);
179 }
181 {
182  ASSERT_ABOVE_(m_count, 0);
183  ret_mean.x(m_accum_x / m_count);
184  ret_mean.y(m_accum_y / m_count);
185  ret_mean.z(m_accum_z / m_count);
186  const_cast<SO_average<3>*>(&m_rot_part)->enable_exception_on_undeterminate =
187  this->enable_exception_on_undeterminate;
188  ret_mean.setRotationMatrix(m_rot_part.get_average());
189 }
double x() const
Common members of all points & poses classes.
Definition: CPoseOrPoint.h:140
Computes weighted and un-weighted averages of SO(2) orientations.
Definition: SO_SE_average.h:42
Computes weighted and un-weighted averages of SE(2) or SE(3) poses.
Definition: SO_SE_average.h:29
void setRotationMatrix(const mrpt::math::CMatrixDouble33 &ROT)
Sets the 3x3 rotation matrix.
Definition: CPose3D.h:242
This base provides a set of functions for maths stuff.
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
A class used to store a 2D pose, including the 2D coordinate point and a heading (phi) angle...
Definition: CPose2D.h:38
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
Definition: CPose3D.h:86
const double & phi() const
Get the phi angle of the 2D pose (in radians)
Definition: CPose2D.h:80
#define ASSERT_ABOVE_(__A, __B)
Definition: exceptions.h:171
Computes weighted and un-weighted averages of SO(3) orientations.
Definition: SO_SE_average.h:84
Lightweight 3D pose (three spatial coordinates, plus three angular coordinates).
Lightweight 2D pose.
Computes weighted and un-weighted averages of SO(2) or SO(3) orientations.
Definition: SO_SE_average.h:24
GLenum GLint GLint y
Definition: glext.h:3538
int sign(T x)
Returns the sign of X as "1" or "-1".
GLenum GLint x
Definition: glext.h:3538
GLfloat GLfloat p
Definition: glext.h:6305
void clear()
Clear the contents of this container.
Definition: ts_hash_map.h:186



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: 7d5e6d718 Fri Aug 24 01:51:28 2018 +0200 at lun nov 2 08:35:50 CET 2020