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