opensurgsim
MockObject.h
1 // This file is a part of the OpenSurgSim project.
2 // Copyright 2013, SimQuest Solutions Inc.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 
16 #ifndef SURGSIM_MATH_UNITTESTS_MOCKOBJECT_H
17 #define SURGSIM_MATH_UNITTESTS_MOCKOBJECT_H
18 
19 #include <Eigen/Core>
20 #include "SurgSim/Math/OdeEquation.h"
21 #include "SurgSim/Math/OdeSolver.h"
22 #include "SurgSim/Math/OdeState.h"
23 
24 namespace SurgSim
25 {
26 
27 namespace Math
28 {
29 
30 class MassPointState : public OdeState
31 {
32 public:
34  {
35  setNumDof(3, 1);
36  getPositions().setLinSpaced(1.0, 1.3);
37  getVelocities().setLinSpaced(0.4, -0.3);
38  }
39 };
40 
41 class MassPoint : public OdeEquation
42 {
43 public:
46  explicit MassPoint(double viscosity = 0.0) :
47  m_mass(0.456),
48  m_viscosity(viscosity),
49  m_gravity(0.0, -9.81, 0.0)
50  {
51  m_f.resize(3);
52  m_M.resize(3, 3);
53  m_D.resize(3, 3);
54  m_K.resize(3, 3);
55  this->m_initialState = std::make_shared<MassPointState>();
56  }
57 
58  void disableGravity()
59  {
60  m_gravity.setZero();
61  }
62 
63  Matrix applyCompliance(const OdeState& state, const Matrix& b) override
64  {
65  SURGSIM_ASSERT(m_odeSolver) << "Ode solver not initialized, it should have been initialized on wake-up";
66 
67  Math::Matrix bTemp = b;
68  for (auto condition : state.getBoundaryConditions())
69  {
70  Math::zeroRow(condition, &bTemp);
71  }
72  auto solution = m_odeSolver->getLinearSolver()->solve(bTemp);
73  for (auto condition : state.getBoundaryConditions())
74  {
75  Math::zeroRow(condition, &solution);
76  }
77  return solution;
78  }
79 
80  void setOdeSolver(std::shared_ptr<SurgSim::Math::OdeSolver> solver)
81  {
82  m_odeSolver = solver;
83  }
84 
86  std::shared_ptr<SurgSim::Math::OdeSolver> m_odeSolver;
87  double m_mass, m_viscosity;
88  Vector3d m_gravity;
89 
90 protected:
91  void computeF(const OdeState& state) override
92  {
93  m_f = m_mass * m_gravity - m_viscosity * state.getVelocities();
94  }
95 
96  void computeM(const OdeState& state) override
97  {
98  m_M.setIdentity();
99  m_M *= m_mass;
100  }
101 
102  void computeD(const OdeState& state) override
103  {
104  m_D.setIdentity();
105  m_D *= m_viscosity;
106  }
107 
108  void computeK(const OdeState& state) override
109  {
110  m_K.setZero();
111  }
112 
113  void computeFMDK(const OdeState& state) override
114  {
115  m_M.setIdentity();
116  m_M *= m_mass;
117  m_D.setIdentity();
118  m_D *= m_viscosity;
119  m_K.setZero();
120  m_f = m_mass * m_gravity - m_viscosity * state.getVelocities();
121  }
122 };
123 
124 
125 
129 {
130 public:
132  {
133  setNumDof(3, 3);
134  getPositions().segment<3>(3) = Vector3d(1.0, 0.0, 0.0);
135  getPositions().segment<3>(6) = Vector3d(2.0, 0.0, 0.0);
136  }
137 };
138 
139 // Model of 3 nodes connected by springs with the 1st node fixed (no mass, no damping, only deformations)
141 {
142 public:
145  m_gravityForce(9)
146  {
147  m_f.resize(9);
148  m_M.resize(9, 9);
149  m_D.resize(9, 9);
150  m_K.resize(9, 9);
151 
152  m_f.setZero();
153  m_K.setZero();
154  m_gravityForce.setZero();
155  m_gravityForce.segment<3>(3) = Vector3d(0.0, 0.01 * -9.81, 0.0);
156  m_gravityForce.segment<3>(6) = Vector3d(0.0, 0.01 * -9.81, 0.0);
157 
158  this->m_initialState = std::make_shared<MassPointsStateForStatic>();
159  }
160 
161  const Vector& getExternalForces() const
162  {
163  return m_gravityForce;
164  }
165 
166  Matrix applyCompliance(const OdeState& state, const Matrix& b) override
167  {
168  SURGSIM_ASSERT(m_odeSolver) << "Ode solver not initialized, it should have been initialized on wake-up";
169 
170  Math::Matrix bTemp = b;
171  for (auto condition : state.getBoundaryConditions())
172  {
173  Math::zeroRow(condition, &bTemp);
174  }
175  auto solution = m_odeSolver->getLinearSolver()->solve(bTemp);
176  for (auto condition : state.getBoundaryConditions())
177  {
178  Math::zeroRow(condition, &solution);
179  }
180  return solution;
181  }
182 
183  void setOdeSolver(std::shared_ptr<SurgSim::Math::OdeSolver> solver)
184  {
185  m_odeSolver = solver;
186  }
187 
188 protected:
189  void computeF(const OdeState& state) override
190  {
191  computeK(state);
192 
193  // Internal deformation forces
194  m_f = -m_K * (state.getPositions() - m_initialState->getPositions());
195 
196  // Gravity pulling on the free nodes
197  m_f += m_gravityForce;
198  }
199 
200  void computeM(const OdeState& state) override
201  {
202  m_M.setZero();
203  }
204 
205  void computeD(const OdeState& state) override
206  {
207  m_D.setZero();
208  }
209 
210  void computeK(const OdeState& state) override
211  {
212  // A fake but valid stiffness matrix (node 0 fixed)
213  // Desired matrix is:
214  //
215  // 1 0 0 0 0 0 0 0 0
216  // 0 1 0 0 0 0 0 0 0
217  // 0 0 1 0 0 0 0 0 0
218  // 0 0 0 10 2 2 2 2 2
219  // 0 0 0 2 10 2 2 2 2
220  // 0 0 0 2 2 10 2 2 2
221  // 0 0 0 2 2 2 10 2 2
222  // 0 0 0 2 2 2 2 10 2
223  // 0 0 0 2 2 2 2 2 10
224  //
225  // Generate it using sparse matrix notation.
226 
227  m_K.resize(9, 9);
228  typedef Eigen::Triplet<double> T;
229  std::vector<T> tripletList;
230  tripletList.reserve(39);
231 
232  // Upper 3x3 identity block
233  for (int counter = 0; counter < 3; ++counter)
234  {
235  tripletList.push_back(T(counter, counter, 1.0));
236  }
237 
238  for (int row = 3; row < 9; ++row)
239  {
240  // Diagonal is 8 more than the rest of the 6x6 block
241  tripletList.push_back(T(row, row, 8.0));
242 
243  // Now add in the 2's over the entire block
244  for (int col = 3; col < 9; ++col)
245  {
246  tripletList.push_back(T(row, col, 2.0));
247  }
248  }
249  m_K.setFromTriplets(tripletList.begin(), tripletList.end());
250  }
251 
252  void computeFMDK(const OdeState& state) override
253  {
254  computeF(state);
255  computeM(state);
256  computeD(state);
257  computeK(state);
258  }
259 
260 private:
262  std::shared_ptr<SurgSim::Math::OdeSolver> m_odeSolver;
263  Vector m_gravityForce;
264 };
265 
268 {
269 public:
272  {
273  m_f.resize(3);
274  m_M.resize(3, 3);
275  m_D.resize(3, 3);
276  m_K.resize(3, 3);
277  this->m_initialState = std::make_shared<MassPointState>();
278  }
279 
280  Matrix applyCompliance(const OdeState& state, const Matrix& b) override
281  {
282  SURGSIM_ASSERT(m_odeSolver) << "Ode solver not initialized, it should have been initialized on wake-up";
283 
284  Math::Matrix bTemp = b;
285  for (auto condition : state.getBoundaryConditions())
286  {
287  Math::zeroRow(condition, &bTemp);
288  }
289  auto solution = m_odeSolver->getLinearSolver()->solve(bTemp);
290  for (auto condition : state.getBoundaryConditions())
291  {
292  Math::zeroRow(condition, &solution);
293  }
294  return solution;
295  }
296 
297  void setOdeSolver(std::shared_ptr<SurgSim::Math::OdeSolver> solver)
298  {
299  m_odeSolver = solver;
300  }
301 
302 protected:
303  void computeF(const OdeState& state) override
304  {
305  double v2 = state.getVelocities().dot(state.getVelocities());
306  m_f = v2 * state.getPositions();
307  }
308 
309  void computeM(const OdeState& state) override
310  {
311  m_M.setIdentity();
312  }
313 
314  void computeD(const OdeState& state) override
315  {
316  m_D = 2.0 * state.getPositions() * state.getVelocities().transpose().sparseView();
317  }
318 
319  void computeK(const OdeState& state) override
320  {
321  m_K.resize(static_cast<Eigen::Index>(state.getNumDof()), static_cast<Eigen::Index>(state.getNumDof()));
322  m_K.setIdentity();
323  m_K *= state.getVelocities().squaredNorm();
324  }
325 
326  void computeFMDK(const OdeState& state) override
327  {
328  computeF(state);
329  computeM(state);
330  computeD(state);
331  computeK(state);
332  }
333 
334 private:
336  std::shared_ptr<SurgSim::Math::OdeSolver> m_odeSolver;
337 };
338 
339 }; // Math
340 
341 }; // SurgSim
342 
343 #endif // SURGSIM_MATH_UNITTESTS_MOCKOBJECT_H
Definition: MockObject.h:41
MassPointsForStatic()
Constructor.
Definition: MockObject.h:144
Wraps glewInit() to separate the glew opengl definitions from the osg opengl definitions only imgui n...
Definition: AddRandomSphereBehavior.cpp:36
void computeF(const OdeState &state) override
Evaluation of the RHS function for a given state.
Definition: MockObject.h:189
SurgSim::Math::Vector & getVelocities()
Retrieves all degrees of freedom&#39;s velocity (non-const version)
Definition: OdeState.cpp:100
void computeFMDK(const OdeState &state) override
Evaluation of , , and .
Definition: MockObject.h:326
void computeM(const OdeState &state) override
Evaluation of the LHS matrix for a given state.
Definition: MockObject.h:200
void computeFMDK(const OdeState &state) override
Evaluation of , , and .
Definition: MockObject.h:113
#define SURGSIM_ASSERT(condition)
Assert that condition is true.
Definition: Assert.h:77
Ode equation of 2nd order of the form with for initial conditions and a set of boundary conditions...
Definition: OdeEquation.h:54
Eigen::Matrix< double, 3, 1 > Vector3d
A 3D vector of doubles.
Definition: Vector.h:57
The state of an ode of 2nd order of the form with boundary conditions.
Definition: OdeState.h:38
void computeM(const OdeState &state) override
Evaluation of the LHS matrix for a given state.
Definition: MockObject.h:96
Definition: MockObject.h:30
void computeD(const OdeState &state) override
Evaluation of for a given state.
Definition: MockObject.h:205
Definition: MockObject.h:140
OdeComplexNonLinear()
Constructor.
Definition: MockObject.h:271
void computeK(const OdeState &state) override
Evaluation of for a given state.
Definition: MockObject.h:210
void computeF(const OdeState &state) override
Evaluation of the RHS function for a given state.
Definition: MockObject.h:303
size_t getNumDof() const
Retrieves the number of degrees of freedom.
Definition: OdeState.cpp:70
Eigen::Matrix< double, Eigen::Dynamic, 1 > Vector
A dynamic size column vector.
Definition: Vector.h:68
void computeF(const OdeState &state) override
Evaluation of the RHS function for a given state.
Definition: MockObject.h:91
void computeK(const OdeState &state) override
Evaluation of for a given state.
Definition: MockObject.h:108
State class for static resolution It contains 3 nodes with 3 dofs each, with positions (0 0 0) (1 0 0...
Definition: MockObject.h:128
Matrix applyCompliance(const OdeState &state, const Matrix &b) override
Calculate the product where is the compliance matrix with boundary conditions applied.
Definition: MockObject.h:63
void computeM(const OdeState &state) override
Evaluation of the LHS matrix for a given state.
Definition: MockObject.h:309
const std::vector< size_t > & getBoundaryConditions() const
Retrieves all boundary conditions.
Definition: OdeState.cpp:149
std::shared_ptr< SurgSim::Math::OdeSolver > m_odeSolver
Ode solver (its type depends on the numerical integration scheme)
Definition: MockObject.h:86
MassPoint(double viscosity=0.0)
Constructor.
Definition: MockObject.h:46
Class for the complex non-linear ODE a = x.v^2.
Definition: MockObject.h:267
virtual void setNumDof(size_t numDofPerNode, size_t numNodes)
Allocates the state for a given number of degrees of freedom.
Definition: OdeState.cpp:55
OdeState()
Default constructor.
Definition: OdeState.cpp:27
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > Matrix
A dynamic size matrix.
Definition: Matrix.h:65
Matrix applyCompliance(const OdeState &state, const Matrix &b) override
Calculate the product where is the compliance matrix with boundary conditions applied.
Definition: MockObject.h:280
SurgSim::Math::Vector & getPositions()
Retrieves all degrees of freedom&#39;s position (non-const version)
Definition: OdeState.cpp:85
void computeD(const OdeState &state) override
Evaluation of for a given state.
Definition: MockObject.h:102
Matrix applyCompliance(const OdeState &state, const Matrix &b) override
Calculate the product where is the compliance matrix with boundary conditions applied.
Definition: MockObject.h:166
void computeD(const OdeState &state) override
Evaluation of for a given state.
Definition: MockObject.h:314
void computeK(const OdeState &state) override
Evaluation of for a given state.
Definition: MockObject.h:319
void computeFMDK(const OdeState &state) override
Evaluation of , , and .
Definition: MockObject.h:252