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