iMSTK
Interactive Medical Simulation Toolkit
imstkPbdObjectGrasping.h
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 #pragma once
8 
9 #include "imstkCollisionInteraction.h"
10 #include "imstkMacros.h"
11 #include "imstkMath.h"
12 #include "imstkPbdConstraint.h"
13 
14 #include <unordered_map>
15 
16 namespace imstk
17 {
18 class AnalyticalGeometry;
19 class PbdObject;
20 class PickingAlgorithm;
21 class PointwiseMap;
22 
33 {
34 public:
35  enum class GraspMode
36  {
37  Vertex, // Grab a vertex (most performant)
38  Cell, // Grab an entire cell/s
39  RayPoint, // Grab a point on the nearest cell along the ray
40  RayCell // Grab a cell along the ray
41  };
42 
49  PbdObjectGrasping(std::shared_ptr<PbdObject> graspedObject,
50  std::shared_ptr<PbdObject> grasperObject = nullptr);
51  ~PbdObjectGrasping() override = default;
52 
53  IMSTK_TYPE_NAME(PbdObjectGrasping)
54 
55 
56  void setStiffness(const double stiffness) { m_stiffness = stiffness; }
60  double getStiffness() const { return m_stiffness; }
62 
66  void setCompliance(const double compliance) { m_compliance = compliance; }
67  double getCompliance() const { return m_compliance; }
69 
74  void beginVertexGrasp(std::shared_ptr<AnalyticalGeometry> geometry);
75 
82  void beginCellGrasp(std::shared_ptr<AnalyticalGeometry> geometry, std::string cdType = "");
83 
90  void beginRayPointGrasp(std::shared_ptr<AnalyticalGeometry> geometry,
91  const Vec3d& rayStart, const Vec3d& rayDir, const double maxDist = -1.0);
92 
99  void beginRayCellGrasp(std::shared_ptr<AnalyticalGeometry> geometry,
100  const Vec3d& rayStart, const Vec3d& rayDir, const double maxDist = -1.0);
101 
106  void regrasp()
107  {
108  m_regrasp = m_isGrasping;
109  }
110 
114  void endGrasp();
115 
119  void addPickConstraints();
120 
124  void removePickConstraints();
125 
131  virtual void addPointToPointConstraint(
132  const std::vector<PbdParticleId>& ptsA,
133  const std::vector<double>& weightsA,
134  const std::vector<PbdParticleId>& ptsB,
135  const std::vector<double>& weightsB,
136  const double stiffnessA, const double stiffnessB);
137 
142  virtual void addBodyToBodyConstraint(
143  const PbdParticleId& graspedBodyId,
144  const PbdParticleId& grasperBodyId,
145  const Vec3d& pointOnBodies,
146  const double compliance);
147 
152  virtual void addPointToBodyConstraint(
153  const PbdParticleId& graspedParticleId,
154  const PbdParticleId& grasperBodyId,
155  const Vec3d& pointOnBody,
156  const double compliance);
157 
161  void setPickingAlgorithm(std::shared_ptr<PickingAlgorithm> pickMethod) { m_pickMethod = pickMethod; }
162  std::shared_ptr<PickingAlgorithm> getPickingAlgorithm() const { return m_pickMethod; }
164 
169  void setGeometryToPick(std::shared_ptr<Geometry> geomToPick, std::shared_ptr<PointwiseMap> map)
170  {
171  m_geomToPick = geomToPick;
172  m_geometryToPickMap = map;
173  }
174 
175  std::shared_ptr<TaskNode> getPickingNode() const { return m_pickingNode; }
176 
177  void initGraphEdges(std::shared_ptr<TaskNode> source, std::shared_ptr<TaskNode> sink) override;
178 
182  bool hasConstraints() const;
183 
187  bool getGraspState() const { return m_isGrasping; }
188 
189 protected:
193  virtual void updatePicking();
194 
198  void updateConstraints();
199 
200  std::shared_ptr<TaskNode> m_pickingNode = nullptr;
201 
202  std::shared_ptr<Geometry> m_geomToPick = nullptr;
203  std::shared_ptr<PointwiseMap> m_geometryToPickMap = nullptr;
204 
205  std::shared_ptr<PbdObject> m_objectToGrasp = nullptr;
206  std::shared_ptr<PbdObject> m_grasperObject = nullptr; // Optional
207  std::shared_ptr<AnalyticalGeometry> m_graspGeom = nullptr;
208 
209  std::shared_ptr<PickingAlgorithm> m_pickMethod = nullptr;
210  GraspMode m_graspMode = GraspMode::Cell;
211 
212  bool m_isGrasping = false;
213  bool m_regrasp = false;
214  bool m_isPrevGrasping = false;
215 
218  double m_stiffness = 0.4; // For deformables
219  double m_compliance = 0.0001; // For rigid bodies (inverse of stiffness)
220 
222  std::vector<std::tuple<PbdParticleId, Vec3d>> m_constraintPts;
223  std::vector<std::shared_ptr<PbdConstraint>> m_constraints;
224 
225 private:
226  std::vector<PbdConstraint*> m_collisionConstraints;
227 };
228 } // namespace imstk
PbdObjectGrasping(std::shared_ptr< PbdObject > graspedObject, std::shared_ptr< PbdObject > grasperObject=nullptr)
Construct PbdObjectGrasping with a object to grasp and and optionally an object that does the graspin...
This class defines grasping of a PbdObject via different picking methods. Where grasping is define as...
void endGrasp()
End a grasp (picking will end on next update)
virtual void addPointToBodyConstraint(const PbdParticleId &graspedParticleId, const PbdParticleId &grasperBodyId, const Vec3d &pointOnBody, const double compliance)
Add a 0 distance constraint between a deformable point and a point on a body.
std::pair< int, int > PbdParticleId
Index pair that refers to a particle in a PbdState. Index 0 is the body id, Index 1 is the particle i...
virtual void addPointToPointConstraint(const std::vector< PbdParticleId > &ptsA, const std::vector< double > &weightsA, const std::vector< PbdParticleId > &ptsB, const std::vector< double > &weightsB, const double stiffnessA, const double stiffnessB)
Add constraint between a point on each element given via barycentric coordinates pt position = weight...
Compound Geometry.
bool m_regrasp
Add grasped points to the current grasp.
void beginRayCellGrasp(std::shared_ptr< AnalyticalGeometry > geometry, const Vec3d &rayStart, const Vec3d &rayDir, const double maxDist=-1.0)
Begin a ray point grasp (picking will begin on the next update)
std::vector< std::shared_ptr< PbdConstraint > > m_constraints
List of PBD constraints.
bool hasConstraints() const
Returns if any grasp constraints are present.
bool getGraspState() const
Returns true if currently grasping, else false.
void setCompliance(const double compliance)
Set/Get the compliance.
void setGeometryToPick(std::shared_ptr< Geometry > geomToPick, std::shared_ptr< PointwiseMap > map)
Set a different geometry to pick with and a mapping back to the physics geometry to select the correc...
void beginCellGrasp(std::shared_ptr< AnalyticalGeometry > geometry, std::string cdType="")
Begin a cell grasp (picking will begin on the next update) Also works for rigid on rigid...
void beginRayPointGrasp(std::shared_ptr< AnalyticalGeometry > geometry, const Vec3d &rayStart, const Vec3d &rayDir, const double maxDist=-1.0)
Begin a ray point grasp (picking will begin on the next update)
Base class for all scene objects. A scene object can optionally be visible and collide with other sce...
void updateConstraints()
Update the constraints used for picking.
void removePickConstraints()
Remove the constraints for picking.
void addPickConstraints()
Compute/generate the constraints for picking.
void setPickingAlgorithm(std::shared_ptr< PickingAlgorithm > pickMethod)
Get/Set the method use for picking, default is CellPicker.
void setStiffness(const double stiffness)
Set/Get the stiffness, 0-1 value that alters the step size in the solver.
virtual void addBodyToBodyConstraint(const PbdParticleId &graspedBodyId, const PbdParticleId &grasperBodyId, const Vec3d &pointOnBodies, const double compliance)
Add 0 distance constraint between two points defined on two separate bodies.
void initGraphEdges()
Initializes the edges of the SceneObject&#39;s computational graph.
virtual void updatePicking()
Update picking state, this should move grasp points.
void beginVertexGrasp(std::shared_ptr< AnalyticalGeometry > geometry)
Begin a vertex grasp (picking will begin on the next update)
void regrasp()
if you already started a grasp, recalculates grasping points As the currently grasped points are alre...
std::vector< std::tuple< PbdParticleId, Vec3d > > m_constraintPts
Vec of virtual particle grasp point ids, and local positions when grasped.