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