yoshinoToylogic / bulletsharp

Automatically exported from code.google.com/p/bulletsharp
MIT License
0 stars 0 forks source link

In a frame-dependent, fully elastic, glancing collision, BulletSharp appears not to conserve energy (large losses instead). #76

Open GoogleCodeExporter opened 8 years ago

GoogleCodeExporter commented 8 years ago
Version:  BulletSharp 2.82.

Here are the parameters of the world.

1. Framerate dependence:  My test is framerate-dependent (not real-time).

2. Time step:  I am using a fixed time step = 1/10,000th of a second (0.0001 
second).

3. Precision:  Bullet and BulletSharp both are built using the double precision 
option.  

4. Solver/Iterations:  I’m using the SequentialImpulseConstraintSolver with 
200 iterations.  

5. Split impulse:  I set SolverInfo.SplitImpulse = 1 and set 
SolverInfo.SplitImpulsePenetrationThreshold = 0, so that split impulse is 
utilized for any/every penetration. I did not change the default value for 
SolverInfo.SplitImpulseTurnErp, because I’m hoping that ERP doesn’t need to 
be tweaked anywhere.

6. CFM:  I did not change the default value for SolverInfo.GlobalCfm.

7. ERP:  I did not change the default values for SolverInfo.Erp or 
SolverInfo.Erp2.

8. CCD:  I set DispatchInfo.UseContinuous = False, because my time steps are so 
small that CCD should not be applicable here.

9. Gravity:  I am using zero gravity (0,0,0).

Here are the parameters of the collision objects:

1. I have two dynamic spheres, each with mass of 1 kilogram and using the same 
collision shape (diameter = 1 meter).  No other collision objects are in this 
simulation.

2. Sphere1 is stationary at the world origin; location (0,0,0), linear velocity 
(0,0,0) and angular velocity (0,0,0).

3. Sphere2 is moving from a different location, on a trajectory that will cause 
a glancing collision; location (10,0.5,0), linear velocity (-10,0,0) and 
angular velocity (0,0,0).

4. I set the coefficient of restitution = 1 for both spheres, so that the 
collision would be fully elastic, because the whole point of this test is to 
see how well BulletSharp can conserve energy in a glancing collision.  (If I 
set restitution < 1 then it would be much more difficult to reconcile ending 
total kinetic energy to beginning total kinetic energy of the system.)

5. I set the coefficient of friction=1 and the coefficient of rolling 
friction=1, so that the force required for Sphere2 to slide or to roll off of 
Sphere1 would be equal to the force pressing against the two spheres during the 
collision.  I did this to ensure that the glancing collision would start both 
spheres rotating (hopefully by an efficient partial transfer from Sphere2’s 
translational energy of motion into both spheres’ rotational energy of 
motion). 

Here are the steps of the test:

1. On every time step and for each sphere, I calculate and log the 
translational energy of motion and the rotational energy of motion, which I sum 
to arrive at total kinetic energy of the system.  I expect total kinetic energy 
of the system to remain constant before, during and after the collision, 
because the collision is fully elastic.

2. Ready, set, go….

3. Sphere2 moves toward the origin with magnitude of velocity = 10 meter / 
second.  Nothing else is moving, so in the first time step, total kinetic 
energy = ½ * Sphere2 Mass * (Sphere2.LinearVelocity.Length) ^2 = 50 kilogram * 
meter^2 / second^2 = 50 joule.

4. Sphere2 encounters Sphere1 in a glancing collision that begins in time step 
9,135 and ends in time step 9,154 (20 time steps).  During those 20 time steps, 
I observe that total kinetic energy decreases by 3.566% to 48.21684 joules.  In 
theory, the total kinetic energy of the system should be constant across all 
time steps, before, during and after the collision.

5. After the collision, the two spheres drift apart until I stop the simulation 
at time step 11,000.

6. Upon reviewing the logs, I can see that no energy is lost at any time other 
than the 20 frames that account for the collision, which leaked 3.566% of total 
energy.  That is a large loss and does not make sense to me.

Frictionless version of the test works perfectly:

1. When I set friction = 0 for both spheres and run the same test above, I can 
see that BulletSharp properly conserves both momentum and energy through the 
fully elastic glancing collision.  This is significant, because (1) it shows 
that BulletSharp is capable of conserving both momentum and energy in a fully 
elastic collision (as long as friction = 0) and (2) it shows that friction is 
the sole cause off the energy loss observed in the test above.  In this 
frictionless scenario, I also can see that no translational energy is shunted 
into angular energy, because without friction, a collision cannot spin a 
sphere.  This scenario makes sense to me.

How I think it should work:

1. Because friction is the force that resists relative motion between two 
bodies in contact, I believe that any non-zero coefficients of friction and 
rolling friction should transfer energy from one fully elastic collision object 
to another fully elastic collision object, without any loss of energy.  Right? 

2. Because the coefficient of restitution is the ratio of the relative velocity 
after impact to the relative velocity before impact, I believe that a collision 
should result in an energy loss only if the coefficient of restitution < 1, 
which then would describe energy lost to heat, sound, vibration, etc.  Right?  
(Restitution < 1 is not applicable in the fully elastic collision described in 
this test.) 

Questions

Based on your experience with BulletSharp and Bullet and physics in general, 
would you expect the energy loss described above to be as large as the 3.566% 
that I observed?  That seems huge.  I was expecting a very tiny loss instead.  
And in theory, shouldn’t the energy loss be zero?

Effects of other solvers on the test:

1. I tried using the NncgConstraintSolver, I and got exactly the same results 
as above.  

2. I tried the direct DantzigSolver, but that solver appeared to override my 
restitution values and set them to *zero* (as if this was a fully inelastic 
collision), so I’m staying away from that solver for the moment.

Thanks!

Original issue reported on code.google.com by patr...@shaughness.com on 30 Jan 2015 at 9:31

GoogleCodeExporter commented 8 years ago
If you can send a minimal code sample, I can check if a C++ version without the 
wrapper behaves the same way.

I don't have experience with this particular issue, nor do I have enough of a 
physics background to know how such collisions should work. BulletSharp is only 
a thin wrapper, so you most likely want to ask about this in the Bullet forum. 
That's where all the physics geeks hang out. :)

Original comment by andres.traks on 30 Jan 2015 at 10:38