Contact bugs

ryanjuckett
Posts: 13
Joined: Tue Mar 11, 2008 9:04 am

Contact bugs

Post by ryanjuckett »

I've been having the following issues related to contacts between objects and was wondering if anyone has encountered them and perhaps found a work around.

1) Some times when a dynamic cube falls on a static axis aligned box it will rocket right through it. It looks like the penetration correction is causing it to launch through the other side very fast. (This never happened before upgrading to 2.67)

2) When I have a dynamic sphere on a static axis aligned box and apply a horizontal impulse it will periodically (about every 5 frames at 60fps) lose its contact point for one frame as it moves. (Not sure if this happened before upgrading to 2.67)

3) As I posted previously at http://www.bulletphysics.com/Bullet/php ... f=9&t=1968 my character capsules will sometimes not remove a contact point properly as far as I can tell. (This never happened before upgrading to 2.67)

4) When moving my character capsule along a static axis aligned box with an impulse it will sometimes skip (bounce very slightly in the air) when near the center of the box as if the penetration correction math gets some floating point issues when the two objects are lined up vertically. (This was happening before upgrading to 2.67 and still happens)

Any thoughts on any of that?
ryanjuckett
Posts: 13
Joined: Tue Mar 11, 2008 9:04 am

Re: Contact bugs

Post by ryanjuckett »

I made a new version of CharacterDemo.cpp in the bullet-2.67 demos that will repro the issue I have been having with a capsule getting stuck on a wall. I've attached a new version of CharacterDemo.cpp that can be copied over the existing one (bullet-2.67\Demos\CharacterDemo\CharacterDemo.cpp) to see the issue.

It builds a couple boxes and a character capsule in a similar order as to what would occur in my codebase and runs a hardcoded sequence of input (at a fixed framerate) that jumps into a wall and gets stuck. All of the important changes I've put in the file can be found by searching for comments that start with JUCKETT.

You can also disable the scripted input by undefining RUN_LOGGED_INPUT on line 354 and using the arrow keys to move and jump. If you do so, you will notice that the capsule will not always get stuck. From what I can tell, you need to hit the wall near the top of the jump.

The code is sort of hacked in there to repro the bug (or what I am assuming is a bug), but should be simple enough that it isn't too hard to follow.
You do not have the required permissions to view the files attached to this post.
ryanjuckett
Posts: 13
Joined: Tue Mar 11, 2008 9:04 am

Re: Contact bugs

Post by ryanjuckett »

So I found the source of issue number 3 listed above where the capsule would get stuck on a wall. This also fixed a few other “stickyness” issues I had been seeing but didn’t list above.

When Bullet finds contact points, it checks if they are near any contacts from the previous frame and if they are close enough, just updates the previous point rather than adding a new one. This allows contact points to maintain persistent data between frames when an object is at rest. In general, when an object moves very little between two frames, the new contact detection pass will find a point very close to the previous one. If an object moves away from the surface, the contact point is removed. If an object moves along a surface at some noticeable speed, the contact point is also removed and a new contact is generated as long as you don’t move off the edge of the other body.

When my capsule hits the wall near the top of its jump arc and keeps pushing into the wall, it gets in a situation where it will move very little (as expected). For a few frames, the new contact point found between the objects is at about the same world position and gets updated (stays persistent) as intended. At this time, something unexpected happens. The contact position generated for one frame is at a noticeably different position from the previous frame without the objects having moved much at all. The new point is a valid point of contact between the surfaces, but not the same point. I haven’t investigated the code path followed when generating the point, but I am assuming it hits a conditional causing the code to follow a different branch based on the very small movement between the frames.

Now the object has two valid points of contact cached up. And each frame from now on, the oldest point is left alone (the object isn’t really moving so it remains a valid point of contact) and the new point keeps getting replaced with the new collision result to maintain its persistence. Although we’ve now got more contacts cached, this isn’t really a bad situation to be in because if we were to ever move, they would each get invalidated as necessary.

This leaves us at the question of why the objects are stuck. Gravity should accumulate and cause the capsule to fall. The reason it doesn’t fall relates to the applied impulse stored in each contact point. When a new contact is added, its impulse starts at zero. During the penetration correction, this value is then modified and is involved in the amount of friction placed on an object (the harder the object pushes into the ground, the more friction applied). When a contact point is replaced (maintaining persistence), its applied impulse is also set to zero with an interesting line commented out next to it (btPersistentManifold.h line 141).

Code: Select all

btScalar	appliedImpulse = 0.f;//m_pointCache[insertIndex].m_appliedImpulse;
The commented code would have maintained the impulse rather than clearing it. Not being too familiar with the high level intent of the penetration correction, I can’t speak on why this happens. Regardless, it would seem the impulse needs to get cleared each frame.

With the stored impulse only getting cleared for new points and replaced points, our old cached point never has it cleared. Every frame, we detect a point of contact, find it is near the newest cached point, replace the newest cached point, and clear its impulse. The impulse of the older cached point ends up accumulating from frame to frame. As the impulse goes up, the friction on the wall goes up and prevents gravity from causing the capsule to fall.

As a temporary solution to this issue, I am clearing all impulses when the contact points are refreshed. This happens in btPersistentManifold.cpp around line 214. I have added the following line of code into this loop.

Code: Select all

manifoldPoint.m_appliedImpulse = 0.f;
It is possible that we should never have gotten into this situation to begin with. In other words, the algorithm generating the contact points should have kept giving us the same result. Depending on the higher level intent of the code, a better solution may exist, but this one seems to have improved the situation for now.

Unfortunately, I am still getting the first issue I listed at the start of this post. I still have to check some more on numbers 2 and 4. Hopefully I can build repro cases for them.
ryanjuckett
Posts: 13
Joined: Tue Mar 11, 2008 9:04 am

Re: Contact bugs

Post by ryanjuckett »

Continuing my ongoing conversation with myself, I’ve managed to make a repro case for a dynamic box falling though a static box (issue 1 above). It’s set up to happen every time within my codebase (haven’t tried getting it to happen within one of the Bullet demos yet). I’ve attached an image below showing the frame by frame (60fps) result of the box falling. It is has been shoved off a ledge and is arcing on its way towards the ground.

The image has the physics wireframe and contact point displays enabled. It looks to me as if on the fourth frame of the image, a proper contact is generated. On the fifth frame it looks like it may have incorrectly picked a contact at the top of the dynamic box and the bottom of the static box.
You do not have the required permissions to view the files attached to this post.
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA

Re: Contact bugs

Post by Erwin Coumans »

First of all, thanks a lot for all the feedback and (self) discussion, it does help us actually. Hopefully you get better insight in Bullet's inner workings. Unfortunately we are currently extremely busy, including wrapping up a new 2.68 release, so it is difficult to help everyone.
It’s set up to happen every time within my codebase
If you have a reproducable issue, please file it to bullet.googlecode.com so it won't be forgotten. Can you share your codebase, or create a reproducable case in a Bullet demo?

Some tests:
If you disable warmstarting in the constraint solver:

Code: Select all

solver->setSolverMode(btSequentialImpulseConstraintSolver::SOLVER_CACHE_FRIENDLY);
it should ignore the m_appliedImpulse for each contact point.

Which version of Bullet are you using? Is this the GJK box-box or ODE box-box?
If it is using a special box-box, please comment out those lines, and see if that helps, in btDefaultCollisionConfiguration.cpp around line 227

Code: Select all

//if ((proxyType0 == BOX_SHAPE_PROXYTYPE) && (proxyType1 == BOX_SHAPE_PROXYTYPE))
//{
//	return m_boxBoxCF;
//}
Or if it is using GJK, please upgrade to latest Bullet 2.68 beta and see if that improves things.

There might be issues with btCapsuleShape*, we need to verify later.
Thanks,
Erwin
ryanjuckett
Posts: 13
Joined: Tue Mar 11, 2008 9:04 am

Re: Contact bugs

Post by ryanjuckett »

Can you share your codebase, or create a reproducable case in a Bullet demo?
I can try getting a the issue to happen in a Bullet demo if I can make it happen in a simpler scene.
Which version of Bullet are you using? Is this the GJK box-box or ODE box-box?
I'm running 2.67 and I think it was going through GJK code. I'll try setting up the 2.68 beta tonight and let you know what happens.
ryanjuckett
Posts: 13
Joined: Tue Mar 11, 2008 9:04 am

Re: Contact bugs

Post by ryanjuckett »

So I tried out the 2.68 beta 3 and it fixes the issue of the box going through the floor. It still has the applied impulse issue that causes the objects to get stuck at times. Disabling WARMSTARTING in the solver fixes the issue (might want to turn that off by default until the impulse stuff is worked out).

I'm also still getting my issue where spheres and capsules will occasionally pop of the ground slightly when moving along it. It's as if they slowly sink into the ground and then resolve to being slightly above ground. I haven't been able to get a repro case in one of the bullet demos yet.

Thanks for the help,
- ryan