Robotics Library  0.7.0
QuaternionBaseAddons.h
Go to the documentation of this file.
1 //
2 // Copyright (c) 2009, Markus Rickert
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are met:
7 //
8 // * Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above copyright notice,
11 // this list of conditions and the following disclaimer in the documentation
12 // and/or other materials provided with the distribution.
13 //
14 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
18 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 // POSSIBILITY OF SUCH DAMAGE.
25 //
26 
27 #ifndef RL_MATH_QUATERNIONBASEADDONS_H
28 #define RL_MATH_QUATERNIONBASEADDONS_H
29 
30 template<typename OtherDerived>
31 Vector3
32 angularVelocity(const QuaternionBase<OtherDerived>& qd) const
33 {
34  return ((qd * this->derived().conjugate()) * Scalar(2)).vec();
35 }
36 
37 template<typename OtherDerived1, typename OtherDerived2>
38 Vector3
39 angularAcceleration(const QuaternionBase<OtherDerived1>& qd, const QuaternionBase<OtherDerived2>& qdd) const
40 {
41  return ((qdd * this->derived().conjugate() + qd * qd.conjugate()) * Scalar(2)).vec();
42 }
43 
44 Quaternion<Scalar>
45 exp() const
46 {
47  Scalar theta = this->derived().vec().norm();
48  Scalar sinTheta = ::sin(theta);
49  Scalar cosTheta = ::cos(theta);
50 
51  Quaternion<Scalar> q;
52 
53  if (theta > Scalar(0))
54  {
55  q.vec() = sinTheta * this->derived().vec() / theta;
56  }
57  else
58  {
59  q.vec().setZero();
60  }
61 
62  q.w() = cosTheta;
63 
64  return q;
65 }
66 
67 Quaternion<Scalar>
68 firstDerivative(const Vector3& omega) const
69 {
70  return (Quaternion<Scalar>(Scalar(0), omega.x(), omega.y(), omega.z()) * this->derived()) * Scalar(0.5);
71 }
72 
73 template<typename OtherDerived>
74 Quaternion<Scalar> lerp(const Scalar& t, const QuaternionBase<OtherDerived>& other) const
75 {
76  return Quaternion<Scalar>((Scalar(1) - t) * coeffs() + t * other.coeffs());
77 }
78 
79 Quaternion<Scalar>
80 log() const
81 {
82  Scalar theta = ::acos(this->derived().w());
83  Scalar sinTheta = ::sin(theta);
84 
85  Quaternion<Scalar> q;
86 
87  if (sinTheta > Scalar(0))
88  {
89  q.vec() = theta * this->derived().vec() / sinTheta;
90  }
91  else
92  {
93  q.vec().setZero();
94  }
95 
96  q.w() = Scalar(0);
97 
98  return q;
99 }
100 
101 template<typename OtherDerived>
102 Quaternion<Scalar>
103 operator+(const QuaternionBase<OtherDerived>& other) const
104 {
105  return Quaternion<Scalar>(this->derived().coeffs() + other.coeffs());
106 }
107 
108 template<typename OtherDerived>
109 Quaternion<Scalar>
110 operator-(const QuaternionBase<OtherDerived>& other) const
111 {
112  return Quaternion<Scalar>(this->derived().coeffs() - other.coeffs());
113 }
114 
115 Quaternion<Scalar>
116 operator*(const Scalar& scalar) const
117 {
118  return Quaternion<Scalar>(this->derived().coeffs() * scalar);
119 }
120 
121 Quaternion<Scalar>
122 operator/(const Scalar& scalar) const
123 {
124  return Quaternion<Scalar>(this->derived().coeffs() / scalar);
125 }
126 
127 Quaternion<Scalar>
128 pow(const Scalar& t) const
129 {
130  return (this->derived().log() * Scalar(t)).exp();
131 }
132 
133 template<typename OtherDerived>
134 Quaternion<Scalar>
135 secondDerivative(const QuaternionBase<OtherDerived>& qd, const Vector3& omega, const Vector3& omegad) const
136 {
137  return (Quaternion<Scalar>(Scalar(0), omegad.x(), omegad.y(), omegad.z()) * this->derived() + Quaternion<Scalar>(Scalar(0), omega.x(), omega.y(), omega.z()) * qd) * Scalar(0.5);
138 }
139 
149 template<typename OtherDerived>
150 void
151 setFromGaussian(const Vector3& rand, const QuaternionBase<OtherDerived>& mean, const Vector3& sigma)
152 {
153  eigen_assert(rand(0) >= Scalar(0));
154  eigen_assert(rand(0) <= Scalar(1));
155  eigen_assert(rand(1) >= Scalar(0));
156  eigen_assert(rand(1) <= Scalar(1));
157  eigen_assert(rand(2) >= Scalar(0));
158  eigen_assert(rand(2) <= Scalar(1));
159 
160  Quaternion<Scalar> tmp;
161  tmp.w() = rand.norm();
162  tmp.vec() = sigma.cwiseProduct(rand);
163 
164  this->derived() = mean * tmp.exp();
165 }
166 
176 void
178 {
179  eigen_assert(rand(0) >= Scalar(0));
180  eigen_assert(rand(0) <= Scalar(1));
181  eigen_assert(rand(1) >= Scalar(0));
182  eigen_assert(rand(1) <= Scalar(1));
183  eigen_assert(rand(2) >= Scalar(0));
184  eigen_assert(rand(2) <= Scalar(1));
185 
186  Scalar sigma1 = ::std::sqrt(Scalar(1) - rand(0));
187  Scalar sigma2 = ::std::sqrt(rand(0));
188  Scalar theta1 = Scalar(2) * static_cast<Scalar>(M_PI) * rand(1);
189  Scalar theta2 = Scalar(2) * static_cast<Scalar>(M_PI) * rand(2);
190 
191  this->derived().w() = ::std::cos(theta2) * sigma2;
192  this->derived().x() = ::std::sin(theta1) * sigma1;
193  this->derived().y() = ::std::cos(theta1) * sigma1;
194  this->derived().z() = ::std::sin(theta2) * sigma2;
195 }
196 
197 template<typename OtherDerived>
198 Quaternion<Scalar>
199 slerpFirstDerivative(const Scalar& t, const QuaternionBase<OtherDerived>& other) const
200 {
201  Quaternion<Scalar> tmp = this->derived().conjugate() * other;
202  return this->derived() * tmp.pow(t) * tmp.log();
203 }
204 
205 template<typename OtherDerived1, typename OtherDerived2, typename OtherDerived3>
206 Quaternion<Scalar>
207 squad(const Scalar& t, const QuaternionBase<OtherDerived1>& a, const QuaternionBase<OtherDerived2>& b, const QuaternionBase<OtherDerived3>& other) const
208 {
209  return this->derived().slerp(t, other).slerp(Scalar(2) * t * (Scalar(1) - t), a.slerp(t, b));
210 }
211 
212 template<typename OtherDerived1, typename OtherDerived2>
213 Quaternion<Scalar>
214 squadControlPoint(const QuaternionBase<OtherDerived1>& previous, const QuaternionBase<OtherDerived2>& next) const
215 {
216  return this->derived() * (((this->derived().conjugate() * previous).log() + (this->derived().conjugate() * next).log()) / Scalar(-4)).exp();
217 }
218 
219 template<typename OtherDerived1, typename OtherDerived2, typename OtherDerived3>
220 Quaternion<Scalar>
221 squadFirstDerivative(const Scalar& t, const QuaternionBase<OtherDerived1>& a, const QuaternionBase<OtherDerived2>& b, const QuaternionBase<OtherDerived3>& other) const
222 {
223  Quaternion<Scalar> u = this->derived().slerp(t, other);
224  Quaternion<Scalar> v = a.slerp(t, b);
225  Quaternion<Scalar> w = u.inverse() * v;
226  Quaternion<Scalar> ud = u * (this->derived().conjugate() * other).log();
227  Quaternion<Scalar> vd = v * (a.conjugate() * b).log();
228  Quaternion<Scalar> wd = u.conjugate() * vd - u.pow(Scalar(-2)) * ud * v;
229  Scalar tmp = Scalar(2) * t * (Scalar(1) - t);
230  return u * (w.pow(tmp) * (Scalar(2) - Scalar(4) * t) * w.log() + w.pow(tmp - Scalar(1)) * tmp * wd) + ud * w.pow(tmp);
231 }
232 
233 #endif // RL_MATH_QUATERNIONBASEADDONS_H
exp
Quaternion< Scalar > exp() const
Definition: QuaternionBaseAddons.h:45
pow
Quaternion< Scalar > pow(const Scalar &t) const
Definition: QuaternionBaseAddons.h:128
lerp
Quaternion< Scalar > lerp(const Scalar &t, const QuaternionBase< OtherDerived > &other) const
Definition: QuaternionBaseAddons.h:74
angularVelocity
Vector3 angularVelocity(const QuaternionBase< OtherDerived > &qd) const
Definition: QuaternionBaseAddons.h:32
squad
Quaternion< Scalar > squad(const Scalar &t, const QuaternionBase< OtherDerived1 > &a, const QuaternionBase< OtherDerived2 > &b, const QuaternionBase< OtherDerived3 > &other) const
Definition: QuaternionBaseAddons.h:207
operator+
Quaternion< Scalar > operator+(const QuaternionBase< OtherDerived > &other) const
Definition: QuaternionBaseAddons.h:103
operator*
Quaternion< Scalar > operator*(const Scalar &scalar) const
Definition: QuaternionBaseAddons.h:116
rl::math::Vector3
::Eigen::Matrix< Real, 3, 1 > Vector3
Definition: Vector.h:46
setFromUniform
void setFromUniform(const Vector3 &rand)
Generate uniformly-distributed random unit quaternions.
Definition: QuaternionBaseAddons.h:177
operator-
Quaternion< Scalar > operator-(const QuaternionBase< OtherDerived > &other) const
Definition: QuaternionBaseAddons.h:110
setFromGaussian
void setFromGaussian(const Vector3 &rand, const QuaternionBase< OtherDerived > &mean, const Vector3 &sigma)
QuTEM (Quaternion Tangent Ellipsoid at the Mean) sampling algorithm.
Definition: QuaternionBaseAddons.h:151
squadControlPoint
Quaternion< Scalar > squadControlPoint(const QuaternionBase< OtherDerived1 > &previous, const QuaternionBase< OtherDerived2 > &next) const
Definition: QuaternionBaseAddons.h:214
angularAcceleration
Vector3 angularAcceleration(const QuaternionBase< OtherDerived1 > &qd, const QuaternionBase< OtherDerived2 > &qdd) const
Definition: QuaternionBaseAddons.h:39
firstDerivative
Quaternion< Scalar > firstDerivative(const Vector3 &omega) const
Definition: QuaternionBaseAddons.h:68
operator/
Quaternion< Scalar > operator/(const Scalar &scalar) const
Definition: QuaternionBaseAddons.h:122
slerpFirstDerivative
Quaternion< Scalar > slerpFirstDerivative(const Scalar &t, const QuaternionBase< OtherDerived > &other) const
Definition: QuaternionBaseAddons.h:199
squadFirstDerivative
Quaternion< Scalar > squadFirstDerivative(const Scalar &t, const QuaternionBase< OtherDerived1 > &a, const QuaternionBase< OtherDerived2 > &b, const QuaternionBase< OtherDerived3 > &other) const
Definition: QuaternionBaseAddons.h:221
secondDerivative
Quaternion< Scalar > secondDerivative(const QuaternionBase< OtherDerived > &qd, const Vector3 &omega, const Vector3 &omegad) const
Definition: QuaternionBaseAddons.h:135
log
Quaternion< Scalar > log() const
Definition: QuaternionBaseAddons.h:80