Simbody  3.8
Contact.h
Go to the documentation of this file.
1 #ifndef SimTK_SIMMATH_CONTACT_H_
2 #define SimTK_SIMMATH_CONTACT_H_
3 
4 /* -------------------------------------------------------------------------- *
5  * Simbody(tm): SimTKmath *
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-12 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 
27 #include "SimTKcommon.h"
29 
30 #include <set>
31 
32 namespace SimTK {
33 
34 
40 
51 
59 
60 
61 class ContactImpl;
62 class UntrackedContactImpl;
63 class BrokenContactImpl;
64 class CircularPointContactImpl;
65 class EllipticalPointContactImpl;
66 class BrickHalfSpaceContactImpl;
67 class TriangleMeshContactImpl;
68 
69 class PointContactImpl; // deprecated
70 
71 
72 //==============================================================================
73 // CONTACT
74 //==============================================================================
86 public:
89  enum Condition {
95  Broken
96  };
100  static const char* nameOfCondition(Condition);
101 
103  Contact() : impl(0) {}
106  Contact(const Contact& source);
109  ~Contact() {clear();}
112  Contact& operator=(const Contact& source);
115  void clear();
117  bool isEmpty() const {return impl==0;}
118 
134  const Transform& getTransform() const;
135 
144  Contact& setTransform(const Transform& X_S1S2);
145 
149 
154 
155  const ContactImpl& getImpl() const {assert(impl); return *impl;}
156  ContactImpl& updImpl() {assert(impl); return *impl;}
157 protected:
158  explicit Contact(ContactImpl* impl);
159 private:
160  ContactImpl* impl;
161 };
162 
163 inline std::ostream& operator<<(std::ostream& o, const Contact& c) {
164  o << "Contact id=" << c.getContactId()
165  << " (typeId=" << c.getTypeId() << "):\n";
166  o << " surf1,surf2=" << c.getSurface1() << ","
167  << c.getSurface2() << "\n";
168  o << " condition=" << Contact::nameOfCondition(c.getCondition()) << "\n";
169  return o;
170 }
171 
172 
173 
174 //==============================================================================
175 // UNTRACKED CONTACT
176 //==============================================================================
183 public:
192 
194  static bool isInstance(const Contact& contact);
197 
198 private:
199  const UntrackedContactImpl& getImpl() const
200  { assert(isInstance(*this));
201  return reinterpret_cast<const UntrackedContactImpl&>
202  (Contact::getImpl()); }
203 };
204 
205 
206 
207 //==============================================================================
208 // BROKEN CONTACT
209 //==============================================================================
217 public:
225  const Transform& X_S1S2, Real separation);
226 
231 
233  static bool isInstance(const Contact& contact);
236 
237 private:
238  const BrokenContactImpl& getImpl() const
239  { assert(isInstance(*this));
240  return reinterpret_cast<const BrokenContactImpl&>(Contact::getImpl()); }
241 };
242 
243 
244 
245 //==============================================================================
246 // CIRCULAR POINT CONTACT
247 //==============================================================================
261 public:
277  (ContactSurfaceIndex surf1, Real radius1,
278  ContactSurfaceIndex surf2, Real radius2,
279  const Transform& X_S1S2, Real radius, Real depth,
280  const Vec3& origin_S1, const UnitVec3& normal_S1);
281 
283  Real getRadius1() const;
285  Real getRadius2() const;
293  Real getDepth() const;
295  const Vec3& getOrigin() const;
299  const UnitVec3& getNormal() const;
300 
302  static bool isInstance(const Contact& contact);
303  static const CircularPointContact& getAs(const Contact& contact)
304  { assert(isInstance(contact));
305  return static_cast<const CircularPointContact&>(contact); }
307  { assert(isInstance(contact));
308  return static_cast<CircularPointContact&>(contact); }
309 
312 
313 private:
314  const CircularPointContactImpl& getImpl() const
315  { assert(isInstance(*this));
316  return reinterpret_cast<const CircularPointContactImpl&>
317  (Contact::getImpl()); }
318 };
319 
320 
321 
322 //==============================================================================
323 // ELLIPTICAL POINT CONTACT
324 //==============================================================================
356 public:
372  const Transform& X_S1S2,
373  const Transform& X_S1C, const Vec2& k, Real depth);
374 
377  const Vec2& getCurvatures() const;
384  const Transform& getContactFrame() const;
389  Real getDepth() const;
390 
392  static bool isInstance(const Contact& contact);
393  static const EllipticalPointContact& getAs(const Contact& contact)
394  { assert(isInstance(contact));
395  return static_cast<const EllipticalPointContact&>(contact); }
397  { assert(isInstance(contact));
398  return static_cast<EllipticalPointContact&>(contact); }
399 
402 
403 private:
404  const EllipticalPointContactImpl& getImpl() const
405  { assert(isInstance(*this));
406  return reinterpret_cast<const EllipticalPointContactImpl&>
407  (Contact::getImpl()); }
408 };
409 
410 
411 
412 //==============================================================================
413 // BRICK HALFSPACE CONTACT
414 //==============================================================================
419 public:
431  ContactSurfaceIndex brick,
432  const Transform& X_HB,
433  int lowestVertex,
434  Real depth);
435 
438  int getLowestVertex() const;
439 
442  Real getDepth() const;
443 
445  static bool isInstance(const Contact& contact);
446 
449  static const BrickHalfSpaceContact& getAs(const Contact& contact)
450  { assert(isInstance(contact));
451  return static_cast<const BrickHalfSpaceContact&>(contact); }
452 
456  { assert(isInstance(contact));
457  return static_cast<BrickHalfSpaceContact&>(contact); }
458 
462 
463 private:
464  const BrickHalfSpaceContactImpl& getImpl() const
465  { assert(isInstance(*this));
466  return reinterpret_cast<const BrickHalfSpaceContactImpl&>
467  (Contact::getImpl()); }
468 };
469 
470 
471 
472 //==============================================================================
473 // TRIANGLE MESH CONTACT
474 //==============================================================================
479 public:
492  ContactSurfaceIndex surf2,
493  const Transform& X_S1S2,
494  const std::set<int>& faces1,
495  const std::set<int>& faces2);
496 
500  const std::set<int>& getSurface1Faces() const;
504  const std::set<int>& getSurface2Faces() const;
505 
507  static bool isInstance(const Contact& contact);
510  static const TriangleMeshContact& getAs(const Contact& contact)
511  { assert(isInstance(contact));
512  return static_cast<const TriangleMeshContact&>(contact); }
516  { assert(isInstance(contact));
517  return static_cast<TriangleMeshContact&>(contact); }
518 
522 
523 private:
524  const TriangleMeshContactImpl& getImpl() const
525  { assert(isInstance(*this));
526  return reinterpret_cast<const TriangleMeshContactImpl&>
527  (Contact::getImpl()); }
528 };
529 
530 
531 
532 
533 //==============================================================================
534 // POINT CONTACT
535 //==============================================================================
543 public:
561  Vec3& location, Vec3& normal, Real radius1, Real radius2, Real depth);
578  Vec3& location, Vec3& normal, Real radius, Real depth);
584  Vec3 getLocation() const;
589  Vec3 getNormal() const;
608  Real getDepth() const;
612  static bool isInstance(const Contact& contact);
617 
618 private:
619  const PointContactImpl& getImpl() const
620  { assert(isInstance(*this));
621  return reinterpret_cast<const PointContactImpl&>(Contact::getImpl()); }
622 };
623 
624 } // namespace SimTK
625 
626 #endif // SimTK_SIMMATH_CONTACT_H_
Includes internal headers providing declarations for the basic SimTK Core classes,...
This is the header file that every Simmath compilation unit should include first.
#define SimTK_SIMMATH_EXPORT
Definition: SimTKmath/include/simmath/internal/common.h:64
This subclass of Contact is used when one ContactGeometry object is a half plane and the other is a B...
Definition: Contact.h:418
static const BrickHalfSpaceContact & getAs(const Contact &contact)
Recast a brick-halfspace contact given as a generic Contact object to a const reference to a concrete...
Definition: Contact.h:449
static ContactTypeId classTypeId()
Obtain the unique small-integer id for the BrickHalfSpaceContact class.
Real getDepth() const
Get the penetration depth (>0) or separation distance (<0) from the brick's lowest vertex to the half...
static BrickHalfSpaceContact & updAs(Contact &contact)
Recast a brick-halfspace contact given as a generic Contact object to a writable reference to a concr...
Definition: Contact.h:455
static bool isInstance(const Contact &contact)
Determine whether a Contact object is a BrickHalfSpaceContact.
int getLowestVertex() const
Get the vertex index (0-7) of the brick's vertex that is closest to or most penetrated into the halfs...
BrickHalfSpaceContact(ContactSurfaceIndex halfSpace, ContactSurfaceIndex brick, const Transform &X_HB, int lowestVertex, Real depth)
Create a BrickHalfSpaceContact object.
This subclass of Contact represents a pair of contact surfaces that were in contact (meaning within c...
Definition: Contact.h:216
Real getSeparation() const
Get the separation (> cutoff >= 0) between the two surfaces at the time we decided the contact had be...
BrokenContact(ContactSurfaceIndex surf1, ContactSurfaceIndex surf2, const Transform &X_S1S2, Real separation)
Create a BrokenContact object.
static bool isInstance(const Contact &contact)
Determine whether a Contact object is a BrokenContact.
static ContactTypeId classTypeId()
Obtain the unique small-integer id for the BrokenContact class.
This subclass of Contact represents a contact between two non-conforming surfaces 1 and 2 that initia...
Definition: Contact.h:260
static bool isInstance(const Contact &contact)
Determine whether a Contact object is a CircularPointContact.
static const CircularPointContact & getAs(const Contact &contact)
Definition: Contact.h:303
Real getEffectiveRadius() const
Get the precalculated effective radius R at the contact point, where R=1/(1/R1+1/R2).
Real getRadius2() const
Get the radius of surface2 at the contact point.
static ContactTypeId classTypeId()
Get the unique small-integer id for the CircularPointContact class.
CircularPointContact(ContactSurfaceIndex surf1, Real radius1, ContactSurfaceIndex surf2, Real radius2, const Transform &X_S1S2, Real radius, Real depth, const Vec3 &origin_S1, const UnitVec3 &normal_S1)
Create a CircularPointContact object.
Real getRadius1() const
Get the radius of surface1 at the contact point.
Real getDepth() const
Get the penetration depth (>0) or separation distance (<0), also known as the "approach".
const UnitVec3 & getNormal() const
Get the z axis of the contact patch frame, which is the common surface normal at the initial contact ...
const Vec3 & getOrigin() const
Get the origin OP of the contact patch frame P, in S1.
static CircularPointContact & updAs(Contact &contact)
Definition: Contact.h:306
This is a unique integer Id assigned to each contact pair when we first begin to track it.
This defines a unique index for all the contact surfaces being handled either by a ContactTrackerSubs...
This is a small integer that serves as the unique typeid for each type of concrete Contact class.
A Contact contains information about the spatial relationship between two surfaces that are near,...
Definition: Contact.h:85
Contact(const Contact &source)
Copy constructor is shallow and reference-counted; this handle will point to the same object as does ...
bool isEmpty() const
See if this handle is empty.
Definition: Contact.h:117
static ContactId createNewContactId()
This creates a new ContactId starting from 1 and increasing for a very long time (to a billion or so)...
~Contact()
Destructor clears the handle, deleting the referenced object if this was the last reference.
Definition: Contact.h:109
static const char * nameOfCondition(Condition)
Returns a human-readable name corresponding to the given Condition; useful for debugging.
ContactSurfaceIndex getSurface1() const
Get the first surface involved in the contact, specified by its index within its contact set or Conta...
ContactImpl & updImpl()
Definition: Contact.h:156
Contact & setCondition(Condition condition)
Set the current Condition.
Contact & operator=(const Contact &source)
Copy assignment is shallow and reference-counted; this handle will point to the same object as does t...
void clear()
Clear this handle, deleting the referenced object if this was the last reference.
const Transform & getTransform() const
Return the transform X_S1S2 giving the pose of surface 2's frame measured and expressed in surface 1'...
Contact()
The default constructor creates an empty handle.
Definition: Contact.h:103
Contact & setTransform(const Transform &X_S1S2)
Set the surface-to-surface relative transform X_S1S2.
Contact & setContactId(ContactId id)
Set the ContactId for this Contact object.
Contact(ContactImpl *impl)
ContactTypeId getTypeId() const
Return a unique small integer corresponding to the concrete type of Contact object being referenced b...
Condition
The Contact::Condition tracks the status of a Contact through its lifetime.
Definition: Contact.h:89
@ Unknown
this is an illegal value
Definition: Contact.h:90
@ Ongoing
was new or ongoing before; still in contact now
Definition: Contact.h:94
@ Anticipated
we expect these to contact soon
Definition: Contact.h:92
@ Untracked
this pair not yet being tracked; might not contact
Definition: Contact.h:91
@ NewContact
first time seen; needs a ContactId assigned
Definition: Contact.h:93
ContactSurfaceIndex getSurface2() const
Get the second surface involved in the contact, specified by its index within its contact set or Cont...
Contact & setSurfaces(ContactSurfaceIndex surf1, ContactSurfaceIndex surf2)
Set the surfaces tracked by this Contact object.
ContactId getContactId() const
Get the persistent ContactId that has been assigned to this Contact object if there is one (otherwise...
Condition getCondition() const
Find out the current condition of this Contact object.
const ContactImpl & getImpl() const
Definition: Contact.h:155
This subclass of Contact represents a contact between two non-conforming surfaces 1 and 2 that initia...
Definition: Contact.h:355
static ContactTypeId classTypeId()
Get the unique small-integer id for the CircularPointContact class.
static const EllipticalPointContact & getAs(const Contact &contact)
Definition: Contact.h:393
EllipticalPointContact(ContactSurfaceIndex surf1, ContactSurfaceIndex surf2, const Transform &X_S1S2, const Transform &X_S1C, const Vec2 &k, Real depth)
Create a EllipticalPointContact object.
static bool isInstance(const Contact &contact)
Determine whether a Contact object is an EllipticalPointContact.
const Transform & getContactFrame() const
Get the frame C in which the contact paraboloid is expressed, as the transform X_S1C.
Real getDepth() const
Get the penetration depth (>0) or separation distance (<0), also known as the "approach".
const Vec2 & getCurvatures() const
Get the relative curvatures at the contact point, ordered kmax,kmin with kmax >= kmin.
static EllipticalPointContact & updAs(Contact &contact)
Definition: Contact.h:396
OBSOLETE – use CircularPointContact or EllipticalPointContact.
Definition: Contact.h:542
PointContact(ContactSurfaceIndex surf1, ContactSurfaceIndex surf2, Vec3 &location, Vec3 &normal, Real radius1, Real radius2, Real depth)
Create a PointContact object representing a general (elliptical) contact.
Vec3 getLocation() const
The location where the two surfaces touch, specified in the ground frame.
Real getEffectiveRadiusOfCurvature() const
Get the effective relative radius of curvature of the contact surface.
PointContact(ContactSurfaceIndex surf1, ContactSurfaceIndex surf2, Vec3 &location, Vec3 &normal, Real radius, Real depth)
Create a PointContact object representing a circularly symmetric contact.
static ContactTypeId classTypeId()
Obtain the unique small-integer id for the PointContact class.
Real getRadiusOfCurvature2() const
Get the second principal relative radius of curvature of the contact surface.
Real getDepth() const
Get the penetration depth.
Vec3 getNormal() const
Get the surface normal at the contact location.
Real getRadiusOfCurvature1() const
Get the first principal relative radius of curvature of the contact surface.
static bool isInstance(const Contact &contact)
Determine whether a Contact object is a PointContact.
This subclass of Contact is used when one or both of the ContactGeometry objects is a TriangleMesh.
Definition: Contact.h:478
const std::set< int > & getSurface2Faces() const
Get the indices of all faces of surface2 that are partly or completely inside surface1.
static bool isInstance(const Contact &contact)
Determine whether a Contact object is a TriangleMeshContact.
const std::set< int > & getSurface1Faces() const
Get the indices of all faces of surface1 that are partly or completely inside surface2.
static TriangleMeshContact & updAs(Contact &contact)
Recast a triangle mesh given as a generic Contact object to a writable reference to a concrete Triang...
Definition: Contact.h:515
static const TriangleMeshContact & getAs(const Contact &contact)
Recast a triangle mesh given as a generic Contact object to a const reference to a concrete TriangleM...
Definition: Contact.h:510
static ContactTypeId classTypeId()
Obtain the unique small-integer id for the TriangleMeshContact class.
TriangleMeshContact(ContactSurfaceIndex surf1, ContactSurfaceIndex surf2, const Transform &X_S1S2, const std::set< int > &faces1, const std::set< int > &faces2)
Create a TriangleMeshContact object.
This subclass of Contact represents a pair of contact surfaces that are not yet being tracked; there ...
Definition: Contact.h:182
UntrackedContact()
Default constructor creates an empty handle.
Definition: Contact.h:185
UntrackedContact(ContactSurfaceIndex surf1, ContactSurfaceIndex surf2)
Create an UntrackedContact object.
static bool isInstance(const Contact &contact)
Determine whether a Contact object is an UntrackedContact.
static ContactTypeId classTypeId()
Obtain the unique small-integer id for the UntrackedContact class.
This is the top-level SimTK namespace into which all SimTK names are placed to avoid collision with o...
Definition: Assembler.h:37
std::ostream & operator<<(std::ostream &o, const ContactForce &f)
Definition: CompliantContactSubsystem.h:387
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:607
SimTK_DEFINE_UNIQUE_INDEX_TYPE(AssemblyConditionIndex)