GeometryHelper.hpp
Go to the documentation of this file.
1 
18 #pragma once
19 
20 #include <Eigen/Geometry>
21 #include <cmath>
22 #include "common_type/Pose.hpp"
25 #include "common_type/Point.hpp"
26 
27 namespace ISM {
29  public:
30 
31  //Methods are all inlined since heavily used in performance relevant code.
32 
43  static PosePtr getReferencePose(const PosePtr& source, const PointPtr& refPoint, const QuaternionPtr& objectToRefPoseQuat) {
44  PosePtr result = PosePtr(new Pose());
45  getReferencePose(source, refPoint, objectToRefPoseQuat, result);
46  return result;
47  }
48 
49  //Faster variant that avoids allocation of local Pose in every call of this method.
50  static void getReferencePose(const PosePtr& source, const PointPtr& refPoint, const QuaternionPtr& objectToRefPoseQuat, PosePtr& result) {
51  result->point = refPoint;
52  result->quat = eigenQuatToQuat(source->quat->eigen * objectToRefPoseQuat->eigen);
53  }
54 
63  static PointPtr getSourcePoint(const PosePtr& refPose, const QuaternionPtr& refToObjectQuat, double radius) {
64  PointPtr result = PointPtr(new Point());
65  getSourcePoint(refPose, refToObjectQuat, radius, result);
66  return result;
67  }
68 
69  //Faster variant that avoids allocation of local Pose in every call of this method.
70  static void getSourcePoint(const PosePtr& refPose, const QuaternionPtr& refToObjectQuat, double radius, PointPtr& result) {
71  Eigen::Vector3d relativeObjectVector = refToObjectQuat->eigen._transformVector(Eigen::Vector3d::UnitX());
72  Eigen::Vector3d absoluteObjectVector = refPose->quat->eigen._transformVector(relativeObjectVector);
73  result->eigen = refPose->point->eigen + (absoluteObjectVector * radius);
74  }
75 
76  static PosePtr getSourcePose(const PosePtr& reference, const PointPtr& sourcePoint, const QuaternionPtr& refToObjectPoseQuat) {
77  PosePtr result = PosePtr(new Pose());
78  getSourcePose(reference, sourcePoint, refToObjectPoseQuat, result);
79  return result;
80  }
81 
82  //Faster variant that avoids allocation of local Pose in every call of this method.
83  static void getSourcePose(const PosePtr& reference, const PointPtr& sourcePoint, const QuaternionPtr& refToObjectPoseQuat, PosePtr& result) {
84  result->point = sourcePoint;
85  result->quat->eigen = reference->quat->eigen * refToObjectPoseQuat->eigen;
86  }
87 
88  static PointPtr applyQuatAndRadiusToPose(const PosePtr& pose, const QuaternionPtr& quat, double radius) {
89  //apply transformation to viewport vector, then scale, than transform to object coordinates and add
90  Eigen::Quaternion<double> rotation = pose->quat->eigen * quat->eigen;
91  Eigen::Vector3d objectPoint = pose->point->eigen;
92 
93  Eigen::Vector3d resultVec = objectPoint + rotation._transformVector(Eigen::Vector3d::UnitX()) * radius;
94 
95  return vectorToPoint(resultVec);
96  }
97 
99  static double constexpr epsylon = 1e-4;
100  static bool isSelfVote(const VoteSpecifierPtr& vote)
101  {
102  if ( !(vote->radius > -epsylon && vote->radius < epsylon) ||
103  !quatEqual(selfQuat, *(vote->objectToRefPoseQuat)))
104  {
105  return false;
106  }
107  return true;
108  }
109 
112  static VoteSpecifierPtr createVoteSpecifier(const PosePtr& sourcePose, const PosePtr& refPose) {
113  if ((refPose->point->eigen - sourcePose->point->eigen).norm() == 0) {
114  //avoid special case
115  sourcePose->point->eigen.x() = (sourcePose->point->eigen.x() + 0.0000001);
116  };
117  Eigen::Vector3d objToRefVector = refPose->point->eigen - sourcePose->point->eigen;
118  Eigen::Vector3d refToObjVector = objToRefVector * -1.0;
119  Eigen::Quaternion<double> p = sourcePose->quat->eigen;
120  Eigen::Quaternion<double> r = refPose->quat->eigen;
121 
122  //rotate everything relative to object pose
123  Eigen::Vector3d relativeRefPoint = p.inverse()._transformVector(objToRefVector);
124 
125  Eigen::Quaternion<double> otr = vectorRotationToEigenQuat(Eigen::Vector3d::UnitX(), relativeRefPoint);
126  Eigen::Quaternion<double> otrp = (p.inverse()) * r;
127 
128  //rotate everything relative to ref pose
129  Eigen::Vector3d relativeObjPoint = r.inverse()._transformVector(refToObjVector);
130  Eigen::Quaternion<double> rto = vectorRotationToEigenQuat(Eigen::Vector3d::UnitX(), relativeObjPoint);
131  Eigen::Quaternion<double> rtop = (r.inverse()) * p;
132 
133  return VoteSpecifierPtr(
134  new VoteSpecifier(
135  eigenQuatToQuat(otr),
136  eigenQuatToQuat(otrp),
137  eigenQuatToQuat(rto),
138  eigenQuatToQuat(rtop),
139  objToRefVector.norm()
140  )
141  );
142  }
143 
144  static PosePtr getPoseFromVote(const PosePtr& source, const VoteSpecifierPtr& vote)
145  {
146  PointPtr referencePoint = applyQuatAndRadiusToPose(source, vote->objectToRefQuat, vote->radius);
147  return getReferencePose(source, referencePoint, vote->objectToRefPoseQuat);
148  }
149 
150  static bool poseEqual(const PosePtr& p1, const PosePtr& p2) {
151  bool overall = (quatEqual(p1->quat, p2->quat) && pointEqual (p1->point, p2->point));
152  return overall;
153  }
154 
155  static Eigen::Vector3d getDirectionVector(const PosePtr& first, const PosePtr& second) {
156 
157  Eigen::Vector3d firstToSecond = second->point->eigen - first->point->eigen;
158  Eigen::Quaternion<double> firstRotation = first->quat->eigen;
159  return firstRotation.inverse()._transformVector(firstToSecond);
160 
161  }
162 
163  static bool sharedNeighborhoodEvaluation(const PosePtr& p1, const PosePtr& p2, double distanceNeighbourThreshold, double angleNeighbourThreshold)
164  {
165  double distance_angle = getAngleBetweenQuats(p1->quat, p2->quat);
166  double distance_position = getDistanceBetweenPoints(p1->point, p2->point);
167 
168  return distanceNeighbourThreshold > distance_position
169  && angleNeighbourThreshold > fabs(distance_angle);
170  }
171 
174  static Eigen::Vector3d pointToVector(const PointPtr& p) {
175  return p->eigen;
176  }
177 
178  static PointPtr vectorToPoint(const Eigen::Vector3d& v) {
179  return PointPtr(new Point(v[0], v[1], v[2]));
180  }
181 
182  static double getDistanceBetweenPoints(const PointPtr& p1, const PointPtr& p2) {
183  return (p1->eigen - p2->eigen).norm();
184 
185  }
186 
187  static double getSquaredDistanceBetweenPoints(const PointPtr &p1, const PointPtr &p2)
188  {
189  return (p1->eigen - p2->eigen).squaredNorm();
190  }
191 
192  static bool pointEqual(const PointPtr& p1, const PointPtr& p2)
193  {
194  bool xAbs = fabs(p1->eigen.x() - p2->eigen.x()) < 0.00001;
195  bool yAbs = fabs(p1->eigen.y() - p2->eigen.y()) < 0.00001;
196  bool zAbs = fabs(p1->eigen.z() - p2->eigen.z()) < 0.00001;
197  return (xAbs && yAbs && zAbs);
198  }
199 
202  static Eigen::Quaternion<double> quatToEigenQuat(const QuaternionPtr& q) {
203  return q->eigen;
204  }
205 
206  static QuaternionPtr eigenQuatToQuat(const Eigen::Quaternion<double>& q) {
207  return QuaternionPtr(new Quaternion(q.w(), q.x(), q.y(), q.z()));
208  }
209 
210  static QuaternionPtr normalize(const QuaternionPtr& quat) {
211  return eigenQuatToQuat(quat->eigen.normalized());
212  }
213 
214  static double getAngleBetweenQuats(const QuaternionPtr& q1, const QuaternionPtr& q2) {
215  return rad2deg( q1->eigen.angularDistance(q2->eigen) );
216  }
217 
218  static Eigen::Vector3d getAxisFromQuat(const QuaternionPtr& quat, const Eigen::Vector3d& viewport = Eigen::Vector3d::UnitX()) {
219  Eigen::Quaternion<double> rotation = quat->eigen;
220  return rotation._transformVector(viewport);
221  }
222 
223  static double getAngleBetweenAxes(const Eigen::Vector3d& v1, const Eigen::Vector3d& v2) {
224 
225  double cosOfAngle = v1.dot(v2) / (v1.norm() * v2.norm());
226  if(cosOfAngle < -1.0) cosOfAngle = -1.0;
227  if(cosOfAngle > 1.0) cosOfAngle = 1.0;
228 
229  return rad2deg(acos(cosOfAngle));
230 
231  }
232 
233  static bool quatEqual(const QuaternionPtr& q1, const QuaternionPtr& q2)
234  {
235  return quatEqual(*q1, *q2);
236  }
237 
238  static bool quatEqual(const Quaternion& q1, const Quaternion& q2) {
239  bool qxAbs = fabs(q1.eigen.x() - q2.eigen.x()) < 0.00001;
240  bool qyAbs = fabs(q1.eigen.y() - q2.eigen.y()) < 0.00001;
241  bool qzAbs = fabs(q1.eigen.z() - q2.eigen.z()) < 0.00001;
242  bool qwAbs = fabs(q1.eigen.w() - q2.eigen.w()) < 0.00001;
243  return (qxAbs && qyAbs && qzAbs && qwAbs);
244  }
245 
246  static Eigen::Quaternion<double> vectorRotationToEigenQuat(const Eigen::Vector3d& v1, const Eigen::Vector3d& v2) {
247  Eigen::Quaternion<double> q;
248  q.setFromTwoVectors(v1, v2);
249  return q;
250  }
251 
252  static QuaternionPtr getQuatFromRPY(const QuaternionPtr& q, const double alpha, const double beta, const double gamma){
253  Eigen::Quaternion<double> eq = q->eigen;
254  Eigen::AngleAxisd rollAngle(deg2rad(alpha), Eigen::Vector3d::UnitX());
255  Eigen::AngleAxisd pitchAngle(deg2rad(beta), Eigen::Vector3d::UnitY());
256  Eigen::AngleAxisd yawAngle(deg2rad(gamma), Eigen::Vector3d::UnitZ());
257 
258  Eigen::Quaterniond rot = yawAngle * pitchAngle * rollAngle;
259 
260 
261  return eigenQuatToQuat(eq * rot);
262 
263  }
264 
265  static QuaternionPtr getAveragePose(const std::vector<QuaternionPtr>& poseQuats) {
266  Eigen::Vector3d combined(0, 0, 0);
267 
268  for (const QuaternionPtr& quat : poseQuats) {
269  combined += quat->eigen._transformVector(Eigen::Vector3d::UnitX());
270  }
271 
272  Eigen::Quaternion<double> ret;
273  ret.setFromTwoVectors(Eigen::Vector3d::UnitX(), combined);
274  return eigenQuatToQuat(ret.normalized());
275  }
276 
277  static bool getNextCombination(const std::vector<unsigned int>::iterator first, std::vector<unsigned int>::iterator k, const std::vector<unsigned int>::iterator last)
278  {
279  if ((first == last) || (first == k) || (last == k))
280  return false;
281 
282  std::vector<unsigned int>::iterator it1 = first;
283  std::vector<unsigned int>::iterator it2 = last;
284  it1++;
285  if (last == it1)
286  return false;
287  it1 = last;
288  it1--;
289  it1 = k;
290  it2--;
291  while (first != it1)
292  {
293  if (*--it1 < *it2)
294  {
295  std::vector<unsigned int>::iterator j = k;
296  while (!(*it1 < *j)) ++j;
297  std::iter_swap(it1,j);
298  it1++;
299  j++;
300  it2 = k;
301  std::rotate(it1,j,last);
302  while (last != j)
303  {
304  j++;
305  it2++;
306  }
307  std::rotate(k,it2,last);
308  return true;
309  }
310  }
311  std::rotate(first,k,last);
312  return false;
313  }
314 
317  static double rad2deg(double rad) {
318  return rad * (180.0 / M_PI);
319  }
320 
321  static double deg2rad(double deg) {
322  return deg * (M_PI / 180.0);
323  }
324 
325  static inline bool checkIfDoubleNaN(double& c)
326  {
327  /*
328  * distance != distance for portable way check for nan
329  * but be aware:
330  * http://stackoverflow.com/questions/570669/checking-if-a-double-or-float-is-nan-in-c
331  */
332  bool isNan = c != c;
333  if (isNan)
334  {
335  std::cerr << " NaN ";
336  }
337  return isNan;
338  }
339 
340  };
341 
342 }
static double deg2rad(double deg)
boost::shared_ptr< Quaternion > QuaternionPtr
Definition: Quaternion.hpp:39
static VoteSpecifierPtr createVoteSpecifier(const PosePtr &sourcePose, const PosePtr &refPose)
static PointPtr vectorToPoint(const Eigen::Vector3d &v)
static double getAngleBetweenQuats(const QuaternionPtr &q1, const QuaternionPtr &q2)
static Eigen::Vector3d getAxisFromQuat(const QuaternionPtr &quat, const Eigen::Vector3d &viewport=Eigen::Vector3d::UnitX())
static QuaternionPtr getQuatFromRPY(const QuaternionPtr &q, const double alpha, const double beta, const double gamma)
static Eigen::Quaternion< double > quatToEigenQuat(const QuaternionPtr &q)
static bool isSelfVote(const VoteSpecifierPtr &vote)
static bool quatEqual(const QuaternionPtr &q1, const QuaternionPtr &q2)
boost::shared_ptr< Point > PointPtr
Definition: Point.hpp:45
static PosePtr getPoseFromVote(const PosePtr &source, const VoteSpecifierPtr &vote)
static QuaternionPtr getAveragePose(const std::vector< QuaternionPtr > &poseQuats)
static PointPtr applyQuatAndRadiusToPose(const PosePtr &pose, const QuaternionPtr &quat, double radius)
static bool pointEqual(const PointPtr &p1, const PointPtr &p2)
static double getAngleBetweenAxes(const Eigen::Vector3d &v1, const Eigen::Vector3d &v2)
static double rad2deg(double rad)
static double getDistanceBetweenPoints(const PointPtr &p1, const PointPtr &p2)
static Eigen::Vector3d getDirectionVector(const PosePtr &first, const PosePtr &second)
EIGEN_MAKE_ALIGNED_OPERATOR_NEW Eigen::Quaternion< double > eigen
Definition: Quaternion.hpp:30
static bool poseEqual(const PosePtr &p1, const PosePtr &p2)
static bool getNextCombination(const std::vector< unsigned int >::iterator first, std::vector< unsigned int >::iterator k, const std::vector< unsigned int >::iterator last)
static double getSquaredDistanceBetweenPoints(const PointPtr &p1, const PointPtr &p2)
boost::shared_ptr< VoteSpecifier > VoteSpecifierPtr
static void getSourcePose(const PosePtr &reference, const PointPtr &sourcePoint, const QuaternionPtr &refToObjectPoseQuat, PosePtr &result)
static bool checkIfDoubleNaN(double &c)
static Eigen::Vector3d pointToVector(const PointPtr &p)
boost::shared_ptr< Pose > PosePtr
Definition: Pose.hpp:79
static Eigen::Quaternion< double > vectorRotationToEigenQuat(const Eigen::Vector3d &v1, const Eigen::Vector3d &v2)
static Quaternion selfQuat
static void getSourcePoint(const PosePtr &refPose, const QuaternionPtr &refToObjectQuat, double radius, PointPtr &result)
static double constexpr epsylon
static PointPtr getSourcePoint(const PosePtr &refPose, const QuaternionPtr &refToObjectQuat, double radius)
static PosePtr getReferencePose(const PosePtr &source, const PointPtr &refPoint, const QuaternionPtr &objectToRefPoseQuat)
static PosePtr getSourcePose(const PosePtr &reference, const PointPtr &sourcePoint, const QuaternionPtr &refToObjectPoseQuat)
this namespace contains all generally usable classes.
static QuaternionPtr eigenQuatToQuat(const Eigen::Quaternion< double > &q)
static bool sharedNeighborhoodEvaluation(const PosePtr &p1, const PosePtr &p2, double distanceNeighbourThreshold, double angleNeighbourThreshold)
static QuaternionPtr normalize(const QuaternionPtr &quat)
static void getReferencePose(const PosePtr &source, const PointPtr &refPoint, const QuaternionPtr &objectToRefPoseQuat, PosePtr &result)
static bool quatEqual(const Quaternion &q1, const Quaternion &q2)


asr_lib_ism
Author(s): Hanselmann Fabian, Heller Florian, Heizmann Heinrich, Kübler Marcel, Mehlhaus Jonas, Meißner Pascal, Qattan Mohamad, Reckling Reno, Stroh Daniel
autogenerated on Wed Jan 8 2020 04:02:40