SE3CubicInterpolator.h
Go to the documentation of this file.
00001 // This file is part of Eigen, a lightweight C++ template library
00002 // for linear algebra.
00003 //
00004 // Copyright (C) 2009-2013 CEA LIST (DIASI/LSI) <xde-support@saxifrage.cea.fr>
00005 //
00006 // This Source Code Form is subject to the terms of the Mozilla
00007 // Public License v. 2.0. If a copy of the MPL was not distributed
00008 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
00009 
00010 #ifndef EIGEN_LGSM_GROUP_SE3_CUBIC_INTERPOLATOR_H
00011 #define EIGEN_LGSM_GROUP_SE3_CUBIC_INTERPOLATOR_H
00012 
00013 
00014 /***************************************************************************************************
00015 * Needed improvement :
00016 
00017 - severals interpolator implemented through standard or static derivation
00018 - implementing generic interpolation algorithm through template class (problem with limit conditions)
00019 
00020 *****************************************************************************************************/
00021 
00022 template<typename Scalar> class SE3CubicInterpolator{
00023 public:
00024   typedef std::vector<Displacement<Scalar>, aligned_allocator<Displacement<Scalar> > > StdVectorDisplacement;
00025   typedef std::vector<Twist<Scalar>, aligned_allocator<Twist<Scalar> > > StdVectorTwist;
00026 
00027   SE3CubicInterpolator(){}
00028 
00029   void setControlPoint(const StdVectorDisplacement& controlPoints, const StdVectorTwist& controlVelocities, const std::vector<Scalar>& t);
00030 
00031   //template<class DisplDerived, class TwistDerived>
00032   //void Interpolate(DisplacementBase<DisplDerived>& pos, TwistBase<TwistDerived>& vel, const Scalar t) const;
00033   void Interpolate(Displacement<Scalar>& pos, Twist<Scalar>& vel, const Scalar time) const;
00034 protected:
00035   std::vector<Scalar> t;
00036   Displacement<Scalar> H1;
00037   StdVectorTwist ksi;
00038   StdVectorTwist bi, ci, di; // revert order
00039   size_t n;
00040 };
00041 
00042 template<typename Scalar>
00043 void SE3CubicInterpolator<Scalar>::setControlPoint(const StdVectorDisplacement& controlPoints, const StdVectorTwist& controlVelocities, const std::vector<Scalar>& ti){ // check if ctrlpts, velocities & time are equal and > 1 
00044   t = ti;
00045   n = t.size();
00046   H1 = controlPoints[0];
00047 
00048   //[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 ?
00049   ksi.clear();
00050   ksi.reserve(n);
00051   bi.clear();
00052   bi.reserve(n-1); 
00053   ci.clear();
00054   ci.reserve(n); 
00055   di.clear();
00056   di.reserve(n-1);
00057 
00058 
00059   StdVectorDisplacement ctrlPts;  ctrlPts.reserve(n);
00060   StdVectorTwist alpha;           alpha.reserve(n);
00061   std::vector<Scalar> step;       step.reserve(n - 1);
00062   std::vector<Scalar> li;         li.reserve(n);
00063   std::vector<Scalar> mui;        mui.reserve(n);
00064   StdVectorTwist zi;              zi.reserve(n);
00065 
00066   Displacement<Scalar> offset = H1.inverse();
00067 
00068   // cubic spline : http://en.wikipedia.org/wiki/Spline_%28mathematics%29#Algorithm_for_computing_Clamped_Cubic_Splines
00069 
00070   for(typename StdVectorDisplacement::const_iterator iter = controlPoints.begin(); iter != controlPoints.end(); iter++){
00071     ctrlPts.push_back(offset*(*iter));
00072     ksi.push_back(ctrlPts.back().log()); // [XXX]PlainObject !
00073   }
00074 
00075   for(unsigned int i = 0; i < n - 1; i++) // n-1
00076     step.push_back(t[i+1] - t[i]);
00077 
00078   Twist<Scalar> dksi1 = ksi[0].dexp().inverse() * controlVelocities[0];
00079   alpha.push_back(3*((ksi[1] - ksi[0])/step[0] - dksi1));
00080 
00081   for(unsigned int i = 1; i < n - 1; i++){
00082     alpha.push_back(3*((ksi[i+1] - ksi[i])/step[i] - (ksi[i] - ksi[i-1])/step[i-1]));
00083   }
00084 
00085   Twist<Scalar> test = ksi.back();
00086   Twist<Scalar> tvel = controlVelocities.back();
00087 
00088   Matrix<Scalar, 6, 6> tm = ksi.back().dexp().inverse();
00089 
00090   Twist<Scalar> tdk = tm*tvel;
00091 
00092   Twist<Scalar> dksin = ksi.back().dexp().inverse() * controlVelocities.back();
00093   alpha.push_back(3*(dksin-(ksi.back() - ksi[n-2])/step.back()));
00094 
00095 
00096   li.push_back(2*step[0]);
00097   mui.push_back(0.5);
00098   zi.push_back(alpha[0]/li[0]);
00099 
00100   for(unsigned int i = 1; i < n - 1; i++){
00101     li.push_back(2*(t[i+1]-t[i-1]) - step[i-1]*mui[i-1]);
00102     mui.push_back(step[i]/li[i]);
00103     zi.push_back((alpha[i]-step[i-1]*zi[i-1])/li[i]);
00104   }
00105 
00106   li.push_back(step[n-2]*(2 - mui[n-2]));
00107   zi.push_back((alpha.back()-step[n-2]*zi[n-2])/li.back());
00108 
00109   ci.push_back(zi.back());
00110 
00111   for(unsigned int i = 1; i < n; i++){
00112     ci.push_back(zi[n-i-1] - mui[n-i-1]*ci[i-1]);
00113     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);
00114     di.push_back((ci[i-1]-ci[i])/3/step[n-i-1]);
00115   }
00116 }
00117 
00118 template<typename Scalar>
00119 //template<class DisplDerived, class TwistDerived>
00120 //void SE3CubicInterpolator<Scalar>::Interpolate(DisplacementBase<DisplDerived>& pos, TwistBase<TwistDerived>& vel, const Scalar time) const { 
00121 void SE3CubicInterpolator<Scalar>::Interpolate(Displacement<Scalar>& pos, Twist<Scalar>& vel, const Scalar time) const { 
00122   assert(time > t[0] || time < t[n-1]); // check in release ?
00123 
00124   size_t k;
00125   for(size_t i = 0; i < n-1; i++){
00126     if(t[i] <= time)
00127       k = i;
00128   }
00129 
00130   if(k == n) k = n-1;
00131 
00132   Scalar dt = time-t[k];
00133   Scalar dt2 = dt*dt;
00134 
00135   Twist<Scalar> b = bi[n-2-k];
00136   Twist<Scalar> c = ci[n-1-k]; 
00137   Twist<Scalar> d = di[n-2-k];
00138 
00139   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
00140   Twist<Scalar> dkisk = bi[n-2-k] + 2*ci[n-1-k]*dt + 3*di[n-2-k]*dt2;
00141 
00142   vel = ksik.dexp()*dkisk;
00143   pos = H1*ksik.exp();
00144 }
00145 
00146 #endif


lgsm
Author(s): Roberto Martín-Martín
autogenerated on Sat Jun 8 2019 18:26:30