GCOP  1.0
body2dcost.h
Go to the documentation of this file.
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