GCOP
1.0
|
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