Simbody
3.4 (development)
|
00001 #ifndef SimTK_SIMBODY_MATTER_SUBTREE_H_ 00002 #define SimTK_SIMBODY_MATTER_SUBTREE_H_ 00003 00004 /* -------------------------------------------------------------------------- * 00005 * Simbody(tm) * 00006 * -------------------------------------------------------------------------- * 00007 * This is part of the SimTK biosimulation toolkit originating from * 00008 * Simbios, the NIH National Center for Physics-Based Simulation of * 00009 * Biological Structures at Stanford, funded under the NIH Roadmap for * 00010 * Medical Research, grant U54 GM072970. See https://simtk.org/home/simbody. * 00011 * * 00012 * Portions copyright (c) 2007-12 Stanford University and the Authors. * 00013 * Authors: Michael Sherman * 00014 * Contributors: * 00015 * * 00016 * Licensed under the Apache License, Version 2.0 (the "License"); you may * 00017 * not use this file except in compliance with the License. You may obtain a * 00018 * copy of the License at http://www.apache.org/licenses/LICENSE-2.0. * 00019 * * 00020 * Unless required by applicable law or agreed to in writing, software * 00021 * distributed under the License is distributed on an "AS IS" BASIS, * 00022 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 00023 * See the License for the specific language governing permissions and * 00024 * limitations under the License. * 00025 * -------------------------------------------------------------------------- */ 00026 00027 #include "SimTKcommon.h" 00028 #include "simbody/internal/common.h" 00029 00030 #include <cassert> 00031 #include <iosfwd> 00032 00033 namespace SimTK { 00034 00035 class SimbodyMatterSubsystem; 00036 class MobilizedBody; 00037 class SimbodyMatterSubtree; 00038 class SimbodyMatterSubtreeResults; 00039 00109 class SimTK_SIMBODY_EXPORT SimbodyMatterSubtree { 00110 public: 00111 SimbodyMatterSubtree(); 00112 SimbodyMatterSubtree(const SimbodyMatterSubtree&); 00113 SimbodyMatterSubtree& operator=(const SimbodyMatterSubtree&); 00114 ~SimbodyMatterSubtree(); 00115 00116 explicit SimbodyMatterSubtree(const SimbodyMatterSubsystem&); 00117 SimbodyMatterSubtree(const SimbodyMatterSubsystem&, 00118 const Array_<MobilizedBodyIndex>& terminalBodies); 00119 00120 void setSimbodyMatterSubsystem(const SimbodyMatterSubsystem& matter); 00121 const SimbodyMatterSubsystem& getSimbodyMatterSubsystem() const; 00122 00123 // This doesn't change the associated SimbodyMatterSubsystem if there 00124 // is one, but does remove all the bodies from the SimbodyMatterSubtree. 00125 void clear(); 00126 00127 SimbodyMatterSubtree& addTerminalBody(MobilizedBodyIndex); 00128 00129 void realizeTopology(); 00130 00131 int getNumSubtreeBodies() const; // includes ancestor 00132 MobilizedBodyIndex getAncestorMobilizedBodyIndex() const; 00133 00134 // These are in the same order they were added; body[i] is the terminus 00135 // of branch i. 00136 const Array_<MobilizedBodyIndex>& getTerminalBodies() const; 00137 00138 // These are indexed by SubtreeBodyIndex starting with 0 for the ancestor 00139 // body and monotonically increasing outwards along a branch. 00140 const Array_<MobilizedBodyIndex>& getAllBodies() const; 00141 00142 // 0 returns an invalid Index 00143 SubtreeBodyIndex getParentSubtreeBodyIndex(SubtreeBodyIndex) const; 00144 const Array_<SubtreeBodyIndex>& 00145 getChildSubtreeBodyIndices(SubtreeBodyIndex) const; 00146 00147 // MODEL STAGE 00148 00149 // State must be realized to at least Stage::Model for this call to work. 00150 // The supplied SimbodyMatterSubtreeResults object is allocated and properly initialized to 00151 // be able to hold computation results from this SimbodyMatterSubtree. 00152 void initializeSubtreeResults(const State&, SimbodyMatterSubtreeResults&) const; 00153 00154 // This can be used as a sanity check that initializeSubtreeResults() was 00155 // already called in this SimbodyMatterSubtree to produce these 00156 // SimbodyMatterSubtreeResults. It is by no means exhaustive but will catch 00157 // egregious errors. 00158 bool isCompatibleSubtreeResults(const SimbodyMatterSubtreeResults&) const; 00159 00160 // POSITION STAGE 00161 00162 // State must be realized to at least Stage::Position for this to work. SimbodyMatterSubtreeResults 00163 // must have already been initialized to work with this SimbodyMatterSubtree. SimbodyMatterSubtreeResults stage 00164 // will be Stage::Position after this call. All body transforms will be the same as 00165 // the corresponding ones in the state, except they will be measured from the ancestor 00166 // frame instead of ground. SimbodyMatterSubtree q's will be identical to corresponding State q's. 00167 void copyPositionsFromState(const State&, SimbodyMatterSubtreeResults&) const; 00168 00169 // State must be realized to Stage::Instance. subQ must be the right length for this 00170 // SimbodyMatterSubtree, and SimbodyMatterSubtreeResults must have been properly initialized. SimbodyMatterSubtreeResults 00171 // stage will be Stage::Position after this call. 00172 void calcPositionsFromSubtreeQ(const State&, const Vector& subQ, SimbodyMatterSubtreeResults&) const; 00173 00174 // Calculates a perturbed position result starting with the subQ's and position results 00175 // which must already be in SimbodyMatterSubtreeResults. 00176 void perturbPositions(const State&, SubtreeQIndex subQIndex, Real perturbation, SimbodyMatterSubtreeResults&) const; 00177 00178 00179 // VELOCITY STAGE 00180 00181 // State must be realized to at least Stage::Velocity for this to work. SimbodyMatterSubtreeResults 00182 // must already be at Stage::Position. SimbodyMatterSubtreeResults stage 00183 // will be Stage::Velocity after this call. All subtree body spatial velocities will be 00184 // the same as in the State, except measured relative to A and expressed in A. SimbodyMatterSubtree u's 00185 // will be identical to corresponding State u's. 00186 void copyVelocitiesFromState(const State&, SimbodyMatterSubtreeResults&) const; 00187 00188 // State must be realized to Stage::Instance. subU must be the right length for this 00189 // SimbodyMatterSubtree, and SimbodyMatterSubtreeResults must already be at Stage::Position. SimbodyMatterSubtreeResults 00190 // stage will be Stage::Velocity after this call. 00191 void calcVelocitiesFromSubtreeU(const State&, const Vector& subU, SimbodyMatterSubtreeResults&) const; 00192 00193 // State must be realized to Stage::Instance and SimbodyMatterSubtreeResults must already be at 00194 // Stage::Position. SimbodyMatterSubtreeResults stage will be Stage::Velocity after this call, but 00195 // all SimbodyMatterSubtree u's and body velocities will be zero. 00196 void calcVelocitiesFromZeroU(const State&, SimbodyMatterSubtreeResults&) const; 00197 00198 // Calculates a perturbed velocity result starting with the subU's and velocity results 00199 // which must already be in SimbodyMatterSubtreeResults. 00200 void perturbVelocities(const State&, SubtreeUIndex subUIndex, Real perturbation, SimbodyMatterSubtreeResults&) const; 00201 00202 00203 // ACCELERATION STAGE 00204 00205 // State must be realized to at least Stage::Acceleration for this to work. SimbodyMatterSubtreeResults 00206 // must already be at Stage::Velocity. SimbodyMatterSubtreeResults stage 00207 // will be Stage::Acceleration after this call. All subtree body spatial accelerations will be 00208 // the same as in the State, except measured relative to A and expressed in A. SimbodyMatterSubtree udots 00209 // will be identical to corresponding State udots. 00210 void copyAccelerationsFromState(const State&, SimbodyMatterSubtreeResults&) const; 00211 00212 // State must be realized to Stage::Instance. subUDot must be the right length for this 00213 // SimbodyMatterSubtree, and SimbodyMatterSubtreeResults must already be at Stage::Velocity. SimbodyMatterSubtreeResults 00214 // stage will be Stage::Acceleration after this call. 00215 void calcAccelerationsFromSubtreeUDot(const State&, const Vector& subUDot, SimbodyMatterSubtreeResults&) const; 00216 00217 // State must be realized to Stage::Instance and SimbodyMatterSubtreeResults must already be at 00218 // Stage::Velocity. SimbodyMatterSubtreeResults stage will be Stage::Acceleration after this call. 00219 // All SimbodyMatterSubtree udots's will be zero, body accelerations will have only their bias values 00220 // (coriolis accelerations from nonzero u's). 00221 void calcAccelerationsFromZeroUDot(const State&, SimbodyMatterSubtreeResults&) const; 00222 00223 // Calculates a perturbed velocity result starting with the subUDot's and acceleration results 00224 // which must already be in SimbodyMatterSubtreeResults. 00225 void perturbAccelerations(const State&, SubtreeUIndex subUDotIndex, Real perturbation, SimbodyMatterSubtreeResults&) const; 00226 00227 class SubtreeRep; 00228 private: 00229 SubtreeRep* rep; 00230 const SubtreeRep& getRep() const {assert(rep);return *rep;} 00231 SubtreeRep& updRep() {assert(rep);return *rep;} 00232 }; 00233 00234 SimTK_SIMBODY_EXPORT std::ostream& 00235 operator<<(std::ostream&, const SimbodyMatterSubtree&); 00236 00237 /* 00238 * This is the writable "cache" for a SimbodyMatterSubtree. Once the full State has 00239 * been realized to the Model stage, a SimbodyMatterSubtree can initialize one of these 00240 * objects and then use it to hold operator results. 00241 */ 00242 class SimTK_SIMBODY_EXPORT SimbodyMatterSubtreeResults { 00243 public: 00244 SimbodyMatterSubtreeResults(); 00245 SimbodyMatterSubtreeResults(const SimbodyMatterSubtreeResults&); 00246 SimbodyMatterSubtreeResults& operator=(const SimbodyMatterSubtreeResults&); 00247 ~SimbodyMatterSubtreeResults(); 00248 00249 void clear(); 00250 00251 void reallocateBodies(int nBodies); 00252 void addMobilities(SubtreeBodyIndex, QIndex qStart, int nq, UIndex uStart, int nu); 00253 void realizeModel(const Vector& stateQ, const Vector& stateU); 00254 00255 Stage getStage() const; 00256 00257 int getNumSubtreeBodies() const; 00258 int getNumSubtreeQs() const; 00259 int getNumSubtreeUs() const; 00260 00261 const Vector& getSubtreeQ() const; 00262 const Transform& getSubtreeBodyTransform(SubtreeBodyIndex) const; // from ancestor frame 00263 00264 const Vector& getSubtreeU() const; 00265 const SpatialVec& getSubtreeBodyVelocity(SubtreeBodyIndex) const; // measured & expressed in ancestor frame 00266 00267 const Vector& getSubtreeUDot() const; 00268 const SpatialVec& getSubtreeBodyAcceleration(SubtreeBodyIndex) const; // measured & expressed in ancestor frame 00269 00270 // These are indexed by SubtreeQIndex and SubtreeUIndex. 00271 const Array_<QIndex>& getQSubset() const; // subset of Subsystem Qs used by this SimbodyMatterSubtree 00272 const Array_<UIndex>& getUSubset() const; // subset of Subsystem Us used by this SimbodyMatterSubtree 00273 00274 void findSubtreeBodyQ(SubtreeBodyIndex, SubtreeQIndex& qStart, int& nq) const; // indices into QSubset 00275 void findSubtreeBodyU(SubtreeBodyIndex, SubtreeUIndex& uStart, int& nu) const; // indices into USubset 00276 00277 class SubtreeResultsRep; 00278 private: 00279 friend class SimbodyMatterSubtree; 00280 SubtreeResultsRep* rep; 00281 const SubtreeResultsRep& getRep() const {assert(rep);return *rep;} 00282 SubtreeResultsRep& updRep() {assert(rep);return *rep;} 00283 }; 00284 00285 SimTK_SIMBODY_EXPORT std::ostream& 00286 operator<<(std::ostream&, const SimbodyMatterSubtreeResults&); 00287 00288 } // namespace SimTK 00289 00290 #endif // SimTK_SIMBODY_MATTER_SUBTREE_H_