00001 #ifndef SimTK_SIMBODY_COMMON_H_ 00002 #define SimTK_SIMBODY_COMMON_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) 2005-7 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 00040 #include "SimTKcommon.h" 00041 00042 #include <cassert> 00043 #include <vector> 00044 #include <limits> 00045 00046 00047 // Shared libraries are messy in Visual Studio. We have to distinguish three 00048 // cases: 00049 // (1) this header is being used to build the simbody shared library (dllexport) 00050 // (2) this header is being used by a *client* of the simbody shared 00051 // library (dllimport) 00052 // (3) we are building the simbody static library, or the client is 00053 // being compiled with the expectation of linking with the 00054 // simbody static library (nothing special needed) 00055 // In the CMake script for building this library, we define one of the symbols 00056 // SimTK_SIMBODY_BUILDING_{SHARED|STATIC}_LIBRARY 00057 // Client code normally has no special symbol defined, in which case we'll 00058 // assume it wants to use the shared library. However, if the client defines 00059 // the symbol SimTK_USE_STATIC_LIBRARIES we'll suppress the dllimport so 00060 // that the client code can be linked with static libraries. Note that 00061 // the client symbol is not library dependent, while the library symbols 00062 // affect only the simbody library, meaning that other libraries can 00063 // be clients of this one. However, we are assuming all-static or all-shared. 00064 00065 #ifdef WIN32 00066 #ifdef _MSC_VER 00067 #pragma warning(disable:4231) // need to use 'extern' template explicit instantiation 00068 #endif 00069 #if defined(SimTK_SIMBODY_BUILDING_SHARED_LIBRARY) 00070 #define SimTK_SIMBODY_EXPORT __declspec(dllexport) 00071 // Keep MS VC++ quiet when it tries to instantiate incomplete template classes in a DLL. 00072 #ifdef _MSC_VER 00073 #pragma warning(disable:4661) 00074 #endif 00075 #elif defined(SimTK_SIMBODY_BUILDING_STATIC_LIBRARY) || defined(SimTK_USE_STATIC_LIBRARIES) 00076 #define SimTK_SIMBODY_EXPORT 00077 #else 00078 #define SimTK_SIMBODY_EXPORT __declspec(dllimport) // i.e., a client of a shared library 00079 #endif 00080 #else 00081 #define SimTK_SIMBODY_EXPORT // Linux, Mac 00082 #endif 00083 00084 // Every SimTK Core library must provide these two routines, with the library 00085 // name appearing after the "version_" and "about_". 00086 extern "C" { 00087 SimTK_SIMBODY_EXPORT void SimTK_version_simbody(int* major, int* minor, int* build); 00088 SimTK_SIMBODY_EXPORT void SimTK_about_simbody(const char* key, int maxlen, char* value); 00089 } 00090 00091 namespace SimTK { 00092 00093 00094 // There are various arrays containing data about certain categories of objects. We want them 00095 // indexable by simple ints for speed, but it would be a disaster to accidentally use the 00096 // wrong int as an index! So we define unique index types here for accessing each category 00097 // to help stay out of trouble. We use different index types for accessing the full array 00098 // of all coordinates (for example) of a Matter Subsystem than we do for accessing subsets 00099 // of those coordinates. 00100 // 00101 // A unique index type is just a type-safe non-negative int, augmented with a "NaN" 00102 // value called InvalidBLAH where BLAH is the type name. For most uses it will behave 00103 // like an int, and it has an implicit conversion *to* int. Importantly though, 00104 // it has no implicit conversion *from* int so you can't pass a plain int or any 00105 // other Index type to an argument expecting a certain Index type. 00106 00107 00108 // MATTER SUBSYSTEM-GLOBAL INDEX TYPES 00109 00110 // This is for arrays indexed by MatterSubsystem-global MobilizedBodyIndex, assigned 00111 // when a MobilizedBody is added to a MatterSubsystem. These will 00112 // be used of course to hold MobilizedBodies but also to hold many different kinds of 00113 // information that may be stored on a per-MobilizedBody basis. 00114 // We also predefine GroundIndex here which is always MobilizedBodyIndex(0). 00115 SimTK_DEFINE_UNIQUE_INDEX_TYPE(MobilizedBodyIndex) 00116 static const MobilizedBodyIndex GroundIndex(0); 00117 00118 // This is for arrays indexed by MatterSubsystem-global ConstraintIndex, assigned when 00119 // a Constraint is added to a Matter Subsystem. 00120 SimTK_DEFINE_UNIQUE_INDEX_TYPE(ConstraintIndex) 00121 00122 // TODO: This is for arrays indexed by MatterSubsystem-global ParticleIndex, 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 call 00126 // these "Ancestor Constrained Bodies") require some additional cached data, such as 00127 // their orientations and velocities in the Ancestor frame, so are each 00128 // allocated a slot in pools of that data. Those pools are indexed by this type. 00129 SimTK_DEFINE_UNIQUE_INDEX_TYPE(AncestorConstrainedBodyPoolIndex) 00130 00131 // This is for "q-like" arrays, that is, arrays which inherently have the same dimension as 00132 // the totoal number of generalized coordinates for the whole Matter Subsystem. 00133 SimTK_DEFINE_UNIQUE_INDEX_TYPE(QIndex) // an index into generalized coordinates q 00134 00135 // This is for "u-like" arrays, that is, arrays which inherently have the same dimension as 00136 // the total number of mobilities (generalized speeds) for the whole Matter Subsystem. This 00137 // includes both u and udot. 00138 SimTK_DEFINE_UNIQUE_INDEX_TYPE(UIndex) // an index into generalized speeds u (and accelerations udot) 00139 00140 // This is for "u-squared" arrays, that is, arrays which allocate space for an nuXnu block 00141 // for each MobilizedBody. 00142 SimTK_DEFINE_UNIQUE_INDEX_TYPE(USquaredIndex) 00143 00144 // This is for "quaternion information" arrays, which have total dimension equal to the 00145 // number of quaternions currently in use as generalized coordinates for modeling the Matter 00146 // Subsystem's MobilizedBodies. Primarily this is for storing the norm of quaternions so we need 00147 // calculate them only once. 00148 SimTK_DEFINE_UNIQUE_INDEX_TYPE(QuaternionPoolIndex) 00149 00150 // This is for "angle information" arrays, which have dimension equal to the total number 00151 // of generalized coordinates currently in use which are just angles in radians. For those 00152 // we want to precalculate some expensive things like sine and cosine so that we can just 00153 // do that once. 00154 SimTK_DEFINE_UNIQUE_INDEX_TYPE(AnglePoolIndex) 00155 00156 // PER-MOBILIZER INDEX TYPES 00157 00158 // The Mobilizer associated with each MobilizedBody, once modeled, has a specific number 00159 // of generalized coordinates q (0-7) and generalized speeds (mobilities) u (0-6). These 00160 // are the index types for the small arrays of Mobilizer-local q's and u's. 00161 SimTK_DEFINE_UNIQUE_INDEX_TYPE(MobilizerQIndex) 00162 SimTK_DEFINE_UNIQUE_INDEX_TYPE(MobilizerUIndex) 00163 00164 // PER-CONSTRAINT INDEX TYPES 00165 00166 // This is the Constraint-specific index of the MobilizedBodies which are *directly* affected 00167 // by a constraint, through body forces as body torques on these bodies. 00168 SimTK_DEFINE_UNIQUE_INDEX_TYPE(ConstrainedBodyIndex) 00169 00170 // This is the Constraint-specific index of the MobilizedBodies whose mobilizers' mobilities 00171 // can appear explicitly in constraint equations, and which are acted upon by the Constraint 00172 // through generation of generalized (mobility) forces. Note that for a multi-dof mobilizer 00173 // we don't select individual mobilities; it is all or nothing so we can use the MobilizedBody 00174 // to stand for its mobilizer. 00175 SimTK_DEFINE_UNIQUE_INDEX_TYPE(ConstrainedMobilizerIndex) 00176 00177 // This is the Constraint-specific index of a coordinate q which can be *directly* affected 00178 // by this constraint through generation of a mobility force on a corresponding mobility. These 00179 // are numbered in order of ConstrainedMobilizerIndex for the mobilizers for which these are the q's. 00180 SimTK_DEFINE_UNIQUE_INDEX_TYPE(ConstrainedQIndex) 00181 00182 // This is the Constraint-specific index of a mobility u which can be *directly* affected 00183 // by this constraint through generation of a mobility force. These are numbered in order 00184 // of ConstrainedMobilizerIndex for the bodies for which these are the u's. 00185 SimTK_DEFINE_UNIQUE_INDEX_TYPE(ConstrainedUIndex) 00186 00187 00188 // This is the Constraint-specific index of a coordinate q which can be involved in any 00189 // constraint equation of this constraint, either directly through ConstrainedMobilizers 00190 // or indirectly as a result of its effects on ConstrainedBodies (that is, this list 00191 // includes all the ConstraintQIndex entries above, plus possibly many more). These are in sorted 00192 // order by subsystem-wide QIndex, and each QIndex appears at most once. 00193 SimTK_DEFINE_UNIQUE_INDEX_TYPE(ParticipatingQIndex) 00194 00195 // This is the Constraint-specific index of a coordinate u which can be involved in any 00196 // constraint equation of this constraint, either directly through ConstrainedMobilizers 00197 // or indirectly as a result of its effects on ConstrainedBodies (that is, this list 00198 // includes all the ConstraintUIndex entries above, plus possibly many more). These are in sorted 00199 // order by subsystem-wide UIndex, and each UIndex appears at most once. 00200 SimTK_DEFINE_UNIQUE_INDEX_TYPE(ParticipatingUIndex) 00201 00202 // SUBTREE INDEX TYPES 00203 00204 // And similarly for other unique Index types. 00205 SimTK_DEFINE_UNIQUE_INDEX_TYPE(SubtreeBodyIndex) 00206 static const SubtreeBodyIndex SubtreeAncestorIndex(0); 00207 00208 SimTK_DEFINE_UNIQUE_INDEX_TYPE(SubtreeQIndex) 00209 SimTK_DEFINE_UNIQUE_INDEX_TYPE(SubtreeUIndex) 00210 00211 // INDEX TYPES FOR OTHER SUBSYSTEMS 00212 00213 SimTK_DEFINE_UNIQUE_INDEX_TYPE(ForceIndex) 00214 SimTK_DEFINE_UNIQUE_INDEX_TYPE(ContactSetIndex) 00215 00216 00217 namespace Exception { 00218 00219 00220 class APIMethodFailed : public Base { 00221 public: 00222 APIMethodFailed(const char* fn, int ln, String method, String cause) : Base(fn,ln) 00223 { 00224 setMessage(method + " failed because:\n " + cause); 00225 } 00226 }; 00227 00228 00229 // This just reports rep-level bad things up to the API level with a helpful string. 00230 class RepLevelException : public Base { 00231 public: 00232 RepLevelException(const char* fn, int ln, String message) : Base(fn,ln) 00233 { 00234 setMessage(message); 00235 } 00236 }; 00237 00238 class MobilizerCantExactlyRepresentRequestedQuantity : public Base { 00239 public: 00240 MobilizerCantExactlyRepresentRequestedQuantity(const char* fn, int ln, 00241 String method, MobilizedBodyIndex body, String quantity) : Base(fn,ln) 00242 { 00243 setMessage(method + "(): the mobilizer for body " + String((int)body) 00244 + " can't represent the given " + quantity + " to machine precision"); 00245 } 00246 private: 00247 }; 00248 00249 class NewtonRaphsonFailure : public Base { 00250 public: 00251 NewtonRaphsonFailure(const char* fn, int ln, String msg) : Base(fn,ln) 00252 { 00253 setMessage("NewtonRaphson failure: " + msg); 00254 } 00255 private: 00256 }; 00257 00258 00259 class LoopConstraintConstructionFailure : public Base { 00260 public: 00261 LoopConstraintConstructionFailure(const char* fn, int ln, String msg) : Base(fn,ln) 00262 { 00263 setMessage("Loop constraint construction failure: " + msg); 00264 } 00265 private: 00266 }; 00267 00268 } // namespace SimTK::Exception 00269 00270 00271 00272 } // namespace SimTK 00273 00274 #endif // SimTK_SIMBODY_COMMON_H_