Robotics Library  0.7.0
PolynomialQuaternion.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_QUATERNIONPOLYNOMIAL_H
28 #define RL_MATH_QUATERNIONPOLYNOMIAL_H
29 
30 #include <cassert>
31 #include <vector>
32 
33 #include "Function.h"
34 #include "Polynomial.h"
35 #include "Quaternion.h"
36 #include "Rotation.h"
37 #include "Vector.h"
38 
39 namespace rl
40 {
41  namespace math
42  {
43  template<>
44  class Polynomial<Quaternion> : public Function<Quaternion>
45  {
46  public:
47  Polynomial<Quaternion>(const ::std::size_t& degree) :
49  y0(),
50  c(degree + 1),
51  x0(0),
52  x1(1)
53  {
54  }
55 
56  virtual ~Polynomial<Quaternion>()
57  {
58  }
59 
60  static Polynomial<Quaternion> CubicFirst(const Quaternion& y0, const Quaternion& y1, const Vector3& yd0, const Vector3& yd1, const Real& x1 = 1)
61  {
62  Real dtheta = y0.angularDistance(y1);
63  Vector3 e = (y0.inverse() * y1).vec();
64 
65  if (e.norm() <= ::std::numeric_limits<Real>::epsilon())
66  {
67  e.setZero();
68  }
69  else
70  {
71  e.normalize();
72  }
73 
75 
76  f.c[0] = Vector3::Zero();
77  f.c[1] = x1 * yd0;
78  f.c[2] = x1 * invB(e, dtheta, yd1) - 3 * e * dtheta;
79  f.c[3] = e * dtheta;
80  f.x1 = x1;
81  f.y0 = y0;
82 
83  return f;
84  }
85 
86  static Polynomial<Quaternion> Linear(const Quaternion& y0, const Quaternion& y1, const Real& x1 = 1)
87  {
88  Real dtheta = y0.angularDistance(y1);
89  Vector3 e = (y0.inverse() * y1).vec();
90 
91  if (e.norm() <= ::std::numeric_limits<Real>::epsilon())
92  {
93  e.setZero();
94  }
95  else
96  {
97  e.normalize();
98  }
99 
101 
102  f.c[0] = Vector3::Zero();
103  f.c[1] = e * dtheta;
104  f.x1 = x1;
105  f.y0 = y0;
106 
107  return f;
108  }
109 
111  {
112  return new Polynomial<Quaternion>(*this);
113  }
114 
115  Vector3& coefficient(const ::std::size_t& i)
116  {
117  return this->c[i];
118  }
119 
120  const Vector3& coefficient(const ::std::size_t& i) const
121  {
122  return this->c[i];
123  }
124 
125  ::std::size_t degree() const
126  {
127  return this->c.size() - 1;
128  }
129 
130  Real duration() const
131  {
132  return this->upper() - this->lower();
133  }
134 
136  {
137  return this->x0;
138  }
139 
140  const Real& lower() const
141  {
142  return this->x0;
143  }
144 
145  Quaternion operator()(const Real& x, const ::std::size_t& derivative = 0) const
146  {
147  assert(derivative <= 2 && "Polynomial<Quaternion>: higher derivatives not implemented");
148 
149  Vector3 axis = this->eval(x);
150  Real theta = axis.norm();
151  Vector3 u;
152 
153  if (theta <= ::std::numeric_limits<Real>::epsilon())
154  {
155  u.setZero();
156  }
157  else
158  {
159  u = axis.normalized();
160  }
161 
162  Quaternion y = this->y0 * AngleAxis(theta, u);
163 
164  if (0 == derivative)
165  {
166  return y;
167  }
168 
169  Polynomial<Quaternion> fd = this->derivative();
170  Vector3 axisd = fd.eval(x);
171  Real thetad = u.dot(axisd);
172  Vector3 w = u.cross(axisd) / theta;
173  Vector3 omega;
174 
175  if (theta > ::std::numeric_limits<Real>::epsilon())
176  {
177  omega = u * thetad + ::std::sin(theta) * w.cross(u) - (1 - ::std::cos(theta)) * w;
178  }
179  else
180  {
181  omega = axisd;
182  }
183 
184  Quaternion yd = y.firstDerivative(omega);
185 
186  if (1 == derivative)
187  {
188  return yd;
189  }
190 
192  Vector3 axisdd = fdd.eval(x);
193  Real thetadd = w.cross(u).dot(axisd) + u.dot(axisdd);
194  Vector3 wd = (u.cross(axisdd) - 2 * thetad * w) / theta;
195  Vector3 omegad;
196 
197  if (theta > ::std::numeric_limits<Real>::epsilon())
198  {
199  omegad = u * thetadd + ::std::sin(theta) * wd.cross(u) - (1 - ::std::cos(theta)) * wd + thetad * w.cross(u) + omega.cross(u * thetad - w);
200  }
201  else
202  {
203  omegad = axisdd;
204  }
205 
206  Quaternion ydd = y.secondDerivative(yd, omega, omegad);
207 
208  if (2 == derivative)
209  {
210  return ydd;
211  }
212 
213  return Quaternion();
214  }
215 
217  {
218  return this->x1;
219  }
220 
221  const Real& upper() const
222  {
223  return this->x1;
224  }
225 
227 
228  protected:
229  ::std::vector<Vector3> c;
230 
232 
234 
235  private:
237  {
238  ::std::size_t degree = this->degree() > 0 ? this->degree() - 1 : 0;
239 
241  f.x0 = this->x0;
242  f.x1 = this->x1;
243 
244  if (0 == this->degree())
245  {
246  f.c[0] = Vector3::Zero();
247  }
248  else
249  {
250  for (::std::size_t i = 0; i < this->degree(); ++i)
251  {
252  f.c[i] = (static_cast<Real>(this->degree() - (i + 1) + 1) * this->c[i] + static_cast<Real>(i + 1) * this->c[i + 1]) / (this->x1 - this->x0);
253  }
254  }
255 
256  return f;
257  }
258 
259  Vector3 eval(const Real& x) const
260  {
261  assert(x > this->lower() - FUNCTION_BOUNDARY);
262  assert(x < this->upper() + FUNCTION_BOUNDARY);
263 
264  Vector3 axis = Vector3::Zero();
265 
266  for (::std::size_t i = 0; i < this->degree() + 1; ++i)
267  {
268  axis += this->c[this->degree() - i] * ::std::pow(x / this->x1, static_cast<int>(this->degree() - i)) * ::std::pow(x / this->x1 - 1, static_cast<int>(i));
269  }
270 
271  return axis;
272  }
273 
274  static Vector3 invB(const Vector3& e, const Real& dtheta, const Vector3& x)
275  {
276  if (dtheta <= ::std::numeric_limits<Real>::epsilon())
277  {
278  return x;
279  }
280 
281  Real cosdtheta = ::std::cos(dtheta);
282  Real sindtheta = ::std::sin(dtheta);
283 
284  return e.dot(x) * e + 0.5f * (dtheta * sindtheta) / (1 - cosdtheta) * e.cross(x).cross(e) + 0.5f * dtheta * e.cross(x);
285  }
286  };
287  }
288 }
289 
290 #endif // RL_MATH_QUATERNIONPOLYNOMIAL_H
pow
Quaternion< Scalar > pow(const Scalar &t) const
Definition: QuaternionBaseAddons.h:128
rl::math::Polynomial< Quaternion >::degree
::std::size_t degree() const
Definition: PolynomialQuaternion.h:125
rl::math::Polynomial< Quaternion >::duration
Real duration() const
Definition: PolynomialQuaternion.h:130
rl::math::Function
A mathematical mapping from Real -> ArrayX.
Definition: Function.h:45
rl::math::Function::x1
Real x1
Definition: Function.h:104
rl::math::Vector3
::Eigen::Matrix< Real, 3, 1 > Vector3
Definition: Vector.h:46
Rotation.h
Polynomial.h
rl::math::Polynomial< Quaternion >::invB
static Vector3 invB(const Vector3 &e, const Real &dtheta, const Vector3 &x)
Definition: PolynomialQuaternion.h:274
rl::math::Polynomial< Quaternion >::x0
Real x0
Definition: PolynomialQuaternion.h:231
rl::math::Polynomial< Quaternion >
Definition: PolynomialQuaternion.h:45
rl::math::Polynomial::degree
::std::size_t degree() const
Definition: Polynomial.h:199
rl::math::Polynomial< Quaternion >::eval
Vector3 eval(const Real &x) const
Definition: PolynomialQuaternion.h:259
rl::math::Polynomial< Quaternion >::coefficient
const Vector3 & coefficient(const ::std::size_t &i) const
Definition: PolynomialQuaternion.h:120
rl::math::Polynomial
A vector-valued polynomial function from Real -> T.
Definition: Polynomial.h:61
Vector.h
rl::math::Polynomial< Quaternion >::clone
Polynomial< Quaternion > * clone() const
Definition: PolynomialQuaternion.h:110
Quaternion.h
rl::math::Function::upper
Real & upper()
Definition: Function.h:74
rl::math::Polynomial::derivative
Polynomial derivative() const
Definition: Polynomial.h:204
rl::math::Polynomial< Quaternion >::upper
Real & upper()
Definition: PolynomialQuaternion.h:216
rl::math::Polynomial< Quaternion >::Linear
static Polynomial< Quaternion > Linear(const Quaternion &y0, const Quaternion &y1, const Real &x1=1)
Definition: PolynomialQuaternion.h:86
rl::math::Polynomial< Quaternion >::coefficient
Vector3 & coefficient(const ::std::size_t &i)
Definition: PolynomialQuaternion.h:115
rl::math::Function::x0
Real x0
Definition: Function.h:102
rl::math::AngleAxis
::Eigen::AngleAxis< Real > AngleAxis
Definition: Rotation.h:50
rl::math::Polynomial< Quaternion >::derivative
Polynomial< Quaternion > derivative() const
Definition: PolynomialQuaternion.h:236
rl::math::Polynomial::c
::std::vector< T > c
Definition: Polynomial.h:657
rl::math::Polynomial< Quaternion >::operator()
Quaternion operator()(const Real &x, const ::std::size_t &derivative=0) const
Evaluates the function or a derivative thereof for a given value x.
Definition: PolynomialQuaternion.h:145
rl::math::Quaternion
::Eigen::Quaternion< Real > Quaternion
Definition: Quaternion.h:42
rl::math::Polynomial< Quaternion >::c
::std::vector< Vector3 > c
Definition: PolynomialQuaternion.h:229
rl::math::FUNCTION_BOUNDARY
static const Real FUNCTION_BOUNDARY
Definition: Function.h:110
rl::math::Polynomial< Quaternion >::x1
Real x1
Definition: PolynomialQuaternion.h:233
rl::math::Polynomial< Quaternion >::lower
Real & lower()
Definition: PolynomialQuaternion.h:135
rl::math::Function::lower
Real & lower()
Definition: Function.h:64
rl::math::Polynomial< Quaternion >::y0
Quaternion y0
Definition: PolynomialQuaternion.h:226
rl::math::Real
double Real
Definition: Real.h:42
Function.h
rl::math::Polynomial< Quaternion >::CubicFirst
static Polynomial< Quaternion > CubicFirst(const Quaternion &y0, const Quaternion &y1, const Vector3 &yd0, const Vector3 &yd1, const Real &x1=1)
Definition: PolynomialQuaternion.h:60
rl::math::Polynomial< Quaternion >::upper
const Real & upper() const
Definition: PolynomialQuaternion.h:221
rl::math::Polynomial< Quaternion >::lower
const Real & lower() const
Definition: PolynomialQuaternion.h:140
rl
Robotics Library.
Definition: AnalogInput.cpp:30