Simbody
|
00001 #ifndef SimTK_SIMBODY_MATTER_SUBSYSTEM_H_ 00002 #define SimTK_SIMBODY_MATTER_SUBSYSTEM_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) 2006-9 Stanford University and the Authors. * 00013 * Authors: Michael Sherman * 00014 * Contributors: Paul Mitiguy * 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 00035 #include "SimTKcommon.h" 00036 #include "simbody/internal/common.h" 00037 #include "simbody/internal/MobilizedBody.h" 00038 00039 #include <cassert> 00040 #include <vector> 00041 #include <iostream> 00042 00043 class SimbodyMatterSubsystemRep; 00044 00045 namespace SimTK { 00046 00047 class MobilizedBody; 00048 class MultibodySystem; 00049 class Constraint; 00050 00124 class SimTK_SIMBODY_EXPORT SimbodyMatterSubsystem : public Subsystem { 00125 public: 00126 00128 SimbodyMatterSubsystem(); 00129 explicit SimbodyMatterSubsystem(MultibodySystem&); 00130 00131 class Subtree; // used for working with a connected subgraph of the MobilizedBody tree 00132 class SubtreeResults; 00133 00134 // These are the same as the compiler defaults but are handy to 00135 // have around explicitly for debugging. 00136 ~SimbodyMatterSubsystem() { 00137 } 00138 SimbodyMatterSubsystem(const SimbodyMatterSubsystem& ss) : Subsystem(ss) { 00139 } 00140 SimbodyMatterSubsystem& operator=(const SimbodyMatterSubsystem& ss) { 00141 Subsystem::operator=(ss); 00142 return *this; 00143 } 00144 00147 bool getShowDefaultGeometry() const; 00148 00151 void setShowDefaultGeometry(bool show); 00152 00153 00155 // PAUL'S FRIENDLY INTERFACE // 00157 00162 Real calcSystemMass(const State& s) const; 00163 00164 00170 Vec3 calcSystemMassCenterLocationInGround(const State& s) const; 00171 00172 00178 MassProperties calcSystemMassPropertiesInGround(const State& s) const; 00179 00185 Inertia calcSystemCentralInertiaInGround(const State& s) const; 00186 00192 Vec3 calcSystemMassCenterVelocityInGround(const State& s) const; 00193 00199 Vec3 calcSystemMassCenterAccelerationInGround(const State& s) const; 00200 00207 SpatialVec calcSystemMomentumAboutGroundOrigin(const State& s) const; 00208 00216 SpatialVec calcSystemCentralMomentum(const State& s) const; 00217 00219 // CONSTRUCTION // 00221 00234 MobilizedBodyIndex adoptMobilizedBody(MobilizedBodyIndex parent, 00235 MobilizedBody& child); 00236 00240 const MobilizedBody& getMobilizedBody(MobilizedBodyIndex) const; 00241 00245 MobilizedBody& updMobilizedBody(MobilizedBodyIndex); 00246 00247 00248 // Note: topology is not marked invalid upon returning a writable reference 00249 // here; that will be done only if a non-const method of the returned 00250 // MobilizedBody is called. That means it is OK to use Ground() to satisfy 00251 // a const argument; it won't have an "invalidate topology" side effect. 00252 00255 const MobilizedBody::Ground& getGround() const; 00258 MobilizedBody::Ground& updGround(); 00261 MobilizedBody::Ground& Ground() {return updGround();} 00262 00273 ConstraintIndex adoptConstraint(Constraint&); 00274 00278 const Constraint& getConstraint(ConstraintIndex) const; 00279 00283 Constraint& updConstraint(ConstraintIndex); 00284 00286 // OPERATORS // 00288 00289 // Operators make use of the State but do not write their results back 00290 // into the State, not even into the State cache. 00291 00332 void calcAcceleration(const State&, 00333 const Vector& mobilityForces, 00334 const Vector_<SpatialVec>& bodyForces, 00335 Vector& udot, // output only; no prescribed motions 00336 Vector_<SpatialVec>& A_GB) const; 00337 00362 void calcDynamicsFromForcesAndMotions(const State&, 00363 const Vector& appliedMobilityForces, // [nu] or [0] 00364 const Vector_<SpatialVec>& appliedBodyForces, // [nb] or [0] 00365 const Vector& udot_p, // [npres] or [0] 00366 Vector& udot, // [nu] (output only) 00367 Vector& lambda_p, // [npres] (output only) 00368 Vector& lambda_r) const; // [m] (output only) 00369 00378 void calcDynamicsFromForces(const State&, 00379 const Vector& appliedMobilityForces, // [nu] or [0] 00380 const Vector_<SpatialVec>& appliedBodyForces, // [nb] or [0] 00381 Vector& udot, // [nu] (output only) 00382 Vector& lambda_p, // [npres] (output only) 00383 Vector& lambda_r) const; // [m] (output only) 00384 00399 void calcAccelerationIgnoringConstraints(const State&, 00400 const Vector& mobilityForces, 00401 const Vector_<SpatialVec>& bodyForces, 00402 Vector& udot, 00403 Vector_<SpatialVec>& A_GB) const; 00404 00431 void calcMInverseV(const State&, 00432 const Vector& v, 00433 Vector& MinvV) const; 00434 00454 void calcResidualForce 00455 (const State& state, 00456 const Vector& appliedMobilityForces, 00457 const Vector_<SpatialVec>& appliedBodyForces, 00458 const Vector& knownUdot, 00459 const Vector& knownMultipliers, 00460 Vector& residualMobilityForces) const; 00461 00510 void calcResidualForceIgnoringConstraints 00511 (const State& state, 00512 const Vector& appliedMobilityForces, 00513 const Vector_<SpatialVec>& appliedBodyForces, 00514 const Vector& knownUdot, 00515 Vector& residualMobilityForces) const; 00516 00532 void calcMV(const State&, const Vector& v, Vector& MV) const; 00533 00540 void calcCompositeBodyInertias(const State&, 00541 Vector_<SpatialMat>& R) const; 00542 00566 void calcAccelerationFromUDot(const State& state, 00567 const Vector& knownUDot, 00568 Vector_<SpatialVec>& A_GB) const; 00569 00576 void calcAccConstraintErr(const State&, 00577 const Vector& knownUdot, 00578 Vector& constraintErr) const; 00579 00584 void calcGV(const State&, 00585 const Vector& v, 00586 Vector& Gv) const; 00587 00594 void calcGtV(const State&, 00595 const Vector& v, 00596 Vector& GtV) const; 00597 00598 00611 void calcM(const State&, Matrix& M) const; 00612 00626 void calcMInv(const State&, Matrix& MInv) const; 00627 00638 void calcG(const State&, Matrix& G) const; 00639 00650 void calcGt(const State&, Matrix& Gt) const; 00651 00674 void calcPtV(const State& s, const Vector& v, Vector& PtV) const; 00675 00691 void calcPNInv(const State& state, Matrix& PNInv) const; 00692 00707 void calcP(const State& state, Matrix& P) const; 00708 00710 void calcPt(const State& state, Matrix& Pt) const; 00711 00723 void calcConstraintForcesFromMultipliers 00724 (const State& s, const Vector& multipliers, 00725 Vector_<SpatialVec>& bodyForcesInG, 00726 Vector& mobilityForces) const; 00727 00759 void calcMobilizerReactionForces 00760 (const State& state, 00761 Vector_<SpatialVec>& forcesAtMInG) const; 00762 00764 void calcSpatialKinematicsFromInternal(const State&, 00765 const Vector& v, 00766 Vector_<SpatialVec>& Jv) const; 00767 00769 void calcInternalGradientFromSpatial(const State&, 00770 const Vector_<SpatialVec>& dEdR, 00771 Vector& dEdQ) const; // really Qbar 00772 00774 Real calcKineticEnergy(const State&) const; 00775 00780 void calcTreeEquivalentMobilityForces(const State&, 00781 const Vector_<SpatialVec>& bodyForces, 00782 Vector& mobilityForces) const; 00783 00784 00785 00787 void calcQDot(const State& s, 00788 const Vector& u, 00789 Vector& qdot) const; 00790 00793 void calcQDotDot(const State& s, 00794 const Vector& udot, 00795 Vector& qdotdot) const; 00796 00803 void multiplyByN(const State& s, bool transpose, 00804 const Vector& in, Vector& out) const; 00805 00813 void multiplyByNInv(const State& s, bool transpose, 00814 const Vector& in, Vector& out) const; 00815 00824 void multiplyByNDot(const State& s, bool transpose, 00825 const Vector& in, Vector& out) const; 00826 00827 // These are available after realizeTopology(). 00828 00837 int getNumBodies() const; 00838 00841 int getNumConstraints() const; 00842 00844 int getNumParticles() const; 00845 00848 int getNumMobilities() const; 00849 00852 int getTotalQAlloc() const; 00853 00856 int getTotalMultAlloc() const; 00857 00864 void setUseEulerAngles(State&, bool) const; 00865 bool getUseEulerAngles (const State&) const; 00866 00867 int getNumQuaternionsInUse(const State&) const; 00868 00869 void setMobilizerIsPrescribed(State&, MobilizedBodyIndex, bool) const; 00870 bool isMobilizerPrescribed (const State&, MobilizedBodyIndex) const; 00871 bool isUsingQuaternion(const State&, MobilizedBodyIndex) const; 00872 QuaternionPoolIndex getQuaternionPoolIndex(const State&, MobilizedBodyIndex) const; 00873 AnglePoolIndex getAnglePoolIndex(const State&, MobilizedBodyIndex) const; 00874 void setConstraintIsDisabled(State&, ConstraintIndex constraint, bool) const; 00875 bool isConstraintDisabled(const State&, ConstraintIndex constraint) const; 00876 00883 void convertToEulerAngles(const State& inputState, State& outputState) const; 00884 00891 void convertToQuaternions(const State& inputState, State& outputState) const; 00892 00893 00894 // PARTICLES 00895 // TODO: not currently implemented. Use a point mass with a Cartesian (translation) 00896 // mobilizer to Ground instead. The idea here would be to special-case particles 00897 // to make them faster; there would be no additional functionality. 00898 00899 // The generalized coordinates for a particle are always the three measure numbers 00900 // (x,y,z) of the particle's Ground-relative Cartesian location vector. The generalized 00901 // speeds are always the three corresponding measure numbers of the particle's 00902 // Ground-relative Cartesian velocity. The generalized applied forces are 00903 // always the three measure numbers of a Ground-relative force vector. 00904 const Vector_<Vec3>& getAllParticleLocations (const State&) const; 00905 const Vector_<Vec3>& getAllParticleVelocities (const State&) const; 00906 00907 const Vec3& getParticleLocation(const State& s, ParticleIndex p) const { 00908 return getAllParticleLocations(s)[p]; 00909 } 00910 const Vec3& getParticleVelocity(const State& s, ParticleIndex p) const { 00911 return getAllParticleVelocities(s)[p]; 00912 } 00913 00914 Vector& updAllParticleMasses(State& s) const; 00915 00916 void setAllParticleMasses(State& s, const Vector& masses) const { 00917 updAllParticleMasses(s) = masses; 00918 } 00919 00920 // Note that particle generalized coordinates, speeds, and applied forces 00921 // are defined to be the particle Cartesian locations, velocities, and 00922 // applied force vectors, so can be set directly at Stage::Model or higher. 00923 00924 // These are the only routines that must be provided by the concrete MatterSubsystem. 00925 Vector_<Vec3>& updAllParticleLocations(State&) const; 00926 Vector_<Vec3>& updAllParticleVelocities(State&) const; 00927 00928 // The following inline routines are provided by the generic MatterSubsystem class 00929 // for convenience. 00930 00931 Vec3& updParticleLocation(State& s, ParticleIndex p) const { 00932 return updAllParticleLocations(s)[p]; 00933 } 00934 Vec3& updParticleVelocity(State& s, ParticleIndex p) const { 00935 return updAllParticleVelocities(s)[p]; 00936 } 00937 00938 void setParticleLocation(State& s, ParticleIndex p, const Vec3& r) const { 00939 updAllParticleLocations(s)[p] = r; 00940 } 00941 void setParticleVelocity(State& s, ParticleIndex p, const Vec3& v) const { 00942 updAllParticleVelocities(s)[p] = v; 00943 } 00944 00945 void setAllParticleLocations(State& s, const Vector_<Vec3>& r) const { 00946 updAllParticleLocations(s) = r; 00947 } 00948 void setAllParticleVelocities(State& s, const Vector_<Vec3>& v) const { 00949 updAllParticleVelocities(s) = v; 00950 } 00951 00953 const Vector& getAllParticleMasses(const State&) const; 00954 00955 const Vector_<Vec3>& getAllParticleAccelerations(const State&) const; 00956 00957 const Vec3& getParticleAcceleration(const State& s, ParticleIndex p) const { 00958 return getAllParticleAccelerations(s)[p]; 00959 } 00960 00961 // POSITION STAGE realizations // 00962 00971 void realizeCompositeBodyInertias(const State&) const; 00972 00981 void realizeArticulatedBodyInertias(const State&) const; 00982 00983 00984 // POSITION STAGE responses // 00985 00993 const SpatialMat& getCompositeBodyInertia(const State&, MobilizedBodyIndex) const; 00994 01003 const SpatialMat& getArticulatedBodyInertia(const State&, MobilizedBodyIndex) const; 01004 01005 // POSITION STAGE operators // 01006 01010 void addInStationForce(const State&, MobilizedBodyIndex bodyB, const Vec3& stationOnB, 01011 const Vec3& forceInG, Vector_<SpatialVec>& bodyForcesInG) const; 01012 01015 void addInBodyTorque(const State&, MobilizedBodyIndex, const Vec3& torqueInG, 01016 Vector_<SpatialVec>& bodyForcesInG) const; 01017 01020 void addInMobilityForce(const State&, MobilizedBodyIndex, MobilizerUIndex which, Real f, 01021 Vector& mobilityForces) const; 01022 01023 // POSITION STAGE solvers // 01024 01030 bool prescribe(State&, Stage) const; 01031 01037 bool projectQConstraints(State& s, Real consAccuracy, const Vector& yWeights, 01038 const Vector& ooTols, Vector& yErrest, System::ProjectOptions) const; 01039 01040 // VELOCITY STAGE responses // 01041 01044 const SpatialVec& getCoriolisAcceleration(const State&, MobilizedBodyIndex) const; 01045 01048 const SpatialVec& getTotalCoriolisAcceleration(const State&, MobilizedBodyIndex) const; 01049 01051 const SpatialVec& getGyroscopicForce(const State&, MobilizedBodyIndex) const; 01052 01057 const SpatialVec& getCentrifugalForces(const State&, MobilizedBodyIndex) const; 01058 01062 const SpatialVec& getTotalCentrifugalForces(const State&, MobilizedBodyIndex) const; 01063 01064 // VELOCITY STAGE operators // 01065 01066 // VELOCITY STAGE solvers // 01067 01073 bool projectUConstraints(State& s, Real consAccuracy, const Vector& yWeights, 01074 const Vector& ooTols, Vector& yErrest, System::ProjectOptions) const; 01075 01076 // ACCELERATION STAGE reponses 01077 01078 01079 // Bookkeeping 01080 SimTK_PIMPL_DOWNCAST(SimbodyMatterSubsystem, Subsystem); 01081 const SimbodyMatterSubsystemRep& getRep() const; 01082 SimbodyMatterSubsystemRep& updRep(); 01083 01084 01085 private: 01086 // OBSOLETE; TODO: remove in SimTK 2.0 01087 void multiplyByQMatrix(const State& s, bool transposeMatrix, const Vector& in, Vector& out) const 01088 { multiplyByN(s,transposeMatrix,in,out);} 01089 // OBSOLETE; TODO: remove in SimTK 2.0 01090 void multiplyByQMatrixInverse(const State& s, bool transposeMatrix, const Vector& in, Vector& out) const 01091 { multiplyByNInv(s,transposeMatrix,in,out);} 01092 // OBSOLETE; TODO: remove in SimTK 2.0 01093 int getNBodies() const {return getNumBodies();} 01094 // OBSOLETE; TODO: remove in SimTK 2.0 01095 int getNConstraints() const {return getNumConstraints();} 01096 // OBSOLETE; TODO: remove in SimTK 2.0 01097 int getNMobilities() const {return getNumMobilities();} 01098 // OBSOLETE; TODO: remove in SimTK 2.0 01099 int getNParticles() const {return getNumParticles();} 01100 01101 }; 01102 01103 SimTK_SIMBODY_EXPORT std::ostream& 01104 operator<<(std::ostream&, const SimbodyMatterSubsystem&); 01105 01106 01107 } // namespace SimTK 01108 01109 #endif // SimTK_SIMBODY_MATTER_SUBSYSTEM_H_