Robotics Library  0.7.0
SplineQuaternion.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_QUATERNIONSPLINE_H
28 #define RL_MATH_QUATERNIONSPLINE_H
29 
30 #include <limits>
31 #include <vector>
32 
33 #include "PolynomialQuaternion.h"
34 #include "Spline.h"
35 
36 namespace rl
37 {
38  namespace math
39  {
40  template<>
41  class Spline<Quaternion> : public Function<Quaternion>
42  {
43  public:
44  typedef ::std::vector<Polynomial<Quaternion>>::const_iterator ConstIterator;
45 
46  typedef ::std::vector<Polynomial<Quaternion>>::const_reverse_iterator ConstReverseIterator;
47 
48  typedef ::std::vector<Polynomial<Quaternion>>::iterator Iterator;
49 
50  typedef ::std::vector<Polynomial<Quaternion>>::reverse_iterator ReverseIterator;
51 
54  polynomials(),
55  x0(0),
56  x1(0)
57  {
58  this->x0 = 0;
59  this->x1 = 0;
60  }
61 
62  virtual ~Spline<Quaternion>()
63  {
64  }
65 
66  static Spline<Quaternion> CubicFirst(const ::std::vector<Real>& x, const ::std::vector<Quaternion>& y, const Vector3& yd0, const Vector3& yd1)
67  {
68  assert(x.size() > 1);
69  assert(x.size() == y.size());
70 
71  ::std::size_t n = x.size();
72 
74 
75  ::std::vector<Real> dtheta(n - 1);
76  ::std::vector<Real> dx(n - 1);
77  ::std::vector<Vector3> e(n - 1);
78 
79  for (::std::size_t i = 0; i < n - 1; ++i)
80  {
81  dx[i] = x[i + 1] - x[i];
82  dtheta[i] = y[i].angularDistance(y[i + 1]);
83  e[i] = (y[i].inverse() * y[i + 1]).vec();
84 
85  if (e[i].norm() <= ::std::numeric_limits<Real>::epsilon())
86  {
87  e[i].setZero();
88  }
89  else
90  {
91  e[i].normalize();
92  }
93  }
94 
95  ::std::vector<Real> a(n);
96  ::std::vector<Real> b(n);
97  ::std::vector<Real> c(n);
98  ::std::vector<Vector3> d(n);
99  Real dOmega;
100  ::std::vector<Vector3> omega(n, Vector3::Zero());
101  ::std::vector<Vector3> omegaprev(n);
102 
103  do
104  {
105  for (::std::size_t i = 1; i < n - 1; ++i)
106  {
107  omegaprev[i] = omega[i];
108  }
109 
110  for (::std::size_t i = 1; i < n - 1; ++i)
111  {
112  a[i] = 2 / dx[i - 1];
113  b[i] = 4 / dx[i - 1] + 4 / dx[i];
114  c[i] = 2 / dx[i];
115  d[i] = (6 * e[i - 1] * dtheta[i - 1]) / ::std::pow(dx[i - 1], 2) + (6 * e[i] * dtheta[i]) / ::std::pow(dx[i], 2) - R(e[i - 1], dtheta[i - 1], omegaprev[i]);
116  }
117 
118  if (n > 2)
119  {
120  d[1] -= a[1] * B(e[0], dtheta[0], yd0);
121  d[n - 2] -= c[n - 2] * invB(e[n - 2], dtheta[n - 2], yd1);
122  }
123 
124  for (::std::size_t i = 2; i < n - 1; ++i)
125  {
126  b[i] -= c[i - 1] * a[i] / b[i - 1];
127  d[i] -= (a[i] / b[i - 1]) * B(e[i - 1], dtheta[i - 1], d[i - 1]);
128  }
129 
130  if (n > 2)
131  {
132  omega[n - 2] = d[n - 2] / b[n - 2];
133  }
134 
135  for (::std::size_t i = 1; i < n - 2; ++i)
136  {
137  omega[n - 2 - i] = (d[n - 2 - i] - c[n - 2 - i] * invB(e[n - 2 - i], dtheta[n - 2 - i], omega[n - 2 - i + 1])) / b[n - 2 - i];
138  }
139 
140  dOmega = 0;
141 
142  for (::std::size_t i = 1; i < n - 1; ++i)
143  {
144  dOmega += (omega[i] - omegaprev[i]).norm();
145  }
146  }
147  while (dOmega > 1.0e-6f);
148 
149  omega[0] = yd0;
150  omega[n - 1] = yd1;
151 
152  for (::std::size_t i = 0; i < n - 1; ++i)
153  {
155  fi.coefficient(0) = Vector3::Zero();
156  fi.coefficient(1) = dx[i] * omega[i];
157  fi.coefficient(2) = dx[i] * invB(e[i], dtheta[i], omega[i + 1]) - 3 * e[i] * dtheta[i];
158  fi.coefficient(3) = e[i] * dtheta[i];
159  fi.upper() = dx[i];
160  fi.y0 = y[i];
161  f.push_back(fi);
162  }
163 
164  return f;
165  }
166 
167  Polynomial<Quaternion>& at(const ::std::size_t& i)
168  {
169  return this->polynomials.at(i);
170  }
171 
172  const Polynomial<Quaternion>& at(const ::std::size_t& i) const
173  {
174  return this->polynomials.at(i);
175  }
176 
178  {
179  return this->polynomials.back();
180  }
181 
183  {
184  return this->polynomials.back();
185  }
186 
187  Iterator begin()
188  {
189  return this->polynomials.begin();
190  }
191 
192  ConstIterator begin() const
193  {
194  return this->polynomials.begin();
195  }
196 
197  void clear()
198  {
199  this->polynomials.clear();
200  }
201 
203  {
204  return new Spline<Quaternion>(*this);
205  }
206 
207  Real duration() const
208  {
209  return this->upper() - this->lower();
210  }
211 
212  bool empty()
213  {
214  return this->polynomials.empty();
215  }
216 
217  Iterator end()
218  {
219  return this->polynomials.end();
220  }
221 
222  ConstIterator end() const
223  {
224  return this->polynomials.end();
225  }
226 
228  {
229  return this->polynomials.front();
230  }
231 
233  {
234  return this->polynomials.front();
235  }
236 
238  {
239  return this->x0;
240  }
241 
242  const Real& lower() const
243  {
244  return this->x0;
245  }
246 
247  Quaternion operator()(const Real& x, const ::std::size_t& derivative = 0) const
248  {
249  assert(x >= this->lower() - FUNCTION_BOUNDARY);
250  assert(x <= this->upper() + FUNCTION_BOUNDARY);
251  assert(this->polynomials.size() > 0);
252 
253  Real x0 = this->lower();
254  ::std::size_t i = 0;
255 
256  for (; x > x0 + this->polynomials[i].duration() && i < this->polynomials.size(); ++i)
257  {
258  x0 += this->polynomials[i].duration();
259  }
260 
261  return this->polynomials[i](x - x0, derivative);
262  }
263 
264  Polynomial<Quaternion>& operator[](const ::std::size_t& i)
265  {
266  return this->polynomials[i];
267  }
268 
269  const Polynomial<Quaternion>& operator[](const ::std::size_t& i) const
270  {
271  return this->polynomials[i];
272  }
273 
274  void pop_back()
275  {
276  if (!this->polynomials.empty())
277  {
278  this->x1 -= this->polynomials.back().duration();
279  this->polynomials.pop_back();
280 
281  if (this->polynomials.empty())
282  {
283  this->x0 = 0;
284  }
285  }
286  }
287 
289  {
290  if (this->polynomials.empty())
291  {
292  this->x0 = polynomial.lower();
293  }
294 
295  this->polynomials.push_back(polynomial);
296  this->x1 += polynomial.duration();
297  }
298 
299  ::std::size_t size() const
300  {
301  return this->polynomials.size();
302  }
303 
304  ReverseIterator rbegin()
305  {
306  return this->polynomials.rbegin();
307  }
308 
309  ConstReverseIterator rbegin() const
310  {
311  return this->polynomials.rbegin();
312  }
313 
314  ReverseIterator rend()
315  {
316  return this->polynomials.rend();
317  }
318 
319  ConstReverseIterator rend() const
320  {
321  return this->polynomials.rend();
322  }
323 
325  {
326  return this->x1;
327  }
328 
329  const Real& upper() const
330  {
331  return this->x1;
332  }
333 
334  protected:
335  ::std::vector<Polynomial<Quaternion>> polynomials;
336 
338 
340 
341  private:
342  static Vector3 B(const Vector3& e, const Real& dtheta, const Vector3& x)
343  {
344  if (dtheta <= ::std::numeric_limits<Real>::epsilon())
345  {
346  return x;
347  }
348 
349  Real cosdtheta = ::std::cos(dtheta);
350  Real sindtheta = ::std::sin(dtheta);
351 
352  return x.dot(e) * e + sindtheta / dtheta * e.cross(x).cross(e) - (1 - cosdtheta) / dtheta * e.cross(x);
353  }
354 
355  static Vector3 invB(const Vector3& e, const Real& dtheta, const Vector3& x)
356  {
357  if (dtheta <= ::std::numeric_limits<Real>::epsilon())
358  {
359  return x;
360  }
361 
362  Real cosdtheta = ::std::cos(dtheta);
363  Real sindtheta = ::std::sin(dtheta);
364 
365  return e.dot(x) * e + 0.5f * (dtheta * sindtheta) / (1 - cosdtheta) * e.cross(x).cross(e) + 0.5f * dtheta * e.cross(x);
366  }
367 
368  static Vector3 R(const Vector3& e, const Real& dtheta, const Vector3& omega)
369  {
370  if (dtheta <= ::std::numeric_limits<Real>::epsilon())
371  {
372  return Vector3::Zero();
373  }
374 
375  Real cosdtheta = ::std::cos(dtheta);
376  Real sindtheta = ::std::sin(dtheta);
377 
378  Real r0 = 0.5f * (dtheta - sindtheta) / (1 - cosdtheta);
379  Real r1 = (dtheta * sindtheta - 2 * (1 - cosdtheta)) / (dtheta * (1 - cosdtheta));
380 
381  return r0 * (omega.dot(omega) - ::std::pow(e.dot(omega), 2)) * e + r1 * e.dot(omega) * e.cross(omega).cross(e);
382  }
383  };
384  }
385 }
386 
387 #endif // RL_MATH_QUATERNIONSPLINE_H
pow
Quaternion< Scalar > pow(const Scalar &t) const
Definition: QuaternionBaseAddons.h:128
rl::math::Spline< Quaternion >::begin
Iterator begin()
Definition: SplineQuaternion.h:187
rl::math::Spline< Quaternion >::CubicFirst
static Spline< Quaternion > CubicFirst(const ::std::vector< Real > &x, const ::std::vector< Quaternion > &y, const Vector3 &yd0, const Vector3 &yd1)
Definition: SplineQuaternion.h:66
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
rl::math::Spline< Quaternion >::end
Iterator end()
Definition: SplineQuaternion.h:217
rl::math::Spline< Quaternion >::x0
Real x0
Definition: SplineQuaternion.h:337
rl::math::Spline< Quaternion >::back
Polynomial< Quaternion > & back()
Definition: SplineQuaternion.h:177
rl::math::Spline< Quaternion >::begin
ConstIterator begin() const
Definition: SplineQuaternion.h:192
rl::math::Spline< Quaternion >::end
ConstIterator end() const
Definition: SplineQuaternion.h:222
rl::math::Polynomial< Quaternion >
Definition: PolynomialQuaternion.h:45
rl::math::Spline::derivative
Spline derivative() const
Definition: Spline.h:720
rl::math::Spline< Quaternion >::rbegin
ReverseIterator rbegin()
Definition: SplineQuaternion.h:304
rl::math::Spline< Quaternion >::size
::std::size_t size() const
Definition: SplineQuaternion.h:299
rl::math::Spline< Quaternion >::upper
Real & upper()
Definition: SplineQuaternion.h:324
rl::math::Spline< Quaternion >::at
const Polynomial< Quaternion > & at(const ::std::size_t &i) const
Definition: SplineQuaternion.h:172
rl::math::Spline::polynomials
::std::vector< Polynomial< T > > polynomials
Definition: Spline.h:920
rl::math::Spline< Quaternion >::polynomials
::std::vector< Polynomial< Quaternion > > polynomials
Definition: SplineQuaternion.h:335
rl::math::Spline< Quaternion >::upper
const Real & upper() const
Definition: SplineQuaternion.h:329
rl::math::Spline< Quaternion >::duration
Real duration() const
Definition: SplineQuaternion.h:207
rl::math::Function::upper
Real & upper()
Definition: Function.h:74
rl::math::Spline< Quaternion >::x1
Real x1
Definition: SplineQuaternion.h:339
rl::math::Spline< Quaternion >
Definition: SplineQuaternion.h:42
rl::math::Spline< Quaternion >::R
static Vector3 R(const Vector3 &e, const Real &dtheta, const Vector3 &omega)
Definition: SplineQuaternion.h:368
rl::math::Spline< Quaternion >::B
static Vector3 B(const Vector3 &e, const Real &dtheta, const Vector3 &x)
Definition: SplineQuaternion.h:342
rl::math::Spline< Quaternion >::ConstIterator
::std::vector< Polynomial< Quaternion > >::const_iterator ConstIterator
Definition: SplineQuaternion.h:44
rl::math::Spline< Quaternion >::front
const Polynomial< Quaternion > & front() const
Definition: SplineQuaternion.h:232
rl::math::Spline< Quaternion >::lower
const Real & lower() const
Definition: SplineQuaternion.h:242
rl::math::Spline< Quaternion >::pop_back
void pop_back()
Definition: SplineQuaternion.h:274
rl::math::Polynomial< Quaternion >::upper
Real & upper()
Definition: PolynomialQuaternion.h:216
rl::math::Spline< 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: SplineQuaternion.h:247
rl::math::Spline< Quaternion >::clone
Spline< Quaternion > * clone() const
Definition: SplineQuaternion.h:202
rl::math::Spline< Quaternion >::Iterator
::std::vector< Polynomial< Quaternion > >::iterator Iterator
Definition: SplineQuaternion.h:48
rl::math::Polynomial< Quaternion >::coefficient
Vector3 & coefficient(const ::std::size_t &i)
Definition: PolynomialQuaternion.h:115
rl::math::Spline< Quaternion >::lower
Real & lower()
Definition: SplineQuaternion.h:237
rl::math::Function::x0
Real x0
Definition: Function.h:102
rl::math::Spline< Quaternion >::rbegin
ConstReverseIterator rbegin() const
Definition: SplineQuaternion.h:309
rl::math::Spline< Quaternion >::rend
ConstReverseIterator rend() const
Definition: SplineQuaternion.h:319
rl::math::Spline< Quaternion >::push_back
void push_back(Polynomial< Quaternion > &polynomial)
Definition: SplineQuaternion.h:288
rl::math::Spline< Quaternion >::at
Polynomial< Quaternion > & at(const ::std::size_t &i)
Definition: SplineQuaternion.h:167
rl::math::Spline< Quaternion >::rend
ReverseIterator rend()
Definition: SplineQuaternion.h:314
rl::math::Quaternion
::Eigen::Quaternion< Real > Quaternion
Definition: Quaternion.h:42
rl::math::FUNCTION_BOUNDARY
static const Real FUNCTION_BOUNDARY
Definition: Function.h:110
rl::math::Spline< Quaternion >::empty
bool empty()
Definition: SplineQuaternion.h:212
Spline.h
rl::math::Spline< Quaternion >::back
const Polynomial< Quaternion > & back() const
Definition: SplineQuaternion.h:182
rl::math::Polynomial< Quaternion >::lower
Real & lower()
Definition: PolynomialQuaternion.h:135
rl::math::Function::lower
Real & lower()
Definition: Function.h:64
rl::math::Spline< Quaternion >::clear
void clear()
Definition: SplineQuaternion.h:197
rl::math::Polynomial< Quaternion >::y0
Quaternion y0
Definition: PolynomialQuaternion.h:226
rl::math::Real
double Real
Definition: Real.h:42
rl::math::Spline< Quaternion >::operator[]
const Polynomial< Quaternion > & operator[](const ::std::size_t &i) const
Definition: SplineQuaternion.h:269
rl::math::Spline< Quaternion >::operator[]
Polynomial< Quaternion > & operator[](const ::std::size_t &i)
Definition: SplineQuaternion.h:264
rl::math::Spline
A piecewise Function of Polynomial functions.
Definition: Spline.h:53
rl::math::Spline::ReverseIterator
::std::vector< Polynomial< T > >::reverse_iterator ReverseIterator
Definition: Spline.h:61
PolynomialQuaternion.h
rl::math::Spline< Quaternion >::ConstReverseIterator
::std::vector< Polynomial< Quaternion > >::const_reverse_iterator ConstReverseIterator
Definition: SplineQuaternion.h:46
rl::math::Spline< Quaternion >::invB
static Vector3 invB(const Vector3 &e, const Real &dtheta, const Vector3 &x)
Definition: SplineQuaternion.h:355
rl::math::Spline< Quaternion >::front
Polynomial< Quaternion > & front()
Definition: SplineQuaternion.h:227
rl
Robotics Library.
Definition: AnalogInput.cpp:30