Commit 99e962d9 authored by Andrew Wilson's avatar Andrew Wilson
Browse files

DOC: Improved in code documentation, updated Collision_Handling documentation for interactions

parent 505ed988
Pipeline #240967 passed with stage
......@@ -133,17 +133,9 @@ To resolve collision I would classify approaches into two categories.
* If we resolve all contacts later we may find that we resolve one such that we create another. For example, stacked cubes A, B, & C. Resolving A-B might move B into C. This would normally require another collision detection pass (likely next step of the simulation). But if you noticed, Ex1 may not require another CD iteration as it does CD while resolving. Given the correct order of CD testing, they would actually resolve.
* Matrix: These approaches assemble matrices to resolve them all in a semi-implicit or implicit manner.
* Semi-Implicit:
* Identical to the matrix-free explicit solutions. ex1 was one iteration of gauss seidel, ex2 was one iteration of jacobi.
* Non-penetration equations are solved in iterative manners, solutions being plugged into latter iterations.
* Order of assembly matters.
* Implicit:
* All non-penetration equations solved simulatenously.
* Order of assembly will produce same solution.
* Non-penetration equations are solved in iterative manners
* Often "constraint" based
Collision Constraints
--------------------------------
......
Collision Handling
==================
:code:`CollisionHandling` classes in iMSTK defines methods for handling collisions. That is, one may want to take action when a collision happens. This is either an instant response (explicit solution) or something added to a system to solve later (implicitly).
:code:`CollisionHandling` classes in iMSTK defines methods for handling collisions. They take input objects (often two) and input collision data. When updated they will consume the collision data to produce appropriate responses. Normally this is a response in a dynamical system. This may either be an instant response at the time of handling or something (such as a constraint) added to the system to solve and produce the response later.
Collision handling methods directly consume collision data which is produced by :code:`CollisionDetection` objects. For this reason, every :code:`CollisionHandling` constructor accepts a :code:`CollisionData` object.
CollisionHandlers and CollisionDetection is normally setup by an interaction through the scene such that the user doesn't have to mess with them unless they want to change parameters of a handler/detection or even subclass them for custom functionalities.
Collision handling happens between a pair of objects. Given this pair the handling has a side. We can either handle the collision for object A, object B, or both at the same time/AB.
LevelSetCH
--------------------------------
With this you will see three strategies then:
The levelSetCH consumes PointDirection data from a collision detection method to produce impulses/movement in a LevelSet using gaussian kernels. One can alter this kernel size, gaussian sigma. If one chooses to use proportional velocity, then the force of the rigid object is considered in how fast the level set is moved.
While the handler is standalone and can be used in other contexts, it finds its main use in the RigidObjectLevelSetCollision interaction which may be used like so:
::
imstkNew<RigidObjectLevelSetCollision> interaction(rbdObj, femurObj);
scene->getCollisionGraph()->addInteraction(interaction);
Should more control be needed one can access the underlying handlers like so:
::
auto colHandlerA = std::dynamic_pointer_cast<RigidBodyCH>(interaction->getCollisionHandlingA());
colHandlerA->setUseFriction(false);
colHandlerA->setBeta(0.05); // inelastic collision
auto colHandlerB = std::dynamic_pointer_cast<LevelSetCH>(interaction->getCollisionHandlingB());
colHandlerB->setLevelSetVelocityScaling(0.01);
colHandlerB->setKernel(3, 1.0);
colHandlerB->setUseProportionalVelocity(true);
PBDCollisionHandling
--------------------------------
Given two input objects (pbd vs pbd or pbd vs colliding/static) and input collision data it will produce collision constraints in a solver to then be solved later. One of the more complex handlers in iMSTK and handles many cases:
The implementation of this handler is broken into two functions:
* Mesh-Non-Mesh Interactions: The PbdObject is garunteed to be a mesh, but the CollidingObject could be mesh, a primitive, an implicit geometry, etc. The following CD data's are handled:
* PointIndexDirection-None: Moves the vertex of the mesh (given by index) in the direction and depth specified by the element.
* Triangle-Vertex/PointDirection: Moves the triangle to the vertex.
* Edge-Vertex/PointDirection: Moves the edge to the vertex.
* Mesh-Mesh Interactions: In the case both are a mesh the following CD data's are handled:
* Vertex-Triangle/Triangle-Vertex: Moves the vertex and triangle to just touching.
* Edge-Edge: Moves the two edges to just touching.
* Edge-Vertex/Vertex-Edge: Moves the vertex and edge to just touching.
Whats supported then:
* PbdObject vs PbdObject mesh collisions.
* PbdObject vs CollidingObject mesh collisions.
* PbdObject vs CollidingObject primitive collisions.
* PbdObject vs CollidingObject implicit geometry collisions.
The PbdCollisionHandling can be used through the PbdObjectCollision interaction like so:
::
// Add collision between the two objects with the following collision strategy
imstkNew<PbdObjectCollision> myCollision(tissueObj, toolObj, "MeshToMeshBruteForceCD");
scene->getCollisionGraph()->addInteraction(myCollision);
If more control is needed that is not available in the PbdObjectCollision, you may attain the handler like so:
::
imstkNew<CustomSPHCollisionHandlerOneSided> handler(sphObj1, Side::A, collisionData);
imstkNew<CustomSPHCollisionHandlerOneSided> handler(sphObj1, Side::A, collisionData);
imstkNew<CustomSPHCollisionHandlerOneSided> handler(sphObj2, Side::B, collisionData);
imstkNew<CustomSPHCollisionHandlerTwoSided> handler(sphObj1, sphObj2, collisionData);
auto pbdHandler = std::dynamic_pointer_cast<PbdCollisionHandling>(myCollision->getCollisionHandlingA());
Generally, having one sided collision handlers is better for modularity, but sometimes it is required to consider both models.
When subclassing one may override the base class handling function which is called to consume the collision data or you may override the constraint addition functions. Such functions are useful when custom response (say constraints) is needed upon contact. See PbdTissueSurfaceNeedleContact example for subclassing.
Typical usage in an iMSTK Scene will be done through iMSTK interactions found in the scene. Interactions agglomerate CollisionHandling (how to consume collision data) and CollisionDetection to produce an interaction between SceneObjects (objects on the scene level).
You can read more about interactions here.
\ No newline at end of file
PBDPickingCH
--------------------------------
The PbdPickingCH consumes CD data to constrain PbdObject vertices in contact with an analytical geometry. It constraints them such that their relative positions to the analytical geometry origin and orientation are maintained. It may only be used with PbdObject vs CollidingObject that has an analytical geometry.
The user can call beginPick or endPick to constrain or unconstrain the PbdObject vertices.
The PbdPickingCH can be used through the PbdObjectPicking interaction like so:
::
// Add picking interaction between a clothObj (PbdObject) and toolObj (with capsule analytical geometry)
imstkNew<PbdObjectPicking> objectPicking(clothObj, toolObj, "PointSetToCapsuleCD");
scene->getCollisionGraph()->addInteraction(objectPicking);
PenaltyCH
--------------------------------
The PenaltyCH uses a penalty response method between a FEM simulated and rigid body object. It consumes CD data between the geometries and produces forces in both models. It currently only works with PointDirection data, of which only primtive collision detection supports. So it is currently limited to implicit and primitive shapes only.
RigidBodyCH
--------------------------------
The RigidBodyCH handles collisions between two RigidObject2's or a RigidObject2 and a CollidingObject (where CollidingObject is static/immovable by the rigid object). Currently it only handles mesh to primitive+implicit and primitive to primitive rigid body shapes. It can be used through the RigidObjectCollision interaction like so:
::
// Create an interaction between a rigid object with a sphere and CollidingObject with plane geometry, resolves undirectionally (always above the plane normal)
auto rbdInteraction = std::make_shared<RigidObjectCollision>(rbdObjSphere, planeObj, "UnidirectionalPlaneToSphereCD");
rbdInteraction->setFriction(0.0);
rbdInteraction->setStiffness(0.0001);
scene->getCollisionGraph()->addInteraction(rbdInteraction);
Another example using between a rigid OBB and an implicit/SDF geometry:
::
// Create an interaction between a rigid object with a OBB geometry and CollidingObject with an SignedDistanceField geometry (great for static curved surfaces)
auto rbdInteraction = std::make_shared<RigidObjectCollision>(cubeObj, planeObj, "ImplicitGeometryToPointSetCD");
rbdInteraction->setFriction(0.0); // Don't use friction
rbdInteraction->setStiffness(0.05);
scene->getCollisionGraph()->addInteraction(rbdInteraction);
SPHCollisionHandling
--------------------------------
The SPHCollisionHandling moves SPH particles out of collision with an object and applies boundary friction to the velocity of the particle. It currently only works with PointDirection data, of which only primtive collision detection supports. So it is currently limited to implicit and primitive shapes only.
One may use it through the SPHCollision interaction like so:
::
// Add collision between the two objects (fluidObj is SPHObject and solidObj is a CollidingObject with primitive geometry)
imstkNew<SphObjectCollision> myCollision(fluidObj, solidObj);
scene->getCollisionGraph()->addInteraction(myCollision);
\ No newline at end of file
......@@ -40,6 +40,12 @@
using namespace imstk;
///
/// \brief This examples is used to demonstrate Triangle Vs Triangle collision
/// of the MeshToMeshBruteForceCD method.
/// It displays the collision data, and allows users to investigate various cases
/// by moving the geometry around with keyboard controls i,j,k,l,o,u
///
int
main()
{
......
......@@ -40,6 +40,12 @@
using namespace imstk;
///
/// \brief This examples is used to demonstrate Triangle Vs Sphere collision
/// of the SurfaceMeshToSphereCD method
/// It displays the collision data, and allows users to investigate various cases
/// by moving the geometry around with keyboard controls i,j,k,l,o,u
///
int
main()
{
......
......@@ -39,6 +39,12 @@
using namespace imstk;
///
/// \brief This examples is used to demonstrate Triangle Vs Triangle collision
/// of the SurfaceMeshToSurfaceMeshCD method.
/// It displays the collision data, and allows users to investigate various cases
/// by moving the geometry around with keyboard controls i,j,k,l,o,u
///
int
main()
{
......
......@@ -177,8 +177,8 @@ makeTissueObj(const std::string& name,
}
///
/// \brief This example demonstrates the collision interaction
/// using Position based dynamics
/// \brief This example demonstrates collision interaction with a 2d pbd
/// simulated tissue/membrane/cloth
///
int
main()
......
......@@ -320,8 +320,8 @@ makeToolObj()
}
///
/// \brief This example demonstrates the collision interaction
/// using Position based dynamics
/// \brief This example demonstrates collision interaction with a 3d pbd
/// simulated tissue (tetrahedral)
///
int
main()
......
......@@ -282,8 +282,9 @@ makeToolObj()
}
///
/// \brief This example demonstrates the collision interaction
/// using Position based dynamics
/// \brief This example demonstrates tetrahedral removal of a pbd simulated mesh
/// using a haptic device. Hold the button the device whilst moving it over elements
/// to remove
///
int
main()
......
......@@ -300,8 +300,8 @@ makeToolObj()
}
///
/// \brief This example demonstrates the tissue needle contact with a 2d surface mesh
/// The needle is constrained at the location on the surface of the 2d mesh.
/// \brief This example demonstrates two-way tissue needle contact with a tetrahedral mesh.
/// Constraints are used at the tetrahedrons faces of intersection
///
int
main()
......
......@@ -101,7 +101,8 @@ makePbdTriangle(const std::string& name)
///
/// \brief This example demonstrates the collision with an infinitely
/// stiff triangle, serves as a test case for jitter
/// stiff triangle, serves as a test case for jitter. The point should
/// be able to rest on the triangle without either moving
///
int
main()
......@@ -111,7 +112,6 @@ main()
// Setup the scene
imstkNew<Scene> scene("PBDTriangleContact");
scene->getConfig()->taskParallelizationEnabled = false;
scene->getActiveCamera()->setPosition(0.12, 4.51, 16.51);
scene->getActiveCamera()->setFocalPoint(0.0, 0.0, 0.0);
scene->getActiveCamera()->setViewUp(0.0, 0.96, -0.28);
......
......@@ -44,7 +44,7 @@ using namespace imstk;
///
/// \brief This examples demonstrates rigid body interaction between
/// two primitives
/// primitives
///
int
main()
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment