|
|
|
@ -2,6 +2,7 @@
@@ -2,6 +2,7 @@
|
|
|
|
|
* @file Quaternion.hpp |
|
|
|
|
* |
|
|
|
|
* All rotations and axis systems follow the right-hand rule. |
|
|
|
|
* The Hamilton quaternion product definition is used. |
|
|
|
|
* |
|
|
|
|
* In order to rotate a vector v by a righthand rotation defined by the quaternion q |
|
|
|
|
* one can use the following operation: |
|
|
|
@ -139,12 +140,12 @@ public:
@@ -139,12 +140,12 @@ public:
|
|
|
|
|
Vector<Type, 4>() |
|
|
|
|
{ |
|
|
|
|
Quaternion &q = *this; |
|
|
|
|
Type cosPhi_2 = Type(cos(euler.phi() / (Type)2.0)); |
|
|
|
|
Type cosTheta_2 = Type(cos(euler.theta() / (Type)2.0)); |
|
|
|
|
Type cosPsi_2 = Type(cos(euler.psi() / (Type)2.0)); |
|
|
|
|
Type sinPhi_2 = Type(sin(euler.phi() / (Type)2.0)); |
|
|
|
|
Type sinTheta_2 = Type(sin(euler.theta() / (Type)2.0)); |
|
|
|
|
Type sinPsi_2 = Type(sin(euler.psi() / (Type)2.0)); |
|
|
|
|
Type cosPhi_2 = Type(cos(euler.phi() / Type(2.0))); |
|
|
|
|
Type cosTheta_2 = Type(cos(euler.theta() / Type(2.0))); |
|
|
|
|
Type cosPsi_2 = Type(cos(euler.psi() / Type(2.0))); |
|
|
|
|
Type sinPhi_2 = Type(sin(euler.phi() / Type(2.0))); |
|
|
|
|
Type sinTheta_2 = Type(sin(euler.theta() / Type(2.0))); |
|
|
|
|
Type sinPsi_2 = Type(sin(euler.psi() / Type(2.0))); |
|
|
|
|
q(0) = cosPhi_2 * cosTheta_2 * cosPsi_2 + |
|
|
|
|
sinPhi_2 * sinTheta_2 * sinPsi_2; |
|
|
|
|
q(1) = sinPhi_2 * cosTheta_2 * cosPsi_2 - |
|
|
|
@ -166,8 +167,8 @@ public:
@@ -166,8 +167,8 @@ public:
|
|
|
|
|
Quaternion &q = *this; |
|
|
|
|
Type angle = aa.norm(); |
|
|
|
|
Vector<Type, 3> axis = aa.unit(); |
|
|
|
|
if (angle < (Type)1e-10) { |
|
|
|
|
q(0) = (Type)1.0; |
|
|
|
|
if (angle < Type(1e-10)) { |
|
|
|
|
q(0) = Type(1.0); |
|
|
|
|
q(1) = q(2) = q(3) = 0; |
|
|
|
|
} else { |
|
|
|
|
Type magnitude = sinf(angle / 2.0f); |
|
|
|
@ -253,11 +254,29 @@ public:
@@ -253,11 +254,29 @@ public:
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Computes the derivative |
|
|
|
|
* Computes the derivative of q_12 when |
|
|
|
|
* rotated with angular velocity expressed in frame 2 |
|
|
|
|
* v_2 = q_12 * v_1 * q_12^-1 |
|
|
|
|
* d/dt q_12 = 0.5 * q_12 * omega_12_2 |
|
|
|
|
* |
|
|
|
|
* @param w direction |
|
|
|
|
* @param w angular rate in frame 2 |
|
|
|
|
*/ |
|
|
|
|
Matrix41 derivative(const Matrix31 &w) const |
|
|
|
|
Matrix41 derivative1(const Matrix31 &w) const |
|
|
|
|
{ |
|
|
|
|
const Quaternion &q = *this; |
|
|
|
|
Quaternion<Type> v(0, w(0, 0), w(1, 0), w(2, 0)); |
|
|
|
|
return q * v * Type(0.5); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Computes the derivative of q_12 when |
|
|
|
|
* rotated with angular velocity expressed in frame 2 |
|
|
|
|
* v_2 = q_12 * v_1 * q_12^-1 |
|
|
|
|
* d/dt q_12 = 0.5 * omega_12_1 * q_12 |
|
|
|
|
* |
|
|
|
|
* @param w angular rate in frame (typically reference frame) |
|
|
|
|
*/ |
|
|
|
|
Matrix41 derivative2(const Matrix31 &w) const |
|
|
|
|
{ |
|
|
|
|
const Quaternion &q = *this; |
|
|
|
|
Quaternion<Type> v(0, w(0, 0), w(1, 0), w(2, 0)); |
|
|
|
@ -265,14 +284,11 @@ public:
@@ -265,14 +284,11 @@ public:
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Invert quaternion |
|
|
|
|
* Invert quaternion in place |
|
|
|
|
*/ |
|
|
|
|
void invert() |
|
|
|
|
{ |
|
|
|
|
Quaternion &q = *this; |
|
|
|
|
q(1) *= -1; |
|
|
|
|
q(2) *= -1; |
|
|
|
|
q(3) *= -1; |
|
|
|
|
*this = this->inversed(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@ -283,12 +299,12 @@ public:
@@ -283,12 +299,12 @@ public:
|
|
|
|
|
Quaternion inversed() |
|
|
|
|
{ |
|
|
|
|
Quaternion &q = *this; |
|
|
|
|
Quaternion ret; |
|
|
|
|
ret(0) = q(0); |
|
|
|
|
ret(1) = -q(1); |
|
|
|
|
ret(2) = -q(2); |
|
|
|
|
ret(3) = -q(3); |
|
|
|
|
return ret; |
|
|
|
|
Type normSq = q.dot(q); |
|
|
|
|
return Quaternion( |
|
|
|
|
q(0)/normSq, |
|
|
|
|
-q(1)/normSq, |
|
|
|
|
-q(2)/normSq, |
|
|
|
|
-q(3)/normSq); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@ -332,8 +348,8 @@ public:
@@ -332,8 +348,8 @@ public:
|
|
|
|
|
Quaternion &q = *this; |
|
|
|
|
Type theta = vec.norm(); |
|
|
|
|
|
|
|
|
|
if (theta < (Type)1e-10) { |
|
|
|
|
q(0) = (Type)1.0; |
|
|
|
|
if (theta < Type(1e-10)) { |
|
|
|
|
q(0) = Type(1.0); |
|
|
|
|
q(1) = q(2) = q(3) = 0; |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
@ -354,8 +370,8 @@ public:
@@ -354,8 +370,8 @@ public:
|
|
|
|
|
{ |
|
|
|
|
Quaternion &q = *this; |
|
|
|
|
|
|
|
|
|
if (theta < (Type)1e-10) { |
|
|
|
|
q(0) = (Type)1.0; |
|
|
|
|
if (theta < Type(1e-10)) { |
|
|
|
|
q(0) = Type(1.0); |
|
|
|
|
q(1) = q(2) = q(3) = 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -386,9 +402,9 @@ public:
@@ -386,9 +402,9 @@ public:
|
|
|
|
|
vec(1) = q(2); |
|
|
|
|
vec(2) = q(3); |
|
|
|
|
|
|
|
|
|
if (axis_magnitude >= (Type)1e-10) { |
|
|
|
|
if (axis_magnitude >= Type(1e-10)) { |
|
|
|
|
vec = vec / axis_magnitude; |
|
|
|
|
vec = vec * wrap_pi((Type)2.0 * atan2f(axis_magnitude, q(0))); |
|
|
|
|
vec = vec * wrap_pi(Type(2.0) * atan2f(axis_magnitude, q(0))); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return vec; |
|
|
|
|