iMSTK
Interactive Medical Simulation Toolkit
imstkTrackingDeviceControl.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 "imstkTrackingDeviceControl.h"
8 #include "imstkDeviceClient.h"
9 #include "imstkLogger.h"
10 #include "imstkMath.h"
11 
12 #include <cmath>
13 
14 namespace imstk
15 {
16 TrackingDeviceControl::TrackingDeviceControl(const std::string& name) :
17  DeviceControl(name),
18  m_translationOffset(Vec3d::Zero()),
19  m_rotationOffset(Quatd::Identity())
20 {
21 }
22 
23 bool
25 {
26  if (m_deviceClient == nullptr)
27  {
28  LOG(WARNING) << "warning: no controlling device set.";
29  return false;
30  }
31 
32  // Retrieve device info
33  const Vec3d prevPos = m_currentPos;
34  const Quatd prevOrientation = m_currentOrientation;
35 
36  m_currentPos = m_deviceClient->getPosition();
37  m_currentOrientation = m_deviceClient->getOrientation();
38  m_currentVelocity = m_deviceClient->getVelocity();
39  m_currentAngularVelocity = m_deviceClient->getAngularVelocity();
40 
41  // Apply inverse if needed
42  if (m_invertFlags & InvertFlag::transX)
43  {
44  m_currentPos[0] = -m_currentPos[0];
45  m_currentVelocity[0] = -m_currentVelocity[0];
46  }
47  if (m_invertFlags & InvertFlag::transY)
48  {
49  m_currentPos[1] = -m_currentPos[1];
50  m_currentVelocity[1] = -m_currentVelocity[1];
51  }
52  if (m_invertFlags & InvertFlag::transZ)
53  {
54  m_currentPos[2] = -m_currentPos[2];
55  m_currentVelocity[2] = -m_currentVelocity[2];
56  }
57  if (m_invertFlags & InvertFlag::rotX)
58  {
59  m_currentOrientation.y() = -m_currentOrientation.y();
60  m_currentOrientation.z() = -m_currentOrientation.z();
61  m_currentAngularVelocity[0] = -m_currentAngularVelocity[0];
62  }
63  if (m_invertFlags & InvertFlag::rotY)
64  {
65  m_currentOrientation.x() = -m_currentOrientation.x();
66  m_currentOrientation.z() = -m_currentOrientation.z();
67  m_currentAngularVelocity[1] = -m_currentAngularVelocity[1];
68  }
69  if (m_invertFlags & InvertFlag::rotZ)
70  {
71  m_currentOrientation.x() = -m_currentOrientation.x();
72  m_currentOrientation.y() = -m_currentOrientation.y();
73  m_currentAngularVelocity[2] = -m_currentAngularVelocity[2];
74  }
75 
76  // Apply Offsets
77  m_currentPos = m_rotationOffset * m_currentPos * m_scaling + m_translationOffset;
78  m_currentOrientation = m_effectorRotationOffset * m_rotationOffset * m_currentOrientation;
79 
80  // Apply scaling
81  m_currentVelocity = m_currentVelocity * m_scaling;
82 
83  // With simulation substeps this may produce 0 deltas, but its fine
84  // Another option is to divide velocity by number of substeps and then
85  // maintain it for N substeps
86  // Note: This velocity will not be as accurate as the one returned by the
87  // haptic device, since the haptic devices runs on a seperate thread at a
88  // higher rate.
90  {
91  m_currentDisplacement = (m_currentPos - prevPos);
92  m_currentVelocity = m_currentDisplacement / dt;
93  }
95  {
96  // Get axis of rotation in current configuration
97  Rotd currentR = Rotd(m_currentOrientation);
98 
99  // Arbitrary normalized basis
100  Vec3d basis = { 1.0, 0.0, 0.0 };
101 
102  // Vectors created by rotating basis using orientations
103  Vec3d vec1 = m_currentOrientation.normalized().toRotationMatrix() * basis;
104  Vec3d vec2 = prevOrientation.normalized().toRotationMatrix() * basis;
105 
106  // Angal between the two vectors after rotation, divided by timestep to get rate
107  auto angle = std::acos(std::min(1.0, std::max(-1.0, vec1.dot(vec2)))) / dt;
108  // Assume small change in rotation axis
109  m_currentAngularVelocity = (angle * currentR.axis());
110  }
111 
112  return true;
113 }
114 
115 const imstk::Vec3d&
117 {
118  return m_currentPos;
119 }
120 
121 void
122 TrackingDeviceControl::setPosition(const Vec3d& pos)
123 {
124  this->m_currentPos = pos;
125 }
126 
127 const imstk::Quatd&
129 {
130  return m_currentOrientation;
131 }
132 
133 void
134 TrackingDeviceControl::setOrientation(const Quatd& orientation)
135 {
136  this->m_currentOrientation = orientation;
137 }
138 
139 void
140 TrackingDeviceControl::setComputeVelocity(const bool computeVelocity)
141 {
142  m_computeVelocity = computeVelocity;
143 }
144 
145 bool
146 TrackingDeviceControl::getComputeVelocity() const
147 {
148  return m_computeVelocity;
149 }
150 
151 void
152 TrackingDeviceControl::setComputeAngularVelocity(const bool computeAngularVelocity)
153 {
154  m_computeAngularVelocity = computeAngularVelocity;
155 }
156 
157 bool
158 TrackingDeviceControl::getComputeAngularVelocity() const
159 {
161 }
162 
163 const imstk::Vec3d&
165 {
166  return m_currentAngularVelocity;
167 }
168 
169 void
170 TrackingDeviceControl::setAngularVelocity(const Vec3d& angularVelocity)
171 {
172  m_currentAngularVelocity = angularVelocity;
173 }
174 
175 const imstk::Vec3d&
177 {
178  return m_currentVelocity;
179 }
180 
181 void
182 TrackingDeviceControl::setVelocity(const Vec3d& velocity)
183 {
184  m_currentVelocity = velocity;
185 }
186 
187 double
189 {
190  return m_scaling;
191 }
192 
193 void
194 TrackingDeviceControl::setTranslationScaling(const double scaling)
195 {
196  m_scaling = scaling;
197 }
198 
199 const Vec3d&
201 {
202  return m_translationOffset;
203 }
204 
205 void
206 TrackingDeviceControl::setTranslationOffset(const Vec3d& t)
207 {
209 }
210 
211 const Quatd&
213 {
214  return m_rotationOffset;
215 }
216 
217 void
218 TrackingDeviceControl::setRotationOffset(const Quatd& r)
219 {
220  m_rotationOffset = r;
221 }
222 
223 const imstk::Quatd&
225 {
227 }
228 
229 void
230 TrackingDeviceControl::setEffectorRotationOffset(const Quatd& r)
231 {
233 }
234 
235 unsigned char
237 {
238  return m_invertFlags;
239 }
240 
241 void
242 TrackingDeviceControl::setInversionFlags(const unsigned char f)
243 {
244  m_invertFlags = f;
245 }
246 } // namespace imstk
Vec3d m_translationOffset
Translation concatenated to the device translation.
virtual bool updateTrackingData(const double dt)
Update tracking data.
Compound Geometry.
double m_scaling
Scaling factor for physical to virtual translations.
unsigned char m_invertFlags
Invert flags to be masked with DeviceTracker::InvertFlag.
const Vec3d & getAngularVelocity() const
Get/Set the angular velocity.
const Vec3d & getTranslationOffset() const
Get/Set the translation offset.
void setComputeAngularVelocity(const bool computeAngularVelocity)
Set/Get whether to compute the anular velocity from previous and current samples Useful if the device...
Quatd m_effectorRotationOffset
Rotation prefixed to the device rotation.
void setComputeVelocity(const bool computeVelocity)
Set/Get whether to compute the velocity from previous and current samples Useful if a device does not...
bool m_computeAngularVelocity
If true, will use current and previous rotations to produce angular velocity, if off, will ask device for angular velocity.
const Quatd & getOrientation() const
Set/Get the orientation of the tracker.
const Quatd & getRotationOffset()
Get/Set the rotation offset, this rotation is applied to the overall device coordinate system...
Quatd m_rotationOffset
Rotation concatenated to the device rotation.
const Vec3d & getPosition() const
Set/Get the position of the tracker.
const Quatd & getEffectorRotationOffset()
Get/Set the roation applied to the end effector, this can be used to register the device in virtual s...
bool m_computeVelocity
If true, will use current and previous positions to produce velocity, if off, will ask device for vel...
const Vec3d & getVelocity() const
Get/Set the linear velocity.
double getTranslationScaling() const
Get/Set the current scaling factor.
unsigned char getInversionFlags()
Get/Set the inversion flags, when set the corresponding axis coordinates or rotation angle will be ne...