GCOP  1.0
splinetparam.h
Go to the documentation of this file.
00001 #ifndef GCOP_SPLINETPARAM_H
00002 #define GCOP_SPLINETPARAM_H
00003 
00004 #include "tparam.h"
00005 #include <unsupported/Eigen/Splines>
00006 
00007 namespace gcop {
00008   
00009   using namespace std;
00010   using namespace Eigen;
00011 
00018   template <typename T, 
00019     int nx, 
00020     int nu,
00021     int np = Dynamic,
00022     int _ntp = Dynamic> class SplineTparam : public Tparam<T, nx, nu, np, _ntp> {
00023     
00024     typedef Matrix<double, nx, 1> Vectornd;
00025     typedef Matrix<double, nu, 1> Vectorcd;
00026     typedef Matrix<double, nx, nx> Matrixnd;
00027     typedef Matrix<double, nx, nu> Matrixncd;
00028     typedef Matrix<double, nu, nx> Matrixcnd;
00029     typedef Matrix<double, nu, nu> Matrixcd;  
00030 
00031     typedef Matrix<double, np, 1> Vectormd;
00032 
00033     typedef Matrix<double, _ntp, 1> Vectorntpd;
00034 
00035     typedef Spline<double, nu> ControlSpline;
00036  
00037   public:
00043     SplineTparam(System<T, nx, nu, np> &sys, const VectorXd tks, int degree = 2);//By default use quadratic spline
00044     
00045     bool To(Vectorntpd &s, 
00046             const vector<double> &ts, 
00047             const vector<T> &xs, 
00048             const vector<Vectorcd> &us,
00049             const Vectormd *p = 0);
00050     
00051     bool From(vector<double> &ts, 
00052               vector<T> &xs, 
00053               vector<Vectorcd> &us,
00054               const Vectorntpd &s,
00055               Vectormd *p = 0);
00056     
00057     VectorXd tks;  
00058     double tf;
00059     int degree; 
00060   };
00061   
00062   template <typename T, int nx, int nu, int np, int _ntp> 
00063     SplineTparam<T, nx, nu, np, _ntp>::SplineTparam(System<T, nx, nu, np> &sys, const VectorXd tks, int degree) :  Tparam<T, nx, nu, np, _ntp>(sys, tks.size()*sys.U.n), tks(tks), degree(degree) {
00064       //normalize tks from 0 to 1
00065       assert(tks.size() > degree+1);//Make sure there are enough points
00066       tf = this->tks(tks.size()-1);//Last element
00067       //Assuming  increasing order normalize so that last element is 1.0:
00068       (this->tks) /= tf;
00069       this->tks(tks.size()-1) = 1.0;//Redundancy
00070       cout<<"tks: "<<tks.transpose()<<endl;
00071   }
00072 
00073   template <typename T, int nx, int nu, int np, int _ntp> 
00074     bool SplineTparam<T, nx, nu, np, _ntp>::To(Vectorntpd &s, 
00075                                              const vector<double> &ts, 
00076                                              const vector<T> &xs, 
00077                                              const vector<Vectorcd> &us,
00078                                              const Vectormd *p) {
00079       //Find control points(uks) given us
00080       int m = degree + 1 + tks.size();//Number of knots
00081       int nofsegments = m - 2*(degree+1)+1;
00082       assert(nofsegments > 0);
00083       //Create knot vector:
00084       VectorXd knotVector(m);
00085       KnotAveraging(tks, degree, knotVector);
00086       //cout<<"knotvector: "<<knotVector.transpose()<<endl;
00087       //cout<<"tks: "<<tks.transpose()<<endl;
00088 
00089       //Initialize variables for least square fit; Fitting each control dimension separately
00090       MatrixXd A(us.size(), tks.size());//Basis Matrix
00091       MatrixXd Asquare(tks.size(), tks.size());//Basis Matrix
00092       VectorXd c(us.size());//RHS 
00093       A.setZero();//Initialize A
00094       //VectorXd b(tks.size());//control points
00095 
00096       //Find Basis Matrix to find the control points:
00097       double tdiff = ts.back() - ts.front();
00098       for(int ind = 0;ind < us.size(); ind++)
00099       {
00100         double ts_normalized = (ts[ind] - ts[0])/tdiff;
00101         int index = ControlSpline::Span(ts_normalized, degree, knotVector);
00102         VectorXd basisFcns = ControlSpline::BasisFunctions(ts_normalized, degree, knotVector);
00103        // cout<<"Index: "<<index<<endl;
00104         //cout<<"BasisFcns: "<<basisFcns.transpose()<<endl;
00105         A.block(ind, index-degree, 1, degree+1) = basisFcns.transpose();//Create Basis Matrix
00106       }
00107       Asquare = (A.transpose()*A);
00108       //cout<<"A: "<<endl<<A<<endl;
00109       //cout<<"Asquare: "<<endl<<Asquare<<endl;
00110       //getchar();
00111       for(int ind = 0; ind < nu; ind++)
00112       {
00113         for(int uind = 0; uind < us.size(); uind++)
00114         {
00115           c(uind) = us[uind](ind);
00116         }
00117         VectorXd b = Asquare.ldlt().solve(A.transpose()*c);
00118         cout<<"Error: "<<(A*b - c).squaredNorm()<<endl;
00119       //  cout<<"c: "<<c.transpose()<<endl;
00120         //cout<<"b: "<<b.transpose()<<endl;
00121         //Copy the elements back into vector s:
00122         for(int sind = 0; sind < tks.size(); sind++)
00123         {
00124           s(sind*nu + ind) = b(sind);
00125         }
00126       }
00127       cout<<"s: "<<s.transpose()<<endl;
00128       //Verify if this s is good:
00129       /*{
00130         MatrixXd controlMatrix(this->sys.U.n, tks.size());
00131         for(int cs = 0; cs < tks.size(); cs++)
00132         {
00133           controlMatrix.col(cs) = s.segment(cs*nu, nu);//Fill Control Matrix
00134         }
00135         ControlSpline cspline = SplineFitting<ControlSpline>::Interpolate(controlMatrix, degree, tks);
00136         for (int i = 0; i < us.size(); ++i) {
00137           Vectorcd usbar = cspline((ts[i] - ts[0])/tdiff);
00138           cout<<"us_pred["<<i<<"]: "<<usbar.transpose()<<"ts: "<<ts[i]<<endl;
00139           cout<<"us_actual["<<i<<"]: "<<us[i].transpose()<<"ts: "<<ts[i]<<endl;
00140         }
00141         getchar();
00142       }
00143       */
00144 
00145       //s.setZero();
00146       return true;
00147     }
00148   
00149   template <typename T, int nx, int nu, int np, int _ntp> 
00150     bool SplineTparam<T, nx, nu, np, _ntp>::From(vector<double> &ts, 
00151                                                   vector<T> &xs, 
00152                                                   vector<Vectorcd> &us,
00153                                                   const Vectorntpd &s,
00154                                                   Vectormd *p) {
00155  
00156 
00157     assert(this->ntp == tks.size()*this->sys.U.n);
00158 
00159     //Create knot matrix:
00160     MatrixXd controlMatrix(this->sys.U.n, tks.size());
00161     for(int cs = 0; cs < tks.size(); cs++)
00162     {
00163       controlMatrix.col(cs) = s.segment(cs*nu, nu);//Fill Control Matrix
00164     }
00165     //cout<<"s: "<<s.transpose()<<endl;//Input control points
00166     //cout<<"Control Matrix: "<<endl<<controlMatrix<<endl;
00167     ControlSpline cspline = SplineFitting<ControlSpline>::Interpolate(controlMatrix, degree, tks);
00168     double tdiff = ts.back() - ts.front();
00169     
00170     this->sys.Reset(xs[0],ts[0]);
00171     for (int i = 0; i < us.size(); ++i) {
00172       us[i] = cspline((ts[i] - ts[0])/tdiff);
00173       //cout<<"ts["<<i<<"]: "<<ts[i]<<endl;
00174       //cout<<"us["<<i<<"]: "<<us[i].transpose()<<"ts: "<<ts[i]<<endl;
00175       this->sys.Step(xs[i+1], us[i], ts[i+1] - ts[i], p);
00176       //cout<<"Xs["<<(i+1)<<"]"<<xs[i+1].transpose()<<endl; #DEBUG
00177       //cout<<"us["<<i<<"]"<<us[i].transpose()<<endl;
00178     }
00179     //getchar();
00180     return true;
00181   }
00182 }
00183 
00184 #endif