7 #include "imstkRigidObjectController.h" 8 #include "imstkDeviceClient.h" 9 #include "imstkLogger.h" 10 #include "imstkRbdConstraint.h" 11 #include "imstkRigidObject2.h" 13 #include <Eigen/Eigenvalues> 18 RigidObjectController::setControlledObject(std::shared_ptr<SceneObject> obj)
20 SceneObjectController::setControlledObject(obj);
21 m_rigidObject = std::dynamic_pointer_cast<RigidObject2>(obj);
22 CHECK(m_rigidObject !=
nullptr) <<
23 "RigidObjectController controlled object must be type RigidObject2";
31 LOG(WARNING) <<
"warning: could not update tracking info.";
35 if (m_rigidObject ==
nullptr)
42 if (m_deviceClient->getTrackingEnabled() &&
m_useSpring)
44 const Vec3d& currPos = m_rigidObject->getRigidBody()->getPosition();
45 const Quatd& currOrientation = m_rigidObject->getRigidBody()->getOrientation();
46 const Vec3d& currVelocity = m_rigidObject->getRigidBody()->getVelocity();
47 const Vec3d& currAngularVelocity = m_rigidObject->getRigidBody()->getAngularVelocity();
48 Vec3d& currForce = *m_rigidObject->getRigidBody()->m_force;
49 Vec3d& currTorque = *m_rigidObject->getRigidBody()->m_torque;
53 const Vec3d& deviceOffset = Vec3d(0.0, 0.0, 0.0);
58 const double mass = m_rigidObject->getRigidBody()->getMass();
62 const Mat3d inertia = m_rigidObject->getRigidBody()->getIntertiaTensor();
69 const double inertiaScale = std::cbrt(inertia.determinant());
71 m_angularKd = 2.0 * std::sqrt(inertiaScale * angularKs);
80 m_fS =
m_linearKs.cwiseProduct(devicePos - currPos - deviceOffset);
81 m_fD =
m_linearKd * (-currVelocity - currAngularVelocity.cross(deviceOffset));
82 Vec3d force = m_fS + m_fD;
85 const Quatd dq = deviceOrientation * currOrientation.inverse();
86 const Rotd angleAxes = Rotd(dq);
87 m_tS = deviceOffset.cross(force) +
m_angularKs.cwiseProduct(angleAxes.axis() * angleAxes.angle());
89 Vec3d torque = m_tS + m_tD;
119 *m_rigidObject->getRigidBody()->m_force = Vec3d(0.0, 0.0, 0.0);
120 *m_rigidObject->getRigidBody()->m_torque = Vec3d(0.0, 0.0, 0.0);
122 (*m_rigidObject->getRigidBody()->m_pos) =
getPosition();
123 (*m_rigidObject->getRigidBody()->m_orientation) =
getOrientation();
133 if (!m_deviceClient->getButton(0))
139 if (m_forceSmoothening)
141 m_forces.push_back(force);
143 if (static_cast<int>(m_forces.size()) > m_smoothingKernelSize)
145 m_forceSum -= m_forces.front();
146 m_forces.pop_front();
148 const Vec3d avgForce = m_forceSum / m_forces.size();
151 m_deviceClient->setForce(avgForce);
156 m_deviceClient->setForce(force);
162 m_deviceClient->setForce(Vec3d(0.0, 0.0, 0.0));
double m_angularKd
Damping coefficient, rotational.
bool m_useCriticalDamping
If on, kd is automatically computed.
bool m_useSpring
If off, pos & orientation directly set.
double m_linearKd
Damping coefficient, linear.
Base class for events which contain a type, priority, and data priority defaults to 0 and uses a grea...
virtual bool updateTrackingData(const double dt)
Update tracking data.
const Quatd & getOrientation() const
Set/Get the orientation of the tracker.
const Vec3d & getPosition() const
Set/Get the position of the tracker.
void postEvent(const T &e)
Emits the event Direct observers will be immediately called, in sync Queued observers will receive th...
void applyForces() override
Apply forces to the haptic device.
Vec3d m_angularKs
Spring 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)
Vec3d m_linearKs
Spring coefficient, linear.