Simbody
|
00001 #ifndef SimTK_SIMMATRIX_SPATIAL_ALGEBRA_H_ 00002 #define SimTK_SIMMATRIX_SPATIAL_ALGEBRA_H_ 00003 00004 /* -------------------------------------------------------------------------- * 00005 * SimTK Core: SimTK Simmatrix(tm) * 00006 * -------------------------------------------------------------------------- * 00007 * This is part of the SimTK Core biosimulation toolkit originating from * 00008 * Simbios, the NIH National Center for Physics-Based Simulation of * 00009 * Biological Structures at Stanford, funded under the NIH Roadmap for * 00010 * Medical Research, grant U54 GM072970. See https://simtk.org. * 00011 * * 00012 * Portions copyright (c) 2005-10 Stanford University and the Authors. * 00013 * Authors: Michael Sherman * 00014 * Contributors: * 00015 * * 00016 * Permission is hereby granted, free of charge, to any person obtaining a * 00017 * copy of this software and associated documentation files (the "Software"), * 00018 * to deal in the Software without restriction, including without limitation * 00019 * the rights to use, copy, modify, merge, publish, distribute, sublicense, * 00020 * and/or sell copies of the Software, and to permit persons to whom the * 00021 * Software is furnished to do so, subject to the following conditions: * 00022 * * 00023 * The above copyright notice and this permission notice shall be included in * 00024 * all copies or substantial portions of the Software. * 00025 * * 00026 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * 00027 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * 00028 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * 00029 * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 00030 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 00031 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * 00032 * USE OR OTHER DEALINGS IN THE SOFTWARE. * 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 // Pre-declare methods here so that we can list them in whatever order we'd 00084 // like them to appear in Doxygen. 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(); // 3 flops 00145 return ~X_FA.R()*findRelativeVelocityInF(p_AB_F,V_FA,V_FB); // 48 flops 00146 } 00147 00175 inline SpatialVec findRelativeVelocityInF(const Vec3& p_AB_F, 00176 const SpatialVec& V_FA, 00177 const SpatialVec& V_FB) 00178 { 00179 // Relative angular velocity of B in A, expressed in F. 00180 const Vec3 w_AB_F = V_FB[0] - V_FA[0]; // 3 flops 00181 // Relative linear velocity of B in A, taken and expressed in F. 00182 const Vec3 p_AB_F_dot = V_FB[1] - V_FA[1]; // 3 flops 00183 // Get linear velocity taken in A by removing the component due 00184 // to A's rotation in F (still expressed in F). 00185 const Vec3 v_AB_F = p_AB_F_dot - V_FA[0] % p_AB_F; // 12 flops 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 // Reverse the velocity but with the result still expressed in A. 00224 const SpatialVec V_BA_A = reverseRelativeVelocityInA(X_AB,V_AB); 00225 // 21 flops 00226 // Then reexpress in B. 00227 return ~X_AB.R()*V_BA_A; // 30 flops 00228 } 00229 00259 inline SpatialVec reverseRelativeVelocityInA(const Transform& X_AB, 00260 const SpatialVec& V_AB) 00261 { 00262 // Change the measurement point from a point coincident with OB 00263 // to a point coincident with OA, and negate since we want A's velocity 00264 // in B rather than the other way around. 00265 const SpatialVec V_BA_A = -shiftVelocityBy(V_AB, -X_AB.p()); // 21 flops 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 ); } // vp=v + wXr 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]); } // mq = mp - r X f 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 // support for efficient matrix multiplication involving the special phi 00420 // matrix 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], // 12 flops 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()); // 3 flops 00481 return SpatialMat( m(0,0) + x*m(1,0), m(0,1) + x*m(1,1), // 108 flops 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()); // 12 flops 00491 } 00492 00493 00494 inline SpatialMat 00495 operator*(const SpatialMat::THerm& m, 00496 const PhiMatrixTranspose& phiT) 00497 { 00498 const Mat33 x = crossMat(phiT.l()); // 3 flops 00499 return SpatialMat( m(0,0) - m(0,1) * x, m(0,1), // 54 flops 00500 m(1,0) - m(1,1) * x, m(1,1) ); // 54 flops 00501 } 00502 00503 inline SpatialMat 00504 operator*(const SpatialMat& m, 00505 const PhiMatrixTranspose& phiT) 00506 { 00507 const Mat33 x = crossMat(phiT.l()); // 3 flops 00508 return SpatialMat( m(0,0) - m(0,1) * x, m(0,1), // 54 flops 00509 m(1,0) - m(1,1) * x, m(1,1) ); // 54 flops 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 } // namespace SimTK 00524 00525 #endif // SimTK_SIMMATRIX_SPATIAL_ALGEBRA_H_