GCOP
1.0
|
00001 #ifndef GCOP_LQSENSORCOST_H 00002 #define GCOP_LQSENSORCOST_H 00003 00004 #include <limits> 00005 #include "lssensorcost.h" 00006 #include <iostream> 00007 00008 namespace gcop { 00009 00010 using namespace std; 00011 using namespace Eigen; 00012 00013 template <typename T = VectorXd, 00014 int _nx = Dynamic, 00015 int _nu = Dynamic, 00016 int _np = Dynamic, 00017 int _ng = Dynamic, 00018 typename Tz = VectorXd, 00019 int _nz = Dynamic> class LqSensorCost : public LsSensorCost<T, _nx, _nu, _np, _ng, Tz, _nz> { 00020 public: 00021 00022 typedef Matrix<double, _ng, 1> Vectorgd; 00023 typedef Matrix<double, _ng, _nx> Matrixgxd; 00024 typedef Matrix<double, _ng, _nu> Matrixgud; 00025 typedef Matrix<double, _ng, _np> Matrixgpd; 00026 typedef Matrix<double, _ng, _nz> Matrixgzd; 00027 00028 typedef Matrix<double, _nx, 1> Vectornd; 00029 typedef Matrix<double, _nu, 1> Vectorcd; 00030 typedef Matrix<double, _np, 1> Vectormd; 00031 00032 typedef Matrix<double, _nx, _nx> Matrixnd; 00033 typedef Matrix<double, _nx, _nu> Matrixncd; 00034 typedef Matrix<double, _nu, _nx> Matrixcnd; 00035 typedef Matrix<double, _nu, _nu> Matrixcd; 00036 00037 // typedef Matrix<double, Dynamic, 1> Vectormd; 00038 typedef Matrix<double, _np, _np> Matrixmd; 00039 typedef Matrix<double, _nx, _np> Matrixnmd; 00040 typedef Matrix<double, _np, _nx> Matrixmnd; 00041 00042 typedef Matrix<double, _nz, 1> Vectorrd; 00043 typedef Matrix<double, _nz, _nz> Matrixrd; 00044 typedef Matrix<double, _nz, _nx> Matrixrnd; 00045 typedef Matrix<double, _nz, _nu> Matrixrcd; 00046 typedef Matrix<double, _nz, _np> Matrixrmd; 00047 00056 LqSensorCost(System<T, _nx, _nu, _np> & sys, Manifold<Tz, _nz> &Z, bool diag = true); 00057 00062 void UpdateGains(); 00063 00064 double L(double t, const Tz &z, const Vectornd &w, 00065 const Vectormd &p, double h, int sensor_index, 00066 Vectornd *Lw = 0, Matrixnd* Lww = 0, 00067 Vectormd *Lp = 0, Matrixmd* Lpp = 0, 00068 Vectorrd *Lz = 0, Matrixrd* Lzz = 0, 00069 Matrixmnd *Lpw = 0, Matrixrnd* Lzw = 0, Matrixrmd* Lzp = 0); 00070 00071 double Lp(const Vectormd &p, 00072 Vectormd *Lp = 0, Matrixmd *Lpp = 0); 00073 00074 bool Res(Vectorgd &g, 00075 double t, const Tz &z, 00076 const Vectornd &w, const Vectormd &p, 00077 double h, int sensor_index, 00078 Matrixgxd *dgdw = 0, Matrixgpd *dgdp = 0, 00079 Matrixgzd *dgdz = 0); 00080 00081 bool Resp(Vectormd &gp, 00082 const Vectormd &p, 00083 Matrixmd *dgdp = 0); 00089 void SetReference(const vector<Tz> *zs, Vectormd *mup = 0); 00090 00091 //const Tz &zf; ///< reference to a desired final state 00092 00093 bool diag; 00094 00095 Matrixrd R; 00096 Matrixnd S; 00097 Matrixmd P; 00098 00099 Matrixnd Ssqrt; 00100 Matrixrd Rsqrt; 00101 Matrixmd Psqrt; 00102 00103 const vector<Tz> *zs; 00104 Vectormd *mup; 00105 00106 protected: 00107 00108 Vectorrd dz; 00109 Vectormd dp; 00110 }; 00111 00112 template <typename T, int _nx, int _nu, int _np, int _ng, typename Tz, int _nz> 00113 LqSensorCost<T, _nx, _nu, _np, _ng, Tz, _nz>::LqSensorCost( 00114 System<T, _nx, _nu, _np> &sys, 00115 Manifold<Tz, _nz> &Z, 00116 bool diag) : 00117 LsSensorCost<T, _nx, _nu, _np, _ng, Tz, _nz>(sys, Z, sys.X.n + Z.n + sys.P.n), diag(diag) { 00118 00119 if (_nz == Dynamic || _nx == Dynamic || _np == Dynamic) { 00120 R.resize(Z.n, Z.n); 00121 S.resize(sys.X.n, sys.X.n); 00122 P.resize(sys.P.n, sys.P.n); 00123 00124 Rsqrt.resize(Z.n, Z.n); 00125 Ssqrt.resize(sys.X.n, sys.X.n); 00126 Psqrt.resize(sys.P.n, sys.P.n); 00127 00128 dp.resize(sys.P.n); 00129 } 00130 00131 R.setIdentity(); 00132 S.setIdentity(); 00133 P.setZero();//Initial guess for parameters should be no prior 00134 00135 UpdateGains(); 00136 00137 zs = 0; 00138 mup = 0; 00139 } 00140 00141 template <typename T, int _nx, int _nu, int _np, int _ng, typename Tz, int _nz> 00142 void LqSensorCost<T, _nx, _nu, _np, _ng, Tz, _nz>::UpdateGains() { 00143 Rsqrt = R.array().sqrt(); 00144 Ssqrt = S.array().sqrt(); 00145 Psqrt = P.array().sqrt(); 00146 } 00147 00148 00149 template <typename T, int _nx, int _nu, int _np, int _ng, typename Tz, int _nz> 00150 void LqSensorCost<T, _nx, _nu, _np, _ng, Tz, _nz>::SetReference(const vector<Tz> *zs, Vectormd *mup) { 00151 this->zs = zs; 00152 //this->mup = mup; 00153 if(mup) 00154 { 00155 this->mup = new VectorXd(mup->size()); 00156 *(this->mup) = *mup;//Copy the vector over 00157 } 00158 //Add assert statments to make sure there are enough measurements and parameters#TODO 00159 } 00160 00161 template <typename T, int _nx, int _nu, int _np, int _ng, typename Tz, int _nz> 00162 bool LqSensorCost<T, _nx, _nu, _np, _ng, Tz, _nz>::Res(Vectorgd &g, 00163 double t, const Tz &z, 00164 const Vectornd &w, const Vectormd &p, 00165 double h,int sensor_index, 00166 Matrixgxd *dgdw, Matrixgpd *dgdp, 00167 Matrixgzd *dgdz) 00168 { 00169 assert(g.size() == this->sys.X.n + this->sys.P.n + this->Z.n); 00170 00171 int &nw = this->sys.X.n; 00172 int &nz = this->Z.n; 00173 int &np = this->sys.P.n; 00174 00175 assert(h > 0); 00176 //int k = round(t/h); 00177 if (zs) { 00178 assert(sensor_index < zs->size()); 00179 this->Z.Lift(dz, (*zs)[sensor_index], z); // difference (on a vector space we have dx = x - xf) 00180 //std::cout<<"dz: "<<dz.transpose()<<"\t"<<t<<"\t"<<h<<endl; 00181 //std::cout<<"zs["<<k<<"]: "<<(*zs)[k].transpose()<<endl; 00182 //std::cout<<"z["<<k<<"]: "<<z.transpose()<<endl; 00183 } 00184 //cout<<"zs["<<sensor_index<<"]: "<<(*zs)[sensor_index].transpose()<<"\t"<<z.transpose()<<endl; 00185 //getchar(); 00186 assert(!std::isnan(dz[0])); 00187 00188 if (diag) 00189 { 00190 g.head(nw) = Ssqrt.diagonal().cwiseProduct(sqrt(h)*w); 00191 g.segment(nw, nz) = Rsqrt.diagonal().cwiseProduct(sqrt(h)*dz); 00192 // cout<<"w: "<<w.transpose()<<endl; 00193 } 00194 else 00195 { 00196 g.head(nw) = Ssqrt*(sqrt(h)*w); 00197 g.segment(nw, nz) = Rsqrt*(sqrt(h)*dz); 00198 } 00199 g.tail(np).setZero(); 00200 //cout<<"g: "<<g.transpose()<<endl; 00201 00202 return true; 00203 } 00204 00205 template <typename T, int _nx, int _nu, int _np, int _ng, typename Tz, int _nz> 00206 bool LqSensorCost<T, _nx, _nu, _np, _ng, Tz, _nz>::Resp(Vectormd &gp, 00207 const Vectormd &p, 00208 Matrixmd *dgdp) 00209 { 00210 if (mup) { 00211 dp = p - *mup;//Error 00212 } 00213 else 00214 dp = p; 00215 00216 if(diag) 00217 { 00218 gp = Psqrt.diagonal().cwiseProduct(dp); 00219 } 00220 else 00221 { 00222 gp = Psqrt*dp; 00223 } 00224 } 00225 00226 template <typename T, int _nx, int _nu, int _np, int _ng, typename Tz, int _nz> 00227 double LqSensorCost<T, _nx, _nu, _np, _ng, Tz, _nz>::L(double t, const Tz &z, const Vectornd &w, 00228 const Vectormd &p, double h, int sensor_index, 00229 Vectornd *Lw, Matrixnd* Lww, 00230 Vectormd *Lp, Matrixmd* Lpp, 00231 Vectorrd *Lz, Matrixrd* Lzz, 00232 Matrixmnd *Lpw, Matrixrnd* Lzw, Matrixrmd* Lzp) 00233 { 00234 //int k = (int)(t/h); 00235 00236 if (zs) { 00237 assert(sensor_index < zs->size()); 00238 this->Z.Lift(dz, (*zs)[sensor_index], z); // difference (on a vector space we have dx = x - xf) 00239 } 00240 assert(!std::isnan(dz[0])); 00241 00242 if (Lz) 00243 if (diag) 00244 *Lz = R.diagonal().cwiseProduct(h*dz); 00245 else 00246 *Lz = R*(h*dz); 00247 00248 if (Lzz) 00249 *Lzz = h*R; 00250 00251 if (Lw) 00252 if (diag) 00253 *Lw = S.diagonal().cwiseProduct(h*w); 00254 else 00255 *Lw = S*(h*w); 00256 00257 if (Lww) 00258 *Lww = h*S; 00259 00260 if(Lp) 00261 Lp->setZero(); 00262 00263 if(Lpp) 00264 Lpp->setZero(); 00265 00266 if (Lzw) 00267 Lzw->setZero(); 00268 00269 if(Lzp) 00270 Lzp->setZero(); 00271 00272 if(Lpw) 00273 Lpw->setZero(); 00274 00275 if (diag) 00276 return h*(dz.dot(R.diagonal().cwiseProduct(dz))/2 + w.dot(S.diagonal().cwiseProduct(w)))/2; 00277 else 00278 return h*(dz.dot(R*dz) + w.dot(S*w))/2; 00279 return 0; 00280 } 00281 00282 template <typename T, int _nx, int _nu, int _np, int _ng, typename Tz, int _nz> 00283 double LqSensorCost<T, _nx, _nu, _np, _ng, Tz, _nz>::Lp(const Vectormd &p, 00284 Vectormd *Lp, Matrixmd *Lpp) 00285 { 00286 if(mup) 00287 dp = p - *mup; 00288 else 00289 dp = p; 00290 00291 if (Lp) 00292 if (diag) 00293 *Lp = P.diagonal().cwiseProduct(dp); 00294 else 00295 *Lp = P*dp; 00296 00297 if (Lpp) 00298 *Lpp = P; 00299 00300 if (diag) 00301 return dp.dot(P.diagonal().cwiseProduct(dp))/2; 00302 else 00303 return dp.dot(P*dp)/2; 00304 } 00305 00306 } 00307 00308 00309 #endif