GCOP
1.0
|
00001 #ifndef GCOP_BODY3D_H 00002 #define GCOP_BODY3D_H 00003 00004 #include "system.h" 00005 #include "body3dmanifold.h" 00006 #include "so3.h" 00007 #include "se3.h" 00008 #include <limits> 00009 #include <iostream> 00010 #include <utility> 00011 #include "function.h" 00012 00013 namespace gcop { 00014 00015 using namespace std; 00016 using namespace Eigen; 00017 00018 typedef Matrix<double, 6, 1> Vector6d; 00019 typedef Matrix<double, 6, 6> Matrix6d; 00020 typedef Matrix<double, 12, 1> Vector12d; 00021 typedef Matrix<double, 12, 12> Matrix12d; 00022 typedef Matrix<double, 12, 6> Matrix12x6d; 00023 00031 template <int c = 6> class Body3d : public System<Body3dState, 12, c> { 00032 protected: 00033 00034 typedef Matrix<double, c, 1> Vectorcd; 00035 typedef Matrix<double, c, c> Matrixcd; 00036 typedef Matrix<double, 6, c> Matrix6xcd; 00037 typedef Matrix<double, 12, c> Matrix12xcd; 00038 typedef Matrix<double, 12, Dynamic> Matrix12Xd; 00039 00040 public: 00041 00042 Body3d(); 00043 00044 Body3d(const Vector3d &ds, double m); 00045 00046 Body3d(const Vector3d &ds, double m, const Vector3d &J); 00047 00048 virtual ~Body3d(); 00049 00050 virtual double Step(Body3dState &xb, double t, const Body3dState &xa, 00051 const Vectorcd &u, double h, const VectorXd *p = 0, 00052 Matrix12d *A = 0, Matrix12xcd *B = 0, Matrix12Xd *C = 0); 00053 00054 virtual bool NoiseMatrix(Matrix12d &Q, double t, const Body3dState &x, 00055 const Vectorcd &u, double h, const VectorXd *p = 0); 00056 00057 00058 double SympStep(double t, Body3dState &xb, const Body3dState &xa, 00059 const Vectorcd &u, double h, const VectorXd *p = 0, 00060 Matrix12d *A = 0, Matrix12xcd *B = 0, Matrix12Xd *C = 0); 00061 00062 double EulerStep(double t, Body3dState &xb, const Body3dState &xa, 00063 const Vectorcd &u, double h, const VectorXd *p = 0, 00064 Matrix12d *A = 0, Matrix12xcd *B = 0, Matrix12Xd *C = 0); 00065 00066 00067 00077 void ID(Vector6d &f, 00078 double t, const Body3dState &xb, const Body3dState &xa, 00079 const Vectorcd &u, double h); 00080 00081 void StateAndControlsToFlat(VectorXd &y, const Body3dState &x, const Vectorcd &u); 00082 00083 void FlatToStateAndControls(Body3dState &x, Vectorcd &u, const std::vector<VectorXd> &y); 00084 00091 static void Compute(Vector3d &J, double m, const Vector3d &ds); 00092 00099 static void Compute(Vector6d &I, double m, const Vector3d &ds); 00100 00101 Vector3d ds; 00102 00103 double m; 00104 00105 Vector3d J; 00106 00107 Vector6d I; 00108 00109 Vector6d Ii; 00110 00111 Vector3d Dw; 00112 00113 Vector3d Dv; 00114 00115 Vector3d fp; 00116 00117 Matrix6xcd Bu; 00118 00119 bool symp; 00120 00121 string name; 00122 00123 double sw; 00124 double sv; 00125 00126 }; 00127 00128 00129 00130 template <int c> 00131 Body3d<c>::Body3d() : 00132 System<Body3dState, 12, c>(Body3dManifold::Instance()), 00133 ds(.6, .6, .2), m(1), 00134 Dw(0,0,0), 00135 Dv(0,0,0), 00136 fp(0,0,0), 00137 Bu(Matrix<double, 6, c>::Identity()), 00138 symp(true), 00139 sw(0), sv(0) { 00140 00141 Compute(J, m, ds); 00142 Compute(I, m, ds); 00143 } 00144 00145 00146 template <int c> 00147 Body3d<c>::Body3d(const Vector3d &ds, double m) : 00148 System<Body3dState, 12, c>(Body3dManifold::Instance()), 00149 ds(ds), m(m), 00150 Dw(0,0,0), 00151 Dv(0,0,0), 00152 fp(0,0,0), 00153 Bu(Matrix<double, 6, c>::Identity()), 00154 symp(true), 00155 sw(0), sv(0) { 00156 00157 Compute(J, m, ds); 00158 Compute(I, m, ds); 00159 } 00160 00161 template <int c> 00162 Body3d<c>::Body3d(const Vector3d &ds, double m, const Vector3d &J) : 00163 System<Body3dState, 12, c>(Body3dManifold::Instance()), 00164 ds(ds), m(m), J(J), 00165 Dw(0,0,0), 00166 Dv(0,0,0), 00167 fp(0,0,0), 00168 Bu(Matrix<double, 6, c>::Identity()), 00169 symp(true), 00170 sw(0), sv(0) { 00171 00172 } 00173 00174 template<int c> Body3d<c>::~Body3d() 00175 { 00176 } 00177 00178 template <int c> 00179 void Body3d<c>::Compute(Vector3d &J, double m, const Vector3d &ds) { 00180 J[0] = m*(ds[1]*ds[1] + ds[2]*ds[2])/3; 00181 J[1] = m*(ds[0]*ds[0] + ds[2]*ds[2])/3; 00182 J[2] = m*(ds[0]*ds[0] + ds[1]*ds[1])/3; 00183 } 00184 00185 template <int c> 00186 void Body3d<c>::Compute(Vector6d &I, double m, const Vector3d &ds) { 00187 I[0] = m*(ds[1]*ds[1] + ds[2]*ds[2])/3; 00188 I[1] = m*(ds[0]*ds[0] + ds[2]*ds[2])/3; 00189 I[2] = m*(ds[0]*ds[0] + ds[1]*ds[1])/3; 00190 I[3] = m; 00191 I[4] = m; 00192 I[5] = m; 00193 } 00194 00195 00196 template <int c> 00197 bool Body3d<c>::NoiseMatrix(Matrix12d &Q, 00198 double t, const Body3dState &x, 00199 const Vectorcd &u, double dt, 00200 const VectorXd *p) { 00201 Q.setZero(); 00202 double dt2 = dt*dt/2; 00203 Q(0,6) = sw*dt2/J(0); 00204 Q(1,7) = sw*dt2/J(1); 00205 Q(2,8) = sw*dt2/J(2); 00206 Q(3,9) = sv*dt2/m; 00207 Q(4,10) = sv*dt2/m; 00208 Q(5,11) = sv*dt2/m; 00209 00210 Q(6,6) = sw*dt/J(0); 00211 Q(7,7) = sw*dt/J(1); 00212 Q(8,8) = sw*dt/J(2); 00213 Q(9,9) = sv*dt/m; 00214 Q(10,10) = sv*dt/m; 00215 Q(11,11) = sv*dt/m; 00216 return true; 00217 } 00218 00219 00220 00221 static void Gcay(Matrix3d& m1, const Vector3d &w, const Vector3d &J, double h, bool plus = true) { 00222 SO3 &so3 = SO3::Instance(); 00223 Matrix3d wh; 00224 so3.hat(wh, w); 00225 00226 Matrix3d Jwh; 00227 Vector3d Jw = J.cwiseProduct(w); 00228 so3.hat(Jwh, Jw); 00229 00230 int s = (plus ? 1 : -1); 00231 00232 m1 = (so3.Id + ((h*h/2)*w)*w.transpose())*J.asDiagonal() + (s*h/2)*(-Jwh + wh*J.asDiagonal()) + (h*h/4*w.dot(Jw))*so3.Id; 00233 /* 00234 m << J1*((h^2*v1^2)/4 + 1) + (J1*h^2*v1^2)/2 + (J2*h^2*v2^2)/4 + (J3*h^2*v3^2)/4, J2*((v1*v2*h^2)/4 + (v3*h)/2) - (J3*h*v3)/2 + (J2*h^2*v1*v2)/4, (J2*h*v2)/2 - J3*((h*v2)/2 - (h^2*v1*v3)/4) + (J3*h^2*v1*v3)/4] 00235 [ (J3*h*v3)/2 - J1*((h*v3)/2 - (h^2*v1*v2)/4) + (J1*h^2*v1*v2)/4, J2*((h^2*v2^2)/4 + 1) + (J1*h^2*v1^2)/4 + (J2*h^2*v2^2)/2 + (J3*h^2*v3^2)/4, J3*((v2*v3*h^2)/4 + (v1*h)/2) - (J1*h*v1)/2 + (J3*h^2*v2*v3)/4] 00236 [ J1*((v1*v3*h^2)/4 + (v2*h)/2) - (J2*h*v2)/2 + (J1*h^2*v1*v3)/4, (J1*h*v1)/2 - J2*((h*v1)/2 - (h^2*v2*v3)/4) + (J2*h^2*v2*v3)/4, J3*((h^2*v3^2)/4 + 1) + (J1*h^2*v1^2)/4 + (J2*h^2*v2^2)/4 + (J3*h^2*v3^2)/2] 00237 00238 */ 00239 } 00240 00241 template <int c> 00242 double Body3d<c>::Step(Body3dState &xb, double t, const Body3dState &xa, 00243 const Matrix<double, c, 1> &u, double h, const VectorXd *p, 00244 Matrix12d *A, Matrix<double, 12, c> *B, Matrix12Xd *C) { 00245 if (symp) 00246 return SympStep(t, xb, xa, u, h, p, A, B, C); 00247 else 00248 return EulerStep(t, xb, xa, u, h, p, A, B, C); 00249 } 00250 00251 template <int c> 00252 double Body3d<c>::SympStep(double t, Body3dState &xb, const Body3dState &xa, 00253 const Matrix<double, c, 1> &u, double h, const VectorXd *p, 00254 Matrix12d *A, Matrix<double, 12, c> *B, Matrix12Xd *C) { 00255 // cwiseProduct 00256 00257 SO3 &so3 = SO3::Instance(); 00258 00259 const Matrix3d &Ra = xa.first; 00260 const Vector3d &pa = xa.second.head<3>(); 00261 const Vector3d &wa = xa.second.segment<3>(3); 00262 const Vector3d &va = xa.second.tail<3>(); 00263 00264 Matrix3d &Rb = xb.first; 00265 00266 Matrix3d Da, Db; 00267 00268 // initialize wb 00269 Vector3d wb = wa; 00270 so3.dcayinv(Da, -h*wa); 00271 so3.dcayinv(Db, h*wb); 00272 00273 Vector3d Jwa = J.cwiseProduct(wa); 00274 Vector3d Jwb = J.cwiseProduct(wb); 00275 00276 Vector3d fuw = Bu.topRows(3)*u; 00277 Vector3d fwd = Db.transpose()*Jwb - Da.transpose()*Jwa - h*fuw; 00278 00279 Matrix3d Gp; 00280 Gcay(Gp, wb, J, h); 00281 00282 Matrix3d Gm; 00283 Gcay(Gm, wa, J, h, false); 00284 00285 // Newton step 00286 Matrix3d Gi = Gp.inverse(); 00287 wb = wb - Gi*fwd; 00288 // wb = wa + Jwa.cross(wa) + h*fuw; 00289 00290 // update Gi 00291 Gcay(Gp, wb, J, h); 00292 Gi = Gp.inverse(); 00293 00294 Matrix3d chwb; 00295 so3.cay(chwb, h*wb); 00296 Rb = Ra*chwb; 00297 00298 Vector3d fuv = Bu.bottomRows(3)*u; 00299 00300 const Matrix3d &I3 = Matrix3d::Identity(); 00301 00302 Vector3d vb; 00303 Vector3d pb; 00304 00305 bool vdamp = (Dv.norm() > 1e-16); // is there linear velocity damping 00306 // modified mass matrix to include damping 00307 Matrix3d Mp; 00308 Matrix3d Mm; 00309 00310 if (vdamp) { 00311 Mp = I3*m + h/2*(Ra*Dv.asDiagonal()); 00312 Mm = I3*m - h/2*(Ra*Dv.asDiagonal()); 00313 00314 vb = Mp.inverse()*(Mm*va + h*(fp + Ra*fuv)); 00315 pb = pa + h*vb; 00316 } else { 00317 vb = va + h/m*(fp + Ra*fuv); 00318 pb = pa + h*vb; 00319 } 00320 00321 xb.second.head<3>() = pb; 00322 xb.second.segment<3>(3) = wb; 00323 xb.second.tail<3>() = vb; 00324 00325 // return 1; 00326 00327 if (A) { 00328 Matrix6d D1; 00329 D1.setZero(); 00330 D1.topLeftCorner<3,3>() = -Gm; 00331 D1.bottomRightCorner<3,3>() = -m*I3; 00332 00333 Matrix6d D2; 00334 D2.setZero(); 00335 Matrix3d fuvh; 00336 so3.hat(fuvh, fuv); 00337 D2.bottomLeftCorner<3,3>() = h*Ra*fuvh; 00338 00339 Matrix6xcd D3; 00340 D3.topRows(3) = -h*Bu.topRows(3); 00341 D3.bottomRows(3) = -h*Ra*Bu.bottomRows(3); 00342 00343 Matrix3d cb; 00344 so3.cay(cb, -h*wb); 00345 00346 Matrix3d Adcb; 00347 so3.Ad(Adcb, cb); 00348 00349 Matrix3d dcb; 00350 so3.dcay(dcb, -h*wb); 00351 00352 Matrix12d A1; 00353 A1.setZero(); 00354 A1.topLeftCorner<3,3>() = Adcb; 00355 A1.block<3,3>(3,3) = I3; 00356 A1.block<3,3>(0,6) = h*dcb*Gi; 00357 A1.block<3,3>(3,9) = (h/m)*I3; 00358 00359 A1.block<3,3>(6,6) = Gi; 00360 A1.block<3,3>(9,9) = I3/m; 00361 00362 Matrix12d A2; 00363 A2.setIdentity(); 00364 A2.block<6,6>(6,0) = -D2; 00365 A2.block<6,6>(6,6) = -D1; 00366 00367 (*A) = A1*A2; 00368 00369 if (B) { 00370 (*B) = -A1.rightCols<6>()*D3; 00371 } 00372 } 00373 return 1; 00374 } 00375 00376 template <int c> 00377 double Body3d<c>::EulerStep(double t, Body3dState &xb, const Body3dState &xa, 00378 const Matrix<double, c, 1> &u, double h, const VectorXd *p, 00379 Matrix12d *A, Matrix<double, 12, c> *B, Matrix12Xd *C) { 00380 // cwiseProduct 00381 00382 SO3 &so3 = SO3::Instance(); 00383 00384 const Matrix3d &Ra = xa.first; 00385 const Vector3d &pa = xa.second.head<3>(); 00386 const Vector3d &wa = xa.second.segment<3>(3); 00387 const Vector3d &va = xa.second.tail<3>(); 00388 00389 Matrix3d &Rb = xb.first; 00390 00391 Vector3d Jwa = J.cwiseProduct(wa); 00392 00393 Vector3d wb = wa + h*(Jwa.cross(wa) + Dw.cwiseProduct(wa) + Bu.topRows(3)*u).cwiseQuotient(J); 00394 00395 Matrix3d chwb; 00396 so3.cay(chwb, h*wb); 00397 Rb = Ra*chwb; 00398 00399 Vector3d fuv = Dv.cwiseProduct(Ra.transpose()*va) + Bu.bottomRows(3)*u; 00400 00401 Vector3d vb = va + h/m*(fp + Ra*fuv); 00402 00403 xb.second.head<3>() = pa + h*vb; 00404 xb.second.segment<3>(3) = wb; 00405 xb.second.tail<3>() = vb; 00406 00407 Matrix3d Jwah; 00408 so3.hat(Jwah, Jwa); 00409 00410 Matrix3d wah; 00411 so3.hat(wah, wa); 00412 00413 const Matrix3d &I3 = Matrix3d::Identity(); 00414 00415 if (A) { 00416 Matrix6d D1; 00417 D1.setZero(); 00418 D1.topLeftCorner<3,3>() = -Matrix3d(J.asDiagonal()) - h*(Jwah + Matrix3d(Dw.asDiagonal())) + wah*(J.asDiagonal()); 00419 D1.bottomRightCorner<3,3>() = -m*I3; 00420 00421 Matrix6d D2; 00422 D2.setZero(); 00423 Matrix3d fuvh; 00424 so3.hat(fuvh, fuv); 00425 D2.bottomLeftCorner<3,3>() = h*Ra*fuvh; 00426 00427 Matrix6xcd D3; 00428 D3.topRows(3) = -h*Bu.topRows(3); 00429 D3.bottomRows(3) = -h*Ra*Bu.bottomRows(3); 00430 00431 Matrix3d cb; 00432 so3.cay(cb, -h*wb); 00433 00434 Matrix3d Adcb; 00435 so3.Ad(Adcb, cb); 00436 00437 Matrix3d dcb; 00438 so3.dcay(dcb, -h*wb); 00439 00440 Matrix12d A1; 00441 A1.setZero(); 00442 A1.topLeftCorner<3,3>() = Adcb; 00443 A1.block<3,3>(3,3) = I3; 00444 A1.block<3,3>(0,6) = h*dcb*J.asDiagonal().inverse(); 00445 A1.block<3,3>(3,9) = (h/m)*I3; 00446 00447 A1.block<3,3>(6,6) = J.asDiagonal().inverse(); 00448 A1.block<3,3>(9,9) = I3/m; 00449 00450 Matrix12d A2; 00451 A2.setIdentity(); 00452 A2.block<3,3>(0,0).diagonal() -= h*Dw.cwiseQuotient(J); 00453 A2.block<3,3>(3,3) -= (h/m)*Ra*Dv.asDiagonal()*Ra; 00454 A2.block<6,6>(6,0) = -D2; 00455 A2.block<6,6>(6,6) = -D1; 00456 00457 (*A) = A1*A2; 00458 00459 if (B) { 00460 (*B) = -A1.rightCols<6>()*D3; 00461 } 00462 } 00463 return 1; 00464 } 00465 00466 00467 00468 00469 template <int c> 00470 void Body3d<c>::ID(Vector6d &f, 00471 double t, const Body3dState &xb, const Body3dState &xa, 00472 const Vectorcd &u, double h) { 00473 } 00474 00475 template <int c> 00476 void Body3d<c>::StateAndControlsToFlat(VectorXd &y, const Body3dState &x, 00477 const Vectorcd &u) { 00478 SO3& so3 = SO3::Instance(); 00479 00480 // Flat outputs are x,y,z, and rpy 00481 y.resize(6); 00482 y.head<3>() = x.second.head<3>(); 00483 y(3) = so3.roll(x.first); 00484 y(4) = so3.pitch(x.first); 00485 y(5) = so3.yaw(x.first); 00486 } 00487 00488 template <int c> 00489 void Body3d<c>::FlatToStateAndControls(Body3dState &x, Vectorcd &u, 00490 const std::vector<VectorXd> &y) { 00491 assert(y.size() >= 2); 00492 00493 SO3& so3 = SO3::Instance(); 00494 00495 VectorXd y0 = y[0]; 00496 VectorXd y1 = y[1]; 00497 00498 x.first.setZero(); 00499 x.second.setZero(); 00500 u.setZero(); 00501 00502 so3.q2g(x.first, y0.tail<3>()); 00503 00504 x.second.head<3>() = y0.head<3>(); 00505 x.second.tail<3>() = y1.head<3>(); 00506 // TODO: fill in angular velocity and controls 00507 x.second(5) = y1(5); 00508 } 00509 } 00510 #endif 00511 00512 00513 00514 /* 00515 00516 for reference: properties that ROS uses 00517 00518 class Geometry 00519 { 00520 public: 00521 enum {SPHERE, BOX, CYLINDER, MESH} type; 00522 }; 00523 00524 class Sphere : public Geometry 00525 { 00526 public: 00527 Sphere() { this->clear(); }; 00528 double radius; 00529 void clear() 00530 { 00531 radius = 0; 00532 }; 00533 }; 00534 00535 class Box : public Geometry 00536 { 00537 public: 00538 Box() { this->clear(); }; 00539 Vector3d dim; 00540 00541 void clear() 00542 { 00543 dim << 1, 1, 1; 00544 }; 00545 }; 00546 00547 class Cylinder : public Geometry 00548 { 00549 public: 00550 Cylinder() { this->clear(); }; 00551 double length; 00552 double radius; 00553 00554 void clear() 00555 { 00556 length = 0; 00557 radius = 0; 00558 }; 00559 }; 00560 00561 class Mesh : public Geometry 00562 { 00563 public: 00564 Mesh() { this->clear(); }; 00565 std::string filename; 00566 Vector3d scale; 00567 00568 void clear() 00569 { 00570 filename.clear(); 00571 scale << 1,1,1; 00572 }; 00573 // bool initXml(TiXmlElement *); 00574 // bool fileExists(std::string filename); 00575 }; 00576 00577 00578 class Material 00579 { 00580 public: 00581 Material() { this->clear(); }; 00582 std::string name; 00583 std::string texture_filename; 00584 Vector4d color; 00585 00586 void clear() 00587 { 00588 color << .5, .5, .5, .5; 00589 texture_filename.clear(); 00590 name.clear(); 00591 }; 00592 // bool initXml(TiXmlElement* config); 00593 }; 00594 class Visual 00595 { 00596 public: 00597 Visual() { this->clear(); }; 00598 Matrix4d origin; 00599 boost::shared_ptr<Geometry> geometry; 00600 00601 std::string material_name; 00602 boost::shared_ptr<Material> material; 00603 00604 void clear() 00605 { 00606 origin.setIdentity(); 00607 material_name.clear(); 00608 material.reset(); 00609 geometry.reset(); 00610 this->group_name.clear(); 00611 }; 00612 // bool initXml(TiXmlElement* config); 00613 std::string group_name; 00614 }; 00615 00616 00617 class Collision 00618 { 00619 public: 00620 Collision() { this->clear(); }; 00621 Matrix4d origin; 00622 // Pose origin; 00623 boost::shared_ptr<Geometry> geometry; 00624 00625 void clear() 00626 { 00627 origin.setIdentity(); 00628 geometry.reset(); 00629 this->group_name.clear(); 00630 }; 00631 // bool initXml(TiXmlElement* config); 00632 std::string group_name; 00633 }; 00634 */