GCOP  1.0
lqsensorcost.h
Go to the documentation of this file.
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