Simbody

SimbodyMatterSubtree.h

Go to the documentation of this file.
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_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines