All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Quaternion.hh
Go to the documentation of this file.
1 /*
2  * Copyright 2011 Nate Koenig
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16 */
17 /* Desc: External interfaces for Gazebo
18  * Author: Nate Koenig
19  * Date: 03 Apr 2007
20  */
21 
22 #ifndef QUATERN_HH
23 #define QUATERN_HH
24 
25 #include <math.h>
26 #include <iostream>
27 #include <cmath>
28 
29 #include "math/Helpers.hh"
30 #include "math/Angle.hh"
31 #include "math/Vector3.hh"
32 #include "math/Matrix3.hh"
33 #include "math/Matrix4.hh"
34 
35 namespace gazebo
36 {
37  namespace math
38  {
41 
43  class Quaternion
44  {
46  public: Quaternion();
47 
53  public: Quaternion(const double &_w, const double &_x, const double &_y,
54  const double &_z);
55 
60  public: Quaternion(const double &_roll, const double &_pitch,
61  const double &_yaw);
62 
66  public: Quaternion(const Vector3 &_axis, const double &_angle);
67 
70  public: Quaternion(const Vector3 &_rpy);
71 
74  public: Quaternion(const Quaternion &_qt);
75 
77  public: ~Quaternion();
78 
81  public: Quaternion &operator =(const Quaternion &qt);
82 
84  public: void Invert();
85 
88  public: inline Quaternion GetInverse() const
89  {
90  double s = 0;
91  Quaternion q(this->w, this->x, this->y, this->z);
92 
93  // use s to test if quaternion is valid
94  s = q.w * q.w + q.x * q.x + q.y * q.y + q.z * q.z;
95 
96  if (math::equal(s, 0.0))
97  {
98  q.w = 1.0;
99  q.x = 0.0;
100  q.y = 0.0;
101  q.z = 0.0;
102  }
103  else
104  {
105  // deal with non-normalized quaternion
106  // div by s so q * qinv = identity
107  q.w = q.w / s;
108  q.x = -q.x / s;
109  q.y = -q.y / s;
110  q.z = -q.z / s;
111  }
112  return q;
113  }
114 
116  public: void SetToIdentity();
117 
120  public: Quaternion GetLog() const;
121 
124  public: Quaternion GetExp() const;
125 
127  public: void Normalize();
128 
134  public: void SetFromAxis(double _x, double _y, double _z, double _a);
135 
139  public: void SetFromAxis(const Vector3 &_axis, double _a);
140 
146  public: void Set(double _u, double _x, double _y, double _z);
147 
150  public: void SetFromEuler(const Vector3 &_vec);
151 
154  public: Vector3 GetAsEuler() const;
155 
158  public: static Quaternion EulerToQuaternion(const Vector3 &_vec);
159 
164  public: static Quaternion EulerToQuaternion(double _x,
165  double _y,
166  double _z);
167 
170  public: double GetRoll();
171 
174  public: double GetPitch();
175 
178  public: double GetYaw();
179 
183  public: void GetAsAxis(Vector3 &_axis, double &_angle) const;
184 
187  public: void Scale(double _scale);
188 
192  public: Quaternion operator+(const Quaternion &_qt) const;
193 
197  public: Quaternion operator+=(const Quaternion &_qt);
198 
202  public: Quaternion operator-(const Quaternion &_qt) const;
203 
207  public: Quaternion operator-=(const Quaternion &_qt);
208 
212  public: inline Quaternion operator*(const Quaternion &_q) const
213  {
214  return Quaternion(
215  this->w*_q.w - this->x*_q.x - this->y*_q.y - this->z*_q.z,
216  this->w*_q.x + this->x*_q.w + this->y*_q.z - this->z*_q.y,
217  this->w*_q.y - this->x*_q.z + this->y*_q.w + this->z*_q.x,
218  this->w*_q.z + this->x*_q.y - this->y*_q.x + this->z*_q.w);
219  }
220 
224  public: Quaternion operator*(const double &_f) const;
225 
229  public: Quaternion operator*=(const Quaternion &qt);
230 
232  public: Vector3 operator*(const Vector3 &v) const;
233 
237  public: bool operator ==(const Quaternion &_qt) const;
238 
242  public: bool operator!=(const Quaternion &_qt) const;
243 
246  public: Quaternion operator-() const;
247 
251  public: inline Vector3 RotateVector(const Vector3 &_vec) const
252  {
253  Quaternion tmp(0.0, _vec.x, _vec.y, _vec.z);
254  tmp = (*this) * (tmp * this->GetInverse());
255  return Vector3(tmp.x, tmp.y, tmp.z);
256  }
257 
261  public: Vector3 RotateVectorReverse(Vector3 _vec) const;
262 
265  public: bool IsFinite() const;
266 
268  public: inline void Correct()
269  {
270  if (!finite(this->x))
271  this->x = 0;
272  if (!finite(this->y))
273  this->y = 0;
274  if (!finite(this->z))
275  this->z = 0;
276  if (!finite(this->w))
277  this->w = 1;
278 
279  if (math::equal(this->w, 0.0) &&
280  math::equal(this->x, 0.0) &&
281  math::equal(this->y, 0.0) &&
282  math::equal(this->z, 0.0))
283  {
284  this->w = 1;
285  }
286  }
287 
289  public: Matrix3 GetAsMatrix3() const;
290 
293  public: Matrix4 GetAsMatrix4() const;
294 
297  public: Vector3 GetXAxis() const;
298 
301  public: Vector3 GetYAxis() const;
302 
305  public: Vector3 GetZAxis() const;
306 
309  public: void Round(int _precision);
310 
314  public: double Dot(const Quaternion &_q) const;
315 
325  public: static Quaternion Squad(double _fT, const Quaternion &_rkP,
326  const Quaternion &_rkA, const Quaternion &_rkB,
327  const Quaternion &_rkQ, bool _shortestPath = false);
328 
336  public: static Quaternion Slerp(double _fT, const Quaternion &_rkP,
337  const Quaternion &_rkQ, bool _shortestPath = false);
338 
339 
341  public: double w;
342 
344  public: double x;
345 
347  public: double y;
348 
350  public: double z;
351 
356  public: friend std::ostream &operator<<(std::ostream &_out,
357  const gazebo::math::Quaternion &_q)
358  {
359  Vector3 v(_q.GetAsEuler());
360  _out << v.x << " " << v.y << " " << v.z;
361  return _out;
362  }
363 
368  public: friend std::istream &operator>>(std::istream &_in,
370  {
371  Angle r, p, y;
372 
373  // Skip white spaces
374  _in.setf(std::ios_base::skipws);
375  _in >> r >> p >> y;
376 
377  _q.SetFromEuler(Vector3(*r, *p, *y));
378 
379  return _in;
380  }
381  };
383  }
384 }
385 #endif
386