Simbody  3.7
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_
SimTK::BrokenContact::isInstance
static bool isInstance(const Contact &contact)
Determine whether a Contact object is a BrokenContact.
SimTK::Contact::getTypeId
ContactTypeId getTypeId() const
Return a unique small integer corresponding to the concrete type of Contact object being referenced b...
SimTK::Contact::Contact
Contact(const Contact &source)
Copy constructor is shallow and reference-counted; this handle will point to the same object as does ...
SimTK::CircularPointContact::classTypeId
static ContactTypeId classTypeId()
Get the unique small-integer id for the CircularPointContact class.
SimTK::Contact::getTransform
const Transform & getTransform() const
Return the transform X_S1S2 giving the pose of surface 2's frame measured and expressed in surface 1'...
SimTK::TriangleMeshContact::getAs
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
SimTK::CircularPointContact::isInstance
static bool isInstance(const Contact &contact)
Determine whether a Contact object is a CircularPointContact.
SimTK::Contact::getCondition
Condition getCondition() const
Find out the current condition of this Contact object.
SimTK::Contact::getContactId
ContactId getContactId() const
Get the persistent ContactId that has been assigned to this Contact object if there is one (otherwise...
SimTK::Contact::nameOfCondition
static const char * nameOfCondition(Condition)
Returns a human-readable name corresponding to the given Condition; useful for debugging.
SimTK::Contact::Ongoing
@ Ongoing
was new or ongoing before; still in contact now
Definition: Contact.h:94
SimTK::UntrackedContact::UntrackedContact
UntrackedContact(ContactSurfaceIndex surf1, ContactSurfaceIndex surf2)
Create an UntrackedContact object.
SimTK::CircularPointContact::getEffectiveRadius
Real getEffectiveRadius() const
Get the precalculated effective radius R at the contact point, where R=1/(1/R1+1/R2).
SimTK::BrickHalfSpaceContact::getAs
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
SimTK::Contact::createNewContactId
static ContactId createNewContactId()
This creates a new ContactId starting from 1 and increasing for a very long time (to a billion or so)...
SimTK::PointContact::getLocation
Vec3 getLocation() const
The location where the two surfaces touch, specified in the ground frame.
SimTK::PointContact::PointContact
PointContact(ContactSurfaceIndex surf1, ContactSurfaceIndex surf2, Vec3 &location, Vec3 &normal, Real radius, Real depth)
Create a PointContact object representing a circularly symmetric contact.
SimTK::TriangleMeshContact::isInstance
static bool isInstance(const Contact &contact)
Determine whether a Contact object is a TriangleMeshContact.
ContactId
SimTK::Contact::clear
void clear()
Clear this handle, deleting the referenced object if this was the last reference.
SimTK::CircularPointContact::getRadius1
Real getRadius1() const
Get the radius of surface1 at the contact point.
SimTK::TriangleMeshContact::getSurface2Faces
const std::set< int > & getSurface2Faces() const
Get the indices of all faces of surface2 that are partly or completely inside surface1.
SimTK::Contact::setCondition
Contact & setCondition(Condition condition)
Set the current Condition.
SimTK::Contact
A Contact contains information about the spatial relationship between two surfaces that are near,...
Definition: Contact.h:85
SimTK_SIMMATH_EXPORT
#define SimTK_SIMMATH_EXPORT
Definition: SimTKmath/include/simmath/internal/common.h:64
SimTK::TriangleMeshContact::TriangleMeshContact
TriangleMeshContact(ContactSurfaceIndex surf1, ContactSurfaceIndex surf2, const Transform &X_S1S2, const std::set< int > &faces1, const std::set< int > &faces2)
Create a TriangleMeshContact object.
SimTK
This is a System that represents the dynamics of a particle moving along a smooth surface.
Definition: Assembler.h:37
SimTK::PointContact::getRadiusOfCurvature2
Real getRadiusOfCurvature2() const
Get the second principal relative radius of curvature of the contact surface.
SimTK::CircularPointContact::getAs
static const CircularPointContact & getAs(const Contact &contact)
Definition: Contact.h:303
SimTK::Contact::Unknown
@ Unknown
this is an illegal value
Definition: Contact.h:90
SimTK::EllipticalPointContact::getCurvatures
const Vec2 & getCurvatures() const
Get the relative curvatures at the contact point, ordered kmax,kmin with kmax >= kmin.
SimTK::PointContact::isInstance
static bool isInstance(const Contact &contact)
Determine whether a Contact object is a PointContact.
SimTK::UnitVec< Real, 1 >
SimTK::EllipticalPointContact::classTypeId
static ContactTypeId classTypeId()
Get the unique small-integer id for the CircularPointContact class.
SimTK::EllipticalPointContact
This subclass of Contact represents a contact between two non-conforming surfaces 1 and 2 that initia...
Definition: Contact.h:355
SimTK::BrickHalfSpaceContact::classTypeId
static ContactTypeId classTypeId()
Obtain the unique small-integer id for the BrickHalfSpaceContact class.
SimTK::PointContact::getRadiusOfCurvature1
Real getRadiusOfCurvature1() const
Get the first principal relative radius of curvature of the contact surface.
SimTK::PointContact::classTypeId
static ContactTypeId classTypeId()
Obtain the unique small-integer id for the PointContact class.
SimTKcommon.h
SimTK::Contact::setContactId
Contact & setContactId(ContactId id)
Set the ContactId for this Contact object.
SimTK::BrickHalfSpaceContact::BrickHalfSpaceContact
BrickHalfSpaceContact(ContactSurfaceIndex halfSpace, ContactSurfaceIndex brick, const Transform &X_HB, int lowestVertex, Real depth)
Create a BrickHalfSpaceContact object.
SimTK::Vec< 3 >
common.h
SimTK::CircularPointContact::getOrigin
const Vec3 & getOrigin() const
Get the origin OP of the contact patch frame P, in S1.
SimTK::UntrackedContact::classTypeId
static ContactTypeId classTypeId()
Obtain the unique small-integer id for the UntrackedContact class.
SimTK::Contact::~Contact
~Contact()
Destructor clears the handle, deleting the referenced object if this was the last reference.
Definition: Contact.h:109
SimTK::Contact::Untracked
@ Untracked
this pair not yet being tracked; might not contact
Definition: Contact.h:91
SimTK::BrokenContact::getSeparation
Real getSeparation() const
Get the separation (> cutoff >= 0) between the two surfaces at the time we decided the contact had be...
SimTK::UntrackedContact::UntrackedContact
UntrackedContact()
Default constructor creates an empty handle.
Definition: Contact.h:185
SimTK::EllipticalPointContact::isInstance
static bool isInstance(const Contact &contact)
Determine whether a Contact object is an EllipticalPointContact.
SimTK::PointContact
OBSOLETE – use CircularPointContact or EllipticalPointContact.
Definition: Contact.h:542
SimTK::CircularPointContact::updAs
static CircularPointContact & updAs(Contact &contact)
Definition: Contact.h:306
SimTK::Contact::setSurfaces
Contact & setSurfaces(ContactSurfaceIndex surf1, ContactSurfaceIndex surf2)
Set the surfaces tracked by this Contact object.
SimTK::Contact::Condition
Condition
The Contact::Condition tracks the status of a Contact through its lifetime.
Definition: Contact.h:89
SimTK::CircularPointContact::getNormal
const UnitVec3 & getNormal() const
Get the z axis of the contact patch frame, which is the common surface normal at the initial contact ...
SimTK::TriangleMeshContact::updAs
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
SimTK::BrickHalfSpaceContact::updAs
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
SimTK::CircularPointContact::getRadius2
Real getRadius2() const
Get the radius of surface2 at the contact point.
SimTK::Contact::updImpl
ContactImpl & updImpl()
Definition: Contact.h:156
SimTK::EllipticalPointContact::getAs
static const EllipticalPointContact & getAs(const Contact &contact)
Definition: Contact.h:393
SimTK::PointContact::getEffectiveRadiusOfCurvature
Real getEffectiveRadiusOfCurvature() const
Get the effective relative radius of curvature of the contact surface.
SimTK::TriangleMeshContact
This subclass of Contact is used when one or both of the ContactGeometry objects is a TriangleMesh.
Definition: Contact.h:478
SimTK::CircularPointContact
This subclass of Contact represents a contact between two non-conforming surfaces 1 and 2 that initia...
Definition: Contact.h:260
SimTK::EllipticalPointContact::getContactFrame
const Transform & getContactFrame() const
Get the frame C in which the contact paraboloid is expressed, as the transform X_S1C.
SimTK::Contact::setTransform
Contact & setTransform(const Transform &X_S1S2)
Set the surface-to-surface relative transform X_S1S2.
SimTK::Contact::Contact
Contact(ContactImpl *impl)
SimTK::BrickHalfSpaceContact::getLowestVertex
int getLowestVertex() const
Get the vertex index (0-7) of the brick's vertex that is closest to or most penetrated into the halfs...
SimTK::BrokenContact::classTypeId
static ContactTypeId classTypeId()
Obtain the unique small-integer id for the BrokenContact class.
SimTK::BrokenContact
This subclass of Contact represents a pair of contact surfaces that were in contact (meaning within c...
Definition: Contact.h:216
SimTK::PointContact::PointContact
PointContact(ContactSurfaceIndex surf1, ContactSurfaceIndex surf2, Vec3 &location, Vec3 &normal, Real radius1, Real radius2, Real depth)
Create a PointContact object representing a general (elliptical) contact.
SimTK::BrickHalfSpaceContact
This subclass of Contact is used when one ContactGeometry object is a half plane and the other is a B...
Definition: Contact.h:418
SimTK::Contact::NewContact
@ NewContact
first time seen; needs a ContactId assigned
Definition: Contact.h:93
SimTK::Contact::getSurface2
ContactSurfaceIndex getSurface2() const
Get the second surface involved in the contact, specified by its index within its contact set or Cont...
SimTK::Contact::isEmpty
bool isEmpty() const
See if this handle is empty.
Definition: Contact.h:117
SimTK::TriangleMeshContact::classTypeId
static ContactTypeId classTypeId()
Obtain the unique small-integer id for the TriangleMeshContact class.
SimTK::Contact::Anticipated
@ Anticipated
we expect these to contact soon
Definition: Contact.h:92
SimTK::Contact::getImpl
const ContactImpl & getImpl() const
Definition: Contact.h:155
ContactTypeId
SimTK::Contact::getSurface1
ContactSurfaceIndex getSurface1() const
Get the first surface involved in the contact, specified by its index within its contact set or Conta...
SimTK::UntrackedContact
This subclass of Contact represents a pair of contact surfaces that are not yet being tracked; there ...
Definition: Contact.h:182
SimTK::Real
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
SimTK::TriangleMeshContact::getSurface1Faces
const std::set< int > & getSurface1Faces() const
Get the indices of all faces of surface1 that are partly or completely inside surface2.
SimTK::UntrackedContact::isInstance
static bool isInstance(const Contact &contact)
Determine whether a Contact object is an UntrackedContact.
SimTK::BrickHalfSpaceContact::isInstance
static bool isInstance(const Contact &contact)
Determine whether a Contact object is a BrickHalfSpaceContact.
SimTK::CircularPointContact::getDepth
Real getDepth() const
Get the penetration depth (>0) or separation distance (<0), also known as the "approach".
SimTK::Contact::Contact
Contact()
The default constructor creates an empty handle.
Definition: Contact.h:103
SimTK::EllipticalPointContact::updAs
static EllipticalPointContact & updAs(Contact &contact)
Definition: Contact.h:396
SimTK::BrokenContact::BrokenContact
BrokenContact(ContactSurfaceIndex surf1, ContactSurfaceIndex surf2, const Transform &X_S1S2, Real separation)
Create a BrokenContact object.
SimTK::SimTK_DEFINE_UNIQUE_INDEX_TYPE
SimTK_DEFINE_UNIQUE_INDEX_TYPE(AssemblyConditionIndex)
SimTK::EllipticalPointContact::getDepth
Real getDepth() const
Get the penetration depth (>0) or separation distance (<0), also known as the "approach".
SimTK::PointContact::getNormal
Vec3 getNormal() const
Get the surface normal at the contact location.
SimTK::PointContact::getDepth
Real getDepth() const
Get the penetration depth.
SimTK::CircularPointContact::CircularPointContact
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.
ContactSurfaceIndex
SimTK::BrickHalfSpaceContact::getDepth
Real getDepth() const
Get the penetration depth (>0) or separation distance (<0) from the brick's lowest vertex to the half...
SimTK::operator<<
std::ostream & operator<<(std::ostream &o, const ContactForce &f)
Definition: CompliantContactSubsystem.h:387
SimTK::Transform_< Real >
SimTK::Contact::operator=
Contact & operator=(const Contact &source)
Copy assignment is shallow and reference-counted; this handle will point to the same object as does t...
SimTK::EllipticalPointContact::EllipticalPointContact
EllipticalPointContact(ContactSurfaceIndex surf1, ContactSurfaceIndex surf2, const Transform &X_S1S2, const Transform &X_S1C, const Vec2 &k, Real depth)
Create a EllipticalPointContact object.