GCOP  1.0
flatoutputtparam.h
Go to the documentation of this file.
00001 #ifndef GCOP_FLATOUTPUTTPARAM_H
00002 #define GCOP_FLATOUTPUTTPARAM_H
00003 
00004 #include "tparam.h"
00005 
00006 namespace gcop {
00007   
00008   using namespace std;
00009   using namespace Eigen;
00010 
00019   template <typename T, 
00020     int nx, 
00021     int nu,
00022     int np = Dynamic,
00023     int _ntp = Dynamic> class FlatOutputTparam : public Tparam<T, nx, nu, np, _ntp> {
00024     
00025     typedef Matrix<double, nx, 1> Vectornd;
00026     typedef Matrix<double, nu, 1> Vectorcd;
00027     typedef Matrix<double, nx, nx> Matrixnd;
00028     typedef Matrix<double, nx, nu> Matrixncd;
00029     typedef Matrix<double, nu, nx> Matrixcnd;
00030     typedef Matrix<double, nu, nu> Matrixcd;  
00031 
00032     typedef Matrix<double, np, 1> Vectormd;
00033 
00034     typedef Matrix<double, _ntp, 1> Vectorntpd;
00035 
00036   protected:
00042     //VectorXd DeCasteljau(vector<VectorXd> &s, double u, int start, int end);
00043     VectorXd DeCasteljau(vector<VectorXd> &s, double u, int start, int end)
00044     {
00045       if(start == end)
00046       {
00047         return s[start];
00048       }
00049       else
00050       {
00051         return ((1-u)*(this->DeCasteljau(s, u, start, end-1)) + u*(this->DeCasteljau(s,u,start+1,end)));
00052       }
00053     }
00054 
00059     void Createknotsforallderivatives(const Vectorntpd &s)
00060     {
00061       for(int count_derivatives = 0; count_derivatives <= numberofderivatives; count_derivatives++)
00062       {
00063         int knotsize = (numberofknots-count_derivatives)>0?(numberofknots-count_derivatives):0;
00064         for(int count_knots = 0;count_knots < knotsize; count_knots++)
00065         {
00066           
00067           if(count_derivatives == 0)
00068           {
00069             if(count_knots >= (1 + numberofderivatives) && 
00070               (!fixfinal || count_knots < numberofknots - (1 + numberofderivatives)))
00071             {
00072               knotsforallderivatives[count_derivatives][count_knots] = s.segment((count_knots-(1+numberofderivatives))*ny,ny);
00073             }
00074           }
00075           else
00076           {
00077             knotsforallderivatives[count_derivatives][count_knots] =knotsforallderivatives[count_derivatives-1][count_knots+1] - knotsforallderivatives[count_derivatives-1][count_knots];
00078           }
00079           //cout<<"knotsforallderivatives["<<count_derivatives<<"]["<<count_knots<<"]:"<<knotsforallderivatives[count_derivatives][count_knots]<<endl;
00080           //getchar();//#DEBUG
00081         }
00082       }
00083     }
00084  
00085   public:
00091     FlatOutputTparam(System<T, nx, nu, np> &sys, int ny_, int numberofknots_, int numberofderivatives_ = 0, bool fixfinal_ = false);
00092     
00093     bool To(Vectorntpd &s, 
00094             const vector<double> &ts, 
00095             const vector<T> &xs, 
00096             const vector<Vectorcd> &us,
00097             const Vectormd *p = 0);
00098     
00099     bool From(vector<double> &ts, 
00100               vector<T> &xs, 
00101               vector<Vectorcd> &us,
00102               const Vectorntpd &s,
00103               Vectormd *p = 0);
00104     
00105     int numberofderivatives;
00106     int numberofknots;
00107     int ny;
00108     vector<vector<VectorXd> > knotsforallderivatives;
00109     bool fixfinal;
00110   };
00111   
00112   template <typename T, int nx, int nu, int np, int _ntp> 
00113     FlatOutputTparam<T, nx, nu, np, _ntp>::FlatOutputTparam(System<T, nx, nu, np> &sys, int ny_, int numberofknots_, int numberofderivatives_, bool fixfinal_) :  Tparam<T, nx, nu, np, _ntp>(sys, (numberofknots_-(numberofderivatives_+1)-fixfinal_*(numberofderivatives_+1))*ny_),ny(ny_), numberofderivatives(numberofderivatives_), numberofknots(numberofknots_), fixfinal(fixfinal_)  {
00114       assert(numberofknots > 0);
00115       assert(ny >0);
00116       knotsforallderivatives.resize(numberofderivatives+1);
00117       for(int count = 0;count < numberofderivatives+1; count++)
00118       {
00119         int knotsize = numberofknots-count;
00120         knotsize = knotsize>0?knotsize:0;
00121         knotsforallderivatives[count].resize(knotsize);
00122       }
00123       knotsforallderivatives[0][0] = VectorXd::Zero(ny,1);
00124   }
00125 
00126   template <typename T, int nx, int nu, int np, int _ntp> 
00127     bool FlatOutputTparam<T, nx, nu, np, _ntp>::To(Vectorntpd &s, 
00128                                              const vector<double> &ts, 
00129                                              const vector<T> &xs, 
00130                                              const vector<Vectorcd> &us,
00131                                              const Vectormd *p) {
00132       //Evaluate the basis matrix at all the points ts:
00133       int N = us.size();
00134       double tf = ts.back();
00135       assert(N+1 > numberofknots);//Assert there are enough points for given number of knots
00136       MatrixXd basis(ny*(N+1), (numberofknots)*ny);
00137       basis.setZero();//Initialize to zero
00138       //Can do inversion separate for each ny. But have to copy back to s separately. #Not very efficient
00139       VectorXd flatoutputs((N+1)*ny);
00140       vector<VectorXd> knotvector(numberofknots);
00141       //Initialize knotvector to zeros to begin with:
00142       for(int count_knots = 0;count_knots < numberofknots; count_knots++)
00143       {
00144         knotvector[count_knots].resize(ny);
00145         knotvector[count_knots].setZero();
00146       }
00147 
00148 
00149       for(int count_knots =0; count_knots < numberofknots; count_knots++)
00150       {
00151         //Set the Knots to be e_i and evaluate across all the samples to find the basis matrix
00152         if(count_knots > 0)
00153         {
00154           knotvector[count_knots-1].setZero();
00155         }
00156         knotvector[count_knots].setConstant(1.0);
00157         
00158         for(int count_samples =0; count_samples <= N; count_samples++)
00159         {
00160           //Evaluate the Bezier curve at given ts using the above knot vector:
00161           basis.block((count_samples)*ny, (count_knots)*ny,ny,ny) = (DeCasteljau(knotvector, (ts[count_samples]/tf), 0,numberofknots-1)).asDiagonal();//The evaluation using P = e_i will be B_n,i(u_i)
00162         }
00163       }
00164 
00165       //Evaluate the flat outputs at the given states and controls:
00166       for(int count_samples = 0; count_samples < N; count_samples++)
00167       {
00168         VectorXd flatoutput;
00169         (this->sys).StateAndControlsToFlat(flatoutput, xs[count_samples], us[count_samples]);
00170         flatoutputs.segment((count_samples)*ny,ny) = flatoutput;
00171         cout<<"Flat output["<<count_samples<<"]: "<<flatoutput.transpose()<<endl;
00172       }
00173       //Tail or final state:
00174       {
00175         VectorXd flatoutput;
00176         (this->sys).StateAndControlsToFlat(flatoutput, xs[N], us[N-1]);//Copying us[N-1] for us[N] since us[N] does not exist
00177         flatoutputs.tail(ny) = flatoutput;
00178         cout<<"Flat output["<<N<<"]: "<<flatoutput.transpose()<<endl;
00179       }
00180       //getchar();//#DEBUG
00181       //cout<<"Basis: "<<endl<<basis<<endl;
00182       //Set the output knot vector(s) as basis.pseudoinverse()*flatoutputsevaluatedatallsamples
00183       VectorXd s_temp = ((basis.transpose()*basis).ldlt().solve(basis.transpose()*flatoutputs));
00184       if(fixfinal)
00185       { 
00186         assert(numberofknots-(numberofderivatives+1) >= 0);
00187         s = s_temp.segment((1+numberofderivatives)*ny, (numberofknots-2*(1+numberofderivatives))*ny);
00188       }
00189       else
00190       {
00191         s = s_temp.tail((numberofknots-(1+numberofderivatives))*ny);
00192       }
00193 
00194       cout<<"Error: "<<(basis*s_temp - flatoutputs).squaredNorm()<<endl;
00195 
00196       for(int i = 0; i < 1+numberofderivatives; i++)
00197       {
00198         knotsforallderivatives[0][i] = flatoutputs.segment(ny*i, ny);
00199       }
00200 
00201       if(fixfinal)
00202       {
00203         assert(numberofknots-(numberofderivatives+1) >= 0);
00204         for(int i = 0; i < 1+numberofderivatives; i++)
00205         {
00206           knotsforallderivatives[0][numberofknots-(i+1)] = flatoutputs.segment((flatoutputs.size()-ny*(i+1)), ny);
00207         }
00208       }
00209       cout<<"flatoutputs.head(ny) " << flatoutputs.head(ny).transpose() << endl; 
00210       cout<<"flatoutputs.tail(ny) " << flatoutputs.tail(ny).transpose() << endl; 
00211       //(this->sys).StateAndControlsToFlat(knotsforallderivatives[0][0], xs[0], us[0]);
00212 
00213       cout<<"s: "<<s.transpose()<<endl;
00214       cout<<"s_temp: "<<s_temp.transpose()<<endl;
00215       //s.setZero();
00216                         return true;
00217     }
00218   
00219   template <typename T, int nx, int nu, int np, int _ntp> 
00220     bool FlatOutputTparam<T, nx, nu, np, _ntp>::From(vector<double> &ts, 
00221                                                   vector<T> &xs, 
00222                                                   vector<Vectorcd> &us,
00223                                                   const Vectorntpd &s,
00224                                                   Vectormd *p) {
00225       assert(this->ntp == (numberofknots-(numberofderivatives+1)-fixfinal*(numberofderivatives+1))*ny);
00226       //Evaluate Flat outputs from the knot inputs (s) at all the input times ts
00227       int N = us.size();
00228       double tf = ts.back();//Replace this with deltat version #TODO
00229       vector<VectorXd> flatoutputsandderivatives(numberofderivatives+1);
00230       Createknotsforallderivatives(s);//Create all the knots before starting evaluation
00231       for(int count_ts = 0; count_ts <= N; count_ts++)
00232       {
00233         double factor_derivative = 1;
00234         for(int count_derivatives =0; count_derivatives <= numberofderivatives ; count_derivatives++)
00235         {
00236           if(numberofknots-count_derivatives>0)//If there are any derivatives to be evaluated then only go further
00237           {
00238             flatoutputsandderivatives[count_derivatives] = (factor_derivative)*(DeCasteljau(knotsforallderivatives[count_derivatives], (ts[count_ts]/tf), 0, numberofknots-count_derivatives-1));
00239             //cout<<"flatoutputandderivatives["<<count_derivatives<<"]: "<<flatoutputsandderivatives[count_derivatives]<<endl;
00240           }
00241           else
00242           {
00243             flatoutputsandderivatives[count_derivatives].resize(ny);
00244             flatoutputsandderivatives[count_derivatives].setZero();
00245           }
00246           factor_derivative *= double(numberofknots-count_derivatives)/tf;//tf is here because u = t/tf;
00247         }
00248         //getchar();
00249         //Evaluate system states and controls using the flat outputs and derivatives
00250         //cout << "flatoutputs::From: " << flatoutputsandderivatives[0].transpose() << endl;
00251         if(count_ts == 0)
00252         {
00253           T xtemp;
00254           (this->sys).FlatToStateAndControls( xtemp, us[count_ts], flatoutputsandderivatives);
00255         }
00256         else if(count_ts == N)
00257         {
00258           Vectorcd utemp;//For last point we do not care abt control
00259           (this->sys).FlatToStateAndControls( xs[count_ts], utemp, flatoutputsandderivatives);
00260         }
00261         else
00262         {
00263           (this->sys).FlatToStateAndControls( xs[count_ts], us[count_ts], flatoutputsandderivatives);
00264         }
00265         //cout<<"us["<<count_ts<<"]: "<<us[count_ts]<<endl;
00266       }
00267 
00268       //cout<<"s: "<<s.transpose()<<endl;
00269                         return true;
00270     }
00271     
00272 }
00273 
00274 #endif