GCOP  1.0
docp.h
Go to the documentation of this file.
00001 #ifndef GCOP_DOCP_H
00002 #define GCOP_DOCP_H
00003 
00004 #include <Eigen/Dense>
00005 #include <vector>
00006 #include <type_traits>
00007 #include <algorithm>
00008 #include <iterator>
00009 #include "system.h"
00010 #include "cost.h"
00011 #include <cmath>
00012 #include "rn.h"
00013 
00014 namespace gcop {
00015   
00016   using namespace std;
00017   using namespace Eigen;
00018  
00019   template <typename T, 
00020     int nx = Dynamic, 
00021     int nu = Dynamic,
00022     int np = Dynamic> class Docp {
00023     
00024     typedef Matrix<double, nx, 1> Vectornd;
00025     typedef Matrix<double, nu, 1> Vectorcd;
00026     typedef Matrix<double, np, 1> Vectormd;
00027 
00028     typedef Matrix<double, nx, nx> Matrixnd;
00029     typedef Matrix<double, nx, nu> Matrixncd;
00030     typedef Matrix<double, nu, nx> Matrixcnd;
00031     typedef Matrix<double, nu, nu> Matrixcd;  
00032     
00033   public:
00052     Docp(System<T, nx, nu, np> &sys, Cost<T, nx, nu, np> &cost, 
00053          vector<double> &ts, vector<T> &xs, vector<Vectorcd> &us, 
00054          Vectormd *p = 0, bool update = true);
00055     
00056     virtual ~Docp();
00057 
00061     virtual void Iterate();
00062 
00067     void Update(bool der = true);
00068     
00069     System<T, nx, nu, np> &sys;    
00070 
00071     Cost<T, nx, nu, np> &cost;     
00072 
00073     std::vector<double> &ts; 
00074 
00075     std::vector<T> &xs;      
00076 
00077     std::vector<Vectorcd> &us;      
00078     
00079     Vectormd *p;               
00080     
00081     std::vector<Matrixnd> As;    
00082     std::vector<Matrixncd> Bs;   
00083     
00084     bool debug;  
00085     
00086     double eps;  
00087 
00088     double J;    
00089 
00090     int nofevaluations;
00091 
00092   };
00093 
00094   using namespace std;
00095   using namespace Eigen;
00096   
00097   template <typename T, int nx, int nu, int np> 
00098     Docp<T, nx, nu, np>::Docp(System<T, nx, nu, np> &sys, 
00099                               Cost<T, nx, nu, np> &cost, 
00100                               vector<double> &ts, 
00101                               vector<T> &xs, 
00102                               vector<Matrix<double, nu, 1> > &us,
00103                               Matrix<double, np, 1> *p,
00104                               bool update) : 
00105     sys(sys), cost(cost), ts(ts), xs(xs), us(us), p(p),
00106     As(us.size()), Bs(us.size()), J(std::numeric_limits<double>::max()), 
00107     debug(true), eps(1e-3), nofevaluations(0)
00108     {
00109       int N = us.size();
00110       assert(N > 0);
00111       assert(ts.size() == N+1);
00112       assert(xs.size() == N+1);
00113 
00114       if (nx == Dynamic || nu == Dynamic) {
00115         for (int i = 0; i < N; ++i) {
00116           As[i].resize(sys.X.n, sys.X.n);
00117           Bs[i].resize(sys.X.n, sys.U.n);
00118         }
00119       }
00120 
00121       if (update) {
00122         Update();
00123       }
00124     }
00125   
00126   template <typename T, int nx, int nu, int np> 
00127     Docp<T, nx, nu, np>::~Docp()
00128     {
00129     }
00130   
00131   template <typename T, int nx, int nu, int np> 
00132     void Docp<T, nx, nu, np>::Update(bool der) {
00133 
00134     typedef Matrix<double, nx, 1> Vectornd;
00135     typedef Matrix<double, nu, 1> Vectorcd;
00136     
00137     Vectornd dx;
00138     Vectorcd du;
00139     Vectornd dfp;
00140     Vectornd dfm;
00141     T xav(xs[0]);
00142     T xbv(xs[0]);
00143     
00144     //    cout << "SIZE=" << ((MbsState*)&xav)->r.size() << endl;
00145     
00146     if (nx == Dynamic) {
00147       dx.resize(sys.X.n);
00148       dfp.resize(sys.X.n);
00149       dfm.resize(sys.X.n);
00150     }
00151     
00152     if (nu == Dynamic)
00153       du.resize(sys.U.n);    
00154 
00155     int N = us.size();
00156 
00157     sys.Reset(xs[0],ts[0]);//Reset the internal state
00158 
00159     for (int k = 0; k < N; ++k) {
00160       double h = ts[k+1] - ts[k];
00161       if (der) {
00162         static const double q = 1093121342312;  // a random number
00163         As[k](0,0) = q;
00164         Bs[k](0,0) = q;
00165         
00166         const T &xa = xs[k];
00167         T &xb = xs[k+1];
00168         const Vectorcd &u = us[k];
00169 
00170         //sys.Step(xb, ts[k], xa, u, h, p, &As[k], &Bs[k], 0);
00171         sys.Step(xs[k+1], us[k], h, p, &As[k], &Bs[k], 0);
00172 
00173         //        cout << "B=" << endl << Bs[k] << endl;
00174         
00175 
00176         //        if (fabs(As[k](0,0) - q) < 1e-10) {
00177         //          autodiff.DF(xb, ts[k], xa, u, h, &As[k], &Bs[k]);
00178         //        }
00179 
00180         
00181         // if no jacobians were provided use finite differences
00182         if (fabs(As[k](0,0) - q) < 1e-10) {
00183                     
00184           assert(sys.X.n > 0 && sys.U.n > 0);
00185 
00186           for (int i = 0; i < sys.X.n; ++i) {
00187             dx.setZero();
00188             dx[i] = eps;
00189             
00190             // xav = xa + dx
00191             sys.X.Retract(xav, xa, dx);
00192             
00193             // reconstruct state using previous time-step
00194             sys.Rec(xav, h);
00195             
00196             // xbv = F(xav)
00197             sys.Step(xbv, ts[k], xav, u, h, p);
00198             
00199             // df = xbv - xb
00200             sys.X.Lift(dfp, xb, xbv);
00201 
00202             // xav = xa - dx
00203             sys.X.Retract(xav, xa, -dx);
00204             
00205             // reconstruct state using previous time-step
00206             sys.Rec(xav, h);
00207             
00208             // xbv = F(xav)
00209             sys.Step(xbv, ts[k], xav, u, h, p);
00210             
00211             // dfm = xbv - xb
00212             sys.X.Lift(dfm, xb, xbv);
00213 
00214             As[k].col(i) = (dfp - dfm)/(2*eps);
00215           }
00216           sys.Reset(xs[k+1],ts[k+1]);//Reset the internal state
00217           //cout<<"As["<<k<<"]: "<<endl<<As[k]<<endl;
00218         }
00219         
00220         if (fabs(Bs[k](0,0) - q) < 1e-10) {
00221           
00222           for (int i = 0; i < sys.U.n; ++i) {
00223             du.setZero();
00224             du[i] = eps;
00225             
00226             // xbv = F(xa, u + du)
00227             sys.Step(xbv, ts[k], xa, u + du, h, p);
00228             
00229             // df = xbv - xb
00230             sys.X.Lift(dfp, xb, xbv);
00231 
00232             // xbv = F(xa, u - du)
00233             sys.Step(xbv, ts[k], xa, u - du, h, p);
00234             
00235             // df = xbv - xb
00236             sys.X.Lift(dfm, xb, xbv);
00237 
00238             Bs[k].col(i) = (dfp - dfm)/eps;
00239           }
00240           sys.Reset(xs[k+1],ts[k+1]);//Reset the internal state
00241          // cout<<"Bs["<<k<<"]: "<<endl<<Bs[k]<<endl;
00242         }        
00243       } else {
00244         sys.Step(xs[k+1], us[k], h, p);
00245       }
00246     }
00247   } 
00248 
00249   template <typename T, int nx, int nu, int np> 
00250     void Docp<T, nx, nu, np>::Iterate() {
00251     cout << "[W] Docp::Iterate: subclasses should implement this!" << endl;
00252   }
00253 }
00254 
00255 #endif