iMSTK
Interactive Medical Simulation Toolkit
Docs/Controllers.md
1 # Controllers
2 
3 Controllers take device input and do something with it. A variety of predefined controls exist in iMSTK as well as some base classes for users to extend their own.
4 
5 ## Virtual Coupling
6 
7 A common iMSTK control is the `PbdObjectController`, used to couple a tool to a 3d tracking device.
8 
9 ```cpp
10 auto controller = myPbdObject->addComponent<PbdObjectController>();
11 controller->setControlledObject(pbdToolObj);
12 controller->setLinearKs(20000.0);
13 controller->setAngularKs(8000000.0);
14 controller->setUseCritDamping(true);
15 controller->setForceScaling(0.05);
16 controller->setSmoothingKernelSize(15);
17 controller->setUseForceSmoothening(true);
18 ```
19 
20 This class applies virtual coupling. Virtual coupling takes a physical and virtual position and couples them with a linear and angular spring.
21 
22 <p align="center">
23  <img src="media/VirtualCoupling.png" alt="Virtual coupling diagram" width="800"/>
24 </p>
25 
26 The spring is kept very tight. But loosening can be used. With a spring when a virtual body contacts a plane extremely large forces are not produced to stop it. Instead a spring is used and the force gradually increases from zero. This creates the ideal haptic experience. The spring used also applies a damper. That damper can be overriden but is automatically determined with critical damping.
27 
28 ```cpp
29 kd = 2.0 * sqrt(mass * ks);
30 ```
31 
32 In an ideal system (one that isn't discretized) this represents a spring that would only cross zero once.
33 
34 ### Ghost Rendering
35 
36 In the below gif one can see the physical tool with a transparent rendering, and the opaque with the virtual tool.
37 
38 <p align="center">
39  <img src="media/rbd1.gif" alt="Virtual coupling in action" width="800"/>
40 </p>
41 
42 To quickly do this in iMSTK one can add a `ObjectControllerGhost` to an entity and provide it the controller. Fade in can be set to fade opacity with a growing force.
43 
44 ```cpp
45 // Add extra component to tool for the ghost
46 auto controllerGhost = lapTool->addComponent<ObjectControllerGhost>();
47 controllerGhost->setUseForceFade(true);
48 controllerGhost->setController(controller);
49 ```
50 
51 ### Force Text Rendering
52 
53 It can often be useful to see the forces experienced by the user. This can be done easily by adding a `ControllerForceText` component.
54 
55 ```cpp
56 auto controllerForceTxt = lapTool->addComponent<ControllerForceText>();
57 controllerForceTxt->setController(controller);
58 ```
59 
60 ## Control Abstract Classes
61 
62 Provided in iMSTK are `MouseControl`, `KeyboardControl`, & `TrackingDeviceControl`. These are abstract base classes inteded for users to subclass and implement their own control via overrides.
63 
64 ```cpp
65 class CustomMouseControl : public MouseControl
66 {
67 public:
68  CustomMouseControl(const std::string& name = "CustomMouseControl") : MouseControl(name) { }
69 
70 protected:
71  void OnButtonPress(const int key) override { }
72  void OnButtonRelease(const int key) override { }
73  void OnScroll(const double dx) override { }
74  void OnMouseMove(const Vec2d pos) override { }
75 };
76 
77 void main()
78 {
79  ...
80  // In main we could set it up like so:
81  auto control = mySceneObject->addComponent<CustomMouseControl>();
82  control->setDevice(viewer->getMouseDevice());
83  ...
84 }
85 ```
86 
87 While subclassing is preferred. C++ lambdas may also be used for fast prototyping. Not recommended at scale:
88 ```cpp
89 void main()
90 {
91  ...
92  connect<KeyEvent>(viewer->getKeyboardDevice(), &KeyboardDeviceClient::keyPress,
93  [&](KeyEvent* e)
94  {
95  if (e->m_key == '1')
96  {
97  }
98  });
99  ...
100 }
101 ```