Simbody
3.5
|
00001 #ifndef SimTK_SIMBODY_COMMON_H_ 00002 #define SimTK_SIMBODY_COMMON_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) 2005-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 00031 #include "SimTKcommon.h" 00032 00033 #include <cassert> 00034 #include <vector> 00035 #include <limits> 00036 00037 00038 // Shared libraries are messy in Visual Studio. We have to distinguish three 00039 // cases: 00040 // (1) this header is being used to build the simbody shared library (dllexport) 00041 // (2) this header is being used by a *client* of the simbody shared 00042 // library (dllimport) 00043 // (3) we are building the simbody static library, or the client is 00044 // being compiled with the expectation of linking with the 00045 // simbody static library (nothing special needed) 00046 // In the CMake script for building this library, we define one of the symbols 00047 // SimTK_SIMBODY_BUILDING_{SHARED|STATIC}_LIBRARY 00048 // Client code normally has no special symbol defined, in which case we'll 00049 // assume it wants to use the shared library. However, if the client defines 00050 // the symbol SimTK_USE_STATIC_LIBRARIES we'll suppress the dllimport so 00051 // that the client code can be linked with static libraries. Note that 00052 // the client symbol is not library dependent, while the library symbols 00053 // affect only the simbody library, meaning that other libraries can 00054 // be clients of this one. However, we are assuming all-static or all-shared. 00055 00056 #ifdef _WIN32 00057 #ifdef _MSC_VER 00058 #pragma warning(disable:4231) // need to use 'extern' template explicit instantiation 00059 #endif 00060 #if defined(SimTK_SIMBODY_BUILDING_SHARED_LIBRARY) 00061 #define SimTK_SIMBODY_EXPORT __declspec(dllexport) 00062 // Keep MS VC++ quiet when it tries to instantiate incomplete template classes in a DLL. 00063 #ifdef _MSC_VER 00064 #pragma warning(disable:4661) 00065 #endif 00066 #elif defined(SimTK_SIMBODY_BUILDING_STATIC_LIBRARY) || defined(SimTK_USE_STATIC_LIBRARIES) 00067 #define SimTK_SIMBODY_EXPORT 00068 #else 00069 #define SimTK_SIMBODY_EXPORT __declspec(dllimport) // i.e., a client of a shared library 00070 #endif 00071 #else 00072 #define SimTK_SIMBODY_EXPORT // Linux, Mac 00073 #endif 00074 00075 // Every SimTK library must provide these two routines, with the library 00076 // name appearing after the "version_" and "about_". 00077 extern "C" { 00078 SimTK_SIMBODY_EXPORT void SimTK_version_simbody(int* major, int* minor, int* build); 00079 SimTK_SIMBODY_EXPORT void SimTK_about_simbody(const char* key, int maxlen, char* value); 00080 } 00081 00082 namespace SimTK { 00083 00084 // MATTER SUBSYSTEM-GLOBAL INDEX TYPES 00085 00086 00095 SimTK_DEFINE_UNIQUE_INDEX_TYPE(MobilizedBodyIndex); 00096 00100 typedef MobilizedBodyIndex MobodIndex; 00101 00105 static const MobilizedBodyIndex GroundIndex(0); 00106 00112 SimTK_DEFINE_UNIQUE_INDEX_TYPE(ConstraintIndex); 00113 00114 // TODO: experimental 00115 SimTK_DEFINE_UNIQUE_INDEX_TYPE(UnilateralContactIndex); 00116 SimTK_DEFINE_UNIQUE_INDEX_TYPE(UnilateralSpeedConstraintIndex); 00117 SimTK_DEFINE_UNIQUE_INDEX_TYPE(BoundedSpeedConstraintIndex); 00118 SimTK_DEFINE_UNIQUE_INDEX_TYPE(ConstraintLimitedFrictionIndex); 00119 SimTK_DEFINE_UNIQUE_INDEX_TYPE(StateLimitedFrictionIndex); 00120 00121 // TODO: This is for arrays indexed by MatterSubsystem-global ParticleIndex, 00122 // as yet to be defined. 00123 SimTK_DEFINE_UNIQUE_INDEX_TYPE(ParticleIndex); 00124 00125 // Constrained Bodies in constraints where the Ancestor body is not Ground (we 00126 // call these "Ancestor Constrained Bodies") require some additional cached 00127 // data, such as their orientations and velocities in the Ancestor frame, so 00128 // are each allocated a slot in pools of that data. Those pools are indexed by 00129 // this type. 00130 SimTK_DEFINE_UNIQUE_INDEX_TYPE(AncestorConstrainedBodyPoolIndex); 00131 00132 // This is for "u-squared" arrays, that is, arrays which allocate space for an 00133 // nuXnu block for each MobilizedBody. 00134 SimTK_DEFINE_UNIQUE_INDEX_TYPE(USquaredIndex); 00135 00136 // This is for "quaternion information" arrays, which have total dimension 00137 // equal to the number of quaternions currently in use as generalized 00138 // coordinates for modeling the Matter Subsystem's MobilizedBodies. Primarily 00139 // this is for storing the norm of quaternions so we need calculate them only 00140 // once. 00141 SimTK_DEFINE_UNIQUE_INDEX_TYPE(QuaternionPoolIndex); 00142 00143 // This is for miscellaneous Real-valued position cache data that individual 00144 // mobilizers ask us to hold for generalized coordinate q precalculations 00145 // (e.g. sines and cosines). 00146 SimTK_DEFINE_UNIQUE_INDEX_TYPE(MobodQPoolIndex); 00147 00148 // These are for indexing the pools of prescribed q's, u's, udots, and calculated forces 00149 // needed to produce the udots. The arrays are allocated in order of MobilizedBodyIndex, and 00150 // then in q and u order within the mobilizer. A mobilier with prescribed positions q gets 00151 // slots in the u and udot pools also to hold derivatives, and similarly if it is the 00152 // velocities u that are prescribed there will be slots in the udot pools. Note that 00153 // the Q index can be used to index qdot and qdotdot arrays if needed. Note that a 00154 // prescribed force is produced whenever there is a udot that is not force driven; that 00155 // includes prescribed udots but also zero and discrete ones. 00156 SimTK_DEFINE_UNIQUE_INDEX_TYPE(PresQPoolIndex); 00157 SimTK_DEFINE_UNIQUE_INDEX_TYPE(PresUPoolIndex); 00158 SimTK_DEFINE_UNIQUE_INDEX_TYPE(PresUDotPoolIndex); 00159 SimTK_DEFINE_UNIQUE_INDEX_TYPE(PresForcePoolIndex); 00160 00161 // PER-MOBILIZER INDEX TYPES 00162 00169 SimTK_DEFINE_UNIQUE_INDEX_TYPE(MobilizerQIndex); 00176 SimTK_DEFINE_UNIQUE_INDEX_TYPE(MobilizerUIndex); 00177 00178 // PER-CONSTRAINT INDEX TYPES 00179 00180 // This is the Constraint-specific index of the MobilizedBodies which are *directly* affected 00181 // by a constraint, through body forces or body torques on these bodies. 00182 SimTK_DEFINE_UNIQUE_INDEX_TYPE(ConstrainedBodyIndex); 00183 00184 // This is the Constraint-specific index of the MobilizedBodies whose mobilizers' mobilities 00185 // can appear explicitly in constraint equations, and which are acted upon by the Constraint 00186 // through generation of generalized (mobility) forces. Note that for a multi-dof mobilizer 00187 // we don't select individual mobilities; it is all or nothing so we can use the MobilizedBody 00188 // to stand for its mobilizer. 00189 SimTK_DEFINE_UNIQUE_INDEX_TYPE(ConstrainedMobilizerIndex); 00190 00191 // This is the Constraint-specific index of a coordinate q which can be *directly* affected 00192 // by this constraint through generation of a mobility force on a corresponding mobility. These 00193 // are numbered in order of ConstrainedMobilizerIndex for the mobilizers for which these are the q's. 00194 SimTK_DEFINE_UNIQUE_INDEX_TYPE(ConstrainedQIndex); 00195 00196 // This is the Constraint-specific index of a mobility u which can be *directly* affected 00197 // by this constraint through generation of a mobility force. These are numbered in order 00198 // of ConstrainedMobilizerIndex for the bodies for which these are the u's. 00199 SimTK_DEFINE_UNIQUE_INDEX_TYPE(ConstrainedUIndex); 00200 00201 00202 // This is the Constraint-specific index of a coordinate q which can be involved in any 00203 // constraint equation of this constraint, either directly through ConstrainedMobilizers 00204 // or indirectly as a result of its effects on ConstrainedBodies (that is, this list 00205 // includes all the ConstraintQIndex entries above, plus possibly many more). These are in sorted 00206 // order by subsystem-wide QIndex, and each QIndex appears at most once. 00207 SimTK_DEFINE_UNIQUE_INDEX_TYPE(ParticipatingQIndex); 00208 00209 // This is the Constraint-specific index of a coordinate u which can be involved in any 00210 // constraint equation of this constraint, either directly through ConstrainedMobilizers 00211 // or indirectly as a result of its effects on ConstrainedBodies (that is, this list 00212 // includes all the ConstraintUIndex entries above, plus possibly many more). These are in sorted 00213 // order by subsystem-wide UIndex, and each UIndex appears at most once. 00214 SimTK_DEFINE_UNIQUE_INDEX_TYPE(ParticipatingUIndex); 00215 00216 // SUBTREE INDEX TYPES 00217 00218 // And similarly for other unique Index types. 00219 SimTK_DEFINE_UNIQUE_INDEX_TYPE(SubtreeBodyIndex); 00220 static const SubtreeBodyIndex SubtreeAncestorIndex(0); 00221 00222 SimTK_DEFINE_UNIQUE_INDEX_TYPE(SubtreeQIndex); 00223 SimTK_DEFINE_UNIQUE_INDEX_TYPE(SubtreeUIndex); 00224 00225 // INDEX TYPES FOR OTHER SUBSYSTEMS 00226 00231 SimTK_DEFINE_UNIQUE_INDEX_TYPE(ForceIndex); 00232 00233 SimTK_DEFINE_UNIQUE_INDEX_TYPE(ContactSetIndex); 00234 00235 00236 namespace Exception { 00237 00238 00239 class APIMethodFailed : public Base { 00240 public: 00241 APIMethodFailed(const char* fn, int ln, String method, String cause) : Base(fn,ln) 00242 { 00243 setMessage(method + " failed because:\n " + cause); 00244 } 00245 }; 00246 00247 00248 // This just reports rep-level bad things up to the API level with a helpful string. 00249 class RepLevelException : public Base { 00250 public: 00251 RepLevelException(const char* fn, int ln, String message) : Base(fn,ln) 00252 { 00253 setMessage(message); 00254 } 00255 }; 00256 00257 class MobilizerCantExactlyRepresentRequestedQuantity : public Base { 00258 public: 00259 MobilizerCantExactlyRepresentRequestedQuantity(const char* fn, int ln, 00260 String method, MobilizedBodyIndex body, String quantity) : Base(fn,ln) 00261 { 00262 setMessage(method + "(): the mobilizer for body " + String((int)body) 00263 + " can't represent the given " + quantity + " to machine precision"); 00264 } 00265 private: 00266 }; 00267 00268 class NewtonRaphsonFailure : public Base { 00269 public: 00270 NewtonRaphsonFailure(const char* fn, int ln, String msg) : Base(fn,ln) 00271 { 00272 setMessage("NewtonRaphson failure: " + msg); 00273 } 00274 private: 00275 }; 00276 00277 class LoopConstraintConstructionFailure : public Base { 00278 public: 00279 LoopConstraintConstructionFailure(const char* fn, int ln, String msg) : Base(fn,ln) 00280 { 00281 setMessage("Loop constraint construction failure: " + msg); 00282 } 00283 private: 00284 }; 00285 00286 } // namespace SimTK::Exception 00287 00288 00289 00290 } // namespace SimTK 00291 00292 #endif // SimTK_SIMBODY_COMMON_H_