CS 6360 Virtual Reality- Assignment 4
March 14, 2007
Physics and Haptics in a VR Environment
This project sets up a simple environment, applies physics and collisions to the scene, and adds haptic feedback to the environment, which allows the user to dynamically interact with the objects in the scene. The environment consists of a six-sided bounding volume, visualized as a wire cube, and a number of spheres placed randomly. Each sphere is given a random mass, color coded as red being more massive than green, and zero initial velocity. Gravity is taken to be a vector of (0.0, -9.81, 0.0).
Timestep Value and Euler Integration
Euler numerical integration is used to advance the system given a parameter deltaT which is the value of each time step. In general, the smaller the time step, the more accurate the system is and the less error is introduced, however, we shall see this is not entirely accurate. To tie the physics simulation into "real" numbers in terms of time and time steps, a Timer class provides function currentSeconds(), which returns the current time since the timer was initialized, in system counted milliseconds. In the GLUT idle callback, the new currentSeconds() newTime is compared to the previous timestamp currentTime. If newTime >= (currentTime + deltaT), the physics function is called, and the physics system is advanced. It was found that the implemented GLUT idle loop operates at roughly one cycle per 0.01 seconds, therefore the most accurate time step for this given implementation is very nearly 0.01. At values from 0.01 up to 0.07, the system tends to grow unstable, and at timesteps smaller than 0.01, the system does not operate at realtime speeds. This is summarized in the table below.
|deltaT = 0.07||The system grows unstable quickly.|
|deltaT = 0.06||Lowest mass objects bounce in box forever.
Higher mass objects diverge.
|deltaT = 0.05||Lower mass objects settle after 4-8 bounces.
Higher mass objects diverge.
|deltaT = 0.04||Higher mass objects exist for several bounces.|
|deltaT = 0.03||Only the most massive objects diverge.|
|deltaT = 0.02||All objects settle.|
|deltaT = 0.01||Threshold of GLUT idle refresh call.|
|deltaT = 0.005||System runs physically accurate but slow.|
Hooke's Law and Penalty Force Parameters
Collisions are implemented using penalty forces. The distance of penetration between two objects is computed, and then used to determine the collision force using Hooke's Law. Therefore, the value of parameter k, the spring constant, determines how the physics system behaves. It was found that a k value of roughly 1000 provides accurate sphere-plane collisions, and acceptable sphere-sphere collisions. At magnitudes smaller k values, the sphere-plane collisions are soft, and the sphere-sphere collisions unnoticeable. At magnitudes larger k values, force is added to the system so that a rest state between the spheres and the planes is impossible, but sphere-sphere collisions are accurate. It should be noted that the idea k values for sphere-plane collisions and sphere-sphere collisions are not the same; this will be explored more in the next section. This is due to the solid (i.e. infinite mass) planes versus the smaller, finite massed spheres. The below table summarizes the observations.
|k = 1||Spheres eventually settle far below ground plane.
No noticeable sphere-sphere collisions.
|k = 10||Spheres settle below ground plane.
No noticeable sphere-sphere collisions.
|k = 100||
Spheres settle in soft ground plane.
|k = 1.0e3||
Correct sphere-plane collisions.
|k = 1.0e4||
More massive spheres bounce on plane forever.
|k = 1.0e5||Sphere-plane collisions cause system to diverge.
Accurate sphere-sphere collisions.
Number of Spheres and System Performance
Working with a deltaT value of 0.01 and a global k value of 1000, real time performance of this implementation can be expected for up to 75 spheres. However, it becomes obvious that a different k value for sphere-plane and sphere-sphere collisions is necessary. As the number of spheres increases, some spheres are instantiated already intersecting other spheres. At low k values, the spheres do not have enough energy to expel the inclusive sphere, and so they operate as blobs rather than individual spheres. More spheres behaving this way leads to decreased performance.
Global k value of 1000.
All spheres "melt" onto ground plane.
Using a separate k value for the sphere-sphere collisions, in this case 1.0e5, provides the necessary force for spheres to expel any instantiated penetrations. However, this system now starts with a non-zero amount of force. The more massive spheres tend to bounce on a bed of less massive spheres, until an empty space on the ground plane can be found. In the idea case, we would expect nearly 100 spheres to fit on the ground plane, but due to the random arrangement, somewhere around 50 spheres can come to rest on the ground plane. As more spheres are added to the system, the extra spheres continue to bounce forever, not finding any real estate to settle. However, this happens at realtime performance. As more spheres are added, more energy is added to the system in the form of non-zero initial velocity. Spheres can bounce into "particle accelerators," the close juxtaposition of spheres in particular combinations that create enough force to launch a sphere out of the system completely. While, no resting state can be found for large number of spheres, upwards of 500-750 spheres can be included before performance starts to drop. At 200 spheres, the implementation runs at about 2.5 seconds per frame. These results are summarized in the table below.
|80 spheres||No intersections, but some spheres are forced out of system.
Most massive spheres bounce forever.
System continues to operate at real time performance.
Image captured at t = 100 seconds.
Image captured at t = 250 seconds.
Haptic feedback was implemented in the scene using the HDAPI calls. The Phantom device is initialized, although the program starts with force feedback disabled. A white sphere is drawn at the location of the Phantom pointer, the position being dramatically scaled down to fit in the established OpenGL scene. The user can control this cursor, and push the other sphere objects around the environment.
By pressing the 'F' key, the user can turn on or turn off force feedback. When forces are enabled, the computed force from the processCollisions() function, which previously performed the sphere-sphere and sphere-plane collisions as well as gravity, computes the force from the cursor-sphere and cursor-plane collisions, and passes this combined force to the HDAPI haptic callback function. No gravity is performed on the cursor sphere. The touchScene() function clamps the cursor's force to keep from overloading the Phantom device, and normalizes the force using hduVecNormalizeInPlace(), which scales the interaction between the cursor, planes, and sphere objects so all can be interacted with. This force is then sent to the Phantom device as the HD_CURRENT_FORCE. The two images below show the cursor interacting with the sphere objects. It is possible to bounce the lower mass objects, and pick them up.
The results from experimenting with the Phantom device were mixed. Different k values for the cursor-sphere and cursor-plane collision equations were experimented with using the above observations as a guide, using k = 1000 for cursor-plane collisions, and k = 1.0e5 for cursor-sphere collisions. The cursor force computations were at one point separate from the processCollisions() function, and included directly in the GLUT draw and idle functions, but at deltaT values similar to discussed above, this made no performance difference. All this was done to make the haptic device collisions feel less rubbery. Pushing the spheres around with the cursor or dragging the cursor along a plane felt much like rubbing two sticky rubber racquet balls together. Essentially, given that the collisions are computed by a penalty force model driven by high k values, this is a correct observation. The result that lightly touching the cursor to a plane resulted in the cursor bouncing away from the wall. Pressing the cursor into the wall a small amount seemed to smooth out the kicking behavior.
Interacting with the sphere objects using the cursor is fairly intuitive. The more massive spheres feel heavier than the less massive spheres, which as mentioned before can be picked up and balanced slightly. However, pushing the spheres around is like pushing a rubber ball with another rubber ball across a rubber surface. Thus, the bouncing and jitters are still evident.
Building simple physics into a virtual environment is a fairly straightforward process, especially with physics on the macro scale, because the behavior of objects under gravity, collisions, and springs are fairly intuitive behaviors driven by simple equations. Using a haptic device to interact directly with these forces is not as straightforward. Surveying the higher level interactions provided by openHaptics, it appears that some of the rubber behavior experienced during the haptics part of this assignment might be solved by more advanced material models. As implemented, though, it would not be a difficult extension to add additional features to this scene such as simple games requiring the user to push objects across a board. Better control over the force feedback via material models and faster update rates might make this current implementation more successful.