opensurgsim
MockObjects.h
1 // This file is a part of the OpenSurgSim project.
2 // Copyright 2013-2016, 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_PHYSICS_UNITTESTS_MOCKOBJECTS_H
17 #define SURGSIM_PHYSICS_UNITTESTS_MOCKOBJECTS_H
18 
19 #include "SurgSim/Collision/Representation.h"
20 #include "SurgSim/Framework/ObjectFactory.h"
21 #include "SurgSim/Framework/Macros.h"
22 #include "SurgSim/Math/Matrix.h"
23 #include "SurgSim/Math/OdeSolver.h"
24 #include "SurgSim/Math/OdeState.h"
26 #include "SurgSim/Math/Vector.h"
27 #include "SurgSim/Physics/Constraint.h"
28 #include "SurgSim/Physics/ConstraintImplementation.h"
29 #include "SurgSim/Physics/Computation.h"
31 #include "SurgSim/Physics/Fem1DRepresentation.h"
32 #include "SurgSim/Physics/Fem2DRepresentation.h"
33 #include "SurgSim/Physics/Fem3DCorotationalTetrahedronRepresentation.h"
34 #include "SurgSim/Physics/Fem3DRepresentation.h"
35 #include "SurgSim/Physics/FemElement.h"
36 #include "SurgSim/Physics/FemPlyReaderDelegate.h"
37 #include "SurgSim/Physics/FemRepresentation.h"
38 #include "SurgSim/Physics/FixedRepresentation.h"
39 #include "SurgSim/Physics/LinearSpring.h"
40 #include "SurgSim/Physics/Localization.h"
41 #include "SurgSim/Physics/Mass.h"
42 #include "SurgSim/Physics/MassSpringLocalization.h"
43 #include "SurgSim/Physics/MassSpringRepresentation.h"
44 #include "SurgSim/Physics/Representation.h"
45 #include "SurgSim/Physics/RigidRepresentation.h"
46 #include "SurgSim/Physics/VirtualToolCoupler.h"
47 
48 namespace SurgSim
49 {
50 namespace Physics
51 {
52 
60 
62 {
63 protected:
64  int m_preUpdateCount;
65  int m_updateCount;
66  int m_postUpdateCount;
67 
68 public:
69  explicit MockRepresentation(const std::string& name = "MockRepresention");
70 
71  virtual ~MockRepresentation();
72 
73  SURGSIM_CLASSNAME(SurgSim::Physics::MockRepresentation);
74 
77  void beforeUpdate(double dt) override;
78 
81  void update(double dt) override;
82 
85  void afterUpdate(double dt) override;
86 
87  int getPreUpdateCount() const;
88 
89  int getUpdateCount() const;
90 
91  int getPostUpdateCount() const;
92 
93  std::shared_ptr<Localization> createLocalization(const SurgSim::DataStructures::Location& location) override;
94 };
95 
97 {
98 public:
100 
101  // Non constant access to the states
102  RigidState& getInitialState();
103  RigidState& getCurrentState();
104  RigidState& getPreviousState();
105 };
106 
108 {
109 public:
111 
112  // Non constant access to the states
113  RigidState& getInitialState();
114  RigidState& getCurrentState();
115  RigidState& getPreviousState();
116 };
117 
119 {
120 public:
121  MockDeformableLocalization(): m_nodeID(0)
122  {
123  }
124 
125  explicit MockDeformableLocalization(std::shared_ptr<Representation> representation) : Localization(), m_nodeID(0)
126  {
127  setRepresentation(representation);
128  }
129 
130  virtual ~MockDeformableLocalization(){}
131 
132  void setLocalNode(size_t nodeID)
133  {
134  m_nodeID = nodeID;
135  }
136 
137  const size_t& getLocalNode() const
138  {
139  return m_nodeID;
140  }
141 
142  bool isValidRepresentation(std::shared_ptr<Representation> representation) override
143  {
144  std::shared_ptr<DeformableRepresentation> defRepresentation =
145  std::dynamic_pointer_cast<DeformableRepresentation>(representation);
146 
147  // Allows to reset the representation to nullptr ...
148  return (defRepresentation != nullptr || representation == nullptr);
149  }
150 
151 private:
152  SurgSim::Math::Vector3d doCalculatePosition(double time) const override
153  {
154  std::shared_ptr<DeformableRepresentation> defRepresentation =
155  std::static_pointer_cast<DeformableRepresentation>(getRepresentation());
156 
157  SURGSIM_ASSERT(defRepresentation != nullptr) << "Deformable Representation is null, it was probably not" <<
158  " initialized";
159  SURGSIM_ASSERT((0.0 <= time) && (time <= 1.0)) << "Time must be between 0.0 and 1.0 inclusive";
160 
161  const SurgSim::Math::Vector3d& currentPoint = defRepresentation->getCurrentState()->getPosition(m_nodeID);
162  const SurgSim::Math::Vector3d& previousPoint = defRepresentation->getPreviousState()->getPosition(m_nodeID);
163 
164  return SurgSim::Math::interpolate(previousPoint, currentPoint, time);
165  }
166 
167  SurgSim::Math::Vector3d doCalculateVelocity(double time) const override
168  {
169  std::shared_ptr<DeformableRepresentation> defRepresentation =
170  std::static_pointer_cast<DeformableRepresentation>(getRepresentation());
171 
172  SURGSIM_ASSERT(defRepresentation != nullptr) << "Deformable Representation is null, it was probably not" <<
173  " initialized";
174  SURGSIM_ASSERT((0.0 <= time) && (time <= 1.0)) << "Time must be between 0.0 and 1.0 inclusive";
175 
176  const SurgSim::Math::Vector3d& currentVelocity = defRepresentation->getCurrentState()->getVelocity(m_nodeID);
177  const SurgSim::Math::Vector3d& previousVelocity = defRepresentation->getPreviousState()->getVelocity(m_nodeID);
178 
179  return SurgSim::Math::interpolate(previousVelocity, currentVelocity, time);
180  }
181 
182 
183  std::shared_ptr<Localization> doCopy() const override
184  {
185  auto localization = std::make_shared<MockDeformableLocalization>(getRepresentation());
186  localization->setLocalNode(getLocalNode());
187  return localization;
188  }
189 
190  size_t m_nodeID;
191 };
192 
194 {
195 public:
196  explicit MockDeformableRepresentation(const std::string& name = "MockDeformableRepresentation");
197 
199 
200  void addExternalGeneralizedForce(std::shared_ptr<Localization> localization,
201  const SurgSim::Math::Vector& generalizedForce,
202  const SurgSim::Math::Matrix& K,
203  const SurgSim::Math::Matrix& D) override;
204 
205 protected:
206  void transformState(std::shared_ptr<SurgSim::Math::OdeState> state,
207  const SurgSim::Math::RigidTransform3d& transform) override;
208  void computeF(const OdeState& state) override;
209  void computeM(const OdeState& state) override;
210  void computeD(const OdeState& state) override;
211  void computeK(const OdeState& state) override;
212  void computeFMDK(const OdeState& state) override;
213 };
214 
216 {
217 public:
218  MockSpring();
219 
220  void addNode(size_t nodeId);
221 
222  void addForce(const OdeState& state, Vector* F, double scale = 1.0) override;
223  void addDamping(const OdeState& state, SparseMatrix* D, double scale = 1.0) override;
224  void addStiffness(const SurgSim::Math::OdeState& state, SurgSim::Math::SparseMatrix* K,
225  double scale = 1.0) override;
226 
227  void addFDK(const OdeState& state, Vector* f, SparseMatrix* D, SparseMatrix* K) override;
228  void addMatVec(const OdeState& state, double alphaD, double alphaK, const Vector& x, Vector* F) override;
229 
230 private:
231  Vector m_F;
232  SparseMatrix m_D, m_K;
233 };
234 
236 {
237 public:
238  MockMassSpring() : MassSpringRepresentation("MassSpring")
239  {
240  }
241 
242  MockMassSpring(const std::string& name,
244  size_t numNodes, std::vector<size_t> nodeBoundaryConditions,
245  double totalMass,
246  double rayleighDampingMass, double rayleighDampingStiffness,
247  double springStiffness, double springDamping,
248  SurgSim::Math::IntegrationScheme integrationScheme);
249 
250  virtual ~MockMassSpring();
251 
252  const Vector3d& getGravityVector() const;
253 
254  const SurgSim::Math::Vector& getExternalForce() const
255  {
256  return m_externalGeneralizedForce;
257  }
258  const SurgSim::Math::SparseMatrix& getExternalStiffness() const
259  {
260  return m_externalGeneralizedStiffness;
261  }
262  const SurgSim::Math::SparseMatrix& getExternalDamping() const
263  {
264  return m_externalGeneralizedDamping;
265  }
266 
267  void clearFMDK();
268 };
269 
271 {
272 public:
273  MockFemElement();
274  explicit MockFemElement(std::shared_ptr<FemElementStructs::FemElementParameter> elementData);
275 
276  void addNode(size_t nodeId);
277 
278  double getVolume(const OdeState& state) const override;
279  Vector computeCartesianCoordinate(const OdeState& state, const Vector& barycentricCoordinate) const override;
280  Vector computeNaturalCoordinate(const SurgSim::Math::OdeState& state, const Vector& globalCoordinate) const
281  override;
282 
283  void initialize(const SurgSim::Math::OdeState& state) override;
284 
285  bool isInitialized() const;
286 
287 private:
288  void initializeMembers();
289  void doUpdateFMDK(const Math::OdeState& state, int options) override;
290  bool m_isInitialized;
291 };
292 
293 // Concrete class for testing
295 {
296 public:
299  explicit MockFemRepresentation(const std::string& name);
300 
302  virtual ~MockFemRepresentation();
303 
304  void setInitialState(std::shared_ptr<SurgSim::Math::OdeState> initialState) override;
305 
306  void loadFem(const std::string& filename) override;
307 
308  void addExternalGeneralizedForce(std::shared_ptr<Localization> localization,
309  const SurgSim::Math::Vector& generalizedForce, const SurgSim::Math::Matrix& K,
310  const SurgSim::Math::Matrix& D) override;
311 
312  std::shared_ptr<FemPlyReaderDelegate> getDelegate();
313 
314  const std::vector<double>& getMassPerNode() const;
315 
316  void clearFMDK();
317 
318  bool hasSetInitialStateBeenCalled();
319 
320 protected:
324  void transformState(std::shared_ptr<OdeState> state, const RigidTransform3d& transform) override;
325 
326  // Flag to be set when setInitialState of this class is called.
327  bool m_setInitialStateCalled;
328 };
329 
331 {
332 public:
333  explicit MockFemRepresentationValidComplianceWarping(const std::string& name) : MockFemRepresentation(name)
334  {}
335 
336 protected:
337  virtual void calculateComplianceWarpingTransformation(const SurgSim::Math::OdeState& state);
338 };
339 
341 {
342 public:
343  explicit MockFem1DRepresentation(const std::string& name);
344 
345  bool doInitialize() override;
346 
347  double getMassPerNode(size_t nodeId);
348 };
349 
351 {
352 public:
353  explicit MockFem2DRepresentation(const std::string& name);
354 
355  double getMassPerNode(size_t nodeId);
356 };
357 
360 {
361 public:
362  explicit MockFem3DCorotationalTetrahedronRepresentation(const std::string& name);
363 
364  SurgSim::Math::Matrix getTransformation(size_t nodeId);
365 };
366 
368 {
369 public:
372 
373  SurgSim::Physics::ConstraintType getConstraintType() const override;
374 
375 private:
376  size_t doGetNumDof() const override;
377 
378  void doBuild(double dt,
379  const ConstraintData& data,
380  const std::shared_ptr<Localization>& localization,
381  MlcpPhysicsProblem* mlcp,
382  size_t indexOfRepresentation,
383  size_t indexOfConstraint,
384  ConstraintSideSign sign) override;
385 };
386 
388 {
389 public:
392 
393  SurgSim::Physics::ConstraintType getConstraintType() const override;
394 
395 private:
396  size_t doGetNumDof() const override;
397 
398  void doBuild(double dt,
399  const ConstraintData& data,
400  const std::shared_ptr<Localization>& localization,
401  MlcpPhysicsProblem* mlcp,
402  size_t indexOfRepresentation,
403  size_t indexOfConstraint,
404  ConstraintSideSign sign) override;
405 };
406 
407 template <class Base>
408 class MockDescendent : public Base
409 {
410 public:
411  MockDescendent() : Base() {}
412  explicit MockDescendent(const std::string& name) : Base(name) {}
413 };
414 
416 {
417 public:
419 
420  explicit MockLocalization(std::shared_ptr<Representation> representation);
421 
422 private:
427  SurgSim::Math::Vector3d doCalculatePosition(double time) const override;
428 
429  SurgSim::Math::Vector3d doCalculateVelocity(double time) const override;
430 
431  std::shared_ptr<Localization> doCopy() const override;
432 };
433 
435 {
436 public:
437  SurgSim::Physics::ConstraintType getConstraintType() const override;
438 
439 private:
440  size_t doGetNumDof() const override;
441 
442  virtual void doBuild(double dt,
443  const ConstraintData& data,
444  const std::shared_ptr<Localization>& localization,
445  MlcpPhysicsProblem* mlcp,
446  size_t indexOfRepresentation,
447  size_t indexOfConstraint,
448  ConstraintSideSign sign);
449 };
450 
452 {
453 public:
455 
456  const SurgSim::DataStructures::OptionalValue<double>& getOptionalLinearStiffness() const;
457  const SurgSim::DataStructures::OptionalValue<double>& getOptionalLinearDamping() const;
458  const SurgSim::DataStructures::OptionalValue<double>& getOptionalAngularStiffness() const;
459  const SurgSim::DataStructures::OptionalValue<double>& getOptionalAngularDamping() const;
460  const SurgSim::DataStructures::OptionalValue<SurgSim::Math::Vector3d>& getOptionalAttachmentPoint() const;
461 
462  void setOptionalLinearStiffness(const SurgSim::DataStructures::OptionalValue<double>& val);
463  void setOptionalLinearDamping(const SurgSim::DataStructures::OptionalValue<double>& val);
464  void setOptionalAngularStiffness(const SurgSim::DataStructures::OptionalValue<double>& val);
465  void setOptionalAngularDamping(const SurgSim::DataStructures::OptionalValue<double>& val);
466  void setOptionalAttachmentPoint(const SurgSim::DataStructures::OptionalValue<SurgSim::Math::Vector3d>& val);
467 
468  const SurgSim::DataStructures::DataGroup& getOutputData() const;
469 };
470 
471 inline std::shared_ptr<Constraint> makeMockConstraint(std::shared_ptr<MockRepresentation> firstRepresentation,
472  std::shared_ptr<MockRepresentation> secondRepresentation)
473 {
475 
476  static auto type = MockConstraintImplementation().getConstraintType();
477  if (firstRepresentation->getConstraintImplementation(type) == nullptr)
478  {
480  std::make_shared<MockConstraintImplementation>());
481  }
482 
483  return std::make_shared<Constraint>(type, std::make_shared<ConstraintData>(),
484  firstRepresentation, Location(),
485  secondRepresentation, Location());
486 }
487 
490 {
491 public:
494  explicit MockCollisionRepresentation(const std::string& name);
495 
496  int getShapeType() const override;
497  std::shared_ptr<Math::Shape> getShape() const override;
498  void update(const double& dt) override;
499 
501  int getNumberOfTimesUpdateCalled() const;
502 
503 private:
505  int m_numberOfTimesUpdateCalled;
506 };
507 
509 {
510 public:
511  explicit MockComputation(bool doCopyState = false);
512 
513  SURGSIM_CLASSNAME(SurgSim::Physics::MockComputation);
514 
515 protected:
516  std::shared_ptr<PhysicsManagerState> doUpdate(const double& dt,
517  const std::shared_ptr<PhysicsManagerState>& state) override;
518 };
519 
520 }; // Physics
521 }; // SurgSim
522 
523 #endif // SURGSIM_PHYSICS_UNITTESTS_MOCKOBJECTS_H
Wraps glewInit() to separate the glew opengl definitions from the osg opengl definitions only imgui n...
Definition: AddRandomSphereBehavior.cpp:36
Finite Element Model 2D is a fem built with 2D FemElement.
Definition: Fem2DRepresentation.h:52
Definition: MockObjects.h:451
A description of a physical mixed LCP system to be solved.
Definition: MlcpPhysicsProblem.h:43
Finite Element Model 1D is a fem built with 1D FemElement.
Definition: Fem1DRepresentation.h:54
Finite Element Model (a.k.a FEM) is a deformable model (a set of nodes connected by FemElement)...
Definition: FemRepresentation.h:46
Eigen::Transform< double, 3, Eigen::Isometry > RigidTransform3d
A 3D rigid (isometric) transform, represented as doubles.
Definition: RigidTransform.h:46
void beforeUpdate(double dt) override
Preprocessing done before the update call.
Definition: MockObjects.cpp:40
Definition: MockObjects.h:235
The Representation class defines the base class for all physics objects.
Definition: Representation.h:53
A Location defines a local position w.r.t.
Definition: Location.h:39
Definition: MockObjects.h:270
Eigen::SparseMatrix< double > SparseMatrix
A sparse matrix.
Definition: SparseMatrix.h:32
static ConstraintImplementationFactory & getFactory()
Definition: ConstraintImplementation.cpp:34
Base class for all deformable representations MassSprings, Finite Element Models,...
Definition: DeformableRepresentation.h:50
Base class for all deformable representations (abstract class)
The FixedRepresentation class represents a physics entity without any motion nor compliance against w...
Definition: FixedRepresentation.h:35
void afterUpdate(double dt) override
Postprocessing done after the update call.
Definition: MockObjects.cpp:50
#define SURGSIM_ASSERT(condition)
Assert that condition is true.
Definition: Assert.h:77
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
Base class for all CosntraintData Derived classes should be specific to a given constraint.
Definition: ConstraintData.h:27
Base class for all Fem Element (1D, 2D, 3D) It handles the node ids to which it is connected and requ...
Definition: FemElement.h:45
Definition: MockObjects.h:96
std::shared_ptr< Localization > createLocalization(const SurgSim::DataStructures::Location &location) override
Computes a localized coordinate w.r.t this representation, given a Location object.
Definition: MockObjects.cpp:70
The RigidRepresentation class defines the dynamic rigid body representation Note that the rigid repre...
Definition: RigidRepresentation.h:42
Definition: MockObjects.h:350
Definition: MockObjects.h:415
bool initialize(const std::weak_ptr< Runtime > &runtime)
Initialize this component, this needs to be called before wakeUp() can be called. ...
Definition: Component.cpp:77
Definition: MockObjects.h:215
Definition: MockObjects.h:340
MassSpring model is a deformable model (a set of masses connected by springs).
Definition: MassSpringRepresentation.h:45
Base class for all springs It handles the node ids to which it is connected and requires all derived ...
Definition: Spring.h:42
The RigidState class describes a state (position and velocity information).
Definition: RigidState.h:31
Definition: MockObjects.h:508
Eigen::Matrix< double, Eigen::Dynamic, 1 > Vector
A dynamic size column vector.
Definition: Vector.h:68
void addImplementation(std::type_index typeIndex, std::shared_ptr< ConstraintImplementation > implementation)
Add an implementation to the internal directory.
Definition: ConstraintImplementationFactory.cpp:105
Base class for all constraint implementations. A ConstraintImplementation defines 1 side of a constra...
Definition: ConstraintImplementation.h:42
A collection of NamedData objects.
Definition: DataGroup.h:68
Definitions of 2x2 and 3x3 rigid (isometric) transforms.
Definitions of small fixed-size square matrix types.
Co-rotational Tetrahedron Finite Element Model 3D is a fem built with co-rotational tetrahedron 3D Fe...
Definition: Fem3DCorotationalTetrahedronRepresentation.h:38
The VirtualToolCoupler couples a rigid object to an input/output device through a spring and damper...
Definition: VirtualToolCoupler.h:58
Definitions of small fixed-size vector types.
void update(double dt) override
Update the representation state to the current time step.
Definition: MockObjects.cpp:45
Definition: MockObjects.h:107
bool isInitialized() const
Definition: Component.cpp:72
Encapsulates a calculation over a selection of objects, needs to be subclassed to be used...
Definition: Computation.h:32
The type of collision detection.
Definition: Representation.h:60
Base class for all solvers of ode equation of order 2 of the form .
Definition: OdeSolver.h:78
Definition: MockObjects.h:294
Definition: MockObjects.h:61
Class to represent a mock collision representation to test if update gets called from the Computation...
Definition: MockObjects.h:489
SurgSim::Physics::ConstraintType getConstraintType() const override
Gets the constraint type for this ConstraintImplementation.
Definition: MockObjects.cpp:580
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > Matrix
A dynamic size matrix.
Definition: Matrix.h:65
This class localize a point on a representation (representation specific)
Definition: Localization.h:39
Definition: MockObjects.h:408