GCOP  1.0
mbslqcost.h
Go to the documentation of this file.
00001 #ifndef GCOP_MBSLQCOST_H
00002 #define GCOP_MBSLQCOST_H
00003 
00004 #include "mbsmanifold.h"
00005 #include "lqcost.h"
00006 
00007 namespace gcop {
00008   
00009   using namespace std;
00010   using namespace Eigen;
00011   
00012   template <int nb, int c> class MbsLqCost : public LqCost<MbsState<nb>, MBS_DIM(nb), c> {
00013 
00014     typedef Matrix<double, MBS_DIM(nb), 1> Vectornd;
00015     typedef Matrix<double, MBS_DIM(nb), MBS_DIM(nb)> Matrixnd;
00016     typedef Matrix<double, c, 1> Vectorcd;
00017     typedef Matrix<double, c, c> Matrixcd;
00018     typedef Matrix<double, MBS_DIM(nb), c> Matrixncd;
00019     
00020   public:
00021     
00022     MbsLqCost(double tf, const MbsState<nb> &xf, bool diag = true);
00023     
00024     double L(double t, const MbsState<nb> &x, const Vectorcd &u,
00025              Vectornd *Lx = 0, Matrixnd *Lxx = 0,
00026              Vectorcd *Lu = 0, Matrixcd *Luu = 0,
00027              Matrixncd *Lxu = 0);
00028   };  
00029   
00030   template <int nb, int c> MbsLqCost<c>::MbsLqCost(double tf, const MbsState<nb> &xf, bool diag) : 
00031     LqCost<MbsState<nb>, MBS_DIM(nb), c>(MbsManifold<nb>::Instance(), tf, xf, diag) {
00032    
00033     this->Qf.diagonal() = Matrix<double, MBS_DIM(nb), 1>::Constant(1);
00034     this->R.diagonal() = Matrix<double, c, 1>::Constant(.1);
00035   }
00036   
00037   template <int nb, int c>
00038     double MbsLqCost<nb, c>::L(double t, const MbsState<nb> &x, const Matrix<double, c, 1> &u,
00039                                Matrix<double, MBS_DIM(nb), 1> *Lx, Matrix<double, MBS_DIM(nb), MBS_DIM(nb)> *Lxx,
00040                                Matrix<double, c, 1> *Lu, Matrix<double, c, c> *Luu,
00041                                Matrix<double, MBS_DIM(nb), c> *Lxu) {
00042     
00043     Matrix<double, MBS_DIM(nb), 1> dx;
00044     this->X.Lift(dx, this->xf, x);
00045     
00046     // check if final state
00047     if (t > this->tf - 1e-10) {
00048       if (Lx) {
00049         if (this->diag)
00050           *Lx = this->Qf.diagonal().cwiseProduct(dx);
00051         else
00052           *Lx = this->Qf*dx;
00053         
00054         // add dcayinv if this->Q(1:3,1:3) != a*Id
00055         //      (*Lx).head(3) = Rt*(*Lx).head<3>();
00056       }
00057       if (Lxx) {
00058         *Lxx = this->Qf;
00059         //      (*Lxx).topLeftCorner(3,3) = Rt*(*Lxx).topLeftCorner<3,3>()*R;
00060       }
00061       
00062       if (Lu)
00063         Lu->setZero();
00064       if (Luu)
00065         Luu->setZero();
00066       if (Lxu)
00067         Lxu->setZero();
00068       
00069       if (this->diag)
00070         return dx.dot(this->Qf.diagonal().cwiseProduct(dx))/2;
00071       else
00072         return dx.dot(this->Qf*dx)/2;
00073       
00074     } else {
00075       if (Lx) {
00076         if (this->diag)
00077           *Lx = this->Q.diagonal().cwiseProduct(dx);
00078         else
00079           *Lx = this->Q*dx;
00080         //      (*Lx).head<3>() = Rat*(*Lx).head<3>();
00081       }
00082       if (Lxx) {
00083         *Lxx = this->Q;
00084         //      (*Lxx).topLeftCorner<3,3>() = Rt*this->Q.topLeftCorner<3,3>()*R;
00085       }
00086       if (Lu)
00087         if (this->diag)
00088           *Lu = this->R.diagonal().cwiseProduct(u);
00089         else
00090           *Lu = this->R*u;
00091       
00092       if (Luu)
00093         *Luu = this->R;
00094       
00095       if (Lxu)
00096         Lxu->setZero();
00097       
00098       if (this->diag)
00099         return (dx.dot(this->Q.diagonal().cwiseProduct(dx)) + u.dot(this->R.diagonal().cwiseProduct(u)))/2;
00100       else
00101         return (dx.dot(this->Q*dx) + u.dot(this->R*u))/2;
00102     }
00103   }  
00104 }
00105 
00106 
00107 #endif