SE3CubicInterpolator.h
Go to the documentation of this file.
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2009-2013 CEA LIST (DIASI/LSI) <xde-support@saxifrage.cea.fr>
5 //
6 // This Source Code Form is subject to the terms of the Mozilla
7 // Public License v. 2.0. If a copy of the MPL was not distributed
8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 
10 #ifndef EIGEN_LGSM_GROUP_SE3_CUBIC_INTERPOLATOR_H
11 #define EIGEN_LGSM_GROUP_SE3_CUBIC_INTERPOLATOR_H
12 
13 
14 /***************************************************************************************************
15 * Needed improvement :
16 
17 - severals interpolator implemented through standard or static derivation
18 - implementing generic interpolation algorithm through template class (problem with limit conditions)
19 
20 *****************************************************************************************************/
21 
22 template<typename Scalar> class SE3CubicInterpolator{
23 public:
24  typedef std::vector<Displacement<Scalar>, aligned_allocator<Displacement<Scalar> > > StdVectorDisplacement;
25  typedef std::vector<Twist<Scalar>, aligned_allocator<Twist<Scalar> > > StdVectorTwist;
26 
28 
29  void setControlPoint(const StdVectorDisplacement& controlPoints, const StdVectorTwist& controlVelocities, const std::vector<Scalar>& t);
30 
31  //template<class DisplDerived, class TwistDerived>
32  //void Interpolate(DisplacementBase<DisplDerived>& pos, TwistBase<TwistDerived>& vel, const Scalar t) const;
33  void Interpolate(Displacement<Scalar>& pos, Twist<Scalar>& vel, const Scalar time) const;
34 protected:
35  std::vector<Scalar> t;
37  StdVectorTwist ksi;
38  StdVectorTwist bi, ci, di; // revert order
39  size_t n;
40 };
41 
42 template<typename Scalar>
43 void SE3CubicInterpolator<Scalar>::setControlPoint(const StdVectorDisplacement& controlPoints, const StdVectorTwist& controlVelocities, const std::vector<Scalar>& ti){ // check if ctrlpts, velocities & time are equal and > 1
44  t = ti;
45  n = t.size();
46  H1 = controlPoints[0];
47 
48  //[XXX] this function assumes the object was just built. We have to clear the vectors if it's not the case. Can we implement a way to add points to an existing spline ?
49  ksi.clear();
50  ksi.reserve(n);
51  bi.clear();
52  bi.reserve(n-1);
53  ci.clear();
54  ci.reserve(n);
55  di.clear();
56  di.reserve(n-1);
57 
58 
59  StdVectorDisplacement ctrlPts; ctrlPts.reserve(n);
60  StdVectorTwist alpha; alpha.reserve(n);
61  std::vector<Scalar> step; step.reserve(n - 1);
62  std::vector<Scalar> li; li.reserve(n);
63  std::vector<Scalar> mui; mui.reserve(n);
64  StdVectorTwist zi; zi.reserve(n);
65 
66  Displacement<Scalar> offset = H1.inverse();
67 
68  // cubic spline : http://en.wikipedia.org/wiki/Spline_%28mathematics%29#Algorithm_for_computing_Clamped_Cubic_Splines
69 
70  for(typename StdVectorDisplacement::const_iterator iter = controlPoints.begin(); iter != controlPoints.end(); iter++){
71  ctrlPts.push_back(offset*(*iter));
72  ksi.push_back(ctrlPts.back().log()); // [XXX]PlainObject !
73  }
74 
75  for(unsigned int i = 0; i < n - 1; i++) // n-1
76  step.push_back(t[i+1] - t[i]);
77 
78  Twist<Scalar> dksi1 = ksi[0].dexp().inverse() * controlVelocities[0];
79  alpha.push_back(3*((ksi[1] - ksi[0])/step[0] - dksi1));
80 
81  for(unsigned int i = 1; i < n - 1; i++){
82  alpha.push_back(3*((ksi[i+1] - ksi[i])/step[i] - (ksi[i] - ksi[i-1])/step[i-1]));
83  }
84 
85  Twist<Scalar> test = ksi.back();
86  Twist<Scalar> tvel = controlVelocities.back();
87 
88  Matrix<Scalar, 6, 6> tm = ksi.back().dexp().inverse();
89 
90  Twist<Scalar> tdk = tm*tvel;
91 
92  Twist<Scalar> dksin = ksi.back().dexp().inverse() * controlVelocities.back();
93  alpha.push_back(3*(dksin-(ksi.back() - ksi[n-2])/step.back()));
94 
95 
96  li.push_back(2*step[0]);
97  mui.push_back(0.5);
98  zi.push_back(alpha[0]/li[0]);
99 
100  for(unsigned int i = 1; i < n - 1; i++){
101  li.push_back(2*(t[i+1]-t[i-1]) - step[i-1]*mui[i-1]);
102  mui.push_back(step[i]/li[i]);
103  zi.push_back((alpha[i]-step[i-1]*zi[i-1])/li[i]);
104  }
105 
106  li.push_back(step[n-2]*(2 - mui[n-2]));
107  zi.push_back((alpha.back()-step[n-2]*zi[n-2])/li.back());
108 
109  ci.push_back(zi.back());
110 
111  for(unsigned int i = 1; i < n; i++){
112  ci.push_back(zi[n-i-1] - mui[n-i-1]*ci[i-1]);
113  bi.push_back((ksi[n-i]-ksi[n-i-1])/step[n-i-1]-step[n-i-1]*(ci[i-1]+2*ci[i])/3);
114  di.push_back((ci[i-1]-ci[i])/3/step[n-i-1]);
115  }
116 }
117 
118 template<typename Scalar>
119 //template<class DisplDerived, class TwistDerived>
120 //void SE3CubicInterpolator<Scalar>::Interpolate(DisplacementBase<DisplDerived>& pos, TwistBase<TwistDerived>& vel, const Scalar time) const {
122  assert(time > t[0] || time < t[n-1]); // check in release ?
123 
124  size_t k;
125  for(size_t i = 0; i < n-1; i++){
126  if(t[i] <= time)
127  k = i;
128  }
129 
130  if(k == n) k = n-1;
131 
132  Scalar dt = time-t[k];
133  Scalar dt2 = dt*dt;
134 
135  Twist<Scalar> b = bi[n-2-k];
136  Twist<Scalar> c = ci[n-1-k];
137  Twist<Scalar> d = di[n-2-k];
138 
139  Twist<Scalar> ksik = ksi[k] + bi[n-2-k]*dt + ci[n-1-k]*dt2 + di[n-2-k]*dt2*dt; // c is longer by one element
140  Twist<Scalar> dkisk = bi[n-2-k] + 2*ci[n-1-k]*dt + 3*di[n-2-k]*dt2;
141 
142  vel = ksik.dexp()*dkisk;
143  pos = H1*ksik.exp();
144 }
145 
146 #endif
void setControlPoint(const StdVectorDisplacement &controlPoints, const StdVectorTwist &controlVelocities, const std::vector< Scalar > &t)
Class describing a Twist.
Definition: Twist.h:141
void Interpolate(Displacement< Scalar > &pos, Twist< Scalar > &vel, const Scalar time) const
PlainObject inverse() const
std::vector< Scalar > t
std::vector< Displacement< Scalar >, aligned_allocator< Displacement< Scalar > > > StdVectorDisplacement
std::vector< Twist< Scalar >, aligned_allocator< Twist< Scalar > > > StdVectorTwist
Displacement< Scalar > H1


lgsm
Author(s): Roberto Martín-Martín
autogenerated on Mon Jun 10 2019 14:05:58