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