Simbody
3.4 (development)
|
00001 #ifndef SimTK_SIMMATRIX_SPATIAL_ALGEBRA_H_ 00002 #define SimTK_SIMMATRIX_SPATIAL_ALGEBRA_H_ 00003 00004 /* -------------------------------------------------------------------------- * 00005 * Simbody(tm): SimTKcommon * 00006 * -------------------------------------------------------------------------- * 00007 * This is part of the SimTK 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/home/simbody. * 00011 * * 00012 * Portions copyright (c) 2005-12 Stanford University and the Authors. * 00013 * Authors: Michael Sherman * 00014 * Contributors: * 00015 * * 00016 * Licensed under the Apache License, Version 2.0 (the "License"); you may * 00017 * not use this file except in compliance with the License. You may obtain a * 00018 * copy of the License at http://www.apache.org/licenses/LICENSE-2.0. * 00019 * * 00020 * Unless required by applicable law or agreed to in writing, software * 00021 * distributed under the License is distributed on an "AS IS" BASIS, * 00022 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 00023 * See the License for the specific language governing permissions and * 00024 * limitations under the License. * 00025 * -------------------------------------------------------------------------- */ 00026 00031 #include "SimTKcommon/SmallMatrix.h" 00032 00033 #include <iostream> 00034 00035 namespace SimTK { 00036 00037 00068 typedef Vec<2, Vec3> SpatialVec; 00070 typedef Row<2, Row3> SpatialRow; 00072 typedef Mat<2,2, Mat33> SpatialMat; 00073 00074 00075 // Pre-declare methods here so that we can list them in whatever order we'd 00076 // like them to appear in Doxygen. 00077 inline SpatialVec findRelativeVelocity( const Transform& X_FA, 00078 const SpatialVec& V_FA, 00079 const Transform& X_FB, 00080 const SpatialVec& V_FB); 00081 inline SpatialVec findRelativeVelocityInF( const Vec3& p_AB_F, 00082 const SpatialVec& V_FA, 00083 const SpatialVec& V_FB); 00084 00085 inline SpatialVec findRelativeAcceleration( const Transform& X_FA, 00086 const SpatialVec& V_FA, 00087 const SpatialVec& A_FA, 00088 const Transform& X_FB, 00089 const SpatialVec& V_FB, 00090 const SpatialVec& A_FB); 00091 inline SpatialVec findRelativeAccelerationInF( const Vec3& p_AB_F, 00092 const SpatialVec& V_FA, 00093 const SpatialVec& A_FA, 00094 const SpatialVec& V_FB, 00095 const SpatialVec& A_FB); 00096 00097 inline SpatialVec reverseRelativeVelocity(const Transform& X_AB, 00098 const SpatialVec& V_AB); 00099 inline SpatialVec reverseRelativeVelocityInA(const Transform& X_AB, 00100 const SpatialVec& V_AB); 00101 00102 inline SpatialVec shiftVelocityBy(const SpatialVec& V_AB, const Vec3& r_A); 00103 inline SpatialVec shiftVelocityFromTo(const SpatialVec& V_A_BP, 00104 const Vec3& fromP_A, 00105 const Vec3& toQ_A); 00106 00107 inline SpatialVec shiftForceBy(const SpatialVec& F_AP, const Vec3& r_A); 00108 inline SpatialVec shiftForceFromTo(const SpatialVec& F_AP, 00109 const Vec3& fromP_A, 00110 const Vec3& toQ_A); 00111 00112 00113 00114 //============================================================================== 00115 // FIND RELATIVE VELOCITY 00116 //============================================================================== 00148 inline SpatialVec findRelativeVelocity(const Transform& X_FA, 00149 const SpatialVec& V_FA, 00150 const Transform& X_FB, 00151 const SpatialVec& V_FB) 00152 { 00153 const Vec3 p_AB_F = X_FB.p() - X_FA.p(); // 3 flops 00154 return ~X_FA.R()*findRelativeVelocityInF(p_AB_F,V_FA,V_FB); // 48 flops 00155 } 00156 00157 00158 00159 //============================================================================== 00160 // FIND RELATIVE VELOCITY IN F 00161 //============================================================================== 00189 inline SpatialVec findRelativeVelocityInF(const Vec3& p_AB_F, 00190 const SpatialVec& V_FA, 00191 const SpatialVec& V_FB) 00192 { 00193 // Relative angular velocity of B in A, expressed in F. 00194 const Vec3 w_AB_F = V_FB[0] - V_FA[0]; // 3 flops 00195 // Relative linear velocity of B in A, taken and expressed in F. 00196 const Vec3 p_AB_F_dot = V_FB[1] - V_FA[1]; // 3 flops 00197 // Get linear velocity taken in A by removing the component due 00198 // to A's rotation in F (still expressed in F). 00199 const Vec3 v_AB_F = p_AB_F_dot - V_FA[0] % p_AB_F; // 12 flops 00200 00201 return SpatialVec(w_AB_F, v_AB_F); 00202 } 00203 00204 00205 00206 //============================================================================== 00207 // FIND RELATIVE ACCELERATION 00208 //============================================================================== 00245 inline SpatialVec findRelativeAcceleration( const Transform& X_FA, 00246 const SpatialVec& V_FA, 00247 const SpatialVec& A_FA, 00248 const Transform& X_FB, 00249 const SpatialVec& V_FB, 00250 const SpatialVec& A_FB) 00251 { 00252 const Vec3 p_AB_F = X_FB.p() - X_FA.p(); // 3 flops 00253 return ~X_FA.R() * // 30 flops 00254 findRelativeAccelerationInF(p_AB_F,V_FA,A_FA,V_FB,A_FB); // 72 flops 00255 } 00256 00257 00258 00259 //============================================================================== 00260 // FIND RELATIVE ACCELERATION IN F 00261 //============================================================================== 00295 inline SpatialVec findRelativeAccelerationInF( const Vec3& p_AB_F, 00296 const SpatialVec& V_FA, 00297 const SpatialVec& A_FA, 00298 const SpatialVec& V_FB, 00299 const SpatialVec& A_FB) 00300 { 00301 const Vec3& w_FA = V_FA[0]; // aliases for convenience 00302 const Vec3& w_FB = V_FB[0]; 00303 const Vec3& b_FA = A_FA[0]; 00304 const Vec3& b_FB = A_FB[0]; 00305 00306 const Vec3 p_AB_F_dot = V_FB[1] - V_FA[1]; // d/dt p taken in F (3 flops) 00307 const Vec3 p_AB_F_dotdot = A_FB[1] - A_FA[1]; // d^2/dt^2 taken in F (3 flops) 00308 00309 const Vec3 w_AB_F = // relative angvel of B in A, exp. in F 00310 w_FB - w_FA; // (3 flops) 00311 const Vec3 v_AB_F = // d/dt p taken in A, exp in F 00312 p_AB_F_dot - w_FA % p_AB_F; // (12 flops) 00313 00314 const Vec3 w_AB_F_dot = b_FB - b_FA; // d/dt of w_AB_F taken in F (3 flops) 00315 const Vec3 v_AB_F_dot = // d/dt v_AB_F taken in F 00316 p_AB_F_dotdot - (b_FA % p_AB_F + w_FA % p_AB_F_dot); // (24 flops) 00317 00318 // We have the derivative in F; change it to derivative in A by adding in 00319 // contribution caused by motion of F in A, that is w_AF X w_AB_F. (Note 00320 // that w_AF=-w_FA.) 00321 const Vec3 b_AB_F = // ang. accel. of B in A, exp. in F 00322 w_AB_F_dot - w_FA % w_AB_F; // (12 flops) 00323 const Vec3 a_AB_F = // taken in A, exp. in F 00324 v_AB_F_dot - w_FA % v_AB_F; // (12 flops) 00325 00326 return SpatialVec(b_AB_F, a_AB_F); // taken in A, expressed in F 00327 } 00328 00329 00330 00331 //============================================================================== 00332 // REVERSE RELATIVE VELOCITY 00333 //============================================================================== 00364 inline SpatialVec reverseRelativeVelocity(const Transform& X_AB, 00365 const SpatialVec& V_AB) 00366 { 00367 // Reverse the velocity but with the result still expressed in A. 00368 const SpatialVec V_BA_A = reverseRelativeVelocityInA(X_AB,V_AB); 00369 // 21 flops 00370 // Then reexpress in B. 00371 return ~X_AB.R()*V_BA_A; // 30 flops 00372 } 00373 00374 00375 00376 //============================================================================== 00377 // REVERSE RELATIVE VELOCITY IN A 00378 //============================================================================== 00408 inline SpatialVec reverseRelativeVelocityInA(const Transform& X_AB, 00409 const SpatialVec& V_AB) 00410 { 00411 // Change the measurement point from a point coincident with OB 00412 // to a point coincident with OA, and negate since we want A's velocity 00413 // in B rather than the other way around. 00414 const SpatialVec V_BA_A = -shiftVelocityBy(V_AB, -X_AB.p()); // 21 flops 00415 return V_BA_A; 00416 } 00417 00418 00419 00420 //============================================================================== 00421 // SHIFT VELOCITY BY 00422 //============================================================================== 00453 inline SpatialVec shiftVelocityBy(const SpatialVec& V_AB, const Vec3& r_A) 00454 { return SpatialVec( V_AB[0], V_AB[1] + V_AB[0] % r_A ); } // vp=v + wXr 00455 00456 00457 //============================================================================== 00458 // SHIFT VELOCITY FROM TO 00459 //============================================================================== 00493 inline SpatialVec shiftVelocityFromTo(const SpatialVec& V_A_BP, 00494 const Vec3& fromP_A, 00495 const Vec3& toQ_A) 00496 { return shiftVelocityBy(V_A_BP, toQ_A - fromP_A); } 00497 00498 00499 00500 //============================================================================== 00501 // SHIFT ACCELERATION BY 00502 //============================================================================== 00536 inline SpatialVec shiftAccelerationBy(const SpatialVec& A_AB, 00537 const Vec3& w_AB, 00538 const Vec3& r_A) 00539 { return SpatialVec( A_AB[0], 00540 A_AB[1] + A_AB[0] % r_A + w_AB % (w_AB % r_A) ); } 00541 00542 00543 00544 //============================================================================== 00545 // SHIFT ACCELERATION FROM TO 00546 //============================================================================== 00585 inline SpatialVec shiftAccelerationFromTo(const SpatialVec& A_A_BP, 00586 const Vec3& w_AB, 00587 const Vec3& fromP_A, 00588 const Vec3& toQ_A) 00589 { return shiftAccelerationBy(A_A_BP, w_AB, toQ_A - fromP_A); } 00590 00591 00592 00593 //============================================================================== 00594 // SHIFT FORCE BY 00595 //============================================================================== 00625 inline SpatialVec shiftForceBy(const SpatialVec& F_AP, const Vec3& r_A) 00626 { return SpatialVec(F_AP[0] - r_A % F_AP[1], F_AP[1]); } // mq = mp - r X f 00627 00628 00629 00630 //============================================================================== 00631 // SHIFT FORCE FROM TO 00632 //============================================================================== 00668 inline SpatialVec shiftForceFromTo(const SpatialVec& F_AP, 00669 const Vec3& fromP_A, 00670 const Vec3& toQ_A) 00671 { return shiftForceBy(F_AP, toQ_A - fromP_A); } 00672 00677 //============================================================================== 00678 // PHI MATRIX 00679 //============================================================================== 00680 // support for efficient matrix multiplication involving the special phi 00681 // matrix 00682 00683 class PhiMatrixTranspose; 00684 00685 class PhiMatrix { 00686 public: 00687 typedef PhiMatrixTranspose TransposeType; 00688 00689 PhiMatrix() { setToNaN(); } 00690 PhiMatrix(const Vec3& l) : l_(l) {} 00691 00692 void setToZero() { l_ = 0; } 00693 void setToNaN() { l_.setToNaN(); } 00694 00695 SpatialMat toSpatialMat() const { 00696 return SpatialMat(Mat33(1), crossMat(l_), 00697 Mat33(0), Mat33(1)); 00698 } 00699 00700 const Vec3& l() const { return l_; } 00701 private: 00702 Vec3 l_; 00703 }; 00704 00705 class PhiMatrixTranspose { 00706 public: 00707 PhiMatrixTranspose(const PhiMatrix& phi) : phi(phi) {} 00708 00709 SpatialMat toSpatialMat() const { 00710 return SpatialMat( Mat33(1) , Mat33(0), 00711 crossMat(-l()) , Mat33(1)); 00712 } 00713 00714 const Vec3& l() const {return phi.l();} 00715 private: 00716 const PhiMatrix& phi; 00717 }; 00718 00719 inline PhiMatrixTranspose 00720 transpose(const PhiMatrix& phi) 00721 { 00722 PhiMatrixTranspose ret(phi); 00723 return ret; 00724 } 00725 00726 inline PhiMatrixTranspose 00727 operator~(const PhiMatrix& phi) {return transpose(phi);} 00728 00729 inline SpatialVec 00730 operator*(const PhiMatrix& phi, 00731 const SpatialVec& v) 00732 { 00733 return SpatialVec(v[0] + phi.l() % v[1], // 12 flops 00734 v[1]); 00735 } 00736 00737 inline SpatialMat 00738 operator*(const PhiMatrix& phi, 00739 const SpatialMat& m) 00740 { 00741 const Mat33 x = crossMat(phi.l()); // 3 flops 00742 return SpatialMat( m(0,0) + x*m(1,0), m(0,1) + x*m(1,1), // 108 flops 00743 m(1,0) , m(1,1)); 00744 } 00745 00746 inline SpatialVec 00747 operator*(const PhiMatrixTranspose& phiT, 00748 const SpatialVec& v) 00749 { 00750 return SpatialVec(v[0], 00751 v[1] + v[0] % phiT.l()); // 12 flops 00752 } 00753 00754 00755 inline SpatialMat 00756 operator*(const SpatialMat::THerm& m, 00757 const PhiMatrixTranspose& phiT) 00758 { 00759 const Mat33 x = crossMat(phiT.l()); // 3 flops 00760 return SpatialMat( m(0,0) - m(0,1) * x, m(0,1), // 54 flops 00761 m(1,0) - m(1,1) * x, m(1,1) ); // 54 flops 00762 } 00763 00764 inline SpatialMat 00765 operator*(const SpatialMat& m, 00766 const PhiMatrixTranspose& phiT) 00767 { 00768 const Mat33 x = crossMat(phiT.l()); // 3 flops 00769 return SpatialMat( m(0,0) - m(0,1) * x, m(0,1), // 54 flops 00770 m(1,0) - m(1,1) * x, m(1,1) ); // 54 flops 00771 } 00772 00773 inline bool 00774 operator==(const PhiMatrix& p1, const PhiMatrix& p2) 00775 { 00776 return p1.l() == p2.l(); 00777 } 00778 00779 inline bool 00780 operator==(const PhiMatrixTranspose& p1, const PhiMatrixTranspose& p2) 00781 { 00782 return p1.l() == p2.l(); 00783 } 00784 } // namespace SimTK 00785 00786 #endif // SimTK_SIMMATRIX_SPATIAL_ALGEBRA_H_