Simbody  3.4 (development)
SpatialAlgebra.h
Go to the documentation of this file.
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_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines