Simbody 3.7
Loading...
Searching...
No Matches
ContactSurface.h
Go to the documentation of this file.
1#ifndef SimTK_SIMBODY_CONTACT_SURFACE_H_
2#define SimTK_SIMBODY_CONTACT_SURFACE_H_
3
4/* -------------------------------------------------------------------------- *
5 * Simbody(tm) *
6 * -------------------------------------------------------------------------- *
7 * This is part of the SimTK biosimulation toolkit originating from *
8 * Simbios, the NIH National Center for Physics-Based Simulation of *
9 * Biological Structures at Stanford, funded under the NIH Roadmap for *
10 * Medical Research, grant U54 GM072970. See https://simtk.org/home/simbody. *
11 * *
12 * Portions copyright (c) 2008-13 Stanford University and the Authors. *
13 * Authors: Peter Eastman, Michael Sherman *
14 * Contributors: *
15 * *
16 * Licensed under the Apache License, Version 2.0 (the "License"); you may *
17 * not use this file except in compliance with the License. You may obtain a *
18 * copy of the License at http://www.apache.org/licenses/LICENSE-2.0. *
19 * *
20 * Unless required by applicable law or agreed to in writing, software *
21 * distributed under the License is distributed on an "AS IS" BASIS, *
22 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
23 * See the License for the specific language governing permissions and *
24 * limitations under the License. *
25 * -------------------------------------------------------------------------- */
26
30#include "SimTKmath.h"
32
33#include <algorithm>
34#include <atomic>
35
36namespace SimTK {
37
38class ContactGeometry;
39
41
42
43
44//==============================================================================
45// CONTACT MATERIAL
46//==============================================================================
90public:
94ContactMaterial() {clear();}
95
136ContactMaterial(Real stiffness, Real dissipation,
137 Real staticFriction, Real dynamicFriction,
138 Real viscousFriction = 0) {
139 setStiffness(stiffness);
140 setDissipation(dissipation);
141 setFriction(staticFriction, dynamicFriction, viscousFriction);
142}
143
146bool isValid() const {return m_stiffness > 0;}
147
150{ SimTK_ERRCHK(isValid(), "ContactMaterial::getStiffness()",
151 "This is an invalid ContactMaterial.");
152 return m_stiffness; }
155{ SimTK_ERRCHK(isValid(), "ContactMaterial::getStiffness23()",
156 "This is an invalid ContactMaterial.");
157 return m_stiffness23; }
160{ SimTK_ERRCHK(isValid(), "ContactMaterial::getDissipation()",
161 "This is an invalid ContactMaterial.");
162 return m_dissipation; }
165{ SimTK_ERRCHK(isValid(), "ContactMaterial::getStaticFriction()",
166 "This is an invalid ContactMaterial.");
167 return m_staticFriction; }
170{ SimTK_ERRCHK(isValid(), "ContactMaterial::getDynamicFriction()",
171 "This is an invalid ContactMaterial.");
172 return m_dynamicFriction; }
175{ SimTK_ERRCHK(isValid(), "ContactMaterial::getViscousFriction()",
176 "This is an invalid ContactMaterial.");
177 return m_viscousFriction; }
178
183 SimTK_ERRCHK1_ALWAYS(stiffness >= 0, "ContactMaterial::setStiffness()",
184 "Stiffness %g is illegal; must be >= 0.", stiffness);
185 m_stiffness = stiffness;
186 m_stiffness23 = std::pow(m_stiffness, Real(2./3.));
187 return *this;
188}
189
194 SimTK_ERRCHK1_ALWAYS(dissipation >= 0, "ContactMaterial::setDissipation()",
195 "Dissipation %g (in 1/speed) is illegal; must be >= 0.", dissipation);
196 m_dissipation = dissipation;
197 return *this;
198}
199
202 Real dynamicFriction,
203 Real viscousFriction = 0)
204{
205 SimTK_ERRCHK1_ALWAYS(0 <= staticFriction, "ContactMaterial::setFriction()",
206 "Illegal static friction coefficient %g.", staticFriction);
207 SimTK_ERRCHK2_ALWAYS(0<=dynamicFriction && dynamicFriction<=staticFriction,
208 "ContactMaterial::setFriction()",
209 "Dynamic coefficient %g illegal; must be between 0 and static"
210 " coefficient %g.", dynamicFriction, staticFriction);
211 SimTK_ERRCHK1_ALWAYS(0 <= viscousFriction, "ContactMaterial::setFriction()",
212 "Illegal viscous friction coefficient %g.", viscousFriction);
213
214 m_staticFriction = staticFriction;
215 m_dynamicFriction = dynamicFriction;
216 m_viscousFriction = viscousFriction;
217 return *this;
218}
219
229static Real calcPlaneStrainStiffness(Real youngsModulus,
230 Real poissonsRatio)
231{
232 SimTK_ERRCHK2_ALWAYS(youngsModulus >= 0 &&
233 -1 < poissonsRatio && poissonsRatio <= 0.5,
234 "ContactMaterial::calcStiffnessForSolid()",
235 "Illegal material properties E=%g, v=%g.",
236 youngsModulus, poissonsRatio);
237
238 return youngsModulus / (1-square(poissonsRatio));
239}
240
241
251 Real poissonsRatio)
252{
253 SimTK_ERRCHK2_ALWAYS(youngsModulus >= 0 &&
254 -1 < poissonsRatio && poissonsRatio < 0.5,
255 "ContactMaterial::calcStiffnessForSolid()",
256 "Illegal material properties E=%g, v=%g.",
257 youngsModulus, poissonsRatio);
258
259 return youngsModulus*(1-poissonsRatio)
260 / ((1+poissonsRatio)*(1-2*poissonsRatio));
261}
262
275 (Real restitution, Real speed) {
276 if (restitution==1) return 0;
277 SimTK_ERRCHK2_ALWAYS(0<=restitution && restitution<=1 && speed>0,
278 "ContactMaterial::calcDissipationFromRestitution()",
279 "Illegal coefficient of restitution or speed (%g,%g).",
280 restitution, speed);
281 return (1-restitution)/speed;
282}
283
287void clear() {
288 m_stiffness = NaN; // unspecified
289 m_stiffness23 = NaN;
290 m_restitution = NaN; // unspecified
291 m_dissipation = 0; // default; no dissipation
292 // default; no friction
293 m_staticFriction=m_dynamicFriction=m_viscousFriction = 0;
294}
295
296//--------------------------------------------------------------------------
297private:
298
299// For compliant contact models.
300Real m_stiffness; // k: stress/%strain=(force/area)/%strain
301Real m_stiffness23; // k^(2/3) in case we need it
302Real m_dissipation; // c: %normalForce/normalVelocity
303
304// For impulsive collisions.
305Real m_restitution; // e: unitless, e=(1-cv)
306
307// Friction.
308Real m_staticFriction; // us: unitless
309Real m_dynamicFriction; // ud: unitless
310Real m_viscousFriction; // uv: %normalForce/slipVelocity
311};
312
313
314
315//==============================================================================
316// CONTACT SURFACE
317//==============================================================================
343public:
345ContactSurface() : m_thickness(0), m_indexOnBody(-1), m_userRef(nullptr) {}
348 const ContactMaterial& material,
349 Real thickness=0)
350: m_shape(shape), m_material(material), m_thickness(thickness),
351 m_indexOnBody(-1), m_userRef(nullptr) {
352 SimTK_ERRCHK1_ALWAYS(thickness >= 0, "ContactSurface::ctor()",
353 "Illegal thickness %g.", thickness);
354}
355
358{ m_shape = shape; return *this; }
359
363 Real thickness = 0)
364{ m_material = material; setThickness(thickness); return *this; }
365
371 SimTK_ERRCHK1_ALWAYS(thickness >= 0, "ContactSurface::setThickness()",
372 "Illegal thickness %g.", thickness);
373 m_thickness = thickness;
374 return *this;
375}
376
378const ContactGeometry& getShape() const {return m_shape;}
379
381const ContactMaterial& getMaterial() const {return m_material;}
382
385Real getThickness() const {return m_thickness;}
386
388ContactGeometry& updShape() {return m_shape;}
389
391ContactMaterial& updMaterial() {return m_material;}
392
395ContactSurface& joinClique(ContactCliqueId clique) {
396 if (!clique.isValid()) return *this;
397 // Although this is a sorted list, we expect it to be very short so
398 // are using linear search to find where this new clique goes.
400 for (p = m_cliques.begin(); p != m_cliques.end(); ++p) {
401 if (*p==clique) return *this; // already a member
402 if (*p>clique) break;
403 }
404 // insert just before p (might be at the end)
405 m_cliques.insert(p, clique);
406 return *this;
407}
408
411void leaveClique(ContactCliqueId clique) {
412 if (!clique.isValid()) return;
413 // We expect this to be a very short list so are using linear search.
415 std::find(m_cliques.begin(), m_cliques.end(), clique);
416 if (p != m_cliques.end()) m_cliques.erase(p);
417}
418
422bool isInSameClique(const ContactSurface& other) const
423{ if (getCliques().empty() || other.getCliques().empty()) return false;//typical
424 return cliquesIntersect(getCliques(), other.getCliques()); }
425
428const Array_<ContactCliqueId,short>& getCliques() const {return m_cliques;}
429
435{
438 // Quick checks: empty or non-overlapping.
439 if (ap==a.end() || bp==b.end()) return false;
440 if (*ap > b.back() || *bp > a.back())
441 return false; // disjoint
442 // Both lists have elements and the elements overlap numerically.
443 while (true) {
444 if (*ap==*bp) return true;
445 // Increment the list with smaller front element.
446 if (*ap < *bp) {++ap; if (ap==a.end()) break;}
447 else {++bp; if (bp==b.end()) break;}
448 }
449 // One of the lists ran out of elements before we found a match.
450 return false;
451}
452
456static ContactCliqueId createNewContactClique()
457{ static std::atomic<int> nextAvailableContactClique(1);
458 return ContactCliqueId(nextAvailableContactClique++); }
459
471ContactSurface& setIndexOnBody(int index) {m_indexOnBody=index; return *this;}
472
487ContactSurface& setUserRef(void* userRef) {m_userRef=userRef; return *this;}
488
493int getIndexOnBody() const {return m_indexOnBody;}
494
499void* getUserRef() const {return m_userRef;}
500
501//----------------------------------------------------------------------
502 private:
503
504ContactGeometry m_shape;
505ContactMaterial m_material;
506Real m_thickness; // default=0; meaning not set
507Array_<ContactCliqueId,short> m_cliques; // sorted
508
509int m_indexOnBody; // default is -1
510void* m_userRef; // default is nullptr
511};
512
513
514
515} // namespace SimTK
516
517#endif // SimTK_SIMBODY_CONTACT_SURFACE_H_
#define SimTK_ERRCHK2_ALWAYS(cond, whereChecked, fmt, a1, a2)
Definition ExceptionMacros.h:289
#define SimTK_ERRCHK1_ALWAYS(cond, whereChecked, fmt, a1)
Definition ExceptionMacros.h:285
#define SimTK_ERRCHK(cond, whereChecked, msg)
Definition ExceptionMacros.h:324
#define SimTK_DEFINE_UNIQUE_INDEX_TYPE(NAME)
Use this macro to define a unique "Index" type which is just a type-safe non-negative int,...
Definition SimTKcommon/include/SimTKcommon/internal/common.h:426
Every Simbody header and source file should include this header before any other Simbody header.
#define SimTK_SIMBODY_EXPORT
Definition Simbody/include/simbody/internal/common.h:68
The Array_<T> container class is a plug-compatible replacement for the C++ standard template library ...
Definition Array.h:1520
T * iterator
Definition Array.h:1540
const T * begin() const
The const version of begin() is the same as cbegin().
Definition Array.h:2214
const T * const_iterator
Definition Array.h:1541
const T * end() const
The const version of end() is the same as cend().
Definition Array.h:2227
const T & back() const
Return a const reference to the last element in this array, which must not be empty.
Definition Array.h:2337
bool empty() const
Return true if there are no elements currently stored in this array.
Definition Array.h:2080
A ContactGeometry object describes the shape of all or part of the boundary of a solid object,...
Definition ContactGeometry.h:110
Define the physical properties of the material from which a contact surface is made,...
Definition ContactSurface.h:89
ContactMaterial & setDissipation(Real dissipation)
Supply material dissipation coefficient c, which is the slope of the coefficient of restitution (e) v...
Definition ContactSurface.h:193
ContactMaterial(Real stiffness, Real dissipation, Real staticFriction, Real dynamicFriction, Real viscousFriction=0)
Create a contact material with a complete set of compliant contact material properties.
Definition ContactSurface.h:136
static Real calcConfinedCompressionStiffness(Real youngsModulus, Real poissonsRatio)
Calculate the contact material stiffness k from its linear elastic material properties Young's modulu...
Definition ContactSurface.h:250
Real getDynamicFriction() const
Return the coefficient of dynamic friction mu_d (unitless).
Definition ContactSurface.h:169
static Real calcPlaneStrainStiffness(Real youngsModulus, Real poissonsRatio)
Calculate the contact material stiffness k from its linear elastic material properties Young's modulu...
Definition ContactSurface.h:229
ContactMaterial & setStiffness(Real stiffness)
Supply material stiffness k=(force/area)/%strain.
Definition ContactSurface.h:182
Real getStiffness() const
Return the material stiffness k=(force/area)/%strain.
Definition ContactSurface.h:149
ContactMaterial & setFriction(Real staticFriction, Real dynamicFriction, Real viscousFriction=0)
Set the friction coefficients for this material.
Definition ContactSurface.h:201
Real getViscousFriction() const
Return the coefficient of viscous friction mu_v (1/velocity).
Definition ContactSurface.h:174
void clear()
Restore this contact material to an invalid state containing no stiffness specification and default v...
Definition ContactSurface.h:287
Real getStiffness23() const
Return precalculated 2/3 power of material stiffness k (k^(2/3)).
Definition ContactSurface.h:154
Real getDissipation() const
Return the material dissipation coefficient c, in units of 1/velocity.
Definition ContactSurface.h:159
static Real calcDissipationFromObservedRestitution(Real restitution, Real speed)
Given an observation of the coefficient of restitution e at a given small impact velocity v,...
Definition ContactSurface.h:275
bool isValid() const
Return false if material properties have not yet been supplied for this contact material.
Definition ContactSurface.h:146
Real getStaticFriction() const
Return the coefficient of static friction mu_s (unitless).
Definition ContactSurface.h:164
ContactMaterial()
Default constructor creates an invalid contact material; you must specify at least stiffness before u...
Definition ContactSurface.h:94
This class combines a piece of ContactGeometry with a ContactMaterial to make an object suitable for ...
Definition ContactSurface.h:342
const ContactMaterial & getMaterial() const
Get read-only access to the material of this contact surface.
Definition ContactSurface.h:381
const Array_< ContactCliqueId, short > & getCliques() const
Return a reference to the list of CliqueIds of the cliques in which this contact surface is a member;...
Definition ContactSurface.h:428
ContactSurface & setMaterial(const ContactMaterial &material, Real thickness=0)
Define a new material for this ContactSurface, optionally providing the thickness of this elastic mat...
Definition ContactSurface.h:362
ContactSurface & setThickness(Real thickness)
Set the thickness of the layer of elastic material coating this contact surface.
Definition ContactSurface.h:370
const ContactGeometry & getShape() const
Get read-only access to the shape of this contact surface.
Definition ContactSurface.h:378
ContactSurface & joinClique(ContactCliqueId clique)
Join a contact clique if not already a member.
Definition ContactSurface.h:395
ContactSurface & setUserRef(void *userRef)
Use this method to store an arbitrary reference pointer with this ContactSurface object.
Definition ContactSurface.h:487
Real getThickness() const
Get the thickness of the elastic material layer on this contact surface, with zero indicating that th...
Definition ContactSurface.h:385
ContactSurface & setIndexOnBody(int index)
For selection or other purposes, you may want to use this method to store an index that can identify ...
Definition ContactSurface.h:471
int getIndexOnBody() const
Return the index that was supplied to the most recent setIndexOnBody() call for this ContactSurface o...
Definition ContactSurface.h:493
ContactSurface & setShape(const ContactGeometry &shape)
Define a new shape for this ContactSurface.
Definition ContactSurface.h:357
void leaveClique(ContactCliqueId clique)
Remove this surface from a contact clique if it is a member.
Definition ContactSurface.h:411
ContactGeometry & updShape()
Get writable access to the shape of this contact surface.
Definition ContactSurface.h:388
static bool cliquesIntersect(const Array_< ContactCliqueId, short > &a, const Array_< ContactCliqueId, short > &b)
Return true if there are any common cliques on two clique lists which must each be sorted in ascendin...
Definition ContactSurface.h:433
void * getUserRef() const
Return the pointer value that was supplied to the most recent setUserRef() call for this ContactSurfa...
Definition ContactSurface.h:499
ContactMaterial & updMaterial()
Get writable access to the material of this contact surface.
Definition ContactSurface.h:391
ContactSurface()
Create an empty ContactSurface.
Definition ContactSurface.h:345
static ContactCliqueId createNewContactClique()
Create a new contact clique and return its unique integer id (thread safe).
Definition ContactSurface.h:456
ContactSurface(const ContactGeometry &shape, const ContactMaterial &material, Real thickness=0)
Create a ContactSurface with a given shape and material.
Definition ContactSurface.h:347
bool isInSameClique(const ContactSurface &other) const
Determine whether this contact surface is a member of any of the same cliques as some other contact s...
Definition ContactSurface.h:422
const Real NaN
This is the IEEE "not a number" constant for this implementation of the default-precision Real type; ...
This is the top-level SimTK namespace into which all SimTK names are placed to avoid collision with o...
Definition Assembler.h:37
unsigned char square(unsigned char u)
Definition Scalar.h:349
SimTK_Real Real
This is the default compiled-in floating point type for SimTK, either float or double.
Definition SimTKcommon/include/SimTKcommon/internal/common.h:606