GCOP
1.0
|
00001 #ifndef GCOP_GNDOEP1_H 00002 #define GCOP_GNDOEP1_H 00003 00004 #include "doep.h" 00005 #include "lqsensorcost.h" 00006 00007 #include <unsupported/Eigen/NonLinearOptimization> 00008 00009 namespace gcop { 00010 00011 00012 using namespace std; 00013 using namespace Eigen; 00014 00015 00016 template <typename T, 00017 int _nx, 00018 int _nu, 00019 int _np, 00020 int _ng, 00021 typename Tz, 00022 int _nz, 00023 typename T1, 00024 int _nx1> class GnCost; 00025 00026 template <typename T = VectorXd, 00027 int _nx = Dynamic, 00028 int _nu = Dynamic, 00029 int _np = Dynamic, 00030 int _ng = Dynamic, 00031 typename Tz = VectorXd, 00032 int _nz = Dynamic, 00033 typename T1 = T, 00034 int _nx1 = _nx> 00035 class GnDoep1 : public Doep<T, _nx, _nu, _np, Tz, _nz, T1, _nx1> { 00036 00037 typedef Matrix<double, _ng, 1> Vectorgd; 00038 typedef Matrix<double, _ng, _nx> Matrixgxd; 00039 typedef Matrix<double, _ng, _nu> Matrixgud; 00040 typedef Matrix<double, _ng, _np> Matrixgpd; 00041 00042 typedef Matrix<double, _nx, 1> Vectornd; 00043 typedef Matrix<double, _nu, 1> Vectorcd; 00044 00045 typedef Matrix<double, _nx, _nx> Matrixnd; 00046 typedef Matrix<double, _nx, _nu> Matrixncd; 00047 typedef Matrix<double, _nu, _nx> Matrixcnd; 00048 typedef Matrix<double, _nu, _nu> Matrixcd; 00049 00050 typedef Matrix<double, _np, 1> Vectormd; 00051 00052 typedef Matrix<double, _np, _np> Matrixmd; 00053 typedef Matrix<double, _nx, _np> Matrixnmd; 00054 typedef Matrix<double, _np, _nx> Matrixmnd; 00055 00056 typedef Matrix<double, _nz, 1> Vectorrd; 00057 typedef Matrix<double, _nz, _nz> Matrixrd; 00058 typedef Matrix<double, _nz, _nx> Matrixrnd; 00059 typedef Matrix<double, _nz, _nu> Matrixrcd; 00060 typedef Matrix<double, _nz, _np> Matrixrmd; 00061 00062 typedef void(*Func_type)(const T &, T1 &); 00063 00064 public: 00093 GnDoep1(System<T, _nx, _nu, _np> &sys, Sensor<T1, _nx1, _nu, _np, Tz, _nz> &sensor, 00094 LqSensorCost<T, _nx, _nu, _np, _ng, Tz, _nz> &cost, 00095 vector<double> &ts, vector<T> &xs, vector<Vectorcd> &us, Vectormd &p, 00096 vector<double> &ts1, Func_type _project=NULL, bool update = true); 00097 00098 virtual ~GnDoep1(); 00099 00104 void Iterate(); 00105 00106 int info; 00107 double fnorm, covfac; 00108 00109 int inputs; 00110 int values; 00111 00112 VectorXd s; 00113 00114 GnCost<T, _nx, _nu, _np, _ng, Tz, _nz, T1, _nx1> *functor; 00115 NumericalDiff<GnCost<T, _nx, _nu, _np, _ng, Tz, _nz, T1, _nx1> > *numDiff; 00116 LevenbergMarquardt<NumericalDiff<GnCost<T, _nx, _nu, _np, _ng, Tz, _nz, T1, _nx1> > > *lm; 00117 }; 00118 00119 00120 // Generic functor 00121 template<typename _Scalar, int NX=Dynamic, int NY=Dynamic> 00122 struct Functor 00123 { 00124 typedef _Scalar Scalar; 00125 enum { 00126 InputsAtCompileTime = NX, 00127 ValuesAtCompileTime = NY 00128 }; 00129 typedef Matrix<Scalar,InputsAtCompileTime,1> InputType; 00130 typedef Matrix<Scalar,ValuesAtCompileTime,1> ValueType; 00131 typedef Matrix<Scalar,ValuesAtCompileTime,InputsAtCompileTime> JacobianType; 00132 00133 const int m_inputs, m_values; 00134 00135 Functor() : m_inputs(InputsAtCompileTime), m_values(ValuesAtCompileTime) {} 00136 Functor(int inputs, int values) : m_inputs(inputs), m_values(values) {} 00137 00138 int inputs() const { return m_inputs; } 00139 int values() const { return m_values; } 00140 00141 // you should define that in the subclass : 00142 // void operator() (const InputType& x, ValueType* v, JacobianType* _j=0) const; 00143 }; 00144 00145 00146 template <typename T, 00147 int _nx = Dynamic, 00148 int _nu = Dynamic, 00149 int _np = Dynamic, 00150 int _ng = Dynamic, 00151 typename Tz=VectorXd, 00152 int _nz = Dynamic, 00153 typename T1 = T, 00154 int _nx1 = _nx> 00155 struct GnCost : Functor<double> { 00156 GnCost<T, _nx, _nu, _np, _ng, Tz, _nz, T1, _nx1>(int inputs, int values) : Functor<double>(inputs, values) {}; 00157 00158 GnDoep1<T, _nx, _nu, _np, _ng, Tz, _nz, T1, _nx1> *doep; 00159 00160 typedef Matrix<double, _nx, 1> Vectornd; 00161 typedef Matrix<double, _np, 1> Vectormd; 00162 typedef Matrix<double, _nu, 1> Vectorcd; 00163 typedef Matrix<double, _ng, 1> Vectorgd; 00164 typedef Matrix<double, _nz, 1> Vectorrd; 00165 00166 int operator()(const VectorXd &s, VectorXd &fvec) const 00167 { 00168 assert(doep); 00169 00170 const int &np = doep->sys.P.n; 00171 const int &nz = doep->sensor.Z.n; 00172 const int &nw = doep->sys.X.n; 00173 const int N = doep->us.size(); 00174 00175 //Update inputs: process noise ws[i], p: 00176 doep->p = s; 00177 //Update sensor measurements using the input parameters and noise ws: 00178 doep->Update(false); 00179 00180 Vectorgd &g = ((LsSensorCost<T, _nx, _nu, _np, _ng, Tz, _nz>&)doep->cost).g; 00181 Vectormd &gp = ((LsSensorCost<T, _nx, _nu, _np, _ng, Tz, _nz>&)doep->cost).gp; 00182 fvec.tail(np).setZero(); 00183 00184 //Compute and set residuals 00185 int i = 0; 00186 int sensor_index = 0; 00187 for(int k = 0; k< N; ++k) 00188 { 00189 double h = doep->ts[k+1] - doep->ts[k]; 00190 //getchar(); 00191 while((doep->ts1[sensor_index] - doep->ts[k])>= 0 && (doep->ts1[sensor_index] - doep->ts[k+1]) < 0)//Nearest state to find the sensor measurement 00192 { 00193 ((LqSensorCost<T, _nx, _nu, _np, _ng, Tz, _nz>&)doep->cost).Res(g, doep->ts[k], doep->zs[sensor_index], doep->ws[k], doep->p, h, sensor_index); 00194 fvec.segment(i,nz) = g.segment(nw,nz); 00195 i += nz; 00196 sensor_index = sensor_index < (doep->ts1.size()-1)?sensor_index+1:sensor_index; 00197 if(sensor_index == (doep->ts1.size()-1)) 00198 break; 00199 fvec.tail(np) += g.tail(np);//The tail is a constant residual for parameters 00200 } 00201 //cout<<"doep->ts: "<<(doep->ts1[sensor_index])<<"\t"<<(doep->ts[k])<<"\t"<<(doep->ts[k+1])<<endl; 00202 //getchar(); 00203 //cout<<"Res: "<<g<<endl; 00204 //cout<<"i: "<<i<<endl; 00205 } 00206 assert(sensor_index == (doep->ts1.size()-1));//Assert that we collected all the sensor data 00207 ((LqSensorCost<T, _nx, _nu, _np, _ng, Tz, _nz>&)doep->cost).Resp(gp, doep->p); 00208 fvec.tail(np) += gp; 00209 //cout<<"Gp: "<<gp<<endl;//#DEBUG 00210 00211 if(doep->debug) 00212 { 00213 std::cout<<"Input: "<<s.transpose()<<endl; 00214 std::cout<<"Fvec: "<<fvec.transpose()<<endl; 00215 //std::cout<<"Resp: "<<fvec.tail(np).transpose()<<"\t"<<doep->p<<endl; 00216 } 00217 std::cout<<"Cost: "<<0.5*(fvec.transpose()*fvec)<<endl; 00218 return 0; 00219 } 00220 }; 00221 00222 using namespace std; 00223 using namespace Eigen; 00224 00225 template <typename T, int _nx, int _nu, int _np, int _ng, typename Tz, int _nz, typename T1, int _nx1> 00226 GnDoep1<T, _nx, _nu, _np, _ng, Tz, _nz, T1, _nx1>::GnDoep1(System<T, _nx, _nu, _np> &sys, Sensor<T1, _nx1, _nu, _np, Tz, _nz> &sensor, 00227 LqSensorCost<T, _nx, _nu, _np, _ng, Tz, _nz> &cost, 00228 vector<double> &ts, 00229 vector<T> &xs, 00230 vector<Vectorcd > &us, 00231 Vectormd &p, 00232 vector<double> &ts1, 00233 Func_type _project, 00234 bool update) : 00235 Doep<T, _nx, _nu, _np, Tz, _nz, T1, _nx1>(sys, sensor, cost, ts, xs, us, p, ts1, _project, false), 00236 inputs(sys.P.n), 00237 values((sensor.Z.n)*ts1.size()+sys.P.n), s(inputs), 00238 functor(0), numDiff(0), lm(0) 00239 { 00240 cout <<"inputs=" <<inputs<<" values= "<<values<< endl; 00241 if(update) 00242 { 00243 this->Update(false); 00244 } 00245 } 00246 00247 template <typename T, int _nx, int _nu, int _np, int _ng, typename Tz, int _nz, typename T1, int _nx1> 00248 GnDoep1<T, _nx, _nu, _np, _ng, Tz, _nz, T1, _nx1>::~GnDoep1() 00249 { 00250 delete lm; 00251 delete numDiff; 00252 delete functor; 00253 } 00254 00255 template <typename T, int _nx, int _nu, int _np, int _ng, typename Tz, int _nz, typename T1, int _nx1> 00256 void GnDoep1<T, _nx, _nu, _np, _ng, Tz, _nz, T1, _nx1>::Iterate() { 00257 00258 if (!lm) { 00259 functor = new GnCost<T, _nx, _nu, _np, _ng, Tz, _nz, T1, _nx1>(inputs, values); 00260 functor->doep = this; 00261 numDiff = new NumericalDiff<GnCost<T, _nx, _nu, _np, _ng, Tz, _nz, T1, _nx1> >(*functor,1e-12); 00262 lm = new LevenbergMarquardt<NumericalDiff<GnCost<T, _nx, _nu, _np, _ng, Tz, _nz, T1, _nx1> > >(*numDiff); 00263 00264 //Set doep noise to zero redundancy: 00265 for(int i = 0;i<(this->ws.size());i++) 00266 this->ws[i].setZero(); 00267 00268 const int &np = this->sys.P.n; 00269 s = this->p;//Set the system parameters to initial guess 00270 } 00271 00272 /* 00273 for (int i = 0, k = 0; k < this->us.size(); ++k) { 00274 memcpy(s.data() + i, this->us[k].data(), this->sys.U.n*sizeof(double)); 00275 i += this->sys.U.n; 00276 } 00277 */ 00278 00279 // lm.parameters.maxfev=10000; 00280 info = lm->minimize(s); 00281 00282 cout <<"info="<<info <<endl; 00283 // check return values 00284 // VERIFY_IS_EQUAL(info, 1); 00285 // VERIFY_IS_EQUAL(lm.nfev(), 26); 00286 } 00287 } 00288 00289 #endif