Simbody

MobilizedBody.h

Go to the documentation of this file.
00001 #ifndef SimTK_SIMBODY_MOBILIZED_BODY_H_
00002 #define SimTK_SIMBODY_MOBILIZED_BODY_H_
00003 
00004 /* -------------------------------------------------------------------------- *
00005  *                      SimTK Core: SimTK Simbody(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) 2007-10 Stanford University and the Authors.        *
00013  * Authors: Michael Sherman                                                   *
00014  * Contributors: Paul Mitiguy, Peter Eastman                                  *
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 
00052 #include "SimTKmath.h"
00053 #include "simbody/internal/common.h"
00054 #include "simbody/internal/Body.h"
00055 #include "simbody/internal/Motion.h"
00056 
00057 #include <cassert>
00058 
00059 namespace SimTK {
00060 
00061 class SimbodyMatterSubsystem;
00062 class Motion;
00063 class MobilizedBody;
00064 class MobilizedBodyImpl;
00065 
00066 // We only want the template instantiation to occur once. This symbol is 
00067 // defined in the SimTK core compilation unit that instantiates the mobilized 
00068 // body class but should not be defined any other time.
00069 #ifndef SimTK_SIMBODY_DEFINING_MOBILIZED_BODY
00070     extern template class PIMPLHandle<MobilizedBody, MobilizedBodyImpl, true>;
00071 #endif
00072 
00076 typedef MobilizedBody Mobod;
00077 
00078 
00133 class SimTK_SIMBODY_EXPORT MobilizedBody : public PIMPLHandle<MobilizedBody, MobilizedBodyImpl, true> {
00134 public:
00135 
00141     enum Direction {
00142         Forward = 0,
00143         Reverse = 1
00144     };
00145 
00149     MobilizedBody& setDefaultMotionType(Motion::Level, Motion::Method=Motion::Prescribed);
00150 
00152     void setMotionType(State&, Motion::Level, Motion::Method=Motion::Prescribed) const;
00153 
00154     bool isAccelerationAlwaysZero(const State&) const;
00155     bool isVelocityAlwaysZero(const State&) const;
00156 
00157 
00159         // STATE ACCESS METHODS //
00161 
00165 
00166 
00181     const Transform& getBodyTransform(const State&) const; // X_GB
00182 
00191     const Rotation& getBodyRotation(const State& s) const {
00192         return getBodyTransform(s).R();
00193     }
00198     const Vec3& getBodyOriginLocation(const State& s) const {
00199         return getBodyTransform(s).p();
00200     }
00201 
00205     const Transform& getMobilizerTransform(const State&) const; // X_FM
00206 
00213     const SpatialVec& getBodyVelocity(const State&) const;          // V_GB
00214 
00218     const Vec3& getBodyAngularVelocity(const State& s) const {      // w_GB
00219         return getBodyVelocity(s)[0]; 
00220     }
00226     const Vec3& getBodyOriginVelocity(const State& s) const {       // v_GB
00227         return getBodyVelocity(s)[1];
00228     }
00229 
00235     const SpatialVec& getMobilizerVelocity(const State&) const;     // V_FM
00236 
00242     const SpatialVec& getBodyAcceleration(const State& s) const;    // A_GB
00243 
00247     const Vec3& getBodyAngularAcceleration(const State& s) const {  // b_GB
00248         return getBodyAcceleration(s)[0]; 
00249     }
00250 
00255     const Vec3& getBodyOriginAcceleration(const State& s) const {   // a_GB
00256         return getBodyAcceleration(s)[1];
00257     }
00258 
00264     const SpatialVec& getMobilizerAcceleration(const State&) const { // A_FM
00265         SimTK_ASSERT_ALWAYS(!"unimplemented method", 
00266             "MobilizedBody::getMobilizerAcceleration() is not yet implemented -- any volunteers?");
00267         return *(new SpatialVec());
00268     }
00269 
00272     const MassProperties& getBodyMassProperties(const State&) const;
00273 
00275     Real getBodyMass(const State& s) const {
00276         return getBodyMassProperties(s).getMass();
00277     }
00278 
00282     const Vec3& getBodyMassCenterStation(const State& s) const {
00283         return getBodyMassProperties(s).getMassCenter();
00284     }
00285 
00289     const Inertia& getBodyInertiaAboutBodyOrigin(const State& s) const {
00290         return getBodyMassProperties(s).getInertia();
00291     }
00292 
00297     const Transform& getInboardFrame (const State&) const;  // X_PF
00302     const Transform& getOutboardFrame(const State&) const;  // X_BM
00303 
00306     void setInboardFrame (State&, const Transform& X_PF) const;
00309     void setOutboardFrame(State&, const Transform& X_BM) const;
00310 
00311     // End of State Access - Bodies
00313 
00317 
00318 
00319 
00320     int getNumQ(const State&) const;
00323     int getNumU(const State&) const;
00324 
00327     QIndex getFirstQIndex(const State&) const;
00328 
00331     UIndex getFirstUIndex(const State&) const;
00332 
00333 
00337     Real getOneQ(const State&, int which) const;
00338 
00342     Real getOneU(const State&, int which) const;
00343 
00347     Vector getQAsVector(const State&) const;
00351     Vector getUAsVector(const State&) const;
00352 
00356     Real getOneQDot   (const State&, int which) const;
00360     Vector getQDotAsVector(const State&) const;
00361 
00366     Real getOneUDot(const State&, int which) const;
00372     Real getOneQDotDot(const State&, int which) const;
00377     Vector getUDotAsVector(const State&) const;
00382     Vector getQDotDotAsVector(const State&) const;
00383 
00394     Vector getTauAsVector(const State&) const;
00400     Real getOneTau(const State&, MobilizerUIndex which) const;
00401 
00402 
00406     void setOneQ(State&, int which, Real v) const;
00410     void setOneU(State&, int which, Real v) const;
00411 
00414     void setQFromVector(State& s, const Vector& v) const;
00417     void setUFromVector(State& s, const Vector& v) const;
00418 
00454 
00455     void setQToFitTransform      (State&, const Transform& X_FM) const;
00460     void setQToFitRotation       (State&, const Rotation&  R_FM) const;
00466     void setQToFitTranslation    (State&, const Vec3&      p_FM) const;
00467 
00474     void setUToFitVelocity          (State&, const SpatialVec& V_FM) const;
00481     void setUToFitAngularVelocity   (State&, const Vec3&       w_FM) const;
00488     void setUToFitLinearVelocity    (State&, const Vec3&       v_FM) const;
00489 
00500     SpatialVec getHCol(const State& s, MobilizerUIndex ux) const;
00501 
00509     SpatialVec getH_FMCol(const State& s, MobilizerUIndex ux) const;
00510 
00511     // End of State Access Methods.
00513 
00515         // BASIC OPERATORS //
00517 
00519 
00551 
00553 
00559     Transform findBodyTransformInAnotherBody(const State& s, 
00560                                              const MobilizedBody& inBodyA) const
00561     {
00562         const Transform& X_GA = inBodyA.getBodyTransform(s);
00563         const Transform& X_GB = this->getBodyTransform(s);
00564 
00565         return ~X_GA*X_GB; // X_AB=X_AG*X_GB
00566     }
00567 
00573     Rotation findBodyRotationInAnotherBody(const State& s, 
00574                                            const MobilizedBody& inBodyA) const
00575     {
00576         const Rotation& R_GA = inBodyA.getBodyRotation(s);
00577         const Rotation& R_GB = this->getBodyRotation(s);
00578 
00579         return ~R_GA*R_GB; // R_AB=R_AG*R_GB
00580     }
00581 
00588     Vec3 findBodyOriginLocationInAnotherBody(const State& s, 
00589                                              const MobilizedBody& toBodyA) const
00590     {   return toBodyA.findStationAtGroundPoint(s,getBodyOriginLocation(s)); }
00591 
00598     SpatialVec findBodyVelocityInAnotherBody(const State& s,
00599                                              const MobilizedBody& inBodyA) const
00600     {
00601         const SpatialVec& V_GB   = this->getBodyVelocity(s);
00602         const SpatialVec& V_GA   = inBodyA.getBodyVelocity(s);
00603         const Vec3        w_AB_G = V_GB[0]-V_GA[0]; // angular velocity of B in A, exp in G   ( 3 flops)
00604 
00605         // Angular velocity was easy, but for linear velocity we have to add in an wXr term.
00606         const Transform&  X_GB       = getBodyTransform(s);
00607         const Transform&  X_GA       = inBodyA.getBodyTransform(s);
00608         const Vec3        p_AB_G     = X_GB.p() - X_GA.p(); // vector from OA to OB, exp in G ( 3 flops)
00609         const Vec3        p_AB_G_dot = V_GB[1]  - V_GA[1];  // d/dt p taken in G              ( 3 flops)
00610 
00611         const Vec3 v_AB_G = p_AB_G_dot - V_GA[0] % p_AB_G;  // d/dt p taken in A, exp in G    (12 flops)
00612 
00613         // We're done, but the answer is expressed in Ground. Reexpress in A and return.
00614         return ~X_GA.R()*SpatialVec(w_AB_G, v_AB_G);        //                                (30 flops)
00615     }
00616 
00622     Vec3 findBodyAngularVelocityInAnotherBody(const State& s,
00623                                        const MobilizedBody& inBodyA) const 
00624     {
00625         const Vec3& w_GB   = getBodyAngularVelocity(s);
00626         const Vec3& w_GA   = inBodyA.getBodyAngularVelocity(s);
00627         const Vec3  w_AB_G = w_GB-w_GA; // angular velocity of B in A, exp in G ( 3 flops)
00628 
00629         // Now reexpress in A.
00630         return inBodyA.expressGroundVectorInBodyFrame(s, w_AB_G); //            (15 flops)
00631     }
00632 
00638     Vec3 findBodyOriginVelocityInAnotherBody(const State& s,
00639                                       const MobilizedBody& inBodyA) const
00640     {
00641         // Doesn't save much to special case this one.
00642         return findBodyVelocityInAnotherBody(s,inBodyA)[1];
00643     }
00644 
00651     SpatialVec findBodyAccelerationInAnotherBody(const State& s,
00652                                                  const MobilizedBody& inBodyA) const
00653     {
00654         const Vec3&       p_GB = this->getBodyOriginLocation(s);
00655         const Transform&  X_GA = inBodyA.getBodyTransform(s);
00656         const SpatialVec& V_GB = this->getBodyVelocity(s);
00657         const SpatialVec& V_GA = inBodyA.getBodyVelocity(s);
00658         const SpatialVec& A_GB = this->getBodyAcceleration(s);
00659         const SpatialVec& A_GA = inBodyA.getBodyAcceleration(s);
00660         const Vec3&       p_GA = X_GA.p();
00661         const Vec3&       w_GA = V_GA[0];
00662         const Vec3&       w_GB = V_GB[0];
00663         const Vec3&       b_GA = A_GA[0];
00664         const Vec3&       b_GB = A_GB[0];
00665 
00666         const Vec3 p_AB_G        = p_GB     - p_GA;         // vector from OA to OB, in G   ( 3 flops)
00667         const Vec3 p_AB_G_dot    = V_GB[1]  - V_GA[1];      // d/dt p taken in G            ( 3 flops)
00668         const Vec3 p_AB_G_dotdot = A_GB[1]  - A_GA[1];      // d^2/dt^2 taken in G          ( 3 flops)
00669 
00670         const Vec3 w_AB_G     = w_GB - w_GA;                // relative ang. vel. of B in A, exp. in G (3 flops)
00671         const Vec3 v_AB_G     = p_AB_G_dot - w_GA % p_AB_G; // d/dt p taken in A, exp in G  (12 flops)
00672 
00673         const Vec3 w_AB_G_dot = b_GB - b_GA;                // d/dt of w_AB_G taken in G    ( 3 flops)
00674         const Vec3 v_AB_G_dot = p_AB_G_dotdot - (b_GA % p_AB_G + w_GA % p_AB_G_dot); // d/dt v_AB_G taken in G
00675                                                                                      //     (24 flops)
00676 
00677         // We have the derivative in G; change it to derivative in A by adding in contribution caused
00678         // by motion of G in A, that is w_AG X w_AB_G. (Note that w_AG=-w_GA.)
00679         const Vec3 b_AB_G = w_AB_G_dot - w_GA % w_AB_G; // ang. accel. of B in A            (12 flops)
00680         const Vec3 a_AB_G = v_AB_G_dot - w_GA % v_AB_G; // taken in A, exp. in G            (12 flops)
00681 
00682         return ~X_GA.R() * SpatialVec(b_AB_G, a_AB_G); // taken in A, expressed in A        (30 flops)
00683     }
00684 
00691     Vec3 findBodyAngularAccelerationInAnotherBody(const State& s,
00692                                                   const MobilizedBody& inBodyA) const
00693     {
00694         const Rotation& R_GA = inBodyA.getBodyRotation(s);
00695         const Vec3&     w_GA = inBodyA.getBodyAngularVelocity(s);
00696         const Vec3&     w_GB = this->getBodyAngularVelocity(s);
00697         const Vec3&     b_GA = inBodyA.getBodyAngularAcceleration(s);
00698         const Vec3&     b_GB = this->getBodyAngularAcceleration(s);
00699 
00700         const Vec3 w_AB_G     = w_GB - w_GA; // relative ang. vel. of B in A, exp. in G (3 flops)
00701         const Vec3 w_AB_G_dot = b_GB - b_GA; // d/dt of w_AB_G taken in G    ( 3 flops)
00702 
00703         // We have the derivative in G; change it to derivative in A by adding 
00704         // in contribution caused by motion of G in A, that is w_AG X w_AB_G. 
00705         // (Note that w_AG=-w_GA.)
00706         const Vec3 b_AB_G = w_AB_G_dot - w_GA % w_AB_G; // ang. accel. of B in A            (12 flops)
00707 
00708         return ~R_GA * b_AB_G; // taken in A, expressed in A                                (15 flops)
00709     }
00710 
00717     Vec3 findBodyOriginAccelerationInAnotherBody(const State& s, 
00718                                           const MobilizedBody& inBodyA) const
00719     {
00720         // Not much to be saved by trying to optimize this since the linear part
00721         // is the most expensive to calculate.
00722         return findBodyAccelerationInAnotherBody(s,inBodyA)[1];
00723     }
00724 
00731     Vec3 findStationLocationInGround(const State& s, const Vec3& stationOnB) const {
00732         return getBodyTransform(s) * stationOnB;
00733     }
00734 
00735 
00745     Vec3 findStationLocationInAnotherBody(const State& s, const Vec3& stationOnB, 
00746                                const MobilizedBody& toBodyA) const
00747     {
00748         return toBodyA.findStationAtGroundPoint(s, findStationLocationInGround(s,stationOnB));
00749     }
00750 
00758     Vec3 findStationVelocityInGround(const State& s, const Vec3& stationOnB) const {
00759         const Vec3& w = getBodyAngularVelocity(s); // in G
00760         const Vec3& v = getBodyOriginVelocity(s);  // in G
00761         const Vec3  r = expressVectorInGroundFrame(s,stationOnB); // 15 flops
00762         return v + w % r;                                         // 12 flops
00763     }
00764 
00765 
00772     Vec3 findStationVelocityInAnotherBody(const State& s, 
00773                                           const Vec3&          stationOnBodyB, // p_BS
00774                                           const MobilizedBody& inBodyA) const
00775     {
00776         const SpatialVec V_AB   = findBodyVelocityInAnotherBody(s,inBodyA); // (51 flops)
00777          // OB->S rexpressed in A but not shifted to OA
00778         const Vec3       p_BS_A = expressVectorInAnotherBodyFrame(s, stationOnBodyB, inBodyA);
00779                                                                             // (30 flops)
00780         return V_AB[1] + (V_AB[0] % p_BS_A);                                // (12 flops)
00781     }
00782 
00783       
00791     Vec3 findStationAccelerationInGround(const State& s, const Vec3& stationOnB) const {
00792         const Vec3& w = getBodyAngularVelocity(s);     // in G
00793         const Vec3& b = getBodyAngularAcceleration(s); // in G
00794         const Vec3& a = getBodyOriginAcceleration(s);  // in G
00795 
00796         const Vec3  r = expressVectorInGroundFrame(s,stationOnB); // 15 flops
00797         return a + b % r + w % (w % r);                           // 33 flops
00798     }
00799 
00805     Vec3 findStationAccelerationInAnotherBody(const State& s,
00806                                               const Vec3&          stationOnBodyB, 
00807                                               const MobilizedBody& inBodyA) const 
00808     {
00809         const Vec3       w_AB = findBodyAngularVelocityInAnotherBody(s,inBodyA);  // ( 18 flops)
00810         const SpatialVec A_AB = findBodyAccelerationInAnotherBody(s,inBodyA);     // (105 flops)
00811          // OB->S rexpressed in A but not shifted to OA
00812         const Vec3       p_BS_A = expressVectorInAnotherBodyFrame(s, stationOnBodyB, inBodyA);
00813                                                                                   // ( 30 flops)
00814 
00815         return A_AB[1] + (A_AB[0] % p_BS_A) + w_AB % (w_AB % p_BS_A);             // ( 33 flops)
00816     }
00817 
00822     void findStationLocationAndVelocityInGround(const State& s, const Vec3& locationOnB,
00823                                                 Vec3& locationOnGround, Vec3& velocityInGround) const
00824     {
00825         const Vec3& p_GB   = getBodyOriginLocation(s);
00826         const Vec3  p_BS_G = expressVectorInGroundFrame(s,locationOnB); // 15 flops
00827         locationOnGround = p_GB + p_BS_G;                               //  3 flops
00828 
00829         const Vec3& w_GB = getBodyAngularVelocity(s);
00830         const Vec3& v_GB = getBodyOriginVelocity(s);
00831         velocityInGround = v_GB + w_GB % p_BS_G;                        // 12 flops
00832     }
00833 
00834 
00839     void findStationLocationVelocityAndAccelerationInGround
00840        (const State& s, const Vec3& locationOnB,
00841         Vec3& locationOnGround, Vec3& velocityInGround, Vec3& accelerationInGround) const
00842     {
00843         const Rotation&  R_GB = getBodyRotation(s);
00844         const Vec3&      p_GB = getBodyOriginLocation(s);
00845 
00846         const Vec3 r = R_GB*locationOnB; // re-express station vector p_BS in G (15 flops)
00847         locationOnGround  = p_GB + r;    // 3 flops
00848 
00849         const Vec3& w = getBodyAngularVelocity(s);      // in G
00850         const Vec3& v = getBodyOriginVelocity(s);       // in G
00851         const Vec3& b = getBodyAngularAcceleration(s);  // in G
00852         const Vec3& a = getBodyOriginAcceleration(s);   // in G
00853 
00854         const Vec3 wXr = w % r; // "whipping" velocity w X r due to angular velocity (9 flops)
00855         velocityInGround     = v + wXr;                 // v + w X r (3 flops)
00856         accelerationInGround = a + b % r + w % wXr;     // 24 flops
00857     }
00858 
00861     Vec3 findMassCenterLocationInGround(const State& s) const {
00862         return findStationLocationInGround(s,getBodyMassCenterStation(s));
00863     }
00864 
00868     Vec3 findMassCenterLocationInAnotherBody(const State& s, const MobilizedBody& toBodyA) const {
00869         return findStationLocationInAnotherBody(s,getBodyMassCenterStation(s),toBodyA);
00870     }
00871 
00878     Vec3 findStationAtGroundPoint(const State& s, const Vec3& locationInG) const {
00879         return ~getBodyTransform(s) * locationInG;
00880     }
00881 
00887     Vec3 findStationAtAnotherBodyStation(const State& s, const MobilizedBody& fromBodyA, 
00888                                 const Vec3& stationOnA) const {
00889         return fromBodyA.findStationLocationInAnotherBody(s, stationOnA, *this);
00890     }
00891 
00895     Vec3 findStationAtAnotherBodyOrigin(const State& s, const MobilizedBody& fromBodyA) const {
00896         return findStationAtGroundPoint(s,fromBodyA.getBodyOriginLocation(s));
00897     }
00898 
00902     Vec3 findStationAtAnotherBodyMassCenter(const State& s, const MobilizedBody& fromBodyA) const {
00903         return fromBodyA.findStationLocationInAnotherBody(s,getBodyMassCenterStation(s),*this);
00904     }
00905 
00909     Transform findFrameTransformInGround
00910        (const State& s, const Transform& frameOnB) const {
00911         return getBodyTransform(s) * frameOnB;
00912     }
00913 
00919     SpatialVec findFrameVelocityInGround
00920        (const State& s, const Transform& frameOnB) const {
00921         return SpatialVec(getBodyAngularVelocity(s),
00922                           findStationVelocityInGround(s,frameOnB.p()));
00923     }
00924 
00931     SpatialVec findFrameAccelerationInGround
00932        (const State& s, const Transform& frameOnB) const {
00933         return SpatialVec(getBodyAngularAcceleration(s),
00934                           findStationAccelerationInGround(s,frameOnB.p()));
00935     }
00936 
00940     Vec3 expressVectorInGroundFrame(const State& s, const Vec3& vectorInB) const {
00941         return getBodyRotation(s)*vectorInB;
00942     }
00943 
00947     Vec3 expressGroundVectorInBodyFrame(const State& s, const Vec3& vectorInG) const {
00948         return ~getBodyRotation(s)*vectorInG;
00949     }
00950 
00956     Vec3 expressVectorInAnotherBodyFrame(const State& s, const Vec3& vectorInB,
00957                                          const MobilizedBody& inBodyA) const
00958     {
00959         return inBodyA.expressGroundVectorInBodyFrame(s, expressVectorInGroundFrame(s,vectorInB));
00960     }
00961 
00965     MassProperties expressMassPropertiesInGroundFrame(const State& s) const {
00966         const MassProperties& M_OB_B = getBodyMassProperties(s);
00967         const Rotation&       R_GB   = getBodyRotation(s);
00968         return M_OB_B.reexpress(~R_GB);
00969     }
00970 
00974     MassProperties expressMassPropertiesInAnotherBodyFrame
00975        (const State& s, const MobilizedBody& inBodyA) const 
00976     {
00977         const MassProperties& M_OB_B = getBodyMassProperties(s);
00978         const Rotation        R_AB   = findBodyRotationInAnotherBody(s,inBodyA);
00979         return M_OB_B.reexpress(~R_AB);
00980     }
00981 
00982     // End of Basic Operators.
00984 
00989 
00990 
00992 
01012     SpatialMat calcBodySpatialInertiaMatrixInGround(const State& s) const
01013     {
01014         if (isGround())
01015             return SpatialMat(Mat33(Infinity)); // sets diagonals to Inf
01016 
01017         const MassProperties& mp   = getBodyMassProperties(s);
01018         const Rotation&       R_GB = getBodyRotation(s);
01019          // re-express in Ground without shifting, convert to spatial mat.
01020         return mp.reexpress(~R_GB).toSpatialMat();
01021     }
01022 
01028     Inertia calcBodyCentralInertia(const State& s, 
01029                                    MobilizedBodyIndex objectBodyB) const
01030     {
01031         return getBodyMassProperties(s).calcCentralInertia();
01032     }
01033 
01037     Inertia calcBodyInertiaAboutAnotherBodyStation(const State& s,
01038                                                    const MobilizedBody& inBodyA, 
01039                                                    const Vec3&          aboutLocationOnBodyA) const
01040     {
01041         // get B's mass props MB, measured about OB, exp. in B
01042         const MassProperties& MB_OB_B = getBodyMassProperties(s);
01043 
01044         // Calculate the vector from the body B origin (current "about" point) to the new "about" point PA,
01045         // expressed in B.
01046         const Vec3 r_OB_PA = findStationAtAnotherBodyStation(s, inBodyA, aboutLocationOnBodyA);
01047 
01048         // Now shift the "about" point for body B's inertia IB to PA, but still expressed in B.
01049         const Inertia IB_PA_B = MB_OB_B.calcShiftedInertia(r_OB_PA);
01050         
01051         // Finally reexpress the inertia in the A frame.
01052         const Rotation R_BA    = inBodyA.findBodyRotationInAnotherBody(s, *this);
01053         const Inertia  IB_PA_A = IB_PA_B.reexpress(R_BA);
01054         return IB_PA_A;
01055     }
01056 
01057 
01060     SpatialVec calcBodyMomentumAboutBodyOriginInGround(const State& s) {
01061         const MassProperties M_OB_G = expressMassPropertiesInGroundFrame(s);
01062         const SpatialVec&    V_GB   = getBodyVelocity(s);
01063         return M_OB_G.toSpatialMat() * V_GB;
01064     }
01065 
01068     SpatialVec calcBodyMomentumAboutBodyMassCenterInGround(const State& s) const {
01069         const MassProperties& M_OB_B = getBodyMassProperties(s);
01070         const Rotation&       R_GB   = getBodyRotation(s);
01071 
01072         // Given a central inertia matrix I, angular velocity w, and mass center velocity v,
01073         // the central angular momentum is Iw and linear momentum is mv.
01074         const Inertia I_CB_B = M_OB_B.calcCentralInertia();
01075         const Inertia I_CB_G = I_CB_B.reexpress(~R_GB);
01076         const Real    mb     = M_OB_B.getMass();
01077         const Vec3&   w_GB   = getBodyAngularVelocity(s);
01078         Vec3          v_G_CB = findStationVelocityInGround(s, M_OB_B.getMassCenter());
01079 
01080         return SpatialVec( I_CB_G*w_GB, mb*v_G_CB );
01081     }
01082 
01086     Real calcStationToStationDistance(const State& s,
01087                                       const Vec3&          locationOnBodyB,
01088                                       const MobilizedBody& bodyA,
01089                                       const Vec3&          locationOnBodyA) const
01090     {
01091         if (isSameMobilizedBody(bodyA))
01092             return (locationOnBodyA-locationOnBodyB).norm();
01093 
01094         const Vec3 r_OG_PB = this->findStationLocationInGround(s,locationOnBodyB);
01095         const Vec3 r_OG_PA = bodyA.findStationLocationInGround(s,locationOnBodyA);
01096         return (r_OG_PA - r_OG_PB).norm();
01097     }
01098 
01103     Real calcStationToStationDistanceTimeDerivative(const State& s,
01104                                                     const Vec3&          locationOnBodyB,
01105                                                     const MobilizedBody& bodyA,
01106                                                     const Vec3&          locationOnBodyA) const
01107     {
01108         if (isSameMobilizedBody(bodyA))
01109             return 0;
01110 
01111         Vec3 rB, rA, vB, vA;
01112         this->findStationLocationAndVelocityInGround(s,locationOnBodyB,rB,vB);
01113         bodyA.findStationLocationAndVelocityInGround(s,locationOnBodyA,rA,vA);
01114         const Vec3 r = rA-rB, v = vA-vB;
01115         const Real d = r.norm();
01116 
01117         // When the points are coincident, the rate of change of distance is just their relative speed.
01118         // Otherwise, it is the speed along the direction of separation. 
01119         if (d==0) return v.norm();
01120         else return dot(v, r/d);
01121     }
01122 
01123 
01128     Real calcStationToStationDistance2ndTimeDerivative(const State& s,
01129                                                        const Vec3&          locationOnBodyB,
01130                                                        const MobilizedBody& bodyA,
01131                                                        const Vec3&          locationOnBodyA) const
01132     {
01133         if (isSameMobilizedBody(bodyA))
01134             return 0;
01135 
01136         Vec3 rB, rA, vB, vA, aB, aA;
01137         this->findStationLocationVelocityAndAccelerationInGround(s,locationOnBodyB,rB,vB,aB);
01138         bodyA.findStationLocationVelocityAndAccelerationInGround(s,locationOnBodyA,rA,vA,aA);
01139 
01140         const Vec3 r = rA-rB, v = vA-vB, a = aA-aB;
01141         const Real d = r.norm();
01142         
01143         // This method is the time derivative of calcFixedPointToPointDistanceTimeDerivative(), so it
01144         // must follow the same two cases. That is, when the points are coincident the change in 
01145         // separation rate is the time derivative of the speed |v|, otherwise it is the time
01146         // derivative of the speed along the separation vector.
01147 
01148         if (d==0) {
01149             // Return d/dt |v|. This has two cases: if |v| is zero, the rate of change of speed is
01150             // just the points' relative acceleration magnitude. Otherwise, it is the acceleration
01151             // in the direction of the current relative velocity vector.
01152             const Real s = v.norm(); // speed
01153             if (s==0) return a.norm();
01154             else return dot(a, v/s);
01155         }
01156 
01157         // Points are separated.
01158         const Vec3 u = r/d;             // u is the separation direction (a unit vector from B to A) 
01159         const Vec3 vp = v - dot(v,u)*u; // velocity perpendicular to separation direction
01160         return dot(a,u) + dot(vp,v)/d;
01161     }
01162 
01163 
01166     Vec3 calcBodyMovingPointVelocityInBody(const State& s,
01167                                            const Vec3& locationOnBodyB, 
01168                                            const Vec3& velocityOnBodyB,
01169                                            const MobilizedBody& inBodyA) const
01170     {
01171         SimTK_ASSERT_ALWAYS(!"unimplemented method", 
01172             "MobilizedBody::calcBodyMovingPointVelocityInBody() is not yet implemented -- any volunteers?");
01173         return Vec3::getNaN();
01174     }
01175 
01176 
01179     Vec3 calcBodyMovingPointAccelerationInBody(const State& s, 
01180                                                const Vec3&          locationOnBodyB, 
01181                                                const Vec3&          velocityOnBodyB, 
01182                                                const Vec3&          accelerationOnBodyB,
01183                                                const MobilizedBody& inBodyA) const
01184     {
01185         SimTK_ASSERT_ALWAYS(!"unimplemented method", 
01186             "MobilizedBody::calcBodyMovingPointAccelerationInBody() is not yet implemented -- any volunteers?");
01187         return Vec3::getNaN();
01188     }
01189 
01196     Real calcMovingPointToPointDistanceTimeDerivative(const State& s,
01197                                                       const Vec3&          locationOnBodyB,
01198                                                       const Vec3&          velocityOnBodyB,
01199                                                       const MobilizedBody& bodyA,
01200                                                       const Vec3&          locationOnBodyA,
01201                                                       const Vec3&          velocityOnBodyA) const
01202     {
01203         SimTK_ASSERT_ALWAYS(!"unimplemented method", 
01204             "MobilizedBody::calcMovingPointToPointDistanceTimeDerivative() is not yet implemented -- any volunteers?");
01205         return NaN;
01206     }
01207 
01214     Real calcMovingPointToPointDistance2ndTimeDerivative(const State& s,
01215                                                          const Vec3&          locationOnBodyB,
01216                                                          const Vec3&          velocityOnBodyB,
01217                                                          const Vec3&          accelerationOnBodyB,
01218                                                          const MobilizedBody& bodyA,
01219                                                          const Vec3&          locationOnBodyA,
01220                                                          const Vec3&          velocityOnBodyA,
01221                                                          const Vec3&          accelerationOnBodyA) const
01222     {
01223         SimTK_ASSERT_ALWAYS(!"unimplemented method", 
01224             "MobilizedBody::calcMovingPointToPointDistance2ndTimeDerivative() is not yet implemented -- any volunteers?");
01225         return NaN;
01226     }
01227 
01228 
01229     // End of High Level Operators.
01231 
01232 
01234             // CONSTRUCTION METHODS //
01236 
01240     MobilizedBody();
01241 
01243     explicit MobilizedBody(MobilizedBodyImpl* r);
01244 
01249 
01250 
01256     MobilizedBody& addBodyDecoration(const Transform& X_BD, const DecorativeGeometry& g) {
01257         (void)updBody().addDecoration(X_BD,g);
01258         return *this;
01259     }
01260 
01264     MobilizedBody& addOutboardDecoration(const Transform& X_MD,  const DecorativeGeometry&);
01265 
01269     MobilizedBody& addInboardDecoration (const Transform& X_FD, const DecorativeGeometry&);
01270 
01272     const Body& getBody() const;
01276     Body& updBody();
01277 
01283     MobilizedBody& setBody(const Body&);
01284 
01291     MobilizedBody& setDefaultMassProperties(const MassProperties& m) {
01292         updBody().setDefaultRigidBodyMassProperties(m); // might not be allowed
01293         return *this;
01294     }
01295 
01297     const MassProperties& getDefaultMassProperties() const {
01298         return getBody().getDefaultRigidBodyMassProperties(); // every body type can do this
01299     }
01300 
01308     void adoptMotion(Motion& ownerHandle);
01309 
01313     void clearMotion();
01314 
01318     bool hasMotion() const;
01319 
01326     const Motion& getMotion() const;
01327 
01333     MobilizedBody& setDefaultInboardFrame (const Transform& X_PF);
01339     MobilizedBody& setDefaultOutboardFrame(const Transform& X_BM);
01340 
01345     const Transform& getDefaultInboardFrame()  const; // X_PF
01349     const Transform& getDefaultOutboardFrame() const; // X_BM
01350 
01356     operator MobilizedBodyIndex() const {return getMobilizedBodyIndex();}
01357 
01363     MobilizedBodyIndex     getMobilizedBodyIndex()  const;
01364 
01368     const MobilizedBody&   getParentMobilizedBody() const;
01369 
01374     const MobilizedBody&   getBaseMobilizedBody()   const;
01375 
01379     const SimbodyMatterSubsystem& getMatterSubsystem() const;
01383     SimbodyMatterSubsystem&       updMatterSubsystem();
01384 
01387     bool isInSubsystem() const;
01388 
01392     bool isInSameSubsystem(const MobilizedBody&) const;
01393 
01398     bool isSameMobilizedBody(const MobilizedBody& mBody) const;
01399 
01402     bool isGround() const;
01403 
01408     int getLevelInMultibodyTree() const;
01409     
01413     MobilizedBody& cloneForNewParent(MobilizedBody& parent) const;
01414 
01415 
01416         // Utility operators //
01417 
01422     Real  getOneFromQPartition(const State&, int which, const Vector& qlike) const;
01423 
01428     Real& updOneFromQPartition(const State&, int which, Vector& qlike) const;
01429 
01433     Real  getOneFromUPartition(const State&, int which, const Vector& ulike) const;
01434 
01439     Real& updOneFromUPartition(const State&, int which, Vector& ulike) const;
01440 
01446     void applyOneMobilityForce(const State& s, int which, Real f, 
01447                                Vector& mobilityForces) const
01448     {
01449         updOneFromUPartition(s,which,mobilityForces) += f;
01450     }
01451 
01458     void applyBodyForce(const State& s, const SpatialVec& spatialForceInG, 
01459                         Vector_<SpatialVec>& bodyForcesInG) const;
01460 
01466     void applyBodyTorque(const State& s, const Vec3& torqueInG, 
01467                          Vector_<SpatialVec>& bodyForcesInG) const;
01468 
01478     void applyForceToBodyPoint(const State& s, const Vec3& pointInB, const Vec3& forceInG,
01479                                Vector_<SpatialVec>& bodyForcesInG) const;
01480 
01481     // End of Construction and Misc Methods.
01483 
01485         // BUILT IN MOBILIZER DECLARATIONS //
01487 
01488     // These are the built-in MobilizedBody types. Types on the same line are
01489     // synonymous. Each of these has a known number of coordinates and speeds 
01490     // (at least a default number) so
01491     // can define routines which return and accept specific-size arguments, e.g.
01492     // Real (for 1-dof mobilizer) and Vec5 (for 5-dof mobilizer). Here is the
01493     // conventional interface that each built-in should provide. The base type
01494     // provides similar routines but using variable-sized or "one at a time"
01495     // arguments. (Vec<1> here will actually be a Real; assume the built-in
01496     // MobilizedBody class is "BuiltIn")
01497     //
01498     //    BuiltIn&       setDefaultQ(const Vec<nq>&);
01499     //    const Vec<nq>& getDefaultQ() const;
01500     //
01501     //    const Vec<nq>& getQ[Dot[Dot]](const State&) const;
01502     //    const Vec<nu>& getU[Dot](const State&) const;
01503     //
01504     //    void setQ(State&, const Vec<nq>&) const;
01505     //    void setU(State&, const Vec<nu>&) const;
01506     //
01507     //    const Vec<nq>& getMyPartQ(const State&, const Vector& qlike) const;
01508     //    const Vec<nu>& getMyPartU(const State&, const Vector& ulike) const;
01509     //   
01510     //    Vec<nq>& updMyPartQ(const State&, Vector& qlike) const;
01511     //    Vec<nu>& updMyPartU(const State&, Vector& ulike) const;
01512     //      
01513 
01514 
01515     class Pin;              typedef Pin             Torsion;
01516     class Universal;
01517     class Cylinder;
01518 
01519     class Weld;
01520     class Slider;           typedef Slider          Prismatic;
01521     class Translation2D;    typedef Translation2D   Cartesian2D, CartesianCoords2D;
01522     class Translation;      typedef Translation     Cartesian, CartesianCoords;
01523     class BendStretch;      typedef BendStretch     PolarCoords;
01524     class TorsionStretch;   typedef TorsionStretch  ConicalCoords2D;
01525     class SphericalCoords;
01526     class CylindricalCoords;
01527     class LineOrientation;
01528 
01529 
01530     class Planar;
01531     class Gimbal;
01532     class Ball;             typedef Ball            Orientation, Spherical;
01533     class Free;
01534     class FreeLine;
01535     class Screw;
01536     class Ellipsoid;
01537     class Custom;
01538     class Ground;
01539     class FunctionBased;
01540     
01541     class PinImpl;
01542     class SliderImpl;
01543     class UniversalImpl;
01544     class CylinderImpl;
01545     class BendStretchImpl;
01546     class TorsionStretchImpl;
01547     class PlanarImpl;
01548     class GimbalImpl;
01549     class BallImpl;
01550     class TranslationImpl;
01551     class SphericalCoordsImpl;
01552     class FreeImpl;
01553     class LineOrientationImpl;
01554     class FreeLineImpl;
01555     class WeldImpl;
01556     class ScrewImpl;
01557     class EllipsoidImpl;
01558     class CustomImpl;
01559     class GroundImpl;
01560     class FunctionBasedImpl;
01561 
01562 };
01563 
01567 class SimTK_SIMBODY_EXPORT MobilizedBody::Pin : public MobilizedBody {
01568 public:
01569         // SPECIALIZED INTERFACE FOR PIN MOBILIZER
01570 
01571     // "Angle" is just a nicer name for a pin joint's lone generalized coordinate q.
01572     Pin& setDefaultAngle(Real angleInRadians) {return setDefaultQ(angleInRadians);}
01573     Real getDefaultAngle() const              {return getDefaultQ();}
01574 
01575         // Friendly, mobilizer-specific access to generalized coordinates and speeds.
01576 
01577     void setAngle(State& s, Real angleInRadians) {setQ(s, angleInRadians);}
01578     Real getAngle(const State& s) const {return getQ(s);}
01579 
01580     void setRate(State& s, Real rateInRadiansPerTime) {setU(s, rateInRadiansPerTime);}
01581     Real getRate(const State& s) const {return getU(s);}
01582 
01583     // Mobility forces are "u-like", that is, one per dof.
01584     Real getAppliedPinTorque(const State& s, const Vector& mobilityForces) const {
01585         return getMyPartU(s,mobilityForces);
01586     }
01587     void applyPinTorque(const State& s, Real torque, Vector& mobilityForces) const {
01588         updMyPartU(s,mobilityForces) += torque;
01589     }
01590 
01591         // STANDARDIZED MOBILIZED BODY INTERFACE
01592 
01593         // required constructors
01594     explicit Pin(Direction=Forward);
01595     Pin(MobilizedBody& parent, const Body&, Direction=Forward);
01596     Pin(MobilizedBody& parent, const Transform& inbFrame,
01597         const Body&,           const Transform& outbFrame,
01598         Direction=Forward);
01599 
01600         // access to generalized coordinates q and generalized speeds u
01601     Pin& setDefaultQ(Real);
01602     Real getDefaultQ() const;
01603 
01604     Real getQ(const State&) const;
01605     Real getQDot(const State&) const;
01606     Real getQDotDot(const State&) const;
01607     Real getU(const State&) const;
01608     Real getUDot(const State&) const;
01609 
01610     void setQ(State&, Real) const;
01611     void setU(State&, Real) const;
01612 
01613     Real getMyPartQ(const State&, const Vector& qlike) const;
01614     Real getMyPartU(const State&, const Vector& ulike) const;
01615    
01616     Real& updMyPartQ(const State&, Vector& qlike) const;
01617     Real& updMyPartU(const State&, Vector& ulike) const;
01618 
01619         // specialize return type for convenience
01620     Pin& addBodyDecoration(const Transform& X_BD, const DecorativeGeometry& g)
01621       { (void)MobilizedBody::addBodyDecoration(X_BD,g); return *this; }
01622     Pin& addOutboardDecoration(const Transform& X_MD,  const DecorativeGeometry& g)
01623       { (void)MobilizedBody::addOutboardDecoration(X_MD,g); return *this; }
01624     Pin& addInboardDecoration (const Transform& X_FD, const DecorativeGeometry& g)
01625       { (void)MobilizedBody::addInboardDecoration(X_FD,g); return *this; }
01626     Pin& setDefaultInboardFrame(const Transform& X_PF)
01627       { (void)MobilizedBody::setDefaultInboardFrame(X_PF); return *this; }
01628     Pin& setDefaultOutboardFrame(const Transform& X_BM)
01629       { (void)MobilizedBody::setDefaultOutboardFrame(X_BM); return *this; }
01630     SimTK_INSERT_DERIVED_HANDLE_DECLARATIONS(Pin, PinImpl, MobilizedBody);
01631 };
01632 
01636 class SimTK_SIMBODY_EXPORT MobilizedBody::Slider : public MobilizedBody {
01637 public:
01638         // SPECIALIZED INTERFACE FOR SLIDER MOBILIZER
01639 
01640     // "Length" is just a nicer name for a sliding joint's lone generalized coordinate q.
01641     Slider& setDefaultLength(Real length) {return setDefaultQ(length);}
01642     Real getDefaultLength() const         {return getDefaultQ();}
01643 
01644         // Friendly, mobilizer-specific access to generalized coordinates and speeds.
01645 
01646     void setLength(State& s, Real length) {setQ(s, length);}
01647     Real getLength(const State& s) const {return getQ(s);}
01648 
01649     void setRate(State& s, Real rateInLengthPerTime) {setU(s, rateInLengthPerTime);}
01650     Real getRate(const State& s) const {return getU(s);}
01651 
01652     // Mobility forces are "u-like", that is, one per dof.
01653     Real getAppliedForce(const State& s, const Vector& mobilityForces) const {
01654         return getMyPartU(s,mobilityForces);
01655     }
01656     void applyForce(const State& s, Real force, Vector& mobilityForces) const {
01657         updMyPartU(s,mobilityForces) += force;
01658     }
01659 
01660         // STANDARDIZED MOBILIZED BODY INTERFACE
01661 
01662         // required constructors
01663     explicit Slider(Direction=Forward);
01664     Slider(MobilizedBody& parent, const Body&, Direction=Forward);
01665     Slider(MobilizedBody& parent, const Transform& inbFrame,
01666            const Body&,           const Transform& outbFrame, Direction=Forward);
01667 
01668         // access to generalized coordinates q and generalized speeds u
01669     Slider& setDefaultQ(Real);
01670     Real getDefaultQ() const;
01671 
01672     Real getQ(const State&) const;
01673     Real getQDot(const State&) const;
01674     Real getQDotDot(const State&) const;
01675     Real getU(const State&) const;
01676     Real getUDot(const State&) const;
01677 
01678     void setQ(State&, Real) const;
01679     void setU(State&, Real) const;
01680 
01681     Real getMyPartQ(const State&, const Vector& qlike) const;
01682     Real getMyPartU(const State&, const Vector& ulike) const;
01683    
01684     Real& updMyPartQ(const State&, Vector& qlike) const;
01685     Real& updMyPartU(const State&, Vector& ulike) const;
01686 
01687         // specialize return type for convenience
01688     Slider& addBodyDecoration(const Transform& X_BD, const DecorativeGeometry& g)
01689       { (void)MobilizedBody::addBodyDecoration(X_BD,g); return *this; }
01690     Slider& addOutboardDecoration(const Transform& X_MD,  const DecorativeGeometry& g)
01691       { (void)MobilizedBody::addOutboardDecoration(X_MD,g); return *this; }
01692     Slider& addInboardDecoration (const Transform& X_FD, const DecorativeGeometry& g)
01693       { (void)MobilizedBody::addInboardDecoration(X_FD,g); return *this; }
01694     Slider& setDefaultInboardFrame(const Transform& X_PF)
01695       { (void)MobilizedBody::setDefaultInboardFrame(X_PF); return *this; }
01696     Slider& setDefaultOutboardFrame(const Transform& X_BM)
01697       { (void)MobilizedBody::setDefaultOutboardFrame(X_BM); return *this; }
01698     SimTK_INSERT_DERIVED_HANDLE_DECLARATIONS(Slider, SliderImpl, MobilizedBody);
01699 };
01700 
01706 class SimTK_SIMBODY_EXPORT MobilizedBody::Screw : public MobilizedBody {
01707 public:
01708     explicit Screw(Real pitch, Direction=Forward);
01709 
01712     Screw(MobilizedBody& parent, const Body&, Real pitch, Direction=Forward);
01713 
01716     Screw(MobilizedBody& parent, const Transform& inbFrame,
01717          const Body&,           const Transform& outbFrame,
01718          Real pitch, Direction=Forward);
01719 
01720     Screw& addBodyDecoration(const Transform& X_BD, const DecorativeGeometry& g) {
01721         (void)MobilizedBody::addBodyDecoration(X_BD,g); return *this;
01722     }
01723     Screw& addOutboardDecoration(const Transform& X_MD,  const DecorativeGeometry& g) {
01724         (void)MobilizedBody::addOutboardDecoration(X_MD,g); return *this;
01725     }
01726     Screw& addInboardDecoration (const Transform& X_FD, const DecorativeGeometry& g) {
01727         (void)MobilizedBody::addInboardDecoration(X_FD,g); return *this;
01728     }
01729 
01730     Screw& setDefaultInboardFrame(const Transform& X_PF) {
01731         (void)MobilizedBody::setDefaultInboardFrame(X_PF); return *this;
01732     }
01733 
01734     Screw& setDefaultOutboardFrame(const Transform& X_BM) {
01735         (void)MobilizedBody::setDefaultOutboardFrame(X_BM); return *this;
01736     }
01737 
01738     Screw& setDefaultPitch(Real pitch);
01739     Real   getDefaultPitch() const;
01740 
01741     Screw& setDefaultQ(Real);
01742     Real   getDefaultQ() const;
01743 
01744     Real getQ(const State&) const;
01745     Real getQDot(const State&) const;
01746     Real getQDotDot(const State&) const;
01747     Real getU(const State&) const;
01748     Real getUDot(const State&) const;
01749 
01750     void setQ(State&, Real) const;
01751     void setU(State&, Real) const;
01752 
01753     Real getMyPartQ(const State&, const Vector& qlike) const;
01754     Real getMyPartU(const State&, const Vector& ulike) const;
01755    
01756     Real& updMyPartQ(const State&, Vector& qlike) const;
01757     Real& updMyPartU(const State&, Vector& ulike) const;
01758     SimTK_INSERT_DERIVED_HANDLE_DECLARATIONS(Screw, ScrewImpl, MobilizedBody);
01759 };
01760 
01764 class SimTK_SIMBODY_EXPORT MobilizedBody::Universal : public MobilizedBody {
01765 public:
01766     explicit Universal(Direction=Forward);
01767 
01770     Universal(MobilizedBody& parent, const Body&, Direction=Forward);
01771 
01774     Universal(MobilizedBody& parent, const Transform& inbFrame,
01775               const Body&,           const Transform& outbFrame, Direction=Forward);
01776 
01777     Universal& addBodyDecoration(const Transform& X_BD, const DecorativeGeometry& g) {
01778         (void)MobilizedBody::addBodyDecoration(X_BD,g); return *this;
01779     }
01780     Universal& addOutboardDecoration(const Transform& X_MD,  const DecorativeGeometry& g) {
01781         (void)MobilizedBody::addOutboardDecoration(X_MD,g); return *this;
01782     }
01783     Universal& addInboardDecoration (const Transform& X_FD, const DecorativeGeometry& g) {
01784         (void)MobilizedBody::addInboardDecoration(X_FD,g); return *this;
01785     }
01786 
01787     Universal& setDefaultInboardFrame(const Transform& X_PF) {
01788         (void)MobilizedBody::setDefaultInboardFrame(X_PF); return *this;
01789     }
01790 
01791     Universal& setDefaultOutboardFrame(const Transform& X_BM) {
01792         (void)MobilizedBody::setDefaultOutboardFrame(X_BM); return *this;
01793     }
01794     SimTK_INSERT_DERIVED_HANDLE_DECLARATIONS(Universal, UniversalImpl, MobilizedBody);
01795 };
01796 
01799 class SimTK_SIMBODY_EXPORT MobilizedBody::Cylinder : public MobilizedBody {
01800 public:
01801     explicit Cylinder(Direction=Forward);
01802 
01805     Cylinder(MobilizedBody& parent, const Body&, Direction=Forward);
01806 
01809     Cylinder(MobilizedBody& parent, const Transform& inbFrame,
01810              const Body&,           const Transform& outbFrame, Direction=Forward);
01811 
01812     Cylinder& addBodyDecoration(const Transform& X_BD, const DecorativeGeometry& g) {
01813         (void)MobilizedBody::addBodyDecoration(X_BD,g); return *this;
01814     }
01815     Cylinder& addOutboardDecoration(const Transform& X_MD,  const DecorativeGeometry& g) {
01816         (void)MobilizedBody::addOutboardDecoration(X_MD,g); return *this;
01817     }
01818     Cylinder& addInboardDecoration (const Transform& X_FD, const DecorativeGeometry& g) {
01819         (void)MobilizedBody::addInboardDecoration(X_FD,g); return *this;
01820     }
01821 
01822     Cylinder& setDefaultInboardFrame(const Transform& X_PF) {
01823         (void)MobilizedBody::setDefaultInboardFrame(X_PF); return *this;
01824     }
01825 
01826     Cylinder& setDefaultOutboardFrame(const Transform& X_BM) {
01827         (void)MobilizedBody::setDefaultOutboardFrame(X_BM); return *this;
01828     }
01829     SimTK_INSERT_DERIVED_HANDLE_DECLARATIONS(Cylinder, CylinderImpl, MobilizedBody);
01830 };
01831 
01840 class SimTK_SIMBODY_EXPORT MobilizedBody::BendStretch : public MobilizedBody {
01841 public:
01842     explicit BendStretch(Direction=Forward);
01843 
01846     BendStretch(MobilizedBody& parent, const Body&, Direction=Forward);
01847 
01850     BendStretch(MobilizedBody& parent, const Transform& inbFrame,
01851                 const Body&,           const Transform& outbFrame, Direction=Forward);
01852 
01853     BendStretch& addBodyDecoration(const Transform& X_BD, const DecorativeGeometry& g) {
01854         (void)MobilizedBody::addBodyDecoration(X_BD,g); return *this;
01855     }
01856     BendStretch& addOutboardDecoration(const Transform& X_MD,  const DecorativeGeometry& g) {
01857         (void)MobilizedBody::addOutboardDecoration(X_MD,g); return *this;
01858     }
01859     BendStretch& addInboardDecoration (const Transform& X_FD, const DecorativeGeometry& g) {
01860         (void)MobilizedBody::addInboardDecoration(X_FD,g); return *this;
01861     }
01862 
01863     BendStretch& setDefaultInboardFrame(const Transform& X_PF) {
01864         (void)MobilizedBody::setDefaultInboardFrame(X_PF); return *this;
01865     }
01866 
01867     BendStretch& setDefaultOutboardFrame(const Transform& X_BM) {
01868         (void)MobilizedBody::setDefaultOutboardFrame(X_BM); return *this;
01869     }
01870     SimTK_INSERT_DERIVED_HANDLE_DECLARATIONS(BendStretch, BendStretchImpl, MobilizedBody);
01871 };
01872 
01877 class SimTK_SIMBODY_EXPORT MobilizedBody::Planar : public MobilizedBody {
01878 public:
01879     explicit Planar(Direction=Forward);
01880 
01883     Planar(MobilizedBody& parent, const Body&, Direction=Forward);
01884 
01887     Planar(MobilizedBody& parent, const Transform& inbFrame,
01888            const Body&,           const Transform& outbFrame,
01889            Direction=Forward);
01890 
01891     Planar& addBodyDecoration(const Transform& X_BD, const DecorativeGeometry& g) {
01892         (void)MobilizedBody::addBodyDecoration(X_BD,g); return *this;
01893     }
01894     Planar& addOutboardDecoration(const Transform& X_MD,  const DecorativeGeometry& g) {
01895         (void)MobilizedBody::addOutboardDecoration(X_MD,g); return *this;
01896     }
01897     Planar& addInboardDecoration (const Transform& X_FD, const DecorativeGeometry& g) {
01898         (void)MobilizedBody::addInboardDecoration(X_FD,g); return *this;
01899     }
01900 
01901     Planar& setDefaultInboardFrame(const Transform& X_PF) {
01902         (void)MobilizedBody::setDefaultInboardFrame(X_PF); return *this;
01903     }
01904 
01905     Planar& setDefaultOutboardFrame(const Transform& X_BM) {
01906         (void)MobilizedBody::setDefaultOutboardFrame(X_BM); return *this;
01907     }
01908 
01909     // Friendly, mobilizer-specific access to coordinates and speeds.
01910     Planar& setDefaultAngle(Real a) {
01911         Vec3 q = getDefaultQ(); q[0] = a; setDefaultQ(q);
01912         return *this;
01913     }
01914     Planar& setDefaultTranslation(const Vec2& r) {
01915         Vec3 q = getDefaultQ(); q.updSubVec<2>(1) = r; setDefaultQ(q);
01916         return *this;
01917     }
01918 
01919     Real getDefaultAngle() const {return getDefaultQ()[0];}
01920     const Vec2& getDefaultTranslation() const {return getDefaultQ().getSubVec<2>(1);}
01921 
01922     void setAngle      (State& s, Real        a) {setOneQ(s,0,a);}
01923     void setTranslation(State& s, const Vec2& r) {setOneQ(s,1,r[0]); setOneQ(s,2,r[1]);}
01924 
01925     Real getAngle(const State& s) const {return getQ(s)[0];}
01926     const Vec2& getTranslation(const State& s) const {return getQ(s).getSubVec<2>(1);}
01927 
01928     // Generic default state Topology methods.
01929     const Vec3& getDefaultQ() const;
01930     Planar& setDefaultQ(const Vec3& q);
01931 
01932     const Vec3& getQ(const State&) const;
01933     const Vec3& getQDot(const State&) const;
01934     const Vec3& getQDotDot(const State&) const;
01935     const Vec3& getU(const State&) const;
01936     const Vec3& getUDot(const State&) const;
01937 
01938     void setQ(State&, const Vec3&) const;
01939     void setU(State&, const Vec3&) const;
01940 
01941     const Vec3& getMyPartQ(const State&, const Vector& qlike) const;
01942     const Vec3& getMyPartU(const State&, const Vector& ulike) const;
01943    
01944     Vec3& updMyPartQ(const State&, Vector& qlike) const;
01945     Vec3& updMyPartU(const State&, Vector& ulike) const;
01946     SimTK_INSERT_DERIVED_HANDLE_DECLARATIONS(Planar, PlanarImpl, MobilizedBody);
01947 };
01948 
01973 class SimTK_SIMBODY_EXPORT MobilizedBody::SphericalCoords : public MobilizedBody {
01974 public:
01975     explicit SphericalCoords(Direction=Forward);
01976 
01979     SphericalCoords(MobilizedBody& parent, const Body&, Direction=Forward);
01980 
01985     SphericalCoords(MobilizedBody& parent, const Transform& inbFrame,
01986                     const Body&,           const Transform& outbFrame,
01987                     Direction=Forward);
01988 
01990     SphericalCoords(MobilizedBody& parent,      const Transform& inbFrame,
01991                     const Body&,                const Transform& outbFrame,
01992                     Real azimuthOffset,         bool azimuthNegated,
01993                     Real zenithOffset,          bool zenithNegated,
01994                     CoordinateAxis radialAxis,  bool radialNegated,
01995                     Direction=Forward);
01996 
01997     SphericalCoords& addBodyDecoration(const Transform& X_BD, const DecorativeGeometry& g) {
01998         (void)MobilizedBody::addBodyDecoration(X_BD,g); return *this;
01999     }
02000     SphericalCoords& addOutboardDecoration(const Transform& X_MD,  const DecorativeGeometry& g) {
02001         (void)MobilizedBody::addOutboardDecoration(X_MD,g); return *this;
02002     }
02003     SphericalCoords& addInboardDecoration (const Transform& X_FD, const DecorativeGeometry& g) {
02004         (void)MobilizedBody::addInboardDecoration(X_FD,g); return *this;
02005     }
02006 
02007     SphericalCoords& setDefaultInboardFrame(const Transform& X_PF) {
02008         (void)MobilizedBody::setDefaultInboardFrame(X_PF); return *this;
02009     }
02010 
02011     SphericalCoords& setDefaultOutboardFrame(const Transform& X_BM) {
02012         (void)MobilizedBody::setDefaultOutboardFrame(X_BM); return *this;
02013     }
02014 
02015     // Friendly, mobilizer-specific access to coordinates and speeds.
02016     SphericalCoords& setDefaultAngles(const Vec2& a) {
02017         Vec3 q = getDefaultQ(); q.updSubVec<2>(0) = a; setDefaultQ(q);
02018         return *this;
02019     }
02020     SphericalCoords& setDefaultRadius(Real r) {
02021         Vec3 q = getDefaultQ(); q[2] = r; setDefaultQ(q);
02022         return *this;
02023     }
02024     SphericalCoords& setRadialAxis(CoordinateAxis);
02025     SphericalCoords& setNegateAzimuth(bool);
02026     SphericalCoords& setNegateZenith(bool);
02027     SphericalCoords& setNegateRadial(bool);
02028 
02029     const Vec2&    getDefaultAngles()      const {return getDefaultQ().getSubVec<2>(0);}
02030     Real           getDefaultTranslation() const {return getDefaultQ()[2];}
02031     
02032     CoordinateAxis getRadialAxis()    const;
02033     bool           isAzimuthNegated() const;
02034     bool           isZenithNegated()  const;
02035     bool           isRadialNegated()  const;
02036 
02037     void setAngles(State& s, const Vec2& a) {setOneQ(s,0,a[0]); setOneQ(s,1,a[1]);}
02038     void setRadius(State& s, Real        r) {setOneQ(s,2,r);}
02039 
02040     const Vec2& getAngles(const State& s) const {return getQ(s).getSubVec<2>(0);}
02041     Real        getRadius(const State& s) const {return getQ(s)[2];}
02042 
02043     // Generic default state Topology methods.
02044     const Vec3& getDefaultQ() const;
02045     SphericalCoords& setDefaultQ(const Vec3& q);
02046 
02047     const Vec3& getQ(const State&) const;
02048     const Vec3& getQDot(const State&) const;
02049     const Vec3& getQDotDot(const State&) const;
02050     const Vec3& getU(const State&) const;
02051     const Vec3& getUDot(const State&) const;
02052 
02053     void setQ(State&, const Vec3&) const;
02054     void setU(State&, const Vec3&) const;
02055 
02056     const Vec3& getMyPartQ(const State&, const Vector& qlike) const;
02057     const Vec3& getMyPartU(const State&, const Vector& ulike) const;
02058    
02059     Vec3& updMyPartQ(const State&, Vector& qlike) const;
02060     Vec3& updMyPartU(const State&, Vector& ulike) const;
02061 
02062     SimTK_INSERT_DERIVED_HANDLE_DECLARATIONS(SphericalCoords, SphericalCoordsImpl, MobilizedBody);
02063 };
02064 
02068 class SimTK_SIMBODY_EXPORT MobilizedBody::Gimbal : public MobilizedBody {
02069 public:
02070     explicit Gimbal(Direction=Forward);
02071 
02074     Gimbal(MobilizedBody& parent, const Body&, Direction=Forward);
02075 
02078     Gimbal(MobilizedBody& parent, const Transform& inbFrame,
02079            const Body&,           const Transform& outbFrame, Direction=Forward);
02080 
02081     Gimbal& addBodyDecoration(const Transform& X_BD, const DecorativeGeometry& g) {
02082         (void)MobilizedBody::addBodyDecoration(X_BD,g); return *this;
02083     }
02084     Gimbal& addOutboardDecoration(const Transform& X_MD,  const DecorativeGeometry& g) {
02085         (void)MobilizedBody::addOutboardDecoration(X_MD,g); return *this;
02086     }
02087     Gimbal& addInboardDecoration (const Transform& X_FD, const DecorativeGeometry& g) {
02088         (void)MobilizedBody::addInboardDecoration(X_FD,g); return *this;
02089     }
02090 
02091     Gimbal& setDefaultInboardFrame(const Transform& X_PF) {
02092         (void)MobilizedBody::setDefaultInboardFrame(X_PF); return *this;
02093     }
02094 
02095     Gimbal& setDefaultOutboardFrame(const Transform& X_BM) {
02096         (void)MobilizedBody::setDefaultOutboardFrame(X_BM); return *this;
02097     }
02098 
02099     // This is just a nicer name for the generalized coordinate.
02100     Gimbal& setDefaultRotation(const Rotation& R_FM) {
02101         return setDefaultQ(R_FM.convertRotationToBodyFixedXYZ());
02102     }
02103     Rotation getDefaultRotation() const {
02104         const Vec3& q = getDefaultQ();
02105         return Rotation(BodyRotationSequence,
02106             q[0], XAxis, q[1], YAxis, q[2], ZAxis);
02107     }
02108 
02109     // This is used only for visualization.
02110     Gimbal& setDefaultRadius(Real r);
02111     Real getDefaultRadius() const;
02112 
02113     // Generic default state Topology methods.
02114     const Vec3& getDefaultQ() const; // X,Y,Z body-fixed Euler angles
02115     Gimbal& setDefaultQ(const Vec3& q);
02116 
02117     const Vec3& getQ(const State&) const;
02118     const Vec3& getQDot(const State&) const;
02119     const Vec3& getQDotDot(const State&) const;
02120     const Vec3& getU(const State&) const;
02121     const Vec3& getUDot(const State&) const;
02122 
02123     void setQ(State&, const Vec3&) const;
02124     void setU(State&, const Vec3&) const;
02125 
02126     const Vec3& getMyPartQ(const State&, const Vector& qlike) const;
02127     const Vec3& getMyPartU(const State&, const Vector& ulike) const;
02128    
02129     Vec3& updMyPartQ(const State&, Vector& qlike) const;
02130     Vec3& updMyPartU(const State&, Vector& ulike) const;
02131     SimTK_INSERT_DERIVED_HANDLE_DECLARATIONS(Gimbal, GimbalImpl, MobilizedBody);
02132 };
02133 
02138 class SimTK_SIMBODY_EXPORT MobilizedBody::Ball : public MobilizedBody {
02139 public:
02140     explicit Ball(Direction=Forward);
02141 
02144     Ball(MobilizedBody& parent, const Body&, Direction=Forward);
02145 
02148     Ball(MobilizedBody& parent, const Transform& inbFrame,
02149          const Body&,           const Transform& outbFrame, Direction=Forward);
02150 
02151     Ball& addBodyDecoration(const Transform& X_BD, const DecorativeGeometry& g) {
02152         (void)MobilizedBody::addBodyDecoration(X_BD,g); return *this;
02153     }
02154     Ball& addOutboardDecoration(const Transform& X_MD,  const DecorativeGeometry& g) {
02155         (void)MobilizedBody::addOutboardDecoration(X_MD,g); return *this;
02156     }
02157     Ball& addInboardDecoration (const Transform& X_FD, const DecorativeGeometry& g) {
02158         (void)MobilizedBody::addInboardDecoration(X_FD,g); return *this;
02159     }
02160 
02161     Ball& setDefaultInboardFrame(const Transform& X_PF) {
02162         (void)MobilizedBody::setDefaultInboardFrame(X_PF); return *this;
02163     }
02164 
02165     Ball& setDefaultOutboardFrame(const Transform& X_BM) {
02166         (void)MobilizedBody::setDefaultOutboardFrame(X_BM); return *this;
02167     }
02168 
02169     // This is just a nicer name for the generalized coordinate.
02170     Ball& setDefaultRotation(const Rotation& R_FM) {
02171         return setDefaultQ(R_FM.convertRotationToQuaternion());
02172     }
02173     Rotation getDefaultRotation() const {return Rotation(getDefaultQ());}
02174 
02175     // This is used only for visualization.
02176     Ball& setDefaultRadius(Real r);
02177     Real getDefaultRadius() const;
02178 
02179     // Generic default state Topology methods.
02180     const Quaternion& getDefaultQ() const;
02181     Ball& setDefaultQ(const Quaternion& q);
02182 
02183     const Vec4& getQ(const State&) const;
02184     const Vec4& getQDot(const State&) const;
02185     const Vec4& getQDotDot(const State&) const;
02186     const Vec3& getU(const State&) const;
02187     const Vec3& getUDot(const State&) const;
02188 
02189     void setQ(State&, const Vec4&) const;
02190     void setU(State&, const Vec3&) const;
02191 
02192     const Vec4& getMyPartQ(const State&, const Vector& qlike) const;
02193     const Vec3& getMyPartU(const State&, const Vector& ulike) const;
02194    
02195     Vec4& updMyPartQ(const State&, Vector& qlike) const;
02196     Vec3& updMyPartU(const State&, Vector& ulike) const;
02197     SimTK_INSERT_DERIVED_HANDLE_DECLARATIONS(Ball, BallImpl, MobilizedBody);
02198 };
02199 
02204 class SimTK_SIMBODY_EXPORT MobilizedBody::Ellipsoid : public MobilizedBody {
02205 public:
02208     explicit Ellipsoid(Direction=Forward); // not very useful until radii are set, but has some defaults
02209 
02212     Ellipsoid(MobilizedBody& parent, const Body&, Direction=Forward);
02213 
02216     Ellipsoid(MobilizedBody& parent, const Transform& inbFrame,
02217               const Body&,           const Transform& outbFrame,
02218               Direction=Forward);
02219 
02223     Ellipsoid(MobilizedBody& parent, const Transform& inbFrame,
02224               const Body&,           const Transform& outbFrame,
02225               const Vec3& radii,
02226               Direction=Forward);
02227 
02228     Ellipsoid& addBodyDecoration(const Transform& X_BD, const DecorativeGeometry& g) {
02229         (void)MobilizedBody::addBodyDecoration(X_BD,g); return *this;
02230     }
02231     Ellipsoid& addOutboardDecoration(const Transform& X_MD,  const DecorativeGeometry& g) {
02232         (void)MobilizedBody::addOutboardDecoration(X_MD,g); return *this;
02233     }
02234     Ellipsoid& addInboardDecoration (const Transform& X_FD, const DecorativeGeometry& g) {
02235         (void)MobilizedBody::addInboardDecoration(X_FD,g); return *this;
02236     }
02237 
02238     Ellipsoid& setDefaultInboardFrame(const Transform& X_PF) {
02239         (void)MobilizedBody::setDefaultInboardFrame(X_PF); return *this;
02240     }
02241 
02242     Ellipsoid& setDefaultOutboardFrame(const Transform& X_BM) {
02243         (void)MobilizedBody::setDefaultOutboardFrame(X_BM); return *this;
02244     }
02245 
02246     // This is just a nicer name for the generalized coordinate.
02247     Ellipsoid& setDefaultRotation(const Rotation& R_FM) {
02248         return setDefaultQ(R_FM.convertRotationToQuaternion());
02249     }
02250     Rotation getDefaultRotation() const {return Rotation(getDefaultQ());}
02251 
02252     Ellipsoid& setDefaultRadii(const Vec3& r);
02253     const Vec3& getDefaultRadii() const;
02254 
02255     // Generic default state Topology methods.
02256     const Quaternion& getDefaultQ() const;
02257     Quaternion& updDefaultQ();
02258     Ellipsoid& setDefaultQ(const Quaternion& q) {updDefaultQ()=q; return *this;}
02259 
02260     const Vec4& getQ(const State&) const;
02261     const Vec4& getQDot(const State&) const;
02262     const Vec4& getQDotDot(const State&) const;
02263     const Vec3& getU(const State&) const;
02264     const Vec3& getUDot(const State&) const;
02265 
02266     void setQ(State&, const Vec4&) const;
02267     void setU(State&, const Vec3&) const;
02268 
02269     const Vec4& getMyPartQ(const State&, const Vector& qlike) const;
02270     const Vec3& getMyPartU(const State&, const Vector& ulike) const;
02271    
02272     Vec4& updMyPartQ(const State&, Vector& qlike) const;
02273     Vec3& updMyPartU(const State&, Vector& ulike) const;
02274 
02275     SimTK_INSERT_DERIVED_HANDLE_DECLARATIONS(Ellipsoid, EllipsoidImpl, MobilizedBody);
02276 };
02277 
02280 class SimTK_SIMBODY_EXPORT MobilizedBody::Translation : public MobilizedBody {
02281 public:
02282     explicit Translation(Direction=Forward);
02283 
02286     Translation(MobilizedBody& parent, const Body&, Direction=Forward);
02287 
02290     Translation(MobilizedBody& parent, const Transform& inbFrame,
02291                 const Body&,           const Transform& outbFrame, Direction=Forward);
02292 
02293     Translation& addBodyDecoration(const Transform& X_BD, const DecorativeGeometry& g) {
02294         (void)MobilizedBody::addBodyDecoration(X_BD,g); return *this;
02295     }
02296     Translation& addOutboardDecoration(const Transform& X_MD,  const DecorativeGeometry& g) {
02297         (void)MobilizedBody::addOutboardDecoration(X_MD,g); return *this;
02298     }
02299     Translation& addInboardDecoration (const Transform& X_FD, const DecorativeGeometry& g) {
02300         (void)MobilizedBody::addInboardDecoration(X_FD,g); return *this;
02301     }
02302 
02303     Translation& setDefaultInboardFrame(const Transform& X_PF) {
02304         (void)MobilizedBody::setDefaultInboardFrame(X_PF); return *this;
02305     }
02306 
02307     Translation& setDefaultOutboardFrame(const Transform& X_BM) {
02308         (void)MobilizedBody::setDefaultOutboardFrame(X_BM); return *this;
02309     }
02310 
02311     // This is just a nicer name for setting this mobilizer's generalized coordinates,
02312     // which together constitute the vector from the F frame's origin to the M
02313     // frame's origin, expressed in F.
02314 
02315     // Set the topological default values for the initial q's.
02316     Translation& setDefaultTranslation(const Vec3& p_FM) {
02317         return setDefaultQ(p_FM);
02318     }
02319 
02320     // Get the topological default values for the initial q's.
02321     const Vec3& getDefaultTranslation() const {
02322         return getDefaultQ();
02323     }
02324 
02325     // Set the current value of q's in the given State. Note that this is
02326     // the *cross-mobilizer* translation, not location in the Ground frame.
02327     void setMobilizerTranslation(State& s, const Vec3& p_FM) const {
02328         setQ(s,p_FM);
02329     }
02330 
02331     // Get the current value of the q's for this mobilizer from the given State.
02332     const Vec3& getMobilizerTranslation(const State& s) const {
02333         return getQ(s);
02334     }
02335 
02336 
02337     // Set the current value of u's in the given State. Note that this is
02338     // the *cross-mobilizer* velocity v_FM, not velocity in the Ground frame.
02339     void setMobilizerVelocity(State& s, const Vec3& v_FM) const {
02340         setU(s,v_FM);
02341     }
02342 
02343     // Get the current value of the u's for this mobilizer from the given State.
02344     const Vec3& getMobilizerVelocity(const State& s) const {
02345         return getU(s);
02346     }
02347 
02348     // Get the value of the udot's for this mobilizer from the given State.
02349     const Vec3& getMobilizerAcceleration(const State& s) const {
02350         return getUDot(s);
02351     }
02352 
02353     // Generic default state Topology methods.
02354     const Vec3& getDefaultQ() const;
02355     Translation& setDefaultQ(const Vec3& q);
02356 
02357     const Vec3& getQ(const State&) const;
02358     const Vec3& getQDot(const State&) const;
02359     const Vec3& getQDotDot(const State&) const;
02360     const Vec3& getU(const State&) const;
02361     const Vec3& getUDot(const State&) const;
02362 
02363     void setQ(State&, const Vec3&) const;
02364     void setU(State&, const Vec3&) const;
02365 
02366     const Vec3& getMyPartQ(const State&, const Vector& qlike) const;
02367     const Vec3& getMyPartU(const State&, const Vector& ulike) const;
02368    
02369     Vec3& updMyPartQ(const State&, Vector& qlike) const;
02370     Vec3& updMyPartU(const State&, Vector& ulike) const;
02371     SimTK_INSERT_DERIVED_HANDLE_DECLARATIONS(Translation, TranslationImpl, MobilizedBody);
02372 };
02373 
02380 class SimTK_SIMBODY_EXPORT MobilizedBody::Free : public MobilizedBody {
02381 public:
02382     explicit Free(Direction=Forward);
02383 
02386     Free(MobilizedBody& parent, const Body&, Direction=Forward);
02387 
02390     Free(MobilizedBody& parent, const Transform& inbFrame,
02391          const Body&,           const Transform& outbFrame,
02392          Direction=Forward);
02393 
02394     Free& addBodyDecoration(const Transform& X_BD, const DecorativeGeometry& g) {
02395         (void)MobilizedBody::addBodyDecoration(X_BD,g); return *this;
02396     }
02397     Free& addOutboardDecoration(const Transform& X_MD,  const DecorativeGeometry& g) {
02398         (void)MobilizedBody::addOutboardDecoration(X_MD,g); return *this;
02399     }
02400     Free& addInboardDecoration (const Transform& X_FD, const DecorativeGeometry& g) {
02401         (void)MobilizedBody::addInboardDecoration(X_FD,g); return *this;
02402     }
02403 
02404     Free& setDefaultInboardFrame(const Transform& X_PF) {
02405         (void)MobilizedBody::setDefaultInboardFrame(X_PF); return *this;
02406     }
02407 
02408     Free& setDefaultOutboardFrame(const Transform& X_BM) {
02409         (void)MobilizedBody::setDefaultOutboardFrame(X_BM); return *this;
02410     }
02411 
02412     // Leaves rotation unchanged.
02413     Free& setDefaultTranslation(const Vec3&);
02414 
02415     // Leaves translation unchanged. The internal representation is a quaternion
02416     // so we guarantee that the stored value is numerically identical to the
02417     // supplied one.
02418     Free& setDefaultQuaternion(const Quaternion&);
02419 
02420     // Leaves translation unchanged. The Rotation matrix will be converted to
02421     // a quaternion for storage.
02422     Free& setDefaultRotation(const Rotation&);
02423     // Sets both translation and rotation. The Rotation part of the Transform 
02424     // will be converted to a quaternion for storage.
02425     Free& setDefaultTransform(const Transform&);
02426 
02427     // These return references to the stored default values.
02428     const Vec3& getDefaultTranslation() const;
02429     const Quaternion& getDefaultQuaternion() const;
02430 
02431     // These next two are derived from the stored values.
02432     Rotation getDefaultRotation() const {
02433         return Rotation(getDefaultQuaternion());
02434     }
02435     Transform getDefaultTransform() const {
02436         return Transform(Rotation(getDefaultQuaternion()), getDefaultTranslation());
02437     }
02438 
02439     // Generic default state Topology methods.
02440 
02441     // Returns (Vec4,Vec3) where the Vec4 is a normalized quaternion.
02442     const Vec7& getDefaultQ() const;
02443 
02444     // Interprets the supplied q as (Vec4,Vec3) where the Vec4 is a possibly
02445     // unnormalized quaternion. The quaternion will be normalized before it is
02446     // stored here, so you may not get back exactly the value supplied here if
02447     // you call getDefaultQ().
02448     Free& setDefaultQ(const Vec7& q);
02449 
02450     // Note that there is no guarantee that the quaternion part of the returned Q is normalized.
02451     const Vec7& getQ(const State&) const;
02452     const Vec7& getQDot(const State&) const;
02453     const Vec7& getQDotDot(const State&) const;
02454 
02455     const Vec6& getU(const State&) const;
02456     const Vec6& getUDot(const State&) const;
02457 
02458     // The Q's in the state are set exactly as supplied without normalization.
02459     void setQ(State&, const Vec7&) const;
02460     void setU(State&, const Vec6&) const;
02461 
02462     const Vec7& getMyPartQ(const State&, const Vector& qlike) const;
02463     const Vec6& getMyPartU(const State&, const Vector& ulike) const;
02464    
02465     Vec7& updMyPartQ(const State&, Vector& qlike) const;
02466     Vec6& updMyPartU(const State&, Vector& ulike) const;
02467     SimTK_INSERT_DERIVED_HANDLE_DECLARATIONS(Free, FreeImpl, MobilizedBody);
02468 };
02469 
02470 
02471 // These are special "ball" and "free" joints designed to allow arbitrary orientations
02472 // for "linear" bodies, such as a CO2 molecule consisting only of point masses arranged
02473 // along a straight line. Such bodies have no inertia about the line and cause singularities
02474 // in the equations of motion if attached to Orientation or Free mobilizers. Instead, use the
02475 // LineOrientation and LineFree moblizers, making sure that the inertialess direction is
02476 // along the outboard body's z axis (that is, Mz). These mobilizers introduce only two
02477 // mobilities (generalized speeds u), being incapable of representing non-zero angular
02478 // velocity of M in F about Mz. The generalized speeds are in fact the wx and wy 
02479 // components of w_FM_M, that is, the x and y components of the angular velocity of M
02480 // in F *expressed in M*. However, at least three generalized coordinates (q's)
02481 // are required to represent the orientation. By default we use four quaternions for
02482 // unconditional stability. Alternatively, you can request a 1-2-3 body fixed 
02483 // Euler angle sequence (that is, about x, then new y, then new z) which will
02484 // suffer a singularity when the y rotation is 90 degrees since that aligns the
02485 // first rotation axis (x) with the last (z) which is the inertialess direction.
02486 
02492 class SimTK_SIMBODY_EXPORT MobilizedBody::LineOrientation : public MobilizedBody {
02493 public:
02494     explicit LineOrientation(Direction=Forward);
02495 
02498     LineOrientation(MobilizedBody& parent, const Body&, Direction=Forward);
02499 
02502     LineOrientation(MobilizedBody& parent, const Transform& inbFrame,
02503                     const Body&,           const Transform& outbFrame, Direction=Forward);
02504 
02505     LineOrientation& addBodyDecoration(const Transform& X_BD, const DecorativeGeometry& g) {
02506         (void)MobilizedBody::addBodyDecoration(X_BD,g); return *this;
02507     }
02508     LineOrientation& addOutboardDecoration(const Transform& X_MD,  const DecorativeGeometry& g) {
02509         (void)MobilizedBody::addOutboardDecoration(X_MD,g); return *this;
02510     }
02511     LineOrientation& addInboardDecoration (const Transform& X_FD, const DecorativeGeometry& g) {
02512         (void)MobilizedBody::addInboardDecoration(X_FD,g); return *this;
02513     }
02514 
02515     LineOrientation& setDefaultInboardFrame(const Transform& X_PF) {
02516         (void)MobilizedBody::setDefaultInboardFrame(X_PF); return *this;
02517     }
02518 
02519     LineOrientation& setDefaultOutboardFrame(const Transform& X_BM) {
02520         (void)MobilizedBody::setDefaultOutboardFrame(X_BM); return *this;
02521     }
02522 
02523     // This is just a nicer name for the generalized coordinate.
02524     LineOrientation& setDefaultRotation(const Rotation& R_FM) {
02525         return setDefaultQ(R_FM.convertRotationToQuaternion());
02526     }
02527     Rotation getDefaultRotation() const {return Rotation(getDefaultQ());}
02528 
02529     // Generic default state Topology methods.
02530     const Quaternion& getDefaultQ() const;
02531     LineOrientation& setDefaultQ(const Quaternion& q);
02532 
02533     const Vec4& getQ(const State&) const;
02534     const Vec4& getQDot(const State&) const;
02535     const Vec4& getQDotDot(const State&) const;
02536     const Vec2& getU(const State&) const;
02537     const Vec2& getUDot(const State&) const;
02538 
02539     void setQ(State&, const Vec4&) const;
02540     void setU(State&, const Vec2&) const;
02541 
02542     const Vec4& getMyPartQ(const State&, const Vector& qlike) const;
02543     const Vec2& getMyPartU(const State&, const Vector& ulike) const;
02544    
02545     Vec4& updMyPartQ(const State&, Vector& qlike) const;
02546     Vec2& updMyPartU(const State&, Vector& ulike) const;
02547     SimTK_INSERT_DERIVED_HANDLE_DECLARATIONS(LineOrientation, LineOrientationImpl, MobilizedBody);
02548 };
02549 
02554 class SimTK_SIMBODY_EXPORT MobilizedBody::FreeLine : public MobilizedBody {
02555 public:
02556     explicit FreeLine(Direction=Forward);
02557 
02560     FreeLine(MobilizedBody& parent, const Body&, Direction=Forward);
02561 
02564     FreeLine(MobilizedBody& parent, const Transform& inbFrame,
02565              const Body&,           const Transform& outbFrame, Direction=Forward);
02566 
02567     FreeLine& addBodyDecoration(const Transform& X_BD, const DecorativeGeometry& g) {
02568         (void)MobilizedBody::addBodyDecoration(X_BD,g); return *this;
02569     }
02570     FreeLine& addOutboardDecoration(const Transform& X_MD,  const DecorativeGeometry& g) {
02571         (void)MobilizedBody::addOutboardDecoration(X_MD,g); return *this;
02572     }
02573     FreeLine& addInboardDecoration (const Transform& X_FD, const DecorativeGeometry& g) {
02574         (void)MobilizedBody::addInboardDecoration(X_FD,g); return *this;
02575     }
02576 
02577     FreeLine& setDefaultInboardFrame(const Transform& X_PF) {
02578         (void)MobilizedBody::setDefaultInboardFrame(X_PF); return *this;
02579     }
02580 
02581     FreeLine& setDefaultOutboardFrame(const Transform& X_BM) {
02582         (void)MobilizedBody::setDefaultOutboardFrame(X_BM); return *this;
02583     }
02584     SimTK_INSERT_DERIVED_HANDLE_DECLARATIONS(FreeLine, FreeLineImpl, MobilizedBody);
02585 };
02586 
02589 class SimTK_SIMBODY_EXPORT MobilizedBody::Weld : public MobilizedBody {
02590 public:
02593     Weld();
02594 
02597     Weld(MobilizedBody& parent, const Body&);
02598 
02601     Weld(MobilizedBody& parent, const Transform& inbFrame,
02602          const Body&,           const Transform& outbFrame);
02603 
02604     Weld& addBodyDecoration(const Transform& X_BD, const DecorativeGeometry& g) {
02605         (void)MobilizedBody::addBodyDecoration(X_BD,g); return *this;
02606     }
02607     Weld& addOutboardDecoration(const Transform& X_MD,  const DecorativeGeometry& g) {
02608         (void)MobilizedBody::addOutboardDecoration(X_MD,g); return *this;
02609     }
02610     Weld& addInboardDecoration (const Transform& X_FD, const DecorativeGeometry& g) {
02611         (void)MobilizedBody::addInboardDecoration(X_FD,g); return *this;
02612     }
02613 
02614     Weld& setDefaultInboardFrame(const Transform& X_PF) {
02615         (void)MobilizedBody::setDefaultInboardFrame(X_PF); return *this;
02616     }
02617 
02618     Weld& setDefaultOutboardFrame(const Transform& X_BM) {
02619         (void)MobilizedBody::setDefaultOutboardFrame(X_BM); return *this;
02620     }
02621     SimTK_INSERT_DERIVED_HANDLE_DECLARATIONS(Weld, WeldImpl, MobilizedBody);
02622 };
02623 
02624 
02628 class SimTK_SIMBODY_EXPORT MobilizedBody::Ground : public MobilizedBody {
02629 public:
02631     Ground();
02632     Ground& addBodyDecoration(const Transform& X_BD, const DecorativeGeometry& g) {
02633         (void)MobilizedBody::addBodyDecoration(X_BD,g); return *this;
02634     }
02635     SimTK_INSERT_DERIVED_HANDLE_DECLARATIONS(Ground, GroundImpl, MobilizedBody);
02636 };
02637 
02638 
02670 class SimTK_SIMBODY_EXPORT MobilizedBody::Custom : public MobilizedBody {
02671 public:
02672     class Implementation;
02673     class ImplementationImpl;
02674 
02675     /* Create a Custom MobilizedBody.
02676      * 
02677      * @param parent         the MobilizedBody's parent body
02678      * @param implementation the object which implements the custom mobilized body.  The MobilizedBody::Custom takes over
02679      *                       ownership of the implementation object, and deletes it when the MobilizedBody itself
02680      *                       is deleted.
02681      * @param body           describes this MobilizedBody's physical properties
02682      * @param direction      whether you want the coordinates defined as though parent & child were swapped
02683      */
02684     Custom(MobilizedBody& parent, Implementation* implementation, const Body& body, Direction direction=Forward);
02685     /* Create a Custom MobilizedBody.
02686      * 
02687      * @param parent         the MobilizedBody's parent body
02688      * @param implementation the object which implements the custom mobilized body.  The MobilizedBody::Custom takes over
02689      *                       ownership of the implementation object, and deletes it when the MobilizedBody itself
02690      *                       is deleted.
02691      * @param inbFrame       the MobilizedBody's inboard reference frame
02692      * @param body           describes this MobilizedBody's physical properties
02693      * @param outbFrame      the MobilizedBody's outboard reference frame
02694      * @param direction      whether you want the coordinates defined as though parent & child were swapped
02695      */
02696     Custom(MobilizedBody& parent, Implementation* implementation, 
02697            const Transform& inbFrame, const Body& body, const Transform& outbFrame,
02698            Direction direction=Forward);
02699     SimTK_INSERT_DERIVED_HANDLE_DECLARATIONS(Custom, CustomImpl, MobilizedBody);
02700 protected:
02701     const Implementation& getImplementation() const;
02702     Implementation&       updImplementation();
02703 
02704     Custom() {}
02705 };
02706 
02707 // We only want the template instantiation to occur once. This symbol is defined in the SimTK core
02708 // compilation unit that defines the MobilizedBody class but should not be defined any other time.
02709 // BE SURE TO DEAL WITH THIS IN MobilizedBody_Instantiation.cpp.
02710 #ifndef SimTK_SIMBODY_DEFINING_MOBILIZED_BODY
02711     extern template class PIMPLHandle<MobilizedBody::Custom::Implementation, MobilizedBody::Custom::ImplementationImpl>;
02712 #endif
02713 
02714 
02715 class SimTK_SIMBODY_EXPORT MobilizedBody::Custom::Implementation 
02716   : public PIMPLHandle<Implementation,ImplementationImpl> 
02717 {
02718 public:
02719     // No default constructor because you have to supply at least the SimbodyMatterSubsystem
02720     // to which this MobilizedBody belongs.
02721 
02723     virtual ~Implementation();
02724 
02729     virtual Implementation* clone() const = 0;
02730 
02754     Implementation(SimbodyMatterSubsystem&, int nu, int nq, int nAngles=0);
02755 
02759     Vector getQ(const State& s) const;
02760     
02762     Vector getU(const State& s) const;
02763 
02767     Vector getQDot(const State& s) const;
02768 
02770     Vector getUDot(const State& s) const;
02771     
02775     Vector getQDotDot(const State& s) const;
02776 
02781     Transform getMobilizerTransform(const State& s) const;
02782 
02789     SpatialVec getMobilizerVelocity(const State& s) const;
02790 
02799     bool getUseEulerAngles(const State& s) const;
02800 
02807     void invalidateTopologyCache() const;
02808 
02813 
02814 
02819     virtual Transform calcMobilizerTransformFromQ(const State& s, int nq, const Real* q) const = 0;
02820 
02821 
02838     virtual SpatialVec multiplyByHMatrix(const State& s, int nu, const Real* u) const = 0;
02839 
02848     virtual void multiplyByHTranspose(const State& s, const SpatialVec& F, int nu, Real* f) const = 0;
02849 
02859     virtual SpatialVec multiplyByHDotMatrix(const State& s, int nu, const Real* u) const = 0;
02860 
02869     virtual void multiplyByHDotTranspose(const State& s, const SpatialVec& F, int nu, Real* f) const = 0;
02870 
02881     virtual void multiplyByN(const State& s, bool transposeMatrix, 
02882                              int nIn, const Real* in, int nOut, Real* out) const;
02883 
02894     virtual void multiplyByNInv(const State& s, bool transposeMatrix, 
02895                                 int nIn, const Real* in, int nOut, Real* out) const;
02896 
02907     virtual void multiplyByNDot(const State& s, bool transposeMatrix, 
02908                                 int nIn, const Real* in, int nOut, Real* out) const;
02909 
02910         // Methods for setting Mobilizer initial conditions. Note -- I've stripped this
02911         // down to the two basic routines but the built-ins have 8 so that you can 
02912         // specify only rotations or translations. I'm not sure that's needed here and
02913         // I suppose you could add more routines later if needed.
02914         // Eventually it might be nice to provide default implementation here that would
02915         // use a root finder to attempt to solve these initial condition problems. For
02916         // most joints there is a much more direct way to do it, and sometimes there
02917         // are behavioral choices to make, which is why it is nice to have mobilizer-specific
02918         // overrides for these.
02919 
02928     virtual void setQToFitTransform(const State&, const Transform& X_FM, int nq, Real* q) const;
02929 
02941     virtual void setUToFitVelocity(const State&, const SpatialVec& V_FM, int nu, Real* u) const;
02942 
02949     virtual void calcDecorativeGeometryAndAppend
02950        (const State& s, Stage stage, Array_<DecorativeGeometry>& geom) const
02951     {
02952     }
02954 
02955 
02964 
02966 
02967 
02968 
02969 
02970 
02971 
02972 
02973 
02974     virtual void realizeTopology(State&) const { }
02975 
02984     virtual void realizeModel(State&) const { }
02985 
02989     virtual void realizeInstance(const State&) const { }
02990 
02995     virtual void realizeTime(const State&) const { }
02996 
03003     virtual void realizePosition(const State&) const { }
03004 
03011     virtual void realizeVelocity(const State&) const { }
03012 
03019     virtual void realizeDynamics(const State&) const { }
03020 
03027     virtual void realizeAcceleration(const State&) const { }
03028 
03034     virtual void realizeReport(const State&) const { }
03036 
03037     friend class MobilizedBody::CustomImpl;
03038 };
03039 
03051 class SimTK_SIMBODY_EXPORT MobilizedBody::FunctionBased : public MobilizedBody::Custom {
03052 public:
03053     /* Create a FunctionBased MobilizedBody.
03054      * 
03055      * @param parent         the MobilizedBody's parent body
03056      * @param body           describes this MobilizedBody's physical properties
03057      * @param nmobilities    the number of generalized coordinates belonging to this MobilizedBody
03058      * @param functions      the Functions describing how the body moves based on its generalized coordinates.
03059      *                       This must be of length 6.  The elements correspond to, in order, x rotation, y rotation, z rotation,
03060      *                       x translation, y translation, and z translation.  The MobilizedBody takes over ownership of the functions,
03061      *                       and automatically deletes them when the MobilizedBody is deleted.
03062      * @param coordIndices   the indices of the generalized coordinates that are inputs to each function.  For example, if coordIndices[2] = {0, 1},
03063      *                       that means that functions[2] takes two input arguments, and q[0] and q[1] respectively should be passed as those arguments.
03064      * @param direction      whether you want the coordinates defined as though parent & child were swapped
03065      */
03066     FunctionBased(MobilizedBody& parent, const Body& body, 
03067                   int nmobilities, const Array_<const Function*>& functions,
03068                   const Array_<Array_<int> >& coordIndices,
03069                   Direction direction=Forward);
03070 
03072     FunctionBased(MobilizedBody& parent, const Body& body, 
03073                   int nmobilities, const std::vector<const Function*>& functions,
03074                   const std::vector<std::vector<int> >& coordIndices,
03075                   Direction direction=Forward) 
03076     {
03077         Array_< Array_<int> > coordCopy(coordIndices); // sorry, must copy
03078         // Use the above constructor.
03079         new(this) FunctionBased(parent,body,nmobilities,
03080                                 ArrayViewConst_<const Function*>(functions), 
03081                                 coordCopy, direction);
03082     }
03083 
03084     /* Create a FunctionBased MobilizedBody.
03085      * 
03086      * @param parent         the MobilizedBody's parent body
03087      * @param inbFrame       the default inboard frame
03088      * @param body           describes this MobilizedBody's physical properties
03089      * @param outbFrame      the default outboard frame
03090      * @param nmobilities    the number of generalized coordinates belonging to this MobilizedBody
03091      * @param functions      the Functions describing how the body moves based on its generalized coordinates.
03092      *                       This must be of length 6.  The elements correspond to, in order, x rotation, y rotation, z rotation,
03093      *                       x translation, y translation, and z translation.  The MobilizedBody takes over ownership of the functions,
03094      *                       and automatically deletes them when the MobilizedBody is deleted.
03095      * @param coordIndices   the indices of the generalized coordinates that are inputs to each function.  For example, if coordIndices[2] = {0, 1},
03096      *                       that means that functions[2] takes two input arguments, and q[0] and q[1] respectively should be passed as those arguments.
03097      * @param direction      whether you want the coordinates defined as though parent & child were swapped
03098      */
03099     FunctionBased(MobilizedBody& parent, const Transform& inbFrame, 
03100                   const Body& body, const Transform& outbFrame, 
03101                   int nmobilities, const Array_<const Function*>& functions,
03102                   const Array_<Array_<int> >& coordIndices,
03103                   Direction direction=Forward);
03104 
03106     FunctionBased(MobilizedBody& parent, const Transform& inbFrame, 
03107                   const Body& body, const Transform& outbFrame, 
03108                   int nmobilities, const std::vector<const Function*>& functions,
03109                   const std::vector<std::vector<int> >& coordIndices,
03110                   Direction direction=Forward)
03111     {
03112         Array_< Array_<int> > coordCopy(coordIndices); // sorry, must copy
03113         // Use the above constructor.
03114         new(this) FunctionBased(parent,inbFrame,body,outbFrame,
03115                                 nmobilities, ArrayViewConst_<const Function*>(functions), 
03116                                 coordCopy, direction);
03117     }
03118 
03119     /* Create a FunctionBased MobilizedBody.
03120      * 
03121      * @param parent         the MobilizedBody's parent body
03122      * @param body           describes this MobilizedBody's physical properties
03123      * @param nmobilities    the number of generalized coordinates belonging to this MobilizedBody
03124      * @param functions      the Functions describing how the body moves based on its generalized coordinates.
03125      *                       This must be of length 6.  The elements correspond to, in order, x rotation, y rotation, z rotation,
03126      *                       x translation, y translation, and z translation.  The MobilizedBody takes over ownership of the functions,
03127      *                       and automatically deletes them when the MobilizedBody is deleted.
03128      * @param coordIndices   the indices of the generalized coordinates that are inputs to each function.  For example, if coordIndices[2] = {0, 1},
03129      *                       that means that functions[2] takes two input arguments, and q[0] and q[1] respectively should be passed as those arguments.
03130      * @param axes           the axes directions (as Vec3's) for each spatial coordinate, which each function describes, and is therefore length 6.
03131      *                       First 3 and last 3 axes must be linearly independent, otherwise there will be redundant speeds for the same motion.
03132      * @param direction      whether you want the coordinates defined as though parent & child were swapped
03133      */
03134     FunctionBased(MobilizedBody& parent, const Body& body, 
03135                   int nmobilities, const Array_<const Function*>& functions,
03136                   const Array_<Array_<int> >& coordIndices, const Array_<Vec3>& axes,
03137                   Direction direction=Forward);
03138 
03140     FunctionBased(MobilizedBody& parent, const Body& body, 
03141                   int nmobilities, const std::vector<const Function*>& functions,
03142                   const std::vector<std::vector<int> >& coordIndices, const std::vector<Vec3>& axes,
03143                   Direction direction=Forward)
03144     {
03145         Array_< Array_<int> > coordCopy(coordIndices); // sorry, must copy
03146         // Use the above constructor.
03147         new(this) FunctionBased(parent,body,
03148                                 nmobilities, ArrayViewConst_<const Function*>(functions), 
03149                                 coordCopy, ArrayViewConst_<Vec3>(axes), 
03150                                 direction);
03151     }
03152 
03153     /* Create a FunctionBased MobilizedBody.
03154      * 
03155      * @param parent         the MobilizedBody's parent body
03156      * @param inbFrame       the default inboard frame
03157      * @param body           describes this MobilizedBody's physical properties
03158      * @param outbFrame      the default outboard frame
03159      * @param nmobilities    the number of generalized coordinates belonging to this MobilizedBody
03160      * @param functions      the Functions describing how the body moves based on its generalized coordinates.
03161      *                       This must be of length 6.  The elements correspond to, in order, x rotation, y rotation, z rotation,
03162      *                       x translation, y translation, and z translation.  The MobilizedBody takes over ownership of the functions,
03163      *                       and automatically deletes them when the MobilizedBody is deleted.
03164      * @param coordIndices   the indices of the generalized coordinates that are inputs to each function.  For example, if coordIndices[2] = {0, 1},
03165      *                       that means that functions[2] takes two input arguments, and q[0] and q[1] respectively should be passed as those arguments.
03166      * @param axes           the axes directions (as Vec3's) for each spatial coordinate, which each function describes, and is therefore length 6.
03167      *                       First 3 and last 3 axes must be linearly independent, otherwise there will be redundant speeds for the same motion.
03168      * @param direction      whether you want the coordinates defined as though parent & child were swapped
03169      */
03170     FunctionBased(MobilizedBody& parent, const Transform& inbFrame, 
03171                   const Body& body, const Transform& outbFrame, 
03172                   int nmobilities, const Array_<const Function*>& functions,
03173                   const Array_<Array_<int> >& coordIndices, const Array_<Vec3>& axes,
03174                   Direction direction=Forward);
03175 
03177     FunctionBased(MobilizedBody& parent, const Transform& inbFrame, 
03178                   const Body& body, const Transform& outbFrame,
03179                   int nmobilities, const std::vector<const Function*>& functions,
03180                   const std::vector<std::vector<int> >& coordIndices, const std::vector<Vec3>& axes,
03181                   Direction direction=Forward)
03182     {
03183         Array_< Array_<int> > coordCopy(coordIndices); // sorry, must copy
03184         // Use the above constructor.
03185         new(this) FunctionBased(parent,inbFrame,body,outbFrame,
03186                                 nmobilities, ArrayViewConst_<const Function*>(functions), 
03187                                 coordCopy, ArrayViewConst_<Vec3>(axes), 
03188                                 direction);
03189     }
03190 private:
03191     FunctionBased() {}
03192 };
03193 
03194 } // namespace SimTK
03195 
03196 #endif // SimTK_SIMBODY_MOBILIZED_BODY_H_
03197 
03198 
03199 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines