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-8 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 <vector>
00040 #include <iosfwd>
00041 
00042 namespace SimTK {
00043 
00044 class SimbodyMatterSubsystem;
00045 class MobilizedBody;
00046 class SimbodyMatterSubtree;
00047 class SimbodyMatterSubtreeResults;
00048 
00116 class SimTK_SIMBODY_EXPORT SimbodyMatterSubtree {
00117 public:
00118     SimbodyMatterSubtree();
00119     SimbodyMatterSubtree(const SimbodyMatterSubtree&);
00120     SimbodyMatterSubtree& operator=(const SimbodyMatterSubtree&);
00121     ~SimbodyMatterSubtree();
00122 
00123     explicit SimbodyMatterSubtree(const SimbodyMatterSubsystem&);
00124     SimbodyMatterSubtree(const SimbodyMatterSubsystem&, 
00125             const std::vector<MobilizedBodyIndex>& terminalBodies);
00126 
00127     void setSimbodyMatterSubsystem(const SimbodyMatterSubsystem& matter);
00128     const SimbodyMatterSubsystem& getSimbodyMatterSubsystem() const;
00129 
00130     // This doesn't change the associated SimbodyMatterSubsystem if there
00131     // is one, but does remove all the bodies from the SimbodyMatterSubtree.
00132     void clear();
00133 
00134     SimbodyMatterSubtree& addTerminalBody(MobilizedBodyIndex);
00135 
00136     void realizeTopology();
00137 
00138     int getNumSubtreeBodies() const; // includes ancestor
00139     MobilizedBodyIndex getAncestorMobilizedBodyIndex() const;
00140 
00141     // These are in the same order they were added; body[i] is the terminus
00142     // of branch i.
00143     const std::vector<MobilizedBodyIndex>& getTerminalBodies() const;
00144 
00145     // These are indexed by SubtreeBodyIndex starting with 0 for the ancestor body
00146     // and monotonically increasing outwards along a branch.
00147     const std::vector<MobilizedBodyIndex>& getAllBodies() const;
00148 
00149     SubtreeBodyIndex getParentSubtreeBodyIndex(SubtreeBodyIndex) const; // 0 returns an invalid Index
00150     const std::vector<SubtreeBodyIndex>& getChildSubtreeBodyIndices(SubtreeBodyIndex) const;
00151 
00152         // MODEL STAGE
00153 
00154     // State must be realized to at least Stage::Model for this call to work. 
00155     // The supplied SimbodyMatterSubtreeResults object is allocated and properly initialized to
00156     // be able to hold computation results from this SimbodyMatterSubtree.
00157     void initializeSubtreeResults(const State&, SimbodyMatterSubtreeResults&) const;
00158 
00159     // This can be used as a sanity check that initializeSubtreeResults() was already called
00160     // in this SimbodyMatterSubtree to produce these SimbodyMatterSubtreeResults. It is by no means exhaustive but
00161     // will catch egregious errors.
00162     bool isCompatibleSubtreeResults(const SimbodyMatterSubtreeResults&) const;
00163 
00164         // POSITION STAGE
00165 
00166     // State must be realized to at least Stage::Position for this to work. SimbodyMatterSubtreeResults
00167     // must have already been initialized to work with this SimbodyMatterSubtree. SimbodyMatterSubtreeResults stage
00168     // will be Stage::Position after this call. All body transforms will be the same as
00169     // the corresponding ones in the state, except they will be measured from the ancestor
00170     // frame instead of ground. SimbodyMatterSubtree q's will be identical to corresponding State q's.
00171     void copyPositionsFromState(const State&, SimbodyMatterSubtreeResults&) const;
00172 
00173     // State must be realized to Stage::Instance. subQ must be the right length for this
00174     // SimbodyMatterSubtree, and SimbodyMatterSubtreeResults must have been properly initialized. SimbodyMatterSubtreeResults
00175     // stage will be Stage::Position after this call.
00176     void calcPositionsFromSubtreeQ(const State&, const Vector& subQ, SimbodyMatterSubtreeResults&) const;
00177 
00178     // Calculates a perturbed position result starting with the subQ's and position results
00179     // which must already be in SimbodyMatterSubtreeResults.
00180     void perturbPositions(const State&, SubtreeQIndex subQIndex, Real perturbation, SimbodyMatterSubtreeResults&) const;
00181 
00182 
00183         // VELOCITY STAGE
00184 
00185     // State must be realized to at least Stage::Velocity for this to work. SimbodyMatterSubtreeResults
00186     // must already be at Stage::Position. SimbodyMatterSubtreeResults stage
00187     // will be Stage::Velocity after this call. All subtree body spatial velocities will be
00188     // the same as in the State, except measured relative to A and expressed in A. SimbodyMatterSubtree u's
00189     // will be identical to corresponding State u's.
00190     void copyVelocitiesFromState(const State&, SimbodyMatterSubtreeResults&) const;
00191 
00192     // State must be realized to Stage::Instance. subU must be the right length for this
00193     // SimbodyMatterSubtree, and SimbodyMatterSubtreeResults must already be at Stage::Position. SimbodyMatterSubtreeResults
00194     // stage will be Stage::Velocity after this call.
00195     void calcVelocitiesFromSubtreeU(const State&, const Vector& subU, SimbodyMatterSubtreeResults&) const;
00196 
00197     // State must be realized to Stage::Instance and SimbodyMatterSubtreeResults must already be at
00198     // Stage::Position. SimbodyMatterSubtreeResults stage will be Stage::Velocity after this call, but
00199     // all SimbodyMatterSubtree u's and body velocities will be zero.
00200     void calcVelocitiesFromZeroU(const State&, SimbodyMatterSubtreeResults&) const;
00201 
00202     // Calculates a perturbed velocity result starting with the subU's and velocity results
00203     // which must already be in SimbodyMatterSubtreeResults.
00204     void perturbVelocities(const State&, SubtreeUIndex subUIndex, Real perturbation, SimbodyMatterSubtreeResults&) const;
00205 
00206 
00207         // ACCELERATION STAGE
00208 
00209     // State must be realized to at least Stage::Acceleration for this to work. SimbodyMatterSubtreeResults
00210     // must already be at Stage::Velocity. SimbodyMatterSubtreeResults stage
00211     // will be Stage::Acceleration after this call. All subtree body spatial accelerations will be
00212     // the same as in the State, except measured relative to A and expressed in A. SimbodyMatterSubtree udots
00213     // will be identical to corresponding State udots.
00214     void copyAccelerationsFromState(const State&, SimbodyMatterSubtreeResults&) const;
00215 
00216     // State must be realized to Stage::Instance. subUDot must be the right length for this
00217     // SimbodyMatterSubtree, and SimbodyMatterSubtreeResults must already be at Stage::Velocity. SimbodyMatterSubtreeResults
00218     // stage will be Stage::Acceleration after this call.
00219     void calcAccelerationsFromSubtreeUDot(const State&, const Vector& subUDot, SimbodyMatterSubtreeResults&) const;
00220 
00221     // State must be realized to Stage::Instance and SimbodyMatterSubtreeResults must already be at
00222     // Stage::Velocity. SimbodyMatterSubtreeResults stage will be Stage::Acceleration after this call.
00223     // All SimbodyMatterSubtree udots's will be zero, body accelerations will have only their bias values
00224     // (coriolis accelerations from nonzero u's).
00225     void calcAccelerationsFromZeroUDot(const State&, SimbodyMatterSubtreeResults&) const;
00226 
00227     // Calculates a perturbed velocity result starting with the subUDot's and acceleration results
00228     // which must already be in SimbodyMatterSubtreeResults.
00229     void perturbAccelerations(const State&, SubtreeUIndex subUDotIndex, Real perturbation, SimbodyMatterSubtreeResults&) const;
00230 
00231     class SubtreeRep;
00232 private:
00233     SubtreeRep* rep;
00234     const SubtreeRep& getRep() const {assert(rep);return *rep;}
00235     SubtreeRep&       updRep()       {assert(rep);return *rep;}
00236 };
00237 
00238 SimTK_SIMBODY_EXPORT std::ostream& 
00239 operator<<(std::ostream&, const SimbodyMatterSubtree&);
00240 
00241 /*
00242  * This is the writable "cache" for a SimbodyMatterSubtree. Once the full State has
00243  * been realized to the Model stage, a SimbodyMatterSubtree can initialize one of these
00244  * objects and then use it to hold operator results.
00245  */
00246 class SimTK_SIMBODY_EXPORT SimbodyMatterSubtreeResults {
00247 public:
00248     SimbodyMatterSubtreeResults();
00249     SimbodyMatterSubtreeResults(const SimbodyMatterSubtreeResults&);
00250     SimbodyMatterSubtreeResults& operator=(const SimbodyMatterSubtreeResults&);
00251     ~SimbodyMatterSubtreeResults();
00252 
00253     void clear();
00254 
00255     void reallocateBodies(int nBodies);
00256     void addMobilities(SubtreeBodyIndex, QIndex qStart, int nq, UIndex uStart, int nu);
00257     void realizeModel(const Vector& stateQ, const Vector& stateU);
00258 
00259     Stage getStage() const;
00260 
00261     int getNumSubtreeBodies() const;
00262     int getNumSubtreeQs() const;
00263     int getNumSubtreeUs() const;
00264 
00265     const Vector&     getSubtreeQ() const;
00266     const Transform&  getSubtreeBodyTransform(SubtreeBodyIndex) const; // from ancestor frame
00267 
00268     const Vector&     getSubtreeU() const;
00269     const SpatialVec& getSubtreeBodyVelocity(SubtreeBodyIndex) const; // measured & expressed  in ancestor frame
00270 
00271     const Vector&     getSubtreeUDot() const;
00272     const SpatialVec& getSubtreeBodyAcceleration(SubtreeBodyIndex) const; // measured & expressed in ancestor frame
00273 
00274     // These are indexed by SubtreeQIndex and SubtreeUIndex.
00275     const std::vector<QIndex>& getQSubset() const; // subset of Subsystem Qs used by this SimbodyMatterSubtree
00276     const std::vector<UIndex>& getUSubset() const; // subset of Subsystem Us used by this SimbodyMatterSubtree
00277 
00278     void findSubtreeBodyQ(SubtreeBodyIndex, SubtreeQIndex& qStart, int& nq) const; // indices into QSubset
00279     void findSubtreeBodyU(SubtreeBodyIndex, SubtreeUIndex& uStart, int& nu) const; // indices into USubset
00280 
00281     class SubtreeResultsRep;
00282 private:
00283     friend class SimbodyMatterSubtree;
00284     SubtreeResultsRep* rep;
00285     const SubtreeResultsRep& getRep() const {assert(rep);return *rep;}
00286     SubtreeResultsRep&       updRep()       {assert(rep);return *rep;}
00287 };
00288 
00289 SimTK_SIMBODY_EXPORT std::ostream& 
00290 operator<<(std::ostream&, const SimbodyMatterSubtreeResults&);
00291 
00292 } // namespace SimTK
00293 
00294 #endif // SimTK_SIMBODY_MATTER_SUBTREE_H_

Generated on Wed Dec 30 11:04:42 2009 for SimTKcore by  doxygen 1.6.1