GCOP
1.0
|
00001 #ifndef GCOP_CONSTRAINTCOST_H 00002 #define GCOP_CONSTRAINTCOST_H 00003 00004 #include <limits> 00005 #include "lscost.h" 00006 #include "constraint.h" 00007 #include <iostream> 00008 00009 namespace gcop { 00010 00011 using namespace std; 00012 using namespace Eigen; 00013 00014 template <typename T, 00015 int _nx = Dynamic, 00016 int _nu = Dynamic, 00017 int _np = Dynamic, 00018 int _ng = Dynamic> class ConstraintCost : public LsCost<T, _nx, _nu, _np, _ng> { 00019 public: 00020 00021 typedef Matrix<double, _ng, 1> Vectorgd; 00022 typedef Matrix<double, _ng, _nx> Matrixgnd; 00023 typedef Matrix<double, _ng, _nu> Matrixgcd; 00024 typedef Matrix<double, _ng, _np> Matrixgmd; 00025 00026 typedef Matrix<double, _nx, 1> Vectornd; 00027 typedef Matrix<double, _nu, 1> Vectorcd; 00028 typedef Matrix<double, _np, 1> Vectormd; 00029 00030 typedef Matrix<double, _nx, _nx> Matrixnd; 00031 typedef Matrix<double, _nx, _nu> Matrixncd; 00032 typedef Matrix<double, _nu, _nx> Matrixcnd; 00033 typedef Matrix<double, _nu, _nu> Matrixcd; 00034 00035 // typedef Matrix<double, Dynamic, 1> Vectormd; 00036 typedef Matrix<double, _np, _np> Matrixmd; 00037 typedef Matrix<double, _nx, _np> Matrixnmd; 00038 typedef Matrix<double, _np, _nx> Matrixmnd; 00039 00047 ConstraintCost(System<T, _nx, _nu, _np> &sys, double tf, Constraint<T, _nx, _nu, _np, _ng> &con); 00048 00049 virtual double L(double t, const T& x, const Vectorcd& u, double h, 00050 const Vectormd *p = 0, 00051 Vectornd *Lx = 0, Matrixnd* Lxx = 0, 00052 Vectorcd *Lu = 0, Matrixcd* Luu = 0, 00053 Matrixncd *Lxu = 0, 00054 Vectormd *Lp = 0, Matrixmd *Lpp = 0, 00055 Matrixmnd *Lpx = 0); 00056 00057 /* 00058 bool Res(Vectorgd &g, 00059 double t, const T &x, const Vectorcd &u, double h, 00060 const Vectormd *p = 0, 00061 Matrixgnd *dgdx = 0, Matrixgcd *dgdu = 0, 00062 Matrixgmd *dgdp = 0); 00063 */ 00064 Constraint<T, _nx, _nu, _np, _ng> &con; 00065 00066 double b; 00067 00068 protected: 00069 00070 Vectorgd gp; 00071 Matrixgnd dgdx; 00072 00073 }; 00074 00075 template <typename T, int _nx, int _nu, int _np, int _ng> 00076 ConstraintCost<T, _nx, _nu, _np, _ng>::ConstraintCost(System<T, _nx, _nu, _np> &sys, 00077 double tf, Constraint<T, _nx, _nu, _np, _ng> &con) : 00078 LsCost<T, _nx, _nu, _np, _ng>(sys, tf, con.ng), con(con), b(1) { 00079 00080 if (_ng == Dynamic) { 00081 gp.resize(con.ng); 00082 } 00083 00084 if (_nx == Dynamic || _ng == Dynamic) { 00085 dgdx.resize(con.ng, sys.X.n); 00086 } 00087 } 00088 00089 template <typename T, int _nx, int _nu, int _np, int _ng> 00090 double ConstraintCost<T, _nx, _nu, _np, _ng>::L(double t, const T &x, const Matrix<double, _nu, 1> &u, 00091 double h, 00092 const Matrix<double, _np, 1> *p, 00093 Matrix<double, _nx, 1> *Lx, Matrix<double, _nx, _nx> *Lxx, 00094 Matrix<double, _nu, 1> *Lu, Matrix<double, _nu, _nu> *Luu, 00095 Matrix<double, _nx, _nu> *Lxu, 00096 Matrix<double, _np, 1> *Lp, Matrix<double, _np, _np> *Lpp, 00097 Matrix<double, _np, _nx> *Lpx) { 00098 00099 double q = 234234023411230; 00100 dgdx[0] = q; // random number 00101 00102 // only consider state constraints for now 00103 this->con(this->g, t, x, u, p, Lx ? &dgdx : 0); 00104 00105 T xb; 00106 Vectornd dx; 00107 Vectorgd gp; 00108 Vectorgd gm; 00109 double eps = 1e-3; 00110 00111 // if no jacobians were provided use finite differences 00112 if (Lx && fabs(dgdx[0] - q) < 1e-10) { 00113 00114 for (int i = 0; i < this->sys.X.n; ++i) { 00115 dx.setZero(); 00116 dx[i] = eps; 00117 00118 // xb = x + dx 00119 this->sys.X.Retract(xb, x, dx); 00120 00121 // reconstruct state using previous time-step 00122 this->sys.Rec(xb, h); 00123 00124 // gp = con(xb) 00125 this->con(gp, t, xb, u, p); 00126 00127 // xb = x - dx 00128 this->sys.X.Retract(xb, x, -dx); 00129 00130 // reconstruct state using previous time-step 00131 this->sys.Rec(xb, h); 00132 00133 // gm = con(xb) 00134 this->con(gm, t, xb, u, p); 00135 00136 dgdx.col(i) = (gp - gm)/(2*eps); 00137 } 00138 } 00139 00140 for (int i = 0; i < con.ng; ++i) { 00141 if (this->g[i] < 0) { // if constraint is satisfied then null it 00142 this->g[i] = 0; 00143 if (Lx) 00144 dgdx.row(i).setZero(); 00145 } 00146 } 00147 00148 if (Lx) 00149 *Lx = b*dgdx.transpose()*this->g; 00150 if (Lxx) { 00151 *Lxx = b*dgdx.transpose()*dgdx; // use a GN approximation to the Hessian 00152 00153 /* 00154 if (this->g[0] > 0) { 00155 Vector3d v = dgdx.segment(3,3); 00156 Matrix3d M= Matrix3d::Identity() - v*v.transpose(); 00157 Lxx->block(3,3,3,3) += -b*M; 00158 } 00159 */ 00160 } 00161 /* if (Lxx) { 00162 Lxx->Identity(); 00163 *Lxx = .01**Lxx; 00164 } 00165 */ 00166 00167 return b/2*this->g.squaredNorm(); 00168 //return b/2*this->g.squaredNorm(); 00169 } 00170 } 00171 00172 00173 #endif