GCOP  1.0
kinrccarpathcost.h
Go to the documentation of this file.
00001 #ifndef GCOP_KINRCCARPATHCOST_H
00002 #define GCOP_KINRCCARPATHCOST_H
00003 
00004 #include <limits>
00005 #include <iostream>
00006 #include "so3.h"
00007 #include "cost.h"
00008 #include "kinrccarpath.h"
00009 #include "kinrccar.h"
00010 
00011 namespace gcop {
00012   
00013   using namespace std;
00014   using namespace Eigen;
00015 
00016   typedef Matrix<double, Dynamic, 6> MatrixX6d;
00017 
00018   class KinRccarPathCost : public Cost<Matrix4d, 6, 2> {
00019 
00020   public:
00021     typedef Matrix<double, 6, 1> Vector6d;
00022     typedef Matrix<double, 6, 6> Matrix6d;
00023     
00024     KinRccarPathCost(double tf, const KinRccarPath &pg);
00025     
00026     double L(double t, const Matrix4d &x, const Vector2d &u, double h,
00027              const VectorXd *p,
00028              Vector6d *Lx = 0, Matrix6d *Lxx = 0,
00029              Vector2d *Lu = 0, Matrix2d *Luu = 0,
00030              Matrix<double, 6, 2> *Lxu = 0, 
00031              VectorXd *Lp = 0, MatrixXd *Lpp = 0, MatrixX6d *Lpx = 0);
00032 
00033 
00034     const KinRccarPath &pg;
00035   };  
00036 
00037 KinRccarPathCost::KinRccarPathCost(double tf, const KinRccarPath &pg) :
00038   Cost<Matrix4d, 6, 2>(pg.sys, tf), pg(pg)
00039 {
00040   
00041 }
00042 
00043 
00044 static Matrix3d r3hat(const Vector3d &a)
00045 {
00046   SO3& so3 = SO3::Instance();
00047   Matrix3d a_hat;
00048 
00049   so3.hat(a_hat, a);
00050   //a_hat << 0,  -a(2),  a(1),
00051   //       a(2),    0,  -a(0),
00052   //      -a(1),  a(0),    0;
00053   return a_hat;
00054 }
00055 
00056 
00057 static Vector3d cross3(Vector3d a, Vector3d b)
00058 {
00059   return a.cross(b);
00060 }
00061 
00062 double KinRccarPathCost::L(double t, const Matrix4d &x, const Vector2d &u, 
00063                           double h,
00064                           const VectorXd *p,
00065                           Vector6d *Lx, Matrix6d *Lxx,
00066                           Vector2d *Lu, Matrix2d *Luu,
00067                           Matrix<double, 6, 2> *Lxu,
00068                           VectorXd *Lp, MatrixXd *Lpp, MatrixX6d *Lpx)
00069 {
00070   double L = 0;
00071 
00072   if (Lu)
00073     Lu->setZero();
00074 
00075   if (Luu)
00076     Luu->setZero();
00077 
00078   if (Lxu)
00079     Lxu->setZero();
00080   
00081   if (Lx)
00082     Lx->setZero();
00083 
00084   if (Lxx)
00085     Lxx->setZero();
00086 
00087   if (Lp)
00088     Lp->setZero();
00089 
00090   if (Lpp)
00091     Lpp->setZero();
00092 
00093   if (Lpx)
00094     Lpx->setZero();
00095   
00096   const Matrix3d &R = x.block<3,3>(0,0); // orientation
00097   const Vector3d &xp = x.block<3,1>(0,3);     // position
00098   
00099   int N = pg.zs.size() - 1;  
00100   h = this->tf/N;
00101 
00102   int k = (int)round(t/h);
00103   assert(k >=0 && k <= N);
00104   
00105   const vector< pair<int, Vector3d> > &I = pg.zs[k];
00106 
00107   //cout << "Kinbody3dtrackCost: k=" << k << " " << I.size() << endl;
00108 
00109   int i0 = pg.estimate_length + 3*pg.extforce;
00110   for (int i = 0; i < I.size(); ++i) {
00111     int l = I[i].first;  // feature index
00112     const Vector3d &z = I[i].second;
00113 
00114     const Vector3d &pf = p->segment<3>(i0 + 3*l);
00115     Vector3d y = R.transpose()*(pf - xp);
00116     Vector3d r = (y - z)/pg.cp;
00117 
00118     L += r.dot(y - z)/2;         // feature cost
00119 
00120     //cout << "feature cost " << i << "=" << r.dot(y - z)/2 << endl;
00121 
00122     if (Lx) {
00123       //Lx->segment<3>(0) = Lx->segment<3>(0) - cross3(y, r);
00124       Lx->segment<3>(0) = Lx->segment<3>(0) - r3hat(y)*r;
00125       Lx->segment<3>(3) = Lx->segment<3>(3) - r;
00126     }
00127 
00128     if (Lxx) {
00129       Lxx->block<3,3>(0,0) += (r3hat(y).transpose()*r3hat(y))/pg.cp + r3hat(r)*r3hat(y)/2. + (r3hat(r)*r3hat(y)).transpose()/2.;
00130       Lxx->block<3,3>(0,3) += (-r3hat(r)/2. + r3hat(y)/pg.cp);
00131       Lxx->block<3,3>(3,0) += (-r3hat(r)/2. + r3hat(y)/pg.cp).transpose();      
00132       Lxx->block<3,3>(3,3) += Matrix3d::Identity()/pg.cp;
00133     }
00134 
00135     if (Lp)
00136       Lp->segment<3>(i0 + 3*l) = R*r;
00137 
00138     if (Lpp)
00139     {
00140       Lpp->block<3,3>(i0 + 3*l, i0 + 3*l) = Matrix3d::Identity()/pg.cp;
00141       //Lpp->block<3,3>(i0 + 3*l, i0 + 3*l) = Matrix3d::Identity();
00142     }
00143 
00144     if (Lpx) {
00145       Lpx->block<3,3>(i0 + 3*l, 0) = R*((r3hat(y)/pg.cp) - r3hat(r));
00146       Lpx->block<3,3>(i0 + 3*l, 3) = -R/pg.cp;
00147       //Lpx->block<3,3>(i0 + 3*l, 3) = Eigen::MatrixXd::Zero(3,3);
00148     }
00149   }
00150 
00151 
00152   if (pg.forces && k < N) {
00153     Vector2d du = u - pg.uos[k];
00154     Vector2d wdu = du.cwiseQuotient(pg.cw);
00155 
00156     L += du.dot(wdu)/2;
00157     if (Lu)
00158       *Lu = wdu;
00159     if (Luu)
00160       *Luu = Vector2d::Ones().cwiseQuotient(pg.cw).asDiagonal();
00161   }
00162 
00163   if (pg.wheel_odometry && k < N) {
00164     double du =  u(0) - pg.vs[k](0);
00165     double wdu = du/pg.cv(0);
00166 
00167     L += du*wdu/2;
00168     if (Lu)
00169       (*Lu)(0) += wdu;
00170     if (Luu)
00171       (*Luu)(0,0) += 1.0/pg.cv(0);
00172   }
00173 
00174   if (pg.yaw_odometry && k < N) {
00175     double l;
00176     if(pg.estimate_length && k < N)
00177     {
00178       l = (*p)(0);
00179     }
00180     else
00181     {
00182       l = pg.sys.d(0);
00183     }
00184 
00185     double du =  u(0)*tan(u(1))/l - pg.vs[k](1);
00186     double wdu = du/pg.cv(1);
00187 
00188     if(pg.estimate_length && k < N)
00189     {
00190       if(Lp)
00191       {
00192         (*Lp)(0) = wdu*(-u(0)*tan(u(1))/(l*l));
00193       }
00194       if(Lpp)
00195       {
00196         (*Lp)(0,0) = wdu*(2*u(0)*tan(u(1))/(l*l*l)) + (-u(0)*tan(u(1))/(l*l))*(-u(0)*tan(u(1))/(l*l))/pg.cv(1);
00197       }
00198     }
00199 
00200     L += du*wdu/2;
00201     if (Lu)
00202     {
00203       (*Lu)(0) += wdu*tan(u(1))/l;
00204       (*Lu)(1) += wdu*u(0)/(l*pow(cos(u(1)),2));
00205     }
00206     if (Luu)
00207     {
00208       (*Luu)(0,0) += pow(tan(u(1))/l,2)/pg.cv(1);
00209       (*Luu)(1,0) += ((tan(u(1))/l)*(u(0)/(l*pow(cos(u(1)),2))) + (u(0)*tan(u(1))/l - pg.vs[k](1))*(1./(l*pow(cos(u(1)),2))))/pg.cv(1);
00210       (*Luu)(0,1) += (*Luu)(1,0);
00211       (*Luu)(1,1) += (pow(u(0)/(l*pow(cos(u(1)),2)),2) + (u(0)*tan(u(1))/l - pg.vs[k](1))*(2*u(0)*tan(u(1))/(l*pow(cos(u(1)),2))))/pg.cv(1);
00212     }
00213     
00214   }
00215   /*
00216   if(Lp)
00217     cout << "Lp: " << endl << *Lp << endl;
00218   if(Lpp)
00219     cout << "Lpp: " << endl << *Lpp << endl;
00220   if(Lpx)
00221     cout << "Lpx: " << endl << *Lpx << endl;
00222   if(Lx)
00223     cout << "Lx: " << endl << *Lx << endl;
00224   if(Lxx)
00225     cout << "Lxx: " << endl << *Lxx << endl;
00226   */
00227 
00228   return L;
00229 }
00230 }
00231 
00232 #endif