iMSTK
Interactive Medical Simulation Toolkit
Docs/Grasping.md
1 # Grasping
2 
3 Grasping constrains a physics simulated object through contact by another. The object doing grasping must be a rigid tool such as shown in the DynamicalModel's section. The object being grasping can be a deformable (such as a tissue) or a rigid (such as a needle or tool).
4 
5 <p align="center">
6  <img src="media/pbdThinTissueGrasp.gif" alt="Grasping thin triangle tissue"/>
7 </p>
8 
9 ```cpp
10 auto grasping = std::make_shared<PbdObjectGrasping>(objectThatGrasps, objectToGrasp);
11 scene->addSceneObject(grasping);
12 ```
13 
14 It is expected a user would link this up with a button, or some other trigger. Activating it with:
15 
16 ```cpp
17 // Vertex based grasping of objectToGrasp
18 grasping->beginVertexGrasp(capsuleGeometryAreaToGrasp);
19 // OR
20 // Grasp lines, triangles, or tetrahedrons
21 grasping->beginCellGrasp(capsuleGeometryAreaToGrasp);
22 ```
23 
24 To release the grasp:
25 
26 ```cpp
27 grasping->endGrasp();
28 ```
29 
30 ## Two-Way or One-Way Grasping
31 
32 iMSTK supports both two-way and one way grasping
33 
34 ### Two-Way
35 
36 With two-way grasping there must be two physics enabled PbdObjects. When the grasp occurs forces will be felt on both objects.
37 
38 As shown earlier this can be setup like so:
39 ```cpp
40 auto grasping = std::make_shared<PbdObjectGrasping>(objectThatGrasps, objectToGrasp);
41 scene->addSceneObject(grasping);
42 ```
43 
44 This can be used together with `PbdObjectController` to feel forces on objects in two-way.
45 
46 <p align="center">
47  <img src="media/pbdHapticGrasping.gif" alt="Grasping thin triangle tissue"/>
48 </p>
49 
50 ### One-Way
51 
52 With one-way grasping one can grasp a physics simulated PbdObject with a non-physics simulated one or even an object using a different `DynamicalModel`.
53 
54 Setup with:
55 ```cpp
56 auto grasping = std::make_shared<PbdObjectGrasping>(objectToGrasp);
57 scene->addSceneObject(grasping);
58 ```
59 
60 Perform the grasp with:
61 ```cpp
62 grasping->beginCellPick(myCapsuleGeometry);
63 ```
64 
65 In the instance of one-way the grasped particles will deform with the `myCapsuleGeometry` as it transforms.
66 
67 ## Mapping
68 
69 The grasping class supports mapping of geometries. One can supply it a `GeometryMap` to map back to another geometry. For example, if the user sets up a TetrahedralMesh with a SurfaceMesh mapped onto it. They can then supply that `GeometryMap` to the `PbdObjectGrasping`. This can be used to grasp only a specific portion of a simulated object. Or to grasp using differing topologies.
70 
71 ## Multi Point Grasping
72 
73 Two graspings may be setup on the same objects.
74 
75 ```cpp
76 auto grasping1 = std::make_shared<PbdObjectGrasping>(myPbdTool1, myPbdNeedle);
77 scene->addSceneObject(grasping1);
78 auto grasping2 = std::make_shared<PbdObjectGrasping>(myPbdTool2, myPbdNeedle);
79 scene->addSceneObject(grasping2);
80 ```
81 
82 Multiple graspings can occur on the same object (needle in this example). Works with two-way as well.
83 
84 ![type:video](./media/pbdRigidBodyGrasping.mp4)
85 
86 ## Grasp Tools in VR
87 
88 ![type:video](./media/vrGrasping.mp4)
89 
90 Grasping tools in VR is common use case. In these instances one can model a pair of hands with `Sphere` geometry, controlled by VR controllers using `PbdObjectController`.
91 
92 ```cpp
93 auto mySphere = std::make_shared<Sphere>(Vec3d(0.0, 0.0, 0.0), 0.2);
94 auto pbdHands = std::make_shared<PbdObject>();
95 pbdHands->setPhysicsGeometry(mySphere);
96 pbdHands->setDynamicalModel(myPbdModel);
97 pbdHands->setRigid(Vec3d(0.0, 0.0, 0.0), 1.0); // Position, Mass
98 
99 // Adds visuals
100 auto visuals = pbdHands->addComponent<VisualModel>();
101 visuals->setGeometry(mySphere);
102 
103 // Control the pbd hands with the VR device
104 auto controller = pbdHands->addComponent<PbdObjectController>();
105 controller->setDevice(myVrViewer->getDeviceClient(VR_CONTROLLER_LEFT));
106 controller->setControlledObject(pbdHands);
107 controller->setLinearKs();
108 controller->setAngularKs();
109 ```
110 
111 Then grasping can be setup between a rigid tool and hand.
112 
113 ```cpp
114 auto grasping = std::make_shared<PbdObjectGrasping>(pbdHands, myPbdTool);
115 scene->addSceneObject(grasping);
116 ```
117 
118 With two-way pbdHands and the controller should "feel" the forces from grasping the tool.
119 
120 ## Grasp with Dilated Geometry
121 
122 Often it is usefult to use collision and grasping. In these instances it's recommended to use a slightly dilated geometry to grasp.
123 
124 ```cpp
125 std::shared_ptr<Capsule> myDilatedCapsule = myCapsule->clone();
126 myDilatedCapsule->setRadius(myDilatedCapsule->getRadius() * 1.2); // 1.2x larger
127 grasping->beginCellGrasp(myDilatedCapsule);
128 ```