Bullet 2.77 Restitution issue.

PepeLui
Posts: 2
Joined: Wed Jan 26, 2011 2:45 pm

Bullet 2.77 Restitution issue.

Post by PepeLui »

Hi,

I've been doing some validation tests to see if Bullet will fulfill the requirements to be used as a physics engine in our simulation.

The first test was to see if Bullet applies restitution forces well. The scenario was: drop a ball, with no initial velocity, with restitution = 1.0 and see if it bounces to the same height. We found out that the ball bounces to much higher distances. Real restitution was something like 1.3. Setting splitImpulse = true, led to real restitution closer than expected but no exactly 1.0.

The problem is that after the collision the ball gets more speed than it should. This exceed of velocity is always around 0.01041675, despite of the height the wall is dropped.

Is this a know issue? is there a work around for it?

Thanks!
youcancallmeAl
Posts: 5
Joined: Thu Jul 21, 2011 5:18 pm

Re: Bullet 2.77 Restitution issue.

Post by youcancallmeAl »

This is also a problem in ver 2.78, and there are several threads on these restitution issues right now. No workaround has been suggested yet, at least to my knowledge.
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA

Re: Bullet 2.77 Restitution issue.

Post by Erwin Coumans »

Most of the restitution issues reported in the forums seem not to enable the 'splitImpulse'. Without using split impulse, the restitution will add energy, that is a known issues of the Baumgarte stabilization in the constraint solver.

Split impulse will deal with that part, so if restitution is important you need to enable it. Continuous collision detection (motion clamping) also causes restitution issues, but this is disabled by default (and only kicks in at higher speeds).

Can you create a reproduction case, with split impulse enabled and no CCD, that shows this behaviour?
Thanks!
Erwin
FlipFlop
Posts: 2
Joined: Mon Aug 08, 2011 8:14 pm

Re: Bullet 2.77 Restitution issue.

Post by FlipFlop »

I've put the settings in BasicDemo to show a restitution issue that's been driving me nuts.

When the falling rigidbody is a BoxShape the restitution works well but when it's a SphereShape there's hardly any bounce at all.

SplitImpulse is enabled and CCD isn't.

I'm trying to use bullet for a soccer game but it's kinda problematic that the ball won't bounce..

Would be nice if it worked well while CCD is enabled too .. sometimes the ball will pass through the net on hard shots.

- FlipFlop
You do not have the required permissions to view the files attached to this post.
FlipFlop
Posts: 2
Joined: Mon Aug 08, 2011 8:14 pm

Re: Bullet 2.77 Restitution issue.

Post by FlipFlop »

Any progress ?
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA

Re: Bullet 2.77 Restitution issue.

Post by Erwin Coumans »

I haven't looked into the problem yet, but if you replace the btSphereShape with a btMultiSphereShape, restitution seems to work.

Code: Select all

btVector3 pos(0,0,0);
btScalar radius(1.0:
shape = new btMultiSphereShape(&pos, &radius,1);
Thanks,
Erwin
User avatar
jarno
Posts: 57
Joined: Tue Mar 16, 2010 1:42 am

Re: Bullet 2.77 Restitution issue.

Post by jarno »

As this issue persists in 2.78 and I believe 2.79 as well, and I'm having the same problem, I traced through it all and found the problem.

It's in btSequentialImpulseConstraintSolver::setupContactConstraint(), particularly this part:

Code: Select all

	btScalar positionalError = 0.f;
	btScalar	velocityError = restitution - rel_vel;// * damping;

	if (penetration>0)
	{
		positionalError = 0;
		velocityError -= penetration / infoGlobal.m_timeStep;
	} else
	{
		positionalError = -penetration * infoGlobal.m_erp/infoGlobal.m_timeStep;
	}
What it tries to do when penetration is larger than 0 (which is what happens when an object is almost but not quite touching another) is calculate the change in velocity required so that collision occurs exactly on the next time step. But that only works if the restitution speed is zero.

When there is no bouncing, ideally you want an object that collides to stop exactly at the collision point. As Bullet takes steps in time, where velocity is kept constant within the time step, this can normally not be guaranteed. Either you stop the object now, while it is still slightly short of actually colliding, or at the next time step when it will likely have moved past the collision point and will then be penetrating. Both these cases tend to attract complaints from end-users, as either objects will either hover above a surface, or stick into it.

The solution attempted to be applied here is to compute a change in velocity so that after the next time step the object will be colliding exactly (i.e. the penetration value will then be 0, assuming no other external forces). In effect, slow the object down to stop it from overshooting (it won't undershoot, as otherwise no contact would have been registered in the first place).

To move a distance equal to the current penetration value over one time step, the new speed has to be:

Code: Select all

new speed = - penetration / timestep
change in speed = new speed - current speed = - penetration / timestep - rel_vel
which is exactly what is implemented, provided restitution speed is zero!

With a non-zero restitution, this actually causes the restitution speed to be slowed down. By how much depends on the penetration value. If the penetration is very close to zero, then you will get very close to the restitution speed. However if the penetration value is relatively large, then the restitution speed can be reduced to a value much smaller than expected and the object will hardly bounce even with a large restitution parameter set.

A similar argument applies when the penetration value is negative. Then there can be an extra boost given to the object (particularly when split impulse is turned off), which makes the object bounce back faster than expected instead of slower.

This was a code change in March 2011 (revision 2326) in relation to predictive contact constraints apparently.

I'm thinking of some ways of fixing this without re-introducing undershoot or overshoot for objects that are expected to not bounce. Possibly use some threshold based on the restitution value to mix in the penetration/timestep term.

---JvdL---
monkeyman
Posts: 22
Joined: Sat Nov 26, 2011 5:41 pm

Re: Bullet 2.77 Restitution issue.

Post by monkeyman »

jarno wrote: What it tries to do when penetration is larger than 0 (which is what happens when an object is almost but not quite touching another) is calculate the change in velocity required so that collision occurs exactly on the next time step. But that only works if the restitution speed is zero.

When there is no bouncing, ideally you want an object that collides to stop exactly at the collision point. As Bullet takes steps in time, where velocity is kept constant within the time step, this can normally not be guaranteed. Either you stop the object now, while it is still slightly short of actually colliding, or at the next time step when it will likely have moved past the collision point and will then be penetrating. Both these cases tend to attract complaints from end-users, as either objects will either hover above a surface, or stick into it.

The solution attempted to be applied here is to compute a change in velocity so that after the next time step the object will be colliding exactly (i.e. the penetration value will then be 0, assuming no other external forces). In effect, slow the object down to stop it from overshooting (it won't undershoot, as otherwise no contact would have been registered in the first place).
Seems like you had a good night of tracing there :)

What is the exact definition of restitution in that code context? Couldn't you try to calculate the desired resulting velocity the next timestep depending on restitution, without any thresholds?

Are constraints actually set up for penetrations that are already on their way of resolving themselves by the way? (like a corner of a box, penetrating into a plane, but where the angular velocity of the box is pulling the corner up)
User avatar
jarno
Posts: 57
Joined: Tue Mar 16, 2010 1:42 am

Re: Bullet 2.77 Restitution issue.

Post by jarno »

monkeyman wrote:What is the exact definition of restitution in that code context?
In that code snippet the restitution is the calculated desired speed after collision. In essence the current speed times the restitution factor set by colobj->setRestitution().

One could change the logic so that if the restitution factor is set to zero, it is inferred that the user's intention is for the object to come to a perfect stop exactly on the collided object, so therefore compute a change in speed that achieves that after one time step, based on the current speed and penetration distance. In all other cases, assume that preserving the user's desired degree of bounciness is most important and use only the current speed and restitution speed to calculate a speed change.
In the former case, the collision will be precise but the speed over the next time step will be physically wrong (the object slows down just before hitting). In the latter case, the speed after collision will be correct, but the implied collision point will be wrong (the object will be taken to start bouncing where it is at the start of the time step, even though it is some distance away from the correct collision point).

As for using a threshold, or actually a smooth step function, it's because I dislike discontinuous behaviour in a physics engine. They tend to bring with them infinite energies and forces. Increasing the restitution factor a tiny bit from 0 would significantly and abruptly alter the behaviour of the simulation. Better to ease in and out of the two behaviours.
Are constraints actually set up for penetrations that are already on their way of resolving themselves by the way?
I haven't looked at that, but I believe it sets up collision constraints for every collision in the collision manifold, even if redundant now or in the near future. Like it is based on an instant snapshot of the scene with no information about where objects are moving to or coming from (I know CCD makes this picture a bit blurrier).

---JvdL---