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  *                      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_

Generated on Thu Aug 12 16:37:26 2010 for SimTKcore by  doxygen 1.6.1