00001 #ifndef SimTK_SIMMATRIX_SPATIAL_ALGEBRA_H_
00002 #define SimTK_SIMMATRIX_SPATIAL_ALGEBRA_H_
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00039 #include "SimTKcommon/SmallMatrix.h"
00040
00041 #include <iostream>
00042
00043 namespace SimTK {
00044
00045
00074
00076 typedef Vec<2, Vec3> SpatialVec;
00078 typedef Row<2, Row3> SpatialRow;
00080 typedef Mat<2,2, Mat33> SpatialMat;
00081
00082
00083
00084
00085 inline SpatialVec findRelativeVelocity(const Transform& X_FA,
00086 const SpatialVec& V_FA,
00087 const Transform& X_FB,
00088 const SpatialVec& V_FB);
00089 inline SpatialVec findRelativeVelocityInF(const Vec3& p_AB_F,
00090 const SpatialVec& V_FA,
00091 const SpatialVec& V_FB);
00092
00093 inline SpatialVec reverseRelativeVelocity(const Transform& X_AB,
00094 const SpatialVec& V_AB);
00095 inline SpatialVec reverseRelativeVelocityInA(const Transform& X_AB,
00096 const SpatialVec& V_AB);
00097
00098 inline SpatialVec shiftVelocityBy(const SpatialVec& V_AB, const Vec3& r_A);
00099 inline SpatialVec shiftVelocityFromTo(const SpatialVec& V_A_BP,
00100 const Vec3& fromP_A,
00101 const Vec3& toQ_A);
00102
00103 inline SpatialVec shiftForceBy(const SpatialVec& F_AP, const Vec3& r_A);
00104 inline SpatialVec shiftForceFromTo(const SpatialVec& F_AP,
00105 const Vec3& fromP_A,
00106 const Vec3& toQ_A);
00107
00139 inline SpatialVec findRelativeVelocity(const Transform& X_FA,
00140 const SpatialVec& V_FA,
00141 const Transform& X_FB,
00142 const SpatialVec& V_FB)
00143 {
00144 const Vec3 p_AB_F = X_FB.p() - X_FA.p();
00145 return ~X_FA.R()*findRelativeVelocityInF(p_AB_F,V_FA,V_FB);
00146 }
00147
00175 inline SpatialVec findRelativeVelocityInF(const Vec3& p_AB_F,
00176 const SpatialVec& V_FA,
00177 const SpatialVec& V_FB)
00178 {
00179
00180 const Vec3 w_AB_F = V_FB[0] - V_FA[0];
00181
00182 const Vec3 p_AB_F_dot = V_FB[1] - V_FA[1];
00183
00184
00185 const Vec3 v_AB_F = p_AB_F_dot - V_FA[0] % p_AB_F;
00186
00187 return SpatialVec(w_AB_F, v_AB_F);
00188 }
00189
00220 inline SpatialVec reverseRelativeVelocity(const Transform& X_AB,
00221 const SpatialVec& V_AB)
00222 {
00223
00224 const SpatialVec V_BA_A = reverseRelativeVelocityInA(X_AB,V_AB);
00225
00226
00227 return ~X_AB.R()*V_BA_A;
00228 }
00229
00259 inline SpatialVec reverseRelativeVelocityInA(const Transform& X_AB,
00260 const SpatialVec& V_AB)
00261 {
00262
00263
00264
00265 const SpatialVec V_BA_A = -shiftVelocityBy(V_AB, -X_AB.p());
00266 return V_BA_A;
00267 }
00268
00269
00300 inline SpatialVec shiftVelocityBy(const SpatialVec& V_AB, const Vec3& r_A)
00301 { return SpatialVec( V_AB[0], V_AB[1] + V_AB[0] % r_A ); }
00302
00336 inline SpatialVec shiftVelocityFromTo(const SpatialVec& V_A_BP,
00337 const Vec3& fromP_A,
00338 const Vec3& toQ_A)
00339 { return shiftVelocityBy(V_A_BP, toQ_A - fromP_A); }
00340
00341
00342
00372 inline SpatialVec shiftForceBy(const SpatialVec& F_AP, const Vec3& r_A)
00373 { return SpatialVec(F_AP[0] - r_A % F_AP[1], F_AP[1]); }
00374
00375
00411 inline SpatialVec shiftForceFromTo(const SpatialVec& F_AP,
00412 const Vec3& fromP_A,
00413 const Vec3& toQ_A)
00414 { return shiftForceBy(F_AP, toQ_A - fromP_A); }
00415
00419
00420
00421
00422 class PhiMatrixTranspose;
00423
00424 class PhiMatrix {
00425 public:
00426 typedef PhiMatrixTranspose TransposeType;
00427
00428 PhiMatrix() { setToNaN(); }
00429 PhiMatrix(const Vec3& l) : l_(l) {}
00430
00431 void setToZero() { l_ = 0.; }
00432 void setToNaN() { l_.setToNaN(); }
00433
00434 SpatialMat toSpatialMat() const {
00435 return SpatialMat(Mat33(1), crossMat(l_),
00436 Mat33(0), Mat33(1));
00437 }
00438
00439 const Vec3& l() const { return l_; }
00440 private:
00441 Vec3 l_;
00442 };
00443
00444 class PhiMatrixTranspose {
00445 public:
00446 PhiMatrixTranspose(const PhiMatrix& phi) : phi(phi) {}
00447
00448 SpatialMat toSpatialMat() const {
00449 return SpatialMat( Mat33(1) , Mat33(0),
00450 crossMat(-l()) , Mat33(1));
00451 }
00452
00453 const Vec3& l() const {return phi.l();}
00454 private:
00455 const PhiMatrix& phi;
00456 };
00457
00458 inline PhiMatrixTranspose
00459 transpose(const PhiMatrix& phi)
00460 {
00461 PhiMatrixTranspose ret(phi);
00462 return ret;
00463 }
00464
00465 inline PhiMatrixTranspose
00466 operator~(const PhiMatrix& phi) {return transpose(phi);}
00467
00468 inline SpatialVec
00469 operator*(const PhiMatrix& phi,
00470 const SpatialVec& v)
00471 {
00472 return SpatialVec(v[0] + phi.l() % v[1],
00473 v[1]);
00474 }
00475
00476 inline SpatialMat
00477 operator*(const PhiMatrix& phi,
00478 const SpatialMat& m)
00479 {
00480 const Mat33 x = crossMat(phi.l());
00481 return SpatialMat( m(0,0) + x*m(1,0), m(0,1) + x*m(1,1),
00482 m(1,0) , m(1,1));
00483 }
00484
00485 inline SpatialVec
00486 operator*(const PhiMatrixTranspose& phiT,
00487 const SpatialVec& v)
00488 {
00489 return SpatialVec(v[0],
00490 v[1] + v[0] % phiT.l());
00491 }
00492
00493
00494 inline SpatialMat
00495 operator*(const SpatialMat::THerm& m,
00496 const PhiMatrixTranspose& phiT)
00497 {
00498 const Mat33 x = crossMat(phiT.l());
00499 return SpatialMat( m(0,0) - m(0,1) * x, m(0,1),
00500 m(1,0) - m(1,1) * x, m(1,1) );
00501 }
00502
00503 inline SpatialMat
00504 operator*(const SpatialMat& m,
00505 const PhiMatrixTranspose& phiT)
00506 {
00507 const Mat33 x = crossMat(phiT.l());
00508 return SpatialMat( m(0,0) - m(0,1) * x, m(0,1),
00509 m(1,0) - m(1,1) * x, m(1,1) );
00510 }
00511
00512 inline bool
00513 operator==(const PhiMatrix& p1, const PhiMatrix& p2)
00514 {
00515 return p1.l() == p2.l();
00516 }
00517
00518 inline bool
00519 operator==(const PhiMatrixTranspose& p1, const PhiMatrixTranspose& p2)
00520 {
00521 return p1.l() == p2.l();
00522 }
00523 }
00524
00525 #endif // SimTK_SIMMATRIX_SPATIAL_ALGEBRA_H_