GCOP  1.0
pqpdem.h
Go to the documentation of this file.
00001 #ifndef GCOP_PQPDEM_H
00002 #define GCOP_PQPDEM_H
00003 
00004 #include "constraint.h"
00005 #include "dem.h"
00006 #include "PQP/PQP.h"
00007 #include "body3dmanifold.h"
00008 
00009 namespace gcop {
00010   
00011   template <typename T = VectorXd,
00012     int _nx = Dynamic, 
00013     int _nu = Dynamic, 
00014     int _np = Dynamic>
00015     class PqpDem : public Constraint<T, _nx, _nu, _np, 1> {
00016   public:
00017   
00018   typedef Matrix<double, 1, 1> Vectorgd;
00019   typedef Matrix<double, 1, _nx> Matrixgxd;
00020   typedef Matrix<double, 1, _nu> Matrixgud;
00021   typedef Matrix<double, 1, _np> Matrixgpd;
00022   
00023   typedef Matrix<double, _nx, 1> Vectornd;
00024   typedef Matrix<double, _nu, 1> Vectorcd;
00025   typedef Matrix<double, _np, 1> Vectormd;
00026   
00027   
00028   PqpDem(const Dem& dem, double cr = 0.1, double sd = 0.0);
00029   virtual ~PqpDem();
00030   
00031   bool operator()(Vectorgd &g,
00032                   double t, const T &x, const Vectorcd &u,
00033                   const Vectormd *p = 0, 
00034                   Matrixgxd *dgdx = 0, Matrixgud *dgdu = 0,
00035                   Matrixgpd *dgdp = 0);
00036 
00037   bool operator()(Vectorgd &g,
00038                   double t, const T &x, 
00039                   Matrixgxd *dgdx = 0) {
00040         Vectorcd u;
00041     return this->operator ()(g, t, x, u, 0, dgdx);
00042   }
00043   
00044   
00045   //  virtual void ToBody3dState(Body3dState &xb, const T &x) const;
00046   
00047   const Dem& dem;   
00048   
00049   PQP_Model *pm;
00050   PQP_REAL pt[3];
00051   PQP_REAL pR[3][3];
00052   
00053   PQP_Model *dm;
00054   PQP_REAL dt[3];
00055   PQP_REAL dR[3][3];
00056   
00057   PQP_DistanceResult dres;
00058   PQP_ToleranceResult tres;
00059   
00060   double cr;       
00061   double sd;       
00062   
00063   Body3dState xb;  
00064   
00065   };
00066 
00067   
00068   template <typename T, int _nx, int _nu, int _np> 
00069     PqpDem<T, _nx, _nu, _np>::PqpDem(const Dem& dem, double cr, double sd) :
00070     Constraint<T, _nx, _nu, _np, 1>(), dem(dem), cr(cr), sd(sd)
00071 {
00072   pm = new PQP_Model;
00073   dm = new PQP_Model;
00074 
00075   PQP_REAL p1[3], p2[3], p3[3], p4[3];
00076 
00077   pm->BeginModel();
00078   p1[0] = 0; p1[1] = cr; p1[2] = 0;
00079   p2[0] = 0; p2[1] = -cr; p2[2] = 0;
00080   p3[0] = cr; p3[1] = 0; p3[2] = 0;
00081   pm->AddTri(p1, p2, p3, 0);  
00082   p1[0] = 0; p1[1] = 0; p1[2] = cr;
00083   p2[0] = 0; p2[1] = 0; p2[2] = -cr;
00084   p3[0] = cr; p3[1] = 0; p3[2] = 0;
00085   pm->AddTri(p1, p2, p3, 1);
00086   pm->EndModel();
00087   pm->MemUsage(1);
00088 
00089   dm->BeginModel();
00090   int count  = 0;
00091   double p00[3], p10[3], p11[3], p01[3];
00092   for (int i=0; i < dem.ni-1; ++i) {
00093     for (int j=0; j < dem.nj-1; ++j) {
00094       dem.Get(p00, i, j);
00095       dem.Get(p10, i+1, j);
00096       dem.Get(p11, i+1, j+1);
00097       dem.Get(p01, i, j+1);
00098       p1[0] = p00[0]; p1[1] = p00[1]; p1[2] = p00[2];
00099       p2[0] = p10[0]; p2[1] = p10[1]; p2[2] = p10[2];
00100       p3[0] = p11[0]; p3[1] = p11[1]; p3[2] = p11[2];
00101       p4[0] = p01[0]; p4[1] = p01[1]; p4[2] = p01[2];
00102       dm->AddTri(p1, p2, p3, count);
00103       dm->AddTri(p1, p3, p4, count+1);
00104       count += 2;
00105     }
00106   }
00107   dm->EndModel();
00108   dm->MemUsage(1);
00109 
00110   pt[0] = pt[1] = pt[2] = 0;
00111   pR[0][0] = pR[1][1] = pR[2][2] = 1.0;
00112   pR[0][1] = pR[1][0] = pR[2][0] = 0.0;
00113   pR[0][2] = pR[1][2] = pR[2][1] = 0.0;
00114 
00115   dt[0] = dt[1] = dt[2] = 0;
00116   dR[0][0] = dR[1][1] = dR[2][2] = 1.0;
00117   dR[0][1] = dR[1][0] = dR[2][0] = 0.0;
00118   dR[0][2] = dR[1][2] = dR[2][1] = 0.0;
00119 }
00120 
00121   template <typename T, int _nx, int _nu, int _np> 
00122     PqpDem<T, _nx, _nu, _np>::~PqpDem()
00123   {
00124     delete dm;
00125     delete pm;
00126   }
00127   
00128   /*
00129   template <typename T, int _nx, int _nu, int _np> 
00130     void PqpDem<T, _nx, _nu, _np>::ToBody3dState(Body3dState &xb, const T &x) const
00131     {
00132       xb = x;
00133     }
00134   */  
00135 
00136 template <typename T, int _nx, int _nu, int _np> 
00137     bool PqpDem<T, _nx, _nu, _np>::operator()(Vectorgd &g,
00138                                               double t, const T &x, const Vectorcd &u,
00139                                               const Vectormd *rho, 
00140                                               Matrixgxd *dgdx, Matrixgud *dgdu,
00141                                               Matrixgpd *dgdp)
00142 {
00143   //  ToBody3dState(xb, x);
00144   
00145   Vector3d p = x.second.head(3);
00146 
00147   pt[0] = p[0];
00148   pt[1] = p[1];
00149   pt[2] = p[2];
00150 
00151   int res = PQP_Distance(&dres, pR, pt, pm, dR, dt, dm, 0.0, 0.0);
00152 
00153   if (res != PQP_OK)
00154     cerr << "Warning: PqpDem:Distance: res=" << res << endl;
00155 
00156   assert(res == PQP_OK);
00157 
00158   double d = dres.Distance();
00159   assert(d>=0);
00160 
00161   // subtract safety distance
00162   d = MAX(0, d - sd);
00163 
00164 
00165   //  if (dem.Inside(dres.P1()[0], dres.P1()[1], dres.P1()[2]))
00166 
00167   bool in = 
00168     dem.Inside(p[0] + cr, p[1], p[2]) ||
00169     dem.Inside(p[0], p[1] + cr, p[2]) ||
00170     dem.Inside(p[0], p[1] - cr, p[2]);
00171 
00172 
00173   if (in)
00174     d = -d;
00175   
00176   // cout << "d=" << d << endl;
00177 
00178   if (dgdx) {
00179     Vector3d p2(dres.P2());
00180     Vector3d dp = p2 - p;
00181     dp.normalize();
00182     dgdx->segment(3,3) = dp;
00183     //    dgdx->head(3).normalize();
00184 
00185     //    MINUS3(g, q, dres.P2());
00186     //    double gn = NORM3(g);
00187     //    DIV3(g,g,gn);
00188     if (in) {
00189       dgdx->segment(3,3) = -dp;
00190     }
00191   }
00192 
00193   g[0] = -d;
00194   return (d > 0);
00195 }
00196 
00197 
00198 
00199 };
00200 
00201 
00202 
00203 #endif