Simbody
|
00001 #ifndef SimTK_SIMBODY_MATTER_SUBTREE_H_ 00002 #define SimTK_SIMBODY_MATTER_SUBTREE_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-9 Stanford University and the Authors. * 00013 * Authors: Michael Sherman * 00014 * Contributors: * 00015 * * 00016 * Permission is hereby granted, free of charge, to any person obtaining a * 00017 * copy of this software and associated documentation files (the "Software"), * 00018 * to deal in the Software without restriction, including without limitation * 00019 * the rights to use, copy, modify, merge, publish, distribute, sublicense, * 00020 * and/or sell copies of the Software, and to permit persons to whom the * 00021 * Software is furnished to do so, subject to the following conditions: * 00022 * * 00023 * The above copyright notice and this permission notice shall be included in * 00024 * all copies or substantial portions of the Software. * 00025 * * 00026 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * 00027 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * 00028 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * 00029 * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 00030 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 00031 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * 00032 * USE OR OTHER DEALINGS IN THE SOFTWARE. * 00033 * -------------------------------------------------------------------------- */ 00034 00035 #include "SimTKcommon.h" 00036 #include "simbody/internal/common.h" 00037 00038 #include <cassert> 00039 #include <iosfwd> 00040 00041 namespace SimTK { 00042 00043 class SimbodyMatterSubsystem; 00044 class MobilizedBody; 00045 class SimbodyMatterSubtree; 00046 class SimbodyMatterSubtreeResults; 00047 00117 class SimTK_SIMBODY_EXPORT SimbodyMatterSubtree { 00118 public: 00119 SimbodyMatterSubtree(); 00120 SimbodyMatterSubtree(const SimbodyMatterSubtree&); 00121 SimbodyMatterSubtree& operator=(const SimbodyMatterSubtree&); 00122 ~SimbodyMatterSubtree(); 00123 00124 explicit SimbodyMatterSubtree(const SimbodyMatterSubsystem&); 00125 SimbodyMatterSubtree(const SimbodyMatterSubsystem&, 00126 const Array_<MobilizedBodyIndex>& terminalBodies); 00127 00128 void setSimbodyMatterSubsystem(const SimbodyMatterSubsystem& matter); 00129 const SimbodyMatterSubsystem& getSimbodyMatterSubsystem() const; 00130 00131 // This doesn't change the associated SimbodyMatterSubsystem if there 00132 // is one, but does remove all the bodies from the SimbodyMatterSubtree. 00133 void clear(); 00134 00135 SimbodyMatterSubtree& addTerminalBody(MobilizedBodyIndex); 00136 00137 void realizeTopology(); 00138 00139 int getNumSubtreeBodies() const; // includes ancestor 00140 MobilizedBodyIndex getAncestorMobilizedBodyIndex() const; 00141 00142 // These are in the same order they were added; body[i] is the terminus 00143 // of branch i. 00144 const Array_<MobilizedBodyIndex>& getTerminalBodies() const; 00145 00146 // These are indexed by SubtreeBodyIndex starting with 0 for the ancestor 00147 // body and monotonically increasing outwards along a branch. 00148 const Array_<MobilizedBodyIndex>& getAllBodies() const; 00149 00150 // 0 returns an invalid Index 00151 SubtreeBodyIndex getParentSubtreeBodyIndex(SubtreeBodyIndex) const; 00152 const Array_<SubtreeBodyIndex>& 00153 getChildSubtreeBodyIndices(SubtreeBodyIndex) const; 00154 00155 // MODEL STAGE 00156 00157 // State must be realized to at least Stage::Model for this call to work. 00158 // The supplied SimbodyMatterSubtreeResults object is allocated and properly initialized to 00159 // be able to hold computation results from this SimbodyMatterSubtree. 00160 void initializeSubtreeResults(const State&, SimbodyMatterSubtreeResults&) const; 00161 00162 // This can be used as a sanity check that initializeSubtreeResults() was 00163 // already called in this SimbodyMatterSubtree to produce these 00164 // SimbodyMatterSubtreeResults. It is by no means exhaustive but will catch 00165 // egregious errors. 00166 bool isCompatibleSubtreeResults(const SimbodyMatterSubtreeResults&) const; 00167 00168 // POSITION STAGE 00169 00170 // State must be realized to at least Stage::Position for this to work. SimbodyMatterSubtreeResults 00171 // must have already been initialized to work with this SimbodyMatterSubtree. SimbodyMatterSubtreeResults stage 00172 // will be Stage::Position after this call. All body transforms will be the same as 00173 // the corresponding ones in the state, except they will be measured from the ancestor 00174 // frame instead of ground. SimbodyMatterSubtree q's will be identical to corresponding State q's. 00175 void copyPositionsFromState(const State&, SimbodyMatterSubtreeResults&) const; 00176 00177 // State must be realized to Stage::Instance. subQ must be the right length for this 00178 // SimbodyMatterSubtree, and SimbodyMatterSubtreeResults must have been properly initialized. SimbodyMatterSubtreeResults 00179 // stage will be Stage::Position after this call. 00180 void calcPositionsFromSubtreeQ(const State&, const Vector& subQ, SimbodyMatterSubtreeResults&) const; 00181 00182 // Calculates a perturbed position result starting with the subQ's and position results 00183 // which must already be in SimbodyMatterSubtreeResults. 00184 void perturbPositions(const State&, SubtreeQIndex subQIndex, Real perturbation, SimbodyMatterSubtreeResults&) const; 00185 00186 00187 // VELOCITY STAGE 00188 00189 // State must be realized to at least Stage::Velocity for this to work. SimbodyMatterSubtreeResults 00190 // must already be at Stage::Position. SimbodyMatterSubtreeResults stage 00191 // will be Stage::Velocity after this call. All subtree body spatial velocities will be 00192 // the same as in the State, except measured relative to A and expressed in A. SimbodyMatterSubtree u's 00193 // will be identical to corresponding State u's. 00194 void copyVelocitiesFromState(const State&, SimbodyMatterSubtreeResults&) const; 00195 00196 // State must be realized to Stage::Instance. subU must be the right length for this 00197 // SimbodyMatterSubtree, and SimbodyMatterSubtreeResults must already be at Stage::Position. SimbodyMatterSubtreeResults 00198 // stage will be Stage::Velocity after this call. 00199 void calcVelocitiesFromSubtreeU(const State&, const Vector& subU, SimbodyMatterSubtreeResults&) const; 00200 00201 // State must be realized to Stage::Instance and SimbodyMatterSubtreeResults must already be at 00202 // Stage::Position. SimbodyMatterSubtreeResults stage will be Stage::Velocity after this call, but 00203 // all SimbodyMatterSubtree u's and body velocities will be zero. 00204 void calcVelocitiesFromZeroU(const State&, SimbodyMatterSubtreeResults&) const; 00205 00206 // Calculates a perturbed velocity result starting with the subU's and velocity results 00207 // which must already be in SimbodyMatterSubtreeResults. 00208 void perturbVelocities(const State&, SubtreeUIndex subUIndex, Real perturbation, SimbodyMatterSubtreeResults&) const; 00209 00210 00211 // ACCELERATION STAGE 00212 00213 // State must be realized to at least Stage::Acceleration for this to work. SimbodyMatterSubtreeResults 00214 // must already be at Stage::Velocity. SimbodyMatterSubtreeResults stage 00215 // will be Stage::Acceleration after this call. All subtree body spatial accelerations will be 00216 // the same as in the State, except measured relative to A and expressed in A. SimbodyMatterSubtree udots 00217 // will be identical to corresponding State udots. 00218 void copyAccelerationsFromState(const State&, SimbodyMatterSubtreeResults&) const; 00219 00220 // State must be realized to Stage::Instance. subUDot must be the right length for this 00221 // SimbodyMatterSubtree, and SimbodyMatterSubtreeResults must already be at Stage::Velocity. SimbodyMatterSubtreeResults 00222 // stage will be Stage::Acceleration after this call. 00223 void calcAccelerationsFromSubtreeUDot(const State&, const Vector& subUDot, SimbodyMatterSubtreeResults&) const; 00224 00225 // State must be realized to Stage::Instance and SimbodyMatterSubtreeResults must already be at 00226 // Stage::Velocity. SimbodyMatterSubtreeResults stage will be Stage::Acceleration after this call. 00227 // All SimbodyMatterSubtree udots's will be zero, body accelerations will have only their bias values 00228 // (coriolis accelerations from nonzero u's). 00229 void calcAccelerationsFromZeroUDot(const State&, SimbodyMatterSubtreeResults&) const; 00230 00231 // Calculates a perturbed velocity result starting with the subUDot's and acceleration results 00232 // which must already be in SimbodyMatterSubtreeResults. 00233 void perturbAccelerations(const State&, SubtreeUIndex subUDotIndex, Real perturbation, SimbodyMatterSubtreeResults&) const; 00234 00235 class SubtreeRep; 00236 private: 00237 SubtreeRep* rep; 00238 const SubtreeRep& getRep() const {assert(rep);return *rep;} 00239 SubtreeRep& updRep() {assert(rep);return *rep;} 00240 }; 00241 00242 SimTK_SIMBODY_EXPORT std::ostream& 00243 operator<<(std::ostream&, const SimbodyMatterSubtree&); 00244 00245 /* 00246 * This is the writable "cache" for a SimbodyMatterSubtree. Once the full State has 00247 * been realized to the Model stage, a SimbodyMatterSubtree can initialize one of these 00248 * objects and then use it to hold operator results. 00249 */ 00250 class SimTK_SIMBODY_EXPORT SimbodyMatterSubtreeResults { 00251 public: 00252 SimbodyMatterSubtreeResults(); 00253 SimbodyMatterSubtreeResults(const SimbodyMatterSubtreeResults&); 00254 SimbodyMatterSubtreeResults& operator=(const SimbodyMatterSubtreeResults&); 00255 ~SimbodyMatterSubtreeResults(); 00256 00257 void clear(); 00258 00259 void reallocateBodies(int nBodies); 00260 void addMobilities(SubtreeBodyIndex, QIndex qStart, int nq, UIndex uStart, int nu); 00261 void realizeModel(const Vector& stateQ, const Vector& stateU); 00262 00263 Stage getStage() const; 00264 00265 int getNumSubtreeBodies() const; 00266 int getNumSubtreeQs() const; 00267 int getNumSubtreeUs() const; 00268 00269 const Vector& getSubtreeQ() const; 00270 const Transform& getSubtreeBodyTransform(SubtreeBodyIndex) const; // from ancestor frame 00271 00272 const Vector& getSubtreeU() const; 00273 const SpatialVec& getSubtreeBodyVelocity(SubtreeBodyIndex) const; // measured & expressed in ancestor frame 00274 00275 const Vector& getSubtreeUDot() const; 00276 const SpatialVec& getSubtreeBodyAcceleration(SubtreeBodyIndex) const; // measured & expressed in ancestor frame 00277 00278 // These are indexed by SubtreeQIndex and SubtreeUIndex. 00279 const Array_<QIndex>& getQSubset() const; // subset of Subsystem Qs used by this SimbodyMatterSubtree 00280 const Array_<UIndex>& getUSubset() const; // subset of Subsystem Us used by this SimbodyMatterSubtree 00281 00282 void findSubtreeBodyQ(SubtreeBodyIndex, SubtreeQIndex& qStart, int& nq) const; // indices into QSubset 00283 void findSubtreeBodyU(SubtreeBodyIndex, SubtreeUIndex& uStart, int& nu) const; // indices into USubset 00284 00285 class SubtreeResultsRep; 00286 private: 00287 friend class SimbodyMatterSubtree; 00288 SubtreeResultsRep* rep; 00289 const SubtreeResultsRep& getRep() const {assert(rep);return *rep;} 00290 SubtreeResultsRep& updRep() {assert(rep);return *rep;} 00291 }; 00292 00293 SimTK_SIMBODY_EXPORT std::ostream& 00294 operator<<(std::ostream&, const SimbodyMatterSubtreeResults&); 00295 00296 } // namespace SimTK 00297 00298 #endif // SimTK_SIMBODY_MATTER_SUBTREE_H_