iMSTK
Interactive Medical Simulation Toolkit
imstkRbdFrictionConstraint.cpp
1 /*
2 ** This file is part of the Interactive Medical Simulation Toolkit (iMSTK)
3 ** iMSTK is distributed under the Apache License, Version 2.0.
4 ** See accompanying NOTICE for details.
5 */
6 
7 #include "imstkRbdFrictionConstraint.h"
8 
9 namespace imstk
10 {
11 RbdFrictionConstraint::RbdFrictionConstraint(
12  std::shared_ptr<RigidBody> obj1,
13  std::shared_ptr<RigidBody> obj2,
14  const Vec3d& contactNormal,
15  const Vec3d& contactPt,
16  const double contactDepth,
17  const double frictionCoefficient,
18  const Side side) : RbdConstraint(obj1, obj2, side),
19  m_contactPt(contactPt), m_contactN(contactNormal),
20  m_contactDepth(contactDepth), m_frictionCoefficient(frictionCoefficient)
21 {
22 }
23 
24 void
25 RbdFrictionConstraint::compute(double imstkNotUsed(dt))
26 {
27  // Displacement from center of mass
28  //const Vec3d r1 = m_contactPt - m_obj1->getPosition();
29  //const Vec3d r2 = m_contactPt - m_obj2->getPosition();
30 
31  // Jacobian of contact
32  J = Eigen::Matrix<double, 3, 4>::Zero();
33  if ((m_side == Side::AB || m_side == Side::A) && !m_obj1->m_isStatic)
34  {
35  const double vN = m_contactN.dot(m_obj1->getVelocity());
36  const Vec3d vTan = m_obj1->getVelocity() - vN * m_contactN;
37  const Vec3d tan = vTan.normalized();
38 
39  // No angular friction
40  J(0, 0) = -tan[0]; J(0, 1) = 0.0;
41  J(1, 0) = -tan[1]; J(1, 1) = 0.0;
42  J(2, 0) = -tan[2]; J(2, 1) = 0.0;
43 
44  const double fNMag = std::max(0.0, m_obj1->getForce().dot(-m_contactN));
45  const double fu = m_frictionCoefficient * fNMag;
46  range[0] = -fu;
47  range[1] = fu;
48  }
49  if ((m_side == Side::AB || m_side == Side::B) && !m_obj2->m_isStatic)
50  {
51  const double vN = m_contactN.dot(m_obj2->getVelocity());
52  const Vec3d vTan = m_obj2->getVelocity() - vN * -m_contactN;
53  const Vec3d tan = vTan.normalized();
54 
55  // No angular friction
56  J(0, 0) = tan[0]; J(0, 1) = 0.0;
57  J(1, 0) = tan[1]; J(1, 1) = 0.0;
58  J(2, 0) = tan[2]; J(2, 1) = 0.0;
59 
60  // Get normal force
61  const double fNMag = std::max(0.0, m_obj2->getForce().dot(m_contactN));
62  const double fu = m_frictionCoefficient * fNMag;
63  range[0] = -fu;
64  range[1] = fu;
65  }
66 
67  /*if both? Kinda need two ranges
68  {
69  J(0, 0) = -tan[0]; J(0, 1) = -tan[1]; J(0, 2) = -tan[2];
70  J(1, 0) = 0.0; J(1, 1) = 0.0; J(1, 2) = 0.0;
71  J(2, 0) = tan[0]; J(2, 1) = tan[1]; J(2, 2) = tan[2];
72  J(3, 0) = 0.0; J(3, 1) = 0.0; J(3, 2) = 0.0;
73 
74  const Vec3d netForce = m_obj1->getForce() + m_obj2->getForce();
75  const double fNMag = std::max(0.0, netForce.dot(m_contactN));
76  const double fu = m_frictionCoefficient * fNMag;
77  range[0] = -fu;
78  range[1] = fu;
79  }*/
80 }
81 } // namespace imstk
void compute(double dt) override
Compute constraint jacobian.
Compound Geometry.
Eigen::Matrix< double, 3, 4 > J
Jacobian, "vanish" to zero.