iMSTK
Interactive Medical Simulation Toolkit
All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Pages
imstkLaparoscopicToolController.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 "imstkLaparoscopicToolController.h"
8 #include "imstkCollidingObject.h"
9 #include "imstkDeviceClient.h"
10 #include "imstkGeometry.h"
11 #include "imstkLogger.h"
12 
13 namespace imstk
14 {
15 void
16 LaparoscopicToolController::setParts(
17  std::shared_ptr<CollidingObject> shaft,
18  std::shared_ptr<CollidingObject> upperJaw,
19  std::shared_ptr<CollidingObject> lowerJaw,
20  std::shared_ptr<Geometry> pickGeom)
21 {
22  m_shaft = shaft;
23  m_upperJaw = upperJaw;
24  m_lowerJaw = lowerJaw;
25  m_pickGeom = pickGeom;
26  m_jawRotationAxis = Vec3d(1, 0, 0);
27 
28  // Record the transforms as 4x4 matrices (this should capture initial displacement/rotation of the jaws/shaft from controller)
29  m_shaftVisualTransform = m_shaft->getVisualGeometry()->getTransform();
30  m_upperJawVisualTransform = m_upperJaw->getVisualGeometry()->getTransform();
31  m_lowerJawVisualTransform = m_lowerJaw->getVisualGeometry()->getTransform();
32 
33  m_shaftCollidingTransform = m_shaft->getCollidingGeometry()->getTransform();
34  m_upperJawCollidingTransform = m_upperJaw->getCollidingGeometry()->getTransform();
35  m_lowerJawCollidingTransform = m_lowerJaw->getCollidingGeometry()->getTransform();
36 
37  m_pickGeomTransform = m_pickGeom->getTransform();
38 }
39 
40 void
41 LaparoscopicToolController::setDevice(std::shared_ptr<DeviceClient> device)
42 {
43  TrackingDeviceControl::setDevice(device);
44  device->setButtonsEnabled(true);
45 }
46 
47 void
49 {
50  if (!updateTrackingData(dt))
51  {
52  LOG(WARNING) << "warning: could not update tracking info.";
53  return;
54  }
55 
56  const Vec3d& controllerPosition = getPosition();
57  const Quatd& controllerOrientation = getOrientation();
58 
59  // Controller transform
60  m_controllerWorldTransform = mat4dTranslate(controllerPosition) * mat4dRotation(controllerOrientation);
61 
62  // Set shaft geometries
63  {
64  m_shaft->getVisualGeometry()->setTransform(m_controllerWorldTransform * m_shaftVisualTransform);
65  m_shaft->getCollidingGeometry()->setTransform(m_controllerWorldTransform * m_shaftCollidingTransform);
66  m_pickGeom->setTransform(m_controllerWorldTransform * m_pickGeomTransform);
67  }
68 
69  // Update jaw angles
70  if (m_deviceClient->getButton(0))
71  {
72  m_jawAngle += m_change * dt;
73  }
74  if (m_deviceClient->getButton(1))
75  {
76  m_jawAngle -= m_change * dt;
77  }
78 
79  // Clamp
80  m_jawAngle = std::max(std::min(m_jawAngle, m_maxJawAngle), 0.0);
81 
82  // Update transforms
83  m_upperJawLocalTransform = mat4dRotation(Rotd(m_jawAngle, m_jawRotationAxis));
84  m_lowerJawLocalTransform = mat4dRotation(Rotd(-m_jawAngle, m_jawRotationAxis));
85  {
86  const Mat4d upperWorldTransform = m_controllerWorldTransform * m_upperJawLocalTransform;
87  m_upperJaw->getVisualGeometry()->setTransform(upperWorldTransform * m_upperJawVisualTransform);
88  m_upperJaw->getCollidingGeometry()->setTransform(upperWorldTransform * m_upperJawCollidingTransform);
89  }
90  {
91  const Mat4d lowerWorldTransform = m_controllerWorldTransform * m_lowerJawLocalTransform;
92  m_lowerJaw->getVisualGeometry()->setTransform(lowerWorldTransform * m_upperJawVisualTransform);
93  m_lowerJaw->getCollidingGeometry()->setTransform(lowerWorldTransform * m_lowerJawCollidingTransform);
94  }
95  m_shaft->getVisualGeometry()->postModified();
96  m_lowerJaw->getVisualGeometry()->postModified();
97  m_upperJaw->getVisualGeometry()->postModified();
98 
99  // Check for transition closed/open
100  if (m_jawState == JawState::Opened && m_jawAngle <= 0.0)
101  {
102  m_jawState = JawState::Closed;
103  this->postEvent(Event(JawClosed()));
104  }
105  // When the jaw angle surpasses this degree it is considered open
106  const double openingDegree = 5.0;
107  if (m_jawState == JawState::Closed && m_jawAngle >= openingDegree * PI / 180.0)
108  {
109  m_jawState = JawState::Opened;
110  this->postEvent(Event(JawOpened()));
111  }
112 }
113 } // namespace imstk
std::shared_ptr< CollidingObject > m_upperJaw
Tool upper jaw.
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.
Compound Geometry.
double m_change
Amount of change in jaw angle per frame.
std::shared_ptr< CollidingObject > m_shaft
Tool shaft.
double m_maxJawAngle
Maximum angle of the jaws.
std::shared_ptr< CollidingObject > m_lowerJaw
Tool lower jaw.
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 update(const double &dt) override
Update controlled laparoscopic tool using latest tracking information.