xiangaodielian / bullet

Automatically exported from code.google.com/p/bullet
Other
0 stars 0 forks source link

Contact stability improvement patch #642

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
As discussed in this thread: 
http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?f=9&t=8146
We are submitting a patch to the bullet solver to address 2 major issues in 
Bullet.
1: At the end of the frame objects are visibly inter-penetrating.
2: Contacts often generate parasite velocities that leads instability in light 
objects with non zero restitution values.
The thread covers the issues and the proposed solution in more details.

I am attaching a patch for version 2.80 svn rev 2531.
I am also attaching a new version of BasicDemo.cpp that highlights the 
stability improvements.
The new version of the demo disables sleeping to help observe the stability 
improvements. The cubes are given a very high restitution value to make the 
stability issues obvious in the non patched version. Even setting restitution 
to zero yields a very visible improvement as the cubes scatter far less.
The demo turns SplitImpulse on, but the improvements actually work with split 
impulse turned off as well.

Original issue reported on code.google.com by laur...@liquiddragon.com on 11 Jul 2012 at 8:01

Attachments:

GoogleCodeExporter commented 9 years ago
That's great, thanks for sharing your improvements.

As you might have noticed, parts of the collision algorithm were refactored, to 
allow (future) multi-threaded processing collision algorithms.

Is there any chance you can update the patch for the latest trunk?

Original comment by erwin.coumans on 11 Jul 2012 at 9:38

GoogleCodeExporter commented 9 years ago
Sorry, i didn't notice the newer versions until now. I don't see any changes in 
the list that should conflict with my patch though so merging should work fine.
Let me know if there are conflicts. 

Original comment by laur...@liquiddragon.com on 11 Jul 2012 at 10:05

GoogleCodeExporter commented 9 years ago
Hi Erwin, here is a newer patch that includes a couple of fixes. We were not 
handling motion states properly in the first patch and had forgotten to update 
the world inertia tensor after the object moved.

Original comment by laur...@liquiddragon.com on 12 Jul 2012 at 10:41

Attachments:

GoogleCodeExporter commented 9 years ago

Thanks for the patch.

I'm looking into various ways to apply this patch, and make some other changes 
that improves stability (reduce jitter).

I prefer to:

1) keep the contact 'lifetime' even though we might not use it anymore
2) make the change optional to change the transform at the beginning instead of 
in 'integrateTransforms' with some option/setting
3) instead of changing the velocity at the beginning of the timestep, we could 
pass in the gravity as an external force in the constraint solver. This should 
eliminate the need for an 'old velocity' member

I'll keep the progress here.

Original comment by erwin.coumans on 11 Aug 2012 at 1:00

GoogleCodeExporter commented 9 years ago
"Even setting restitution to zero yields a very visible improvement as the 
cubes scatter far less."

I ran the demo in an unmodified version of Bullet and set the resitution to 
zero. THe difference was not/barely noticeable and both come to a rest soon.

Assuming there would be some improvement (although I didn't notice it): what 
change is responsible for the improvement in the zero-restitution case exactly?

Original comment by erwin.coumans on 13 Aug 2012 at 8:31

GoogleCodeExporter commented 9 years ago
Hi Erwin,
Making this patch an optional setting is definitely the way to go. If only 
because it is incompatible with CCD.

We thought of passing the external forces to the solver instead of storing an 
old velocity. The reasons we decided to store the old velocity are:
1. If gravity was the only continuous external force in your world you could 
save on memory. However things like circular gravity fields, magnetic fields, 
air flows and so on would be impossible to implement correctly. Therefore you 
need to store a vector3 per rigid body either way. 
2. The old velocity is actually useful to return correct impact information to 
the main engine (Something we did not include in the patch since it was not 
directly related).

Regarding the zero restitution increased stability, the statement is definitely 
debatable and might be due to the choices of tests we made :)
I am attaching a few comparison screenshots to explain what we based the 
statement on:

the bigCube shots are the easiest to quantify. Both shots were taken 5000 
frames into the simulation.
In the classic Bullet version and counting from the left, column zero is 
completely gone, column 1 largely decimated and column 2 is just starting to 
drift. There is also a lot of visible drift coming towards the camera in all 
the columns.
In the patched version, column 0 is only partially collapsed and column 1 shows 
significant drift but is still intact. There is also way less drift in the 
camera direction.

The midCube shots uses cubes falling on each other instead of starting in 
contact and the screens were captured 500 frames into the simulation. There 
seems to be less scatter on the patched version.

The reason for the improvement even with zero restitution is probably due the 
commenting out of this line:

//re-calculate friction direction every frame, todo: check if this is really 
needed
btPlaneSpace1(cp.m_normalWorldOnB,cp.m_lateralFrictionDir1,cp.m_lateralFrictionD
ir2);

Original comment by laur...@liquiddragon.com on 15 Aug 2012 at 11:28

Attachments:

GoogleCodeExporter commented 9 years ago
I had a look at the removing this line

//re-calculate friction direction every frame, todo: check if this is really 
needed
btPlaneSpace1(cp.m_normalWorldOnB,cp.m_lateralFrictionDir1,cp.m_lateralFrictionD
ir2);

and it introduces a (small) friction problem: if the relative velocity at the 
beginning of the frame is zero (projected on the contact normal), the friction 
direction will be zero. In other words, the friction is disabled for that 
simulation frame. This will lead to better stability/less scattering, but at 
the cost of realism.

I'm still working on reproducing the restitution issue, but without some of the 
other changes.

Original comment by erwin.coumans on 31 Aug 2012 at 3:14

GoogleCodeExporter commented 9 years ago
The latest trunk has some changes that a similar to your patch.

1) Restitution is computed using the velocities without the applied 
forces/torques
2) You can disable the 'btPlaneSpace' line using a solverMode flag:

I didn't change the btDiscreteDynamicsWorld for now. If others request it we 
can add some customizations.

https://code.google.com/p/bullet/source/detail?r=2547

Thanks for the patch!

Original comment by erwin.coumans on 31 Aug 2012 at 7:49