GCOP
1.0
|
00001 #ifndef GCOP_BODY2DCOST_H 00002 #define GCOP_BODY2DCOST_H 00003 00004 #include "lqcost.h" 00005 #include <limits> 00006 #include "body2dtrack.h" 00007 #include "body2d.h" 00008 #include "se2.h" 00009 #include <iostream> 00010 #include <assert.h> 00011 00012 namespace gcop { 00013 00014 using namespace std; 00015 using namespace Eigen; 00016 00017 typedef Matrix<double, 6, 1> Vector6d; 00018 typedef Matrix<double, 6, 6> Matrix6d; 00019 typedef Matrix<double, 6, 3> Matrix63d; 00020 typedef pair<Matrix3d, Vector3d> Body2dState; 00021 00022 template<int c = 3> 00023 class Body2dCost : public LqCost<Body2dState, 6, c, Dynamic, 9> { 00024 public: 00025 typedef Matrix<double, c, 1> Vectorcd; 00026 typedef Matrix<double, 6, c> Matrix6cd; 00027 typedef Matrix<double, 3, c> Matrix3cd; 00028 typedef Matrix<double, c, c> Matrixcd; 00029 00030 Body2dCost(Body2d<c> &sys, double tf, const Body2dState &xf); 00031 00032 double L(double t, const Body2dState &x, const Vectorcd &u, double h, 00033 Vector6d *Lx = 0, Matrix6d *Lxx = 0, 00034 Vectorcd *Lu = 0, Matrixcd *Luu = 0, 00035 Matrix6cd *Lxu = 0); 00036 00037 00038 Body2dTrack *track; 00039 double ko; 00040 00041 }; 00042 00043 00044 template<int c> 00045 Body2dCost<c>::Body2dCost(Body2d<c> &sys, double tf, const Body2dState &xf) : 00046 LqCost<Body2dState, 6, c, Dynamic, 9>(sys, tf, xf), track(0), ko(.3) 00047 { 00048 this->Q(0,0) = .01; 00049 this->Q(1,1) = .01; 00050 this->Q(2,2) = .01; 00051 this->Q(3,3) = .1; 00052 this->Q(4,4) = .1; 00053 this->Q(5,5) = .1; 00054 00055 this->Qf(0,0) = 5; 00056 this->Qf(1,1) = 5; 00057 this->Qf(2,2) = 5; 00058 this->Qf(3,3) = 1; 00059 this->Qf(4,4) = 1; 00060 this->Qf(5,5) = 1; 00061 00062 this->R.setIdentity(); 00063 } 00064 00065 00066 00067 template<int c> 00068 double Body2dCost<c>::L(double t, const Body2dState& x, const Vectorcd& u, double h, 00069 Vector6d *Lx, Matrix6d* Lxx, 00070 Vectorcd *Lu, Matrixcd* Luu, 00071 Matrix6cd *Lxu) 00072 { 00073 Vector6d xe; 00074 // Vector3d ge; 00075 // SE2::Instance().plog(ge, x.fthis->irst); 00076 // xe.head(3) = ge; 00077 00078 Vector3d q; 00079 Matrix3d gi; 00080 00081 00082 Matrix2d P; 00083 bool inside = false; 00084 if (track && 0) { 00085 Vector2d p = x.first.topRightCorner<2,1>(); //current position 00086 00087 // Vector2d s = track->w/2*this->xf->first.block<2,1>(0,1); // from center to a 00088 Vector2d s = track->w/2*this->xf->first.block(0,1,2,1); // from center to a 00089 Vector2d a(this->xf->first(0,2) + s(0), this->xf->first(1,2) + s(1)); 00090 Vector2d b(this->xf->first(0,2) - s(0), this->xf->first(1,2) - s(1)); 00091 Vector2d v = b - a; 00092 double vn = v.norm(); 00093 v = v/vn; 00094 00095 Matrix3d gp = this->xf->first; // projected position 00096 double r = v.transpose()*(p - a); 00097 if (r < 0) { 00098 gp.topRightCorner<2,1>() = a; 00099 } else 00100 if (r > vn) { 00101 gp.topRightCorner<2,1>() = b; 00102 } else { 00103 inside = true; 00104 gp.topRightCorner<2,1>() = a + v*r; 00105 SE2::Instance().inv(gi, gp); 00106 P = Matrix2d::Identity() - v*v.transpose(); 00107 } 00108 } else { 00109 SE2::Instance().inv(gi, this->xf->first); 00110 } 00111 00112 Matrix3d dg = gi*x.first; 00113 SE2::Instance().g2q(q, dg); 00114 xe.head(3) = q; 00115 xe.tail(3) = x.second; 00116 00117 Matrix3d m; 00118 SE2::Instance().Tg(m, dg); 00119 00120 if (t > this->tf - 1e-10) { 00121 if (Lx) { 00122 *Lx = this->Qf*xe; 00123 if (track && inside) 00124 Lx->segment<2>(1) = P*Lx->segment<2>(1); 00125 (*Lx).head(3) = m.transpose()*(*Lx).head(3); 00126 } 00127 if (Lxx) { 00128 *Lxx = this->Qf; 00129 if (track && inside) 00130 Lxx->block<2,2>(1,1) = P*Lxx->block<2,2>(1,1)*P; 00131 (*Lxx).topLeftCorner(3,3) = m.transpose()*(*Lxx).topLeftCorner(3,3)*m; 00132 } 00133 if (Lu) 00134 Lu->setZero(); 00135 if (Luu) 00136 Luu->setZero(); 00137 if (Lxu) 00138 Lxu->setZero(); 00139 00140 return xe.dot(this->Qf*xe)/2; 00141 00142 } else { 00143 if (Lx) { 00144 *Lx = this->Q*(h*xe); 00145 (*Lx).head(3) = h*m.transpose()*(*Lx).head(3); 00146 } 00147 if (Lxx) { 00148 *Lxx = h*this->Q; 00149 (*Lxx).topLeftCorner(3,3) = h*m.transpose()*this->Q.topLeftCorner(3,3)*m; 00150 } 00151 if (Lu) 00152 *Lu = h*(this->R*u); 00153 if (Luu) 00154 *Luu = h*this->R; 00155 if (Lxu) 00156 Lxu->setZero(); 00157 00158 double e = h*(xe.dot(this->Q*xe) + u.dot(this->R*u))/2; 00159 00160 if (track) { 00161 double dmax = 1; 00162 00163 double eo = 0; 00164 Vector2d p(x.first(0,2), x.first(1,2)); 00165 00166 bool closest = true; 00167 int l = 0; 00168 00169 double dmin = 1e16; 00170 if (closest) { 00171 for (int j = 0; j < track->ls.size(); ++j) { 00172 Vector2d v = p - track->ls[j]; 00173 double d = v.norm(); 00174 if (d < dmin) { 00175 dmin = d; 00176 l = j; 00177 } 00178 } 00179 00180 if (dmin < dmax) { 00181 Vector2d v = p - track->ls[l]; 00182 double d = v.norm(); 00183 00184 double w = 1/d - 1/dmax; 00185 eo += ko/2*w*w; 00186 double d2 = d*d; 00187 double d3 = d2*d; 00188 double d4 = d3*d; 00189 const Matrix2d &R = x.first.topLeftCorner<2,2>(); 00190 if (Lx) 00191 Lx->tail<2>() += R.transpose()*(-ko*w*v/d3); 00192 if (Lxx) 00193 Lxx->bottomRightCorner<2,2>() += R.transpose()*( (ko*(1/d+3/d2-1/dmax-2/(dmax*d))/d4*v)*v.transpose() - (ko*w/d3)*Matrix2d::Identity())*R; 00194 } 00195 } else { 00196 for (int j = 0; j < track->ls.size(); ++j) { 00197 Vector2d v = p - track->ls[closest ? l : j]; 00198 double d = v.norm(); 00199 if (d > dmax) 00200 continue; 00201 00202 double w = 1/d - 1/dmax; 00203 eo += ko/2*w*w; 00204 double d2 = d*d; 00205 double d3 = d2*d; 00206 double d4 = d3*d; 00207 const Matrix2d &R = x.first.topLeftCorner<2,2>(); 00208 if (Lx) 00209 Lx->tail<2>() += R.transpose()*(-ko*w*v/d3); 00210 if (Lxx) 00211 Lxx->bottomRightCorner<2,2>() += R.transpose()*( (ko*(1/d+3/d2-1/dmax-2/(dmax*d))/d4*v)*v.transpose() - (ko*w/d3)*Matrix2d::Identity())*R; 00212 00213 if (closest) 00214 break; 00215 } 00216 } 00217 cout << "obstacle cost=" << eo << " t=" << t << " tf=" << this->tf << endl; 00218 e += eo; 00219 } 00220 return e; 00221 } 00222 } 00223 } 00224 00225 #endif