GCOP  1.0
kinbodyprojtrackcost.h
Go to the documentation of this file.
00001 #ifndef GCOP_KINBODYPROJTRACKCOST_H
00002 #define GCOP_KINBODYPROJTRACKCOST_H
00003 
00004 #include <limits>
00005 #include <iostream>
00006 #include "cost.h"
00007 #include "kinbodyprojtrack.h"
00008 #include "kinbody3d.h"
00009 
00010 namespace gcop {
00011   
00012   using namespace std;
00013   using namespace Eigen;
00014 
00015   typedef Matrix<double, Dynamic, 6> MatrixX6d;
00016 
00017 
00018   template <int _nu = 6>
00019   class KinbodyProjTrackCost : public Cost<Matrix4d, 6, _nu> {
00020 
00021   private:
00022     MatrixXd d_xxt(Vector3d x);
00023     MatrixXd kron(MatrixXd A, MatrixXd B);
00024   public:
00025     typedef Matrix<double, _nu, _nu> Matrixud;
00026     typedef Matrix<double, _nu, 1> Vectorud;
00027     typedef Matrix<double, 6, 1> Vector6d;
00028     typedef Matrix<double, 6, 6> Matrix6d;
00029 
00030     KinbodyProjTrackCost(double tf, const KinbodyProjTrack<_nu> &pg);
00031     
00032     double L(double t, const Matrix4d &x, const Vectorud &u, double h,
00033              const VectorXd *p,
00034              Vector6d *Lx = 0, Matrix6d *Lxx = 0,
00035              Vectorud *Lu = 0, Matrixud *Luu = 0,
00036              Matrix<double, 6, _nu> *Lxu = 0, 
00037              VectorXd *Lp = 0, MatrixXd *Lpp = 0, MatrixX6d *Lpx = 0);
00038 
00039     void test_d_xxt();
00040     void test_kron();
00041     void test_grads();
00042 
00043     const KinbodyProjTrack<_nu> &pg;
00044   };  
00045 
00046 template <int _nu>
00047 KinbodyProjTrackCost<_nu>::KinbodyProjTrackCost(double tf, const KinbodyProjTrack<_nu> &pg) :
00048   Cost<Matrix4d, 6, _nu>(pg.sys, tf), pg(pg)
00049 {
00050   
00051 }
00052 
00053 
00054 static Matrix3d r3hat(const Vector3d &a)
00055 {
00056   SO3& so3 = SO3::Instance();
00057   Matrix3d a_hat;
00058 
00059   so3.hat(a_hat, a);
00060   //a_hat << 0,  -a(2),  a(1),
00061   //       a(2),    0,  -a(0),
00062   //      -a(1),  a(0),    0;
00063   return a_hat;
00064 }
00065 
00066 
00067 static Vector3d cross3(Vector3d a, Vector3d b)
00068 {
00069   return a.cross(b);
00070 }
00071 
00072 template <int _nu>
00073 void KinbodyProjTrackCost<_nu>::test_kron()
00074 {
00075   MatrixXd A = MatrixXd::Identity(6,6);
00076   MatrixXd B = MatrixXd::Zero(2,1);
00077   B << 3, 2;
00078 
00079   cout << "A:" << endl << A << endl;
00080   cout << "B:" << endl << B << endl;
00081   cout << "kron(A,B): " << endl << kron(A,B) << endl;
00082   cout << "kron(B,A): " << endl << kron(B,A) << endl;
00083 }
00084 
00085 template <int _nu>
00086 void KinbodyProjTrackCost<_nu>::test_d_xxt()
00087 {
00088   Vector3d x(3,-2,1);
00089   cout << "x: " << endl << x << endl; 
00090   cout << "d_xxt: " << endl << d_xxt(x) << endl; 
00091 }
00092 
00093 template <int _nu>
00094 void KinbodyProjTrackCost<_nu>::test_grads()
00095 {
00096   Vector6d Lx;
00097   Matrix6d Lxx;
00098   VectorXd Lp;
00099   Lp.resize(15,1);
00100   MatrixXd  Lpp;
00101   Lpp.resize(15,15); 
00102   MatrixX6d Lpx;
00103   Lpx.resize(15,6);
00104 
00105   Lx.setZero();
00106   Lxx.setZero();
00107   Lp.setZero();
00108   Lpp.setZero();
00109   Lpx.setZero();
00110 
00111   Matrix<double, 5, 3> ls;
00112   Matrix<double, 5, 3> zs;
00113 
00114   ls << -8.049191900011810,  -4.430035622659032,   0.937630384099677,
00115    9.150136708685952,   9.297770703985531,  -6.847738366449034,
00116    9.411855635212312,   9.143338964858913,  -0.292487025543176,
00117    6.005609377776004,  -7.162273227455693,  -1.564774347474501,
00118    8.314710503781342,   5.844146591191087,   9.189848527858061;
00119 
00120   zs << 0.438021624604109,  -0.288302180913201,  -0.851480421888765,
00121    0.234909466397926,   0.387309344924147,  -0.891520618904055,
00122    0.399428923259037,   0.397492249355858,  -0.826109222177157,
00123    0.544326983672147,   0.068898439211757,  -0.836038958374887,
00124    0.705665941886738,   0.264747508473682,  -0.657224722007686;
00125   
00126 
00127   double L = 0;
00128 
00129   double t = 5.119059895756811;
00130   double t2 = 5.691258590395267; 
00131   Matrix3d R1, R2;
00132   R1 << cos(t), -sin(t), 0,
00133         sin(t), cos(t),  0,
00134              0,      0,  1;
00135   R2 <<      1,      0,  0,
00136          0, cos(t2), -sin(t2),
00137          0, sin(t2),  cos(t2);
00138   Matrix3d R = R2*R1; // orientation
00139   Vector3d xp;     // position
00140   xp <<   -4.920527348259758+5,
00141   26.535034245560773,
00142   15.294369849016380;
00143   
00144   cout << "R: " << endl << R << endl;
00145   cout << "xp: " << endl << xp << endl;
00146   cout << "ls: " << endl << ls << endl;
00147   cout << "zs: " << endl << zs << endl;
00148   cout << "sigmaR: " << endl << 1./pg.cp << endl;
00149 
00150   Matrix3d eye = MatrixXd::Identity(3,3);
00151    
00152   for (int i = 0; i < ls.rows(); ++i) {
00153     const Vector3d &z = zs.block<1,3>(i,0);
00154     const Vector3d &pf = ls.block<1,3>(i,0);
00155     Vector3d y = R.transpose()*(pf - xp);
00156     y /= y.norm();
00157     Vector3d r = (y - z)/pg.cp;
00158 
00159     L += r.dot(y - z)/2;         // feature cost
00160 
00161     double normlp = (pf - xp).norm();
00162     Vector3d lphat = (pf - xp)/normlp;
00163     Matrix3d lphat_d = (eye - lphat*lphat.transpose())/normlp;
00164 
00165     //cout << "feature cost " << i << "=" << r.dot(y - z)/2 << endl;
00166 
00167     Lx.segment<3>(0) += - r3hat(y)*r;
00168     Lx.segment<3>(3) += - R.transpose()*lphat_d*R*r;
00169 
00170     Lxx.block<3,3>(0,0) += (r3hat(y).transpose()*r3hat(y))/pg.cp + (r3hat(r)*r3hat(y))/2. + (r3hat(r)*r3hat(y)).transpose()/2.;
00171     Lxx.block<3,3>(3,0) += -r3hat(R.transpose()*lphat_d*R*r)/2. + R.transpose()*lphat_d*R*r3hat(r) - R.transpose() *lphat_d*R*r3hat(y)/pg.cp;
00172     Lxx.block<3,3>(3,3) += -R.transpose()*(-lphat_d*R*R.transpose()*lphat_d*R/pg.cp + (kron((R*r).transpose(), eye)*d_xxt(pf-xp)*R)/normlp + (eye - lphat*lphat.transpose())*(R*r*lphat.transpose()*R)/(normlp*normlp));
00173 
00174     Lp.segment<3>(3*i) = lphat_d*R*r;
00175 
00176     Lpp.block<3,3>(3*i, 3*i) = lphat_d*R*R.transpose()*lphat_d/pg.cp - (kron((R*r).transpose(), eye)*d_xxt(pf-xp))/normlp - (eye - lphat*lphat.transpose())*(R*r*lphat.transpose())/(normlp*normlp);
00177     
00178     Lpx.block<3,3>(3*i, 0) = -lphat_d*R*r3hat(r) + lphat_d*R*r3hat(y)/pg.cp;
00179     Lpx.block<3,3>(3*i, 3) = -lphat_d*R*R.transpose()*lphat_d*R/pg.cp + kron((R*r).transpose(), eye)*d_xxt(pf-xp)*R/normlp + (eye - lphat*lphat.transpose())*(R*r*lphat.transpose()*R)/(normlp*normlp);
00180   }
00181 
00182   Lxx.block<3,3>(0,3) = Lxx.block<3,3>(3,0).transpose();
00183 
00184   cout << "L: " << endl << L << endl;
00185   cout << "Lx: " << endl << Lx << endl;
00186   cout << "Lxx: " << endl << Lxx << endl;
00187   cout << "Lp: " << endl << Lp << endl;
00188   cout << "Lpp: " << endl << Lpp << endl;
00189   cout << "Lpx: " << endl << Lpx << endl;
00190 }
00191 
00192 template <int _nu>
00193 MatrixXd KinbodyProjTrackCost<_nu>::kron(MatrixXd A, MatrixXd B)
00194 {
00195   int m = B.rows();
00196   int n = B.cols();
00197   MatrixXd k = Eigen::MatrixXd(A.rows()*m, A.cols()*n);
00198   for(int i = 0; i < A.rows(); i++)
00199   {
00200     for(int j = 0; j < A.cols(); j++)
00201     {
00202       k.block(i*m, j*n, m, n) = A(i,j)*B;
00203     }
00204   }
00205   return k;
00206 }
00207 
00208 // Gives Hessian of stack(xhat*xhat^T) with respect to x
00209 template <int _nu>
00210 MatrixXd KinbodyProjTrackCost<_nu>::d_xxt(Vector3d x)
00211 {
00212   double x1 = x(0);
00213   double x2 = x(1);
00214   double x3 = x(2);
00215 
00216   MatrixXd hess = MatrixXd(9,3);
00217 
00218   double mag2_x = x1*x1 + x2*x2 + x3*x3; 
00219 
00220   hess <<                  (2*x1)/mag2_x - (2*x1*x1*x1)/pow(mag2_x,2),   
00221                                           -(2*x1*x1*x2)/pow(mag2_x,2),
00222                                           -(2*x1*x1*x3)/pow(mag2_x,2),
00223                                x2/mag2_x - (2*x1*x2*x1)/pow(mag2_x,2),   
00224                                x1/mag2_x - (2*x1*x2*x2)/pow(mag2_x,2),  
00225                                           -(2*x1*x2*x3)/pow(mag2_x,2),
00226                                x3/mag2_x - (2*x1*x3*x1)/pow(mag2_x,2),
00227                                           -(2*x1*x3*x2)/pow(mag2_x,2),
00228                                x1/mag2_x - (2*x1*x3*x3)/pow(mag2_x,2),
00229                                x2/mag2_x - (2*x1*x2*x1)/pow(mag2_x,2),
00230                                x1/mag2_x - (2*x1*x2*x2)/pow(mag2_x,2),
00231                                           -(2*x1*x2*x3)/pow(mag2_x,2),
00232                                           -(2*x2*x2*x1)/pow(mag2_x,2),
00233                            (2*x2)/mag2_x - (2*x2*x2*x2)/pow(mag2_x,2),
00234                                           -(2*x2*x2*x3)/pow(mag2_x,2),
00235                                           -(2*x2*x3*x1)/pow(mag2_x,2),
00236                                x3/mag2_x - (2*x2*x3*x2)/pow(mag2_x,2),
00237                                x2/mag2_x - (2*x2*x3*x3)/pow(mag2_x,2),
00238                                x3/mag2_x - (2*x1*x3*x1)/pow(mag2_x,2),
00239                                           -(2*x1*x3*x2)/pow(mag2_x,2),
00240                                x1/mag2_x - (2*x1*x3*x3)/pow(mag2_x,2),
00241                                           -(2*x2*x3*x1)/pow(mag2_x,2),
00242                                x3/mag2_x - (2*x2*x3*x2)/pow(mag2_x,2),
00243                                x2/mag2_x - (2*x2*x3*x3)/pow(mag2_x,2),
00244                                           -(2*x3*x3*x1)/pow(mag2_x,2),
00245                                           -(2*x3*x3*x2)/pow(mag2_x,2),
00246                            (2*x3)/mag2_x - (2*x3*x3*x3)/pow(mag2_x,2);
00247   return hess;
00248 }
00249 
00250 template <int _nu>
00251 double KinbodyProjTrackCost<_nu>::L(double t, const Matrix4d &x, const Vectorud &u, 
00252                           double h,
00253                           const VectorXd *p,
00254                           Vector6d *Lx, Matrix6d *Lxx,
00255                           Vectorud *Lu, Matrixud *Luu,
00256                           Matrix<double, 6, _nu> *Lxu,
00257                           VectorXd *Lp, MatrixXd *Lpp, MatrixX6d *Lpx)
00258 {
00259   double L = 0;
00260 
00261   //cout << "x: " << endl << x << endl;
00262 
00263   if (Lu)
00264     Lu->setZero();
00265 
00266   if (Luu)
00267     Luu->setZero();
00268 
00269   if (Lxu)
00270     Lxu->setZero();
00271   
00272   if (Lx)
00273     Lx->setZero();
00274 
00275   if (Lxx)
00276     Lxx->setZero();
00277 
00278   if (Lp)
00279     Lp->setZero();
00280 
00281   if (Lpp)
00282     Lpp->setZero();
00283 
00284   if (Lpx)
00285     Lpx->setZero();
00286   
00287   //const Matrix3d &g = x.first;
00288 
00289   const Matrix3d &R = x.block<3,3>(0,0); // orientation
00290   const Vector3d &xp = x.block<3,1>(0,3);     // position
00291   
00292   int N = pg.Is.size() - 1;
00293   
00294   h = this->tf/N;
00295 
00296   //  int k = (h < 1e-16 ? N : (int)round(t/h));
00297 
00298   int k = (int)round(t/h);
00299   assert(k >=0 && k <= N);
00300   const vector< pair<int, Vector3d> > &I = pg.Is[k];
00301 
00302   //cout << "Kinbody3dtrackCost: k=" << k << " " << I.size() << endl;
00303 
00304   Matrix3d eye = MatrixXd::Identity(3,3);
00305 
00306   int i0 = 3*pg.extforce;
00307   for (int i = 0; i < I.size(); ++i) {
00308     int l = pg.cis[I[i].first];  // feature index
00309     const Vector3d &z = I[i].second;
00310 
00311     const Vector3d &pf = p->segment<3>(i0 + 3*l);
00312     Vector3d y = R.transpose()*(pf - xp);
00313     y /= y.norm();
00314     Vector3d r = (y - z)/pg.cp;
00315 
00316     L += r.dot(y - z)/2;         // feature cost
00317 
00318     double normlp = (pf - xp).norm();
00319     Vector3d lphat = (pf - xp)/normlp;
00320     Matrix3d lphat_d = (eye - lphat*lphat.transpose())/normlp;
00321 
00322     //cout << "feature cost " << i << "=" << r.dot(y - z)/2 << endl;
00323 
00324     if (Lx) {
00325       //Lx->segment<3>(0) = Lx->segment<3>(0) - cross3(y, r);
00326       Lx->segment<3>(0) = Lx->segment<3>(0) - r3hat(y)*r;
00327       Lx->segment<3>(3) = Lx->segment<3>(3) - R.transpose()*lphat_d*R*r;
00328     }
00329 
00330     if (Lxx) {
00331       Lxx->block<3,3>(0,0) += (r3hat(y).transpose()*r3hat(y))/pg.cp + (r3hat(r)*r3hat(y))/2. + (r3hat(r)*r3hat(y)).transpose()/2.;
00332       Lxx->block<3,3>(3,0) += -r3hat(R.transpose()*lphat_d*R*r)/2. + R.transpose()*lphat_d*R*r3hat(r) - R.transpose() *lphat_d*R*r3hat(y)/pg.cp;
00333       Lxx->block<3,3>(3,3) += -R.transpose()*(-lphat_d*R*R.transpose()*lphat_d*R/pg.cp + (kron((R*r).transpose(), eye)*d_xxt(pf-xp)*R)/normlp + (eye - lphat*lphat.transpose())*(R*r*lphat.transpose()*R)/(normlp*normlp));
00334     }
00335 
00336     if (Lp)
00337       Lp->segment<3>(i0 + 3*l) = lphat_d*R*r;
00338 
00339     if (Lpp)
00340     {
00341       Lpp->block<3,3>(i0 + 3*l, i0 + 3*l) = lphat_d*R*R.transpose()*lphat_d/pg.cp - (kron((R*r).transpose(), eye)*d_xxt(pf-xp))/normlp - (eye - lphat*lphat.transpose())*(R*r*lphat.transpose())/(normlp*normlp);
00342     }
00343 
00344     if (Lpx) {
00345       Lpx->block<3,3>(i0 + 3*l, 0) = -lphat_d*R*r3hat(r) + lphat_d*R*r3hat(y)/pg.cp;
00346       Lpx->block<3,3>(i0 + 3*l, 3) = -lphat_d*R*R.transpose()*lphat_d*R/pg.cp + kron((R*r).transpose(), eye)*d_xxt(pf-xp)*R/normlp + (eye - lphat*lphat.transpose())*(R*r*lphat.transpose()*R)/(normlp*normlp);
00347       //Lpx->block<3,3>(i0 + 3*l, 3) = Eigen::MatrixXd::Zero(3,3);
00348     }
00349   }
00350 
00351   if(Lxx)
00352   {
00353     Lxx->block<3,3>(0,3) = Lxx->block<3,3>(3,0).transpose();
00354   }
00355 
00356   if (pg.forces && k < N) {
00357     Vectorud du = u - pg.uos[k];
00358     Vectorud wdu = du.cwiseQuotient(pg.cw);
00359 
00360     L += du.dot(wdu)/2;
00361     if (Lu)
00362       *Lu = wdu;
00363     if (Luu)
00364       *Luu = Vector6d::Ones().cwiseQuotient(pg.cw).asDiagonal();
00365   }
00366 
00367   /*
00368   if(Lp)
00369     cout << "Lp: " << endl << *Lp << endl;
00370   if(Lpp)
00371     cout << "Lpp: " << endl << *Lpp << endl;
00372   if(Lpx)
00373     cout << "Lpx: " << endl << *Lpx << endl;
00374   if(Lx)
00375     cout << "Lx: " << endl << *Lx << endl;
00376   if(Lxx)
00377     cout << "Lxx: " << endl << *Lxx << endl;
00378   */
00379 
00380   return L;
00381 }
00382 }
00383 
00384 #endif