iMSTK
Interactive Medical Simulation Toolkit
All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Pages
Docs/Devices.md
1 # Devices
2 
3 ## Overview
4 
5 Devices in iMSTK give live interactive input for iMSTK. In iMSTK devices only provide input data, they do no logic using this data. Controllers are instead used to implement the device inputs.
6 
7 Examples of devices are:
8 
9 - `KeyboardDeviceClient`
10  - Provides an interface for the keyboard. Including checks for keys up/down and events for press/release events.
11 - `MouseDeviceClient`
12  - Provides an interface for the mouse. Including checks for buttons up/down, getting mouse position, and recieving button press/release, scroll, and move events.
13 - `OpenVRDeviceClient`
14  - Provides an interface for VR headset and controllers. Including checks for buttons down/up/touched, getting the 3d position & orientation, and button press/release/touch/untouch events.
15 - `HapticDeviceClient`
16  - Provides an interface for haptic devices. Including checks for buttons up/down,getting the position & orientation, and button press/release events.
17 
18 Note: `KeyboardDeviceClient`, `MouseDeviceClient`, and `OpenVRDeviceClient` can only be provided via a Viewer as they are tied to the OS.
19 
20 HTC Vive Controller | Oculus Touch Controller
21 :-------------------------:|:-------------------------:
22 ![](media/VRController.png) | ![](media/VRController2.png)
23 
24 
25 3D Touch | Falcon
26 :-------------------------:|:-------------------------:
27 ![](media/TouchDevice.png) | ![](media/falcon.png)
28 
29 ## Keyboard and Mouse
30 
31 One can get a `KeyboardDeviceClient` and `MouseDeviceClient` from the `VTKViewer`:
32 
33 ```cpp
34 auto viewer = std::make_shared<VTKViewer>();
35 viewer->setActiveScene(...);
36 
37 std::shared_ptr<KeyboardDeviceClient> keyboardDevice = viewer->getKeyboardDevice();
38 std::shared_ptr<MouseDeviceClient> mouseDevice = viewer->getMouseDevice();
39 
40 auto simManager = std::make_shared<SimulationManager>();
41 simManager->addModule(viewer);
42 simManager->start();
43 ```
44 
45 Directly query the device with:
46 
47 ```cpp
48 if (keyboardDevice->getButton('o') == KEY_PRESS)
49 {
50  printf("Key is down\n");
51 }
52 ```
53 
54 Get callback events, only once, when the button is pressed.
55 
56 ```cpp
57 connect<KeyEvent>(keyboardDevice, &KeyboardDeviceClient::keyPress,
58 [](KeyEvent* e)
59 {
60  printf("%d key was pressed\n", e->m_key);
61 });
62 ```
63 Alternatively, connect directly to an function on an object.
64 
65 ```cpp
66 class MyObject : public EventObject
67 {
68 public:
69  void activate(KeyEvent* e) { }
70 };
71 auto myObject = std::make_shared<MyObject>();
72 connect<KeyEvent>(keyboardDevice, &KeyboardDeviceClient::keyPress, myObject, &MyObject::activate);
73 ```
74 
75 ## Virtual Reality Devices
76 
77 iMSTK supports OpenVR, when a `VTKOpenVRViewer` is used, a device `OpenVRDeviceClient` can be acquired for each controller or the headset itself.
78 
79 ```cpp
80 auto viewer = std::make_shared<VTKOpenVRViewer>();
81 viewer->setActiveScene(...);
82 std::shared_ptr<OpenVRDeviceClient> leftController = viewer->getOpenVRDeviceClient(OPENVR_LEFT_CONTROLLER);
83 std::shared_ptr<OpenVRDeviceClient> rightController = viewer->getOpenVRDeviceClient(OPENVR_RIGHT_CONTROLLER);
84 std::shared_ptr<OpenVRDeviceClient> headset = viewer->getOpenVRDeviceClient(OPENVR_HMD);
85 
86 auto simManager = std::make_shared<SimulationManager>();
87 simManager->addModule(viewer);
88 simManager->start();
89 ```
90 
91 Directly get the state or use events from the VR device. OpenVR controllers have buttons with press, release, touched, an untouched events.
92 
93 VR controllers are useful because they give you positions and orientations. These can be acquired like so:
94 
95 ```cpp
96 Vec3d position = leftController->getPosition();
97 Quatd orientation = leftController->getOrientation();
98 ```
99 
100 ## OpenHaptics Devices
101 
102 OpenHaptics can be used as a backend for devices. They can be used a lot like OpenVR controllers. They report position and orientation, they also have buttons. The same code above can be used to get position & orientation. Additionally they emit button events similar to all the other devices.
103 
104 Haptic devices also allow one to feel forces. A user may send a force to the device to be rendered. Haptics are run on another thread at a very fast. Ideally >1000hz when virtual coupling is used. But >500hz is also reasonable.
105 
106 The default avaiable haptic device can be acquired like so:
107 
108 ```cpp
109 std::shared_ptr<DeviceManager> hapticManager = DeviceManagerFactory::makeDeviceManager();
110 driver->addModule(hapticManager);
111 std::shared_ptr<DeviceClient> deviceClient = hapticManager->makeDeviceClient();
112 ```
113 
114 To run this `DeviceManager` would be added to the `SimulationManager`.
115 
116 ```cpp
117 auto simManager = std::make_shared<SimulationManager>();
118 simManager->addModule(hapticManager);
119 // typically you would add a VTKViewer and SceneManager here
120 simManager->start();
121 ```
122 
123 To apply force on a haptic device so they can feel feedback use:
124 
125 ```cpp
126 client->applyForce(Vec3d(0.0, 1.0, 0.0));
127 ```
128 
129 CAUTION: Large forces could cause haptic devices to move violently.
130 
131 ## Haply Devices
132 
133 The Haply Inverse3 haptic device is supported in iMSTK. If Haply Hardware API is built with it will be the default device and can be used just as the OpenHaptics device is. By default the Haply pen is searched for and used, if found. One can get a list of Haply port names:
134 
135 ```cpp
136 // Haply Inverse3
137 HaplyDeviceManager::getInverse3PortNames();
138 // Haply Pen
139 HaplyDeviceManager::getHandlePortNames();
140 ```
141 
142 ## VRPN Devices
143 
144 iMSTK supports the Tracker, Button and Analog device types of the VRPN library. It utilizes the normal VRPN server that will be in the installation directory when VRPN is enabled. The VRPNManager utilizes the VRPN client protocol to connect to the server and retrieve the data delivered by the VRPN. As VRPN uses TCP/IP for communication devices may be connected to a remote machine. With VRPN most of the device configuration is being done in the vrpn.cfg that is being used, ports, speeds, or world to virtual space transforms can be set up there. To use VRPN in iMSTK vrpn_server has to be started from the command line. When VRPN is enabled it will be installed in the iMSTK binary directory.
145 
146 ```cpp
147 auto server = std::make_shared<VRPNDeviceManager>("localhost", 38833);
148 auto client = vrpnManager->makeDeviceClient("Tracker0", VRPNTracker)
149 
150 auto manager = std::make_shared<SimulationManager>();
151 manager->addModule(server)
152 ```
153 
154 If a special device is needs there are multiple extensions points, VRPNDeviceClient can be derived from and data could be mapped there. There are some VRPN devices that map data, or a specific VRPN device client could be implemented by overriding the update() method in the client.
155 
156 ## DummyClient Devices
157 
158 DummyClient is a `DeviceClient` it can often be useful to supply to a control instead of a device client. It implements no API and just lets users set/get the position and orientation directly. For example, it can be used in Unity or Unreal VR controls. It's often used in examples to map mouse input too before supplying the DeviceClient to a control.