iMSTK
Interactive Medical Simulation Toolkit
imstkRigidBodyModel2.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 "imstkDynamicalModel.h"
10 #include "imstkRigidBodyState2.h"
11 
12 #include <list>
13 #include <unordered_map>
14 
15 namespace imstk
16 {
17 template<typename ScalarType>
19 class RbdConstraint;
20 struct RigidBody;
21 
23 {
24  double m_dt = 0.001;
25  Vec3d m_gravity = Vec3d(0.0, -9.8, 0.0);
26  unsigned int m_maxNumIterations = 10;
27  double m_velocityDamping = 1.0;
28  double m_angularVelocityDamping = 1.0;
29  double m_epsilon = 1e-4;
30  int m_maxNumConstraints = -1;
31 };
32 
44 class RigidBodyModel2 : public DynamicalModel<RigidBodyState2>
45 {
46 public:
47  using StorageIndex = Eigen::SparseMatrix<double>::StorageIndex;
48 
50  ~RigidBodyModel2() override = default;
51 
55  virtual void setTimeStep(const double timeStep) override { m_config->m_dt = timeStep; }
56 
60  virtual double getTimeStep() const override { return m_config->m_dt; }
61 
62  std::shared_ptr<RigidBodyModel2Config> getConfig() const { return m_config; }
63  const std::list<std::shared_ptr<RbdConstraint>>& getConstraints() const { return m_constraints; }
64  std::shared_ptr<ProjectedGaussSeidelSolver<double>> getSolver() const { return m_pgsSolver; }
65 
70  std::shared_ptr<RigidBody> addRigidBody();
71 
75  void addConstraint(std::shared_ptr<RbdConstraint> constraint) { m_constraints.push_back(constraint); }
76 
80  void removeRigidBody(std::shared_ptr<RigidBody> body);
81 
85  bool initialize() override;
86 
92  void updateMass();
93 
97  void configure(std::shared_ptr<RigidBodyModel2Config> config);
98 
102  void computeTentativeVelocities();
103 
107  void solveConstraints();
108 
112  void integrate();
113 
114  std::shared_ptr<TaskNode> getComputeTentativeVelocitiesNode() const { return m_computeTentativeVelocities; }
115  std::shared_ptr<TaskNode> getSolveNode() const { return m_solveNode; }
116  std::shared_ptr<TaskNode> getIntegrateNode() const { return m_integrateNode; }
117 
118 protected:
122  void initGraphEdges(std::shared_ptr<TaskNode> source, std::shared_ptr<TaskNode> sink) override;
123 
124  std::shared_ptr<RigidBodyModel2Config> m_config;
125 
126  std::shared_ptr<TaskNode> m_computeTentativeVelocities;
127  std::shared_ptr<TaskNode> m_solveNode;
128  std::shared_ptr<TaskNode> m_integrateNode;
129 
130  std::shared_ptr<ProjectedGaussSeidelSolver<double>> m_pgsSolver;
131  Eigen::SparseMatrix<double> m_Minv;
132  std::list<std::shared_ptr<RbdConstraint>> m_constraints;
133  std::vector<std::shared_ptr<RigidBody>> m_bodies;
134  std::unordered_map<RigidBody*, StorageIndex> m_locations;
135  bool m_modified = true;
136  size_t m_maxBodiesParallel = 10; // After 10 bodies, parallel for's are used
137 
138  Eigen::VectorXd F; // Reaction forces
139 };
140 } // namespace imstk
Abstract class for rigid body constraints. A RbdConstraint should mainly provide a constraint jacobia...
Solves a linear system using the projected gauss seidel method. Only good for diagonally dominant sys...
Compound Geometry.
virtual double getTimeStep() const override
Returns the time step size.
virtual void setTimeStep(const double timeStep) override
Set the time step size.
This class implements a constraint based rigid body linear system with pgs solver.
void addConstraint(std::shared_ptr< RbdConstraint > constraint)
Adds a constraint to be solved.
Serves as a handle to the body.
Base class for mathematical model of the physics governing the dynamic object.