Simbody  3.4 (development)
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  *                               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_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines