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