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