7 #include "imstkPbdObjectController.h" 8 #include "imstkDeviceClient.h" 9 #include "imstkLogger.h" 10 #include "imstkPbdObject.h" 12 #include <Eigen/Eigenvalues> 17 PbdObjectController::setControlledObject(std::shared_ptr<SceneObject> obj)
19 m_pbdObject = std::dynamic_pointer_cast<PbdObject>(obj);
20 CHECK(m_pbdObject !=
nullptr) <<
"Controlled object must be a PbdObject";
21 CHECK(m_pbdObject->getPbdBody()->bodyType == PbdBody::Type::RIGID)
22 <<
"PbdObjectController can only operate on pbd rigid bodies";
23 SceneObjectController::setControlledObject(obj);
29 if (m_deviceClient ==
nullptr)
35 LOG(WARNING) <<
"warning: could not update tracking info.";
39 if (m_pbdObject ==
nullptr)
46 if (m_deviceClient->getTrackingEnabled() &&
m_useSpring)
53 m_pbdObject->getPbdBody()->externalForce = Vec3d(0.0, 0.0, 0.0);
54 m_pbdObject->getPbdBody()->externalTorque = Vec3d(0.0, 0.0, 0.0);
56 (*m_pbdObject->getPbdBody()->vertices)[0] =
getPosition();
66 const Vec3d& currPos = (*m_pbdObject->getPbdBody()->vertices)[0];
67 const Quatd& currOrientation = (*m_pbdObject->getPbdBody()->orientations)[0];
68 const Vec3d& currVelocity = (*m_pbdObject->getPbdBody()->velocities)[0];
69 const Vec3d& currAngularVelocity = (*m_pbdObject->getPbdBody()->angularVelocities)[0];
70 Vec3d& currForce = m_pbdObject->getPbdBody()->externalForce;
71 Vec3d& currTorque = m_pbdObject->getPbdBody()->externalTorque;
75 const Vec3d hapticOffsetLocal = currOrientation._transformVector(m_hapticOffset);
80 const double mass = (*m_pbdObject->getPbdBody()->masses)[0];
83 const double fudge = 1.00;
84 m_linearKd = 2.0 * std::sqrt(mass * linearKs) * fudge;
86 const Mat3d inertia = (*m_pbdObject->getPbdBody()->inertias)[0];
93 const double inertiaScale = std::cbrt(inertia.determinant());
95 m_angularKd = 2.0 * std::sqrt(inertiaScale * angularKs) * fudge;
104 m_fS =
m_linearKs.cwiseProduct(devicePos - currPos - hapticOffsetLocal);
105 m_fD =
m_linearKd * (-currVelocity - currAngularVelocity.cross(hapticOffsetLocal));
106 Vec3d force = m_fS + m_fD;
109 const Quatd dq = deviceOrientation * currOrientation.inverse();
110 const Rotd angleAxes = Rotd(dq);
111 m_tS = hapticOffsetLocal.cross(force) +
m_angularKs.cwiseProduct(angleAxes.axis() * angleAxes.angle());
113 Vec3d torque = m_tS + m_tD;
116 currTorque += torque;
143 m_pbdObject->getPbdBody()->externalForce = Vec3d(0.0, 0.0, 0.0);
144 m_pbdObject->getPbdBody()->externalTorque = Vec3d(0.0, 0.0, 0.0);
146 (*m_pbdObject->getPbdBody()->vertices)[0] =
getPosition();
164 if (m_forceSmoothening)
166 m_forces.push_back(force);
168 if (static_cast<int>(m_forces.size()) > m_smoothingKernelSize)
170 m_forceSum -= m_forces.front();
171 m_forces.pop_front();
173 const Vec3d avgForce = m_forceSum / m_forces.size();
176 m_deviceClient->setForce(avgForce);
181 m_deviceClient->setForce(force);
bool m_useSpring
If off, pos & orientation directly set.
virtual bool updateTrackingData(const double dt)
Update tracking data.
void applyForces() override
Apply forces to the haptic device.
Vec3d m_angularKs
Spring coefficient, rotational.
unsigned char m_invertFlags
Invert flags to be masked with DeviceTracker::InvertFlag.
double m_angularKd
Damping coefficient, rotational.
void update(const double &dt) override
Update controlled scene object using latest tracking information.
Vec3d getDeviceForce() const
Return the device applied force (scaled)
const Quatd & getOrientation() const
Set/Get the orientation of the tracker.
double m_linearKd
Damping coefficient, linear.
bool m_useCriticalDamping
If on, kd is automatically computed.
const Vec3d & getPosition() const
Set/Get the position of the tracker.
Vec3d m_inversionParams
Inversion parameters for each axis.
Vec3d m_linearKs
Spring coefficient, linear.