PlusLib  2.9.0
Software library for tracked ultrasound image acquisition, calibration, and processing.
vtkPlusSteamVRTracker.cxx
Go to the documentation of this file.
1 /*=Plus=header=begin======================================================
2 Program: Plus
3 Copyright (c) Laboratory for Percutaneous Surgery. All rights reserved.
4 See License.txt for details.
5 =========================================================Plus=header=end*/
6 
7 // Local includes
8 #include "PlusConfigure.h"
10 #include "vtkPlusDataSource.h"
11 
12 // VTK includes
13 #include <vtkMatrix4x4.h>
14 #include <vtkXMLDataElement.h>
15 #include <vtkMath.h>
16 #include <vtkSmartPointer.h>
17 
18 // OpenVR includes
19 #include <openvr.h>
20 
21 // STL includes
22 #include <sstream>
23 
24 //----------------------------------------------------------------------------
25 
27 
28 //----------------------------------------------------------------------------
29 void vtkPlusSteamVRTracker::PrintSelf(ostream& os, vtkIndent indent)
30 {
31  Superclass::PrintSelf(os, indent);
32 }
33 
34 //----------------------------------------------------------------------------
36  : vtkPlusDevice()
37  , HMDSource(nullptr)
38  , LeftControllerSource(nullptr)
39  , RightControllerSource(nullptr)
40  , VRContext(nullptr)
41  , SteamVRConnectionTimeout(10.0)
42 {
43  this->FrameNumber = 0;
44  this->StartThreadForInternalUpdates = true;
45 }
46 
47 //----------------------------------------------------------------------------
49 {
50  if (VRContext != nullptr)
51  {
52  delete VRContext;
53  VRContext = nullptr;
54  }
55 
56  if (HMDSource != nullptr)
57  {
58  HMDSource->Delete();
59  HMDSource = nullptr;
60  }
61  if (LeftControllerSource != nullptr)
62  {
63  LeftControllerSource->Delete();
64  LeftControllerSource = nullptr;
65  }
66  if (RightControllerSource != nullptr)
67  {
68  RightControllerSource->Delete();
69  RightControllerSource = nullptr;
70  }
71 }
72 
73 //----------------------------------------------------------------------------
75 {
76  LOG_TRACE("Searching for Tracking System:")
77 
78  if (vr::VR_IsHmdPresent())
79  {
80  LOG_TRACE("HMD found!");
81  return PLUS_SUCCESS;
82  }
83  else
84  {
85  LOG_TRACE("No HMD was found in the system.");
86  return PLUS_FAIL;
87  }
88 }
89 
90 //----------------------------------------------------------------------------
92 {
93  vr::HmdError err;
94  this->VRContext = vr::VR_Init(&err, vr::EVRApplicationType::VRApplication_Scene);
95 
96  if (this->VRContext == nullptr)
97  {
98  LOG_ERROR("Unable to initialize SteamVR system: " << vr::VR_GetVRInitErrorAsEnglishDescription(err));
99  return PLUS_FAIL;
100  }
101  else
102  {
103  LOG_DEBUG("SteamVR runtime successfully initialized");
104 
105  int baseStationsCount = 0;
106  for (uint32_t td = vr::k_unTrackedDeviceIndex_Hmd; td < vr::k_unMaxTrackedDeviceCount; td++)
107  {
108  if (this->VRContext->IsTrackedDeviceConnected(td))
109  {
110  if (this->VRContext->GetTrackedDeviceClass(td) == vr::ETrackedDeviceClass::TrackedDeviceClass_TrackingReference)
111  {
112  baseStationsCount++;
113  }
114  }
115  }
116 
117  // Check whether both base stations are found, not mandatory but just in case...
118  if (baseStationsCount < 2)
119  {
120  LOG_ERROR("There was a problem identifying the base stations, please check that they are powered on.");
121  return PLUS_FAIL;
122  }
123  }
124  return PLUS_SUCCESS;
125 }
126 
127 //----------------------------------------------------------------------------
129 {
130  LOG_TRACE("Shutting down SteamVR connection.");
131  vr::VR_Shutdown();
132 
133  return PLUS_SUCCESS;
134 }
135 
136 //----------------------------------------------------------------------------
138 {
139  vr::TrackedDevicePose_t trackedDevicePose[vr::k_unMaxTrackedDeviceCount];
140 
141  // Obtain tracking device poses
142  this->VRContext->GetDeviceToAbsoluteTrackingPose(vr::ETrackingUniverseOrigin::TrackingUniverseStanding, 0, trackedDevicePose, vr::k_unMaxTrackedDeviceCount);
143 
144  vtkNew<vtkMatrix4x4> matrix;
145  for (vr::TrackedDeviceIndex_t nDevice = 0; nDevice < vr::k_unMaxTrackedDeviceCount; nDevice++)
146  {
147  if ((trackedDevicePose[nDevice].bDeviceIsConnected) && (trackedDevicePose[nDevice].bPoseIsValid))
148  {
149  float v[3] = { trackedDevicePose[nDevice].mDeviceToAbsoluteTracking.m[0][3], trackedDevicePose[nDevice].mDeviceToAbsoluteTracking.m[1][3], trackedDevicePose[nDevice].mDeviceToAbsoluteTracking.m[2][3] };
150  float r1[3] = { trackedDevicePose[nDevice].mDeviceToAbsoluteTracking.m[0][0], trackedDevicePose[nDevice].mDeviceToAbsoluteTracking.m[0][1], trackedDevicePose[nDevice].mDeviceToAbsoluteTracking.m[0][2] };
151  float r2[3] = { trackedDevicePose[nDevice].mDeviceToAbsoluteTracking.m[1][0], trackedDevicePose[nDevice].mDeviceToAbsoluteTracking.m[1][1], trackedDevicePose[nDevice].mDeviceToAbsoluteTracking.m[1][2] };
152  float r3[3] = { trackedDevicePose[nDevice].mDeviceToAbsoluteTracking.m[2][0], trackedDevicePose[nDevice].mDeviceToAbsoluteTracking.m[2][1], trackedDevicePose[nDevice].mDeviceToAbsoluteTracking.m[2][2] };
153 
154  matrix->Identity();
155  matrix->Element[0][0] = r1[0];
156  matrix->Element[0][1] = r1[1];
157  matrix->Element[0][2] = r1[2];
158  matrix->Element[1][0] = r2[0];
159  matrix->Element[1][1] = r2[1];
160  matrix->Element[1][2] = r2[2];
161  matrix->Element[2][0] = r3[0];
162  matrix->Element[2][1] = r3[1];
163  matrix->Element[2][2] = r3[2];
164  matrix->Element[0][3] = v[0] * 1000;
165  matrix->Element[1][3] = v[1] * 1000;
166  matrix->Element[2][3] = v[2] * 1000;
167 
168  if (this->VRContext->GetTrackedDeviceClass(nDevice) == vr::TrackedDeviceClass_HMD && this->HMDSource != nullptr)
169  {
170  this->ToolTimeStampedUpdate(this->HMDSource->GetSourceId(), matrix, ToolStatus(TOOL_OK), this->FrameNumber, NULL, NULL);
171  }
172  if (this->VRContext->GetTrackedDeviceClass(nDevice) == vr::TrackedDeviceClass_Controller)
173  {
174  if (this->VRContext->GetControllerRoleForTrackedDeviceIndex(nDevice) == vr::TrackedControllerRole_LeftHand && this->LeftControllerSource != nullptr)
175  {
176  this->ToolTimeStampedUpdate(this->LeftControllerSource->GetSourceId(), matrix, ToolStatus(TOOL_OK), this->FrameNumber, NULL, NULL);
177  }
178  else if (this->VRContext->GetControllerRoleForTrackedDeviceIndex(nDevice) == vr::TrackedControllerRole_RightHand && this->RightControllerSource != nullptr)
179  {
180  this->ToolTimeStampedUpdate(this->RightControllerSource->GetSourceId(), matrix, ToolStatus(TOOL_OK), this->FrameNumber, NULL, NULL);
181  }
182  }
183  else if (this->VRContext->GetTrackedDeviceClass(nDevice) == vr::TrackedDeviceClass_GenericTracker)
184  {
185  vtkPlusDataSource* aSource(nullptr);
186  if (this->GetToolByPortName("GenericTracker", aSource) == PLUS_SUCCESS)
187  {
188  this->ToolTimeStampedUpdate(aSource->GetSourceId(), matrix, ToolStatus(TOOL_OK), this->FrameNumber, NULL, NULL);
189  }
190  }
191  }
192  }
193  this->FrameNumber++;
194  return PLUS_SUCCESS;
195 }
196 
197 //----------------------------------------------------------------------------
199 {
200  vtkPlusDataSource* aSource(nullptr);
201  if (this->GetToolByPortName("HMD", aSource) == PLUS_FAIL)
202  {
203  LOG_WARNING("Unable to locate tool with port name \"HMD\". Will not record HMD tracking for this session.");
204  }
205  else
206  {
207  this->HMDSource = aSource;
208  }
209 
210  if (this->GetToolByPortName("LeftController", aSource) == PLUS_FAIL)
211  {
212  LOG_WARNING("Unable to locate tool with port name \"LeftController\". Will not record left controller tracking for this session.");
213  }
214  else
215  {
216  this->LeftControllerSource = aSource;
217  }
218 
219  if (this->GetToolByPortName("RightController", aSource) == PLUS_FAIL)
220  {
221  LOG_WARNING("Unable to locate tool with port name \"RightController\". Will not record right controller tracking for this session.");
222  }
223  else
224  {
225  this->RightControllerSource = aSource;
226  }
227 
228  return PLUS_SUCCESS;
229 }
vtkPlusDataSource * HMDSource
virtual void PrintSelf(ostream &os, vtkIndent indent) VTK_OVERRIDE
Abstract interface for tracker and video devices.
Definition: vtkPlusDevice.h:60
void PrintSelf(ostream &os, vtkIndent indent)
virtual PlusStatus InternalDisconnect()
std::string GetSourceId() const
igsioStatus PlusStatus
Definition: PlusCommon.h:40
virtual PlusStatus ToolTimeStampedUpdate(const std::string &aToolSourceId, vtkMatrix4x4 *matrix, ToolStatus status, unsigned long frameNumber, double unfilteredtimestamp, const igsioFieldMapType *customFields=NULL)
vtkPlusDataSource * RightControllerSource
#define PLUS_FAIL
Definition: PlusCommon.h:43
virtual PlusStatus Probe()
vtkPlusDataSource * LeftControllerSource
unsigned long FrameNumber
#define PLUS_SUCCESS
Definition: PlusCommon.h:44
PlusStatus GetToolByPortName(const char *aPortName, vtkPlusDataSource *&aSource)
virtual PlusStatus NotifyConfigured()
virtual PlusStatus InternalUpdate()
bool StartThreadForInternalUpdates
virtual PlusStatus InternalConnect()
vtkStandardNewMacro(vtkPlusSteamVRTracker)
Position vectors of rods v
Definition: algo3.m:14
Interface to a 3D positioning tool, video source, or generalized data stream.