Quaternion.hh
00001 /* 00002 * Copyright 2011 Nate Koenig & Andrew Howard 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 * 00016 */ 00017 /* Desc: External interfaces for Gazebo 00018 * Author: Nate Koenig 00019 * Date: 03 Apr 2007 00020 * SVN: $Id$ 00021 */ 00022 00023 #ifndef QUATERN_HH 00024 #define QUATERN_HH 00025 00026 #include <iostream> 00027 #include <math.h> 00028 #include <cmath> 00029 00030 #include "math/Angle.hh" 00031 #include "math/Vector3.hh" 00032 #include "math/Matrix3.hh" 00033 #include "math/Matrix4.hh" 00034 00035 namespace gazebo 00036 { 00037 namespace math 00038 { 00039 00042 00044 class Quaternion 00045 { 00047 public: Quaternion(); 00048 00054 public: Quaternion( const double &w, const double &x, const double &y, 00055 const double &z); 00056 00058 public: Quaternion( const double &_roll, const double &_pitch, 00059 const double &_yaw ); 00060 00062 public: Quaternion( const Vector3 &_axis, const double &_angle ); 00063 00065 public: Quaternion( const Vector3 &_rpy); 00066 00069 public: Quaternion( const Quaternion &qt ); 00070 00072 public: ~Quaternion(); 00073 00076 public: const Quaternion &operator=(const Quaternion &qt); 00077 00079 public: void Invert(); 00080 00083 public: inline Quaternion GetInverse() const 00084 { 00085 Quaternion q; 00086 double norm = this->w*this->w + this->x*this->x + 00087 this->y*this->y + this->z*this->z; 00088 00089 if (norm > 0.0) 00090 { 00091 q.w = this->w / norm; 00092 q.x = -this->x / norm; 00093 q.y = -this->y / norm; 00094 q.z = -this->z / norm; 00095 } 00096 return q; 00097 } 00098 00100 public: void SetToIdentity(); 00101 00102 public: Quaternion GetLog() const; 00103 public: Quaternion GetExp() const; 00104 00106 public: void Normalize(); 00107 00113 public: void SetFromAxis(double x, double y, double z, double a); 00114 00118 public: void SetFromAxis(const Vector3 &_axis, double _a); 00119 00121 public: void Set(double u, double x, double y, double z); 00122 00125 public: void SetFromEuler(const Vector3 &vec); 00126 00129 public: Vector3 GetAsEuler() const; 00130 00132 public: static Quaternion EulerToQuaternion( const Vector3 &vec ); 00133 00135 public: static Quaternion EulerToQuaternion( double x, double y, double z); 00136 00138 public: double GetRoll(); 00139 00141 public: double GetPitch(); 00142 00144 public: double GetYaw(); 00145 00147 public: void GetAsAxis(Vector3 &axis, double &angle) const; 00148 00151 public: void Scale(double scale); 00152 00156 public: Quaternion operator+( const Quaternion &qt ) const; 00157 00161 public: Quaternion operator+=( const Quaternion &qt ); 00162 00166 public: Quaternion operator-( const Quaternion &qt ) const; 00167 00171 public: Quaternion operator-=( const Quaternion &qt ); 00172 00176 public: inline Quaternion operator*( const Quaternion &_q ) const 00177 { 00178 return Quaternion( 00179 this->w*_q.w - this->x*_q.x - this->y*_q.y - this->z*_q.z, 00180 this->w*_q.x + this->x*_q.w + this->y*_q.z - this->z*_q.y, 00181 this->w*_q.y - this->x*_q.z + this->y*_q.w + this->z*_q.x, 00182 this->w*_q.z + this->x*_q.y - this->y*_q.x + this->z*_q.w); 00183 } 00184 00188 public: Quaternion operator*( const double &_f ) const; 00189 00193 public: Quaternion operator*=( const Quaternion &qt ); 00194 00196 public: Vector3 operator*( const Vector3 &v ) const; 00197 00201 public: bool operator==(const Quaternion &_qt) const; 00202 00206 public: bool operator!=(const Quaternion &_qt) const; 00207 00209 public: Quaternion operator-() const; 00210 00213 public: inline Vector3 RotateVector(const Vector3 &_vec) const 00214 { 00215 Quaternion tmp(0.0, _vec.x, _vec.y, _vec.z); 00216 tmp = (*this) * (tmp * this->GetInverse()); 00217 return Vector3(tmp.x, tmp.y, tmp.z); 00218 } 00219 00221 public: Vector3 RotateVectorReverse(Vector3 vec) const; 00222 00225 public: bool IsFinite() const; 00226 00228 public: inline void Correct() 00229 { 00230 if (!finite(this->x)) 00231 this->x = 0; 00232 if (!finite(this->y)) 00233 this->y = 0; 00234 if (!finite(this->z)) 00235 this->z = 0; 00236 if (!finite(this->w)) 00237 this->w = 1; 00238 00239 if (this->w == 0 && this->x == 0 && this->y == 0 && this->z == 0) 00240 this->w = 1; 00241 } 00242 00244 public: Matrix3 GetAsMatrix3() const; 00245 00247 public: Matrix4 GetAsMatrix4() const; 00248 00249 public: Vector3 GetXAxis() const; 00250 public: Vector3 GetYAxis() const; 00251 public: Vector3 GetZAxis() const; 00252 00254 public: void Round(int _precision); 00255 00257 public: double Dot(const Quaternion &_q) const; 00258 00260 public: static Quaternion Squad(double _fT, const Quaternion &_rkP, 00261 const Quaternion &_rkA, const Quaternion &_rkB, 00262 Quaternion &_rkQ, bool _shortestPath = false); 00263 00265 public: static Quaternion Slerp (double _fT, const Quaternion &_rkP, 00266 const Quaternion &_rkQ, bool _shortestPath = false); 00267 00268 00270 public: double w; 00271 00273 public: double x; 00274 00276 public: double y; 00277 00279 public: double z; 00280 00285 public: friend std::ostream &operator<<( std::ostream &out, 00286 const gazebo::math::Quaternion &q ) 00287 { 00288 Vector3 v( q.GetAsEuler() ); 00289 //v.x = v.x * 180.0 / M_PI; 00290 //v.y = v.y * 180.0 / M_PI; 00291 //v.z = v.z * 180.0 / M_PI; 00292 00293 /*if (std::isnan(v.x)) 00294 v.x = 90.0; 00295 if (std::isnan(v.y)) 00296 v.y = 90.0; 00297 if (std::isnan(v.z)) 00298 v.z = 90.0; 00299 */ 00300 00301 out << v.x << " " << v.y << " " << v.z; 00302 00303 return out; 00304 } 00305 00310 public: friend std::istream &operator>>( std::istream &in, 00311 gazebo::math::Quaternion &q ) 00312 { 00313 Angle r, p, y; 00314 00315 // Skip white spaces 00316 in.setf( std::ios_base::skipws ); 00317 in >> r >> p >> y; 00318 00319 q.SetFromEuler(Vector3(*r,*p,*y)); 00320 00321 return in; 00322 } 00323 00324 00325 }; 00326 00328 } 00329 00330 } 00331 #endif

1.7.5.1