Sometimes, an application may wish to know details about the collision interactions between a specific collidable and one or more other collidables. These details may include items such as contact forces or the penetration regions between the opposing meshes. This section describes ways in which these details can be observed through the use of collision responses.
Applications can track collision information by creating CollisionResponse components for the collidables in question and adding them to the MechModel using setCollisionResponse():
An alternate version of setCollisionResponse() creates the response component internally and returns it:
During every simulation step, the MechModel will update its response components to reflect the current collision conditions between the associated collidables.
The first collidable specified for a collision response must be a specific collidable component, while the second may be either another collidable or a group of collidables represented by a Collidable.Group:
When a compound collidable is specified, the response component will collect collision information for all its subcollidables.
As as with collision behaviors, the same response cannot be added to an application twice:
The complete set of methods for managing collision responses are similar to those for behaviors,
where getCollisionResponse() and clearCollisionResponse() respectively return and clear response components that have been previously set using one of the setCollisionResponse() methods.
Information that can be obtained from a CollisionResponse component includes whether or not the collidable is in collision, the current contact points, forces and pressures acting on the vertices of the colliding meshes, and the underlying CollisionHandler objects that maintain the contact constraints between each colliding mesh. Much of the available information is similar to that which can be displayed using collision rendering (Section 7.5).
The information methods provided by CollisionResponse are listed below. Many take a cidx argument to request information for either the first or second collidable, which refer, respectively, to the collidables specified by the arguments collidable0 and collidable1 in the setCollisionResponse() methods.
Queries if the collidables associated with the response are in contact. Note that this may be true even if the method getContactData() returns an empty list; this can occur, for instance, for vertex penetration contact when the collision meshes intersect in a small region without any interpenetrating vertices.
Returns a list of the most recently computed contacts between the collidables. Each contact is described by a ContactData object supplying information about the contact points on each collidable, the normal, and contact and friction forces. If there are no current contacts, the returned list is empty. For more details on this information, consult the API documentation for ContactData and ContactPoint.
Map<Vertex3d,Vector3d> getContactForces(int cidx)
Returns a map of the contact forces acting the on the vertices of the collision meshes of either the first or second collidable, as specified by setting cidx to 0 or 1. This information is most useful and accurate when using vertex penetration contact (Section 18.104.22.168).
Map<Vertex3d,Vector3d> getContactForces(int cidx)
Returns a map of the contact pressures acting the on the vertices of the collision meshes of either the first or second collidable, as specified by setting cidx to 0 or 1. This information is most useful and accurate when using vertex penetration contact (Section 22.214.171.124).
ArrayList<PenetrationRegion> getPenetrationRegions(int cidx)
Returns a list of all the penetration regions on either the first or second collidable, as specified by setting cidx to 0 or 1. Penetration regions are available only if the collision manager’s collider type is set to AJL_CONTOUR (Section 7.4.2).
Returns the CollisionHandlers for all currently active collisions associated with the collidables of the response.
A typical usage scenario for collision responses is to create them before the simulation is run, possibly in the root model build() method, and then query them when the simulation is running, such from the apply() method of a Monitor (Section 5.3). For example, in the root model build() method, the response could be created with the call
and then used in some runtime code as follows:
If for some reason it is difficult to store a reference to the response between its construction and its use, thengetCollisionResponse() can be used to retrieve it:
As with contact rendering, the information returned by a collision response may sometimes appear to lag the simulation by one time step. That is because contacts are computed at the end of each time step , and then used to compute the contact forces during the next step . The information returned by a response at the end of step is thus based on contacts detected at the end of step , along with contact forces that are computed during step and used to calculate the updated positions and velocities at the end of that step.
A simple example of using a CollisionResponse is given by
This shows an FEM model of a ball rolling down an inclined plane, with a collision response combined with a Monitor used to print out the contact positions and forces at each time step. Contact forces are also rendered in the viewer. The model’s source code, excluding include statements, is shown below:
The build method creates a simple FEM ball and inclined plane, and positions the ball to an appropriate drop position (lines 27-42). The collisions are enabled between the ball and the plate, along with a CollisionResponse that is stored in the global reference myResp to allow it to be accessed from the monitor (lines 47-48).
The monitor itself is implemented by the class ContactMonitor, which is created by subclassing MonitorBase and overriding the apply() method to print out the contact information (lines 5-21). It does this by using the response’s getContactData() method to obtain a list of the contacts, and if there are any, printing the number of contacts, the time step start time (t0), and the position and force of each contact. An instance of the monitor is created and added to the root model at line 51.
Rendering is set so that the collision manager renders both the contact and friction forces in the viewer (lines 55-60), using blue arrows with a radius of 0.02 (line 60) and a scale factor for the arrow length of 0.0001 (line 58). To make the ball easy to see through, its elements are made invisible, and instead is rendered using only its surface mesh, with face rendering disabled and edges drawn with a width of 2 (lines 63-67).
To run this example in ArtiSynth, select All demos > tutorial > ContactForceMonitor from the Models menu. Running the model will result in the ball colliding with the plane, showing the contact and friction forces as blue arrows (Figure 7.19, while the monitor prints out the contact positions and forces to the console at each time step, producing output like this: