GCOP
1.0
|
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