Experimenting with sub0.2 spheres and boxes

Post Reply
sparkprime
Posts: 508
Joined: Fri May 30, 2008 2:51 am
Location: Ossining, New York
Contact:

Experimenting with sub0.2 spheres and boxes

Post by sparkprime »

Using small objects in Bullet is generally frowned upon and many have reported problems with their simulations when doing so. However, since I sold my car I don't think I own any objects that can be decomposed into convex parts which are wider than 20cm on every axis. Certainly nothing in my home, as chairs, tables, etc do not fit these requirements. Scaling the world isn't much fun, so ideally we would want to be able to just use these values in our simulations and for everything to just work.

As I have become more knowledgeable about Bullet, I have learnt about various things that can be tweaked to affect the simulation. So I wanted to see if they could be used to allow stable small-scale simulations without having to scale the world.

For the sake of experiment, I had a go at creating a basic pool/snooker game. The balls were 0.02 radius spheres, the cushions were boxes 0.04 wide, and I also had some dynamic boxes on the table with the balls, these were the same size as the balls, i..e had halfwidths of 0.02,0.02,0.02.

Gravity was 9.8.

The first thing I did was change the internal time step to something more appropriate for this scale. A sphere resting on a plane will fall ( 0.5 )( 9.8 )( t^2 ) units every internal tick. For the default 60hz this is 0.001 units. For a 1 radius sphere, this is only 0.1% of its radius. For the 0.02 radius sphere however, it is 5% of the sphere's radius.

To make this fair I could either change gravity to a tiny 0.196 or increase the internal step frequency to about 500hz. I chose the latter. A pool simulation is tiny and a 500hz simulation is perfectly within the realms of even my modest PC which is an early Pentium 4 running at 1800mhz.

The balls had a linear and angular sleep threshold of 0, i.e. they never deactivated. I gave them a mass of 0.75 for no particular reason. Their restitution was 0.9 and the friction was 0.1.

The "slate" of the table was a static plane shape, with restitution 0.2 and a friction of 0.3.

The "cushions" were boxes with restitution 0.7 and friction 0.5

Chucking balls onto the table works quite well and they behave very realistically. One can see the effect of spinning the ball, especially after collisions with cushions.

There are still some issues however.

If there is no restitution, the balls and boxes tend to "twitch" occasionally when you zoom in on them. This is a very pronounced effect at 60hz but 500hz almost defeats it. A stack of 3 boxes seemed no worse than a single box. In the sphere case, the sphere bounces on the spot. The boxes tend to wobble as the problem seems to only affect a single contact at a time. It didn't matter whether i put the rigid bodies on the slate or on the cushion, so the problem occurs with a static plane and static box.

Setting angular damping to 1 (i'm using my damping patch otherwise this wouldn't actually work) gets rid of the twitching.

It was at this point I tried tweaking gContactBreakingThreshold from its default value of 0.02 to 0.002 and other sensible values. It seemed to make no difference. Setting it to 0 caused objects to sink through each other but not the floor or the cushions. Setting it to extreme values causes various weirdness but nothing made it behave obviously better than the default of 0.02

I also tried increasing and decreasing the number of solver iterations but this had no effect either. Even on performance. I think the number of bodies being simulated is just too low.

With restitution the twitch turns into a continual jitter/bounce. Presumably this is the same problem but exasperated as the artifacts take longer to decay.

Changing the "erp" value produces some changes. With erp==0 there is no twitch but objects sink into the floor as if it was a quicksand. With erp > 0.2 (the default) the twitch turned into a rapid jitter.

With linearSlop set above the default of 0, the twitch goes away while the objects are stationary, but setting it too high makes the objects sink into the ground. 0.000001 seemed to work. What does linearSlop do?

Setting the contact solver info's damping attribute to various values seemed to make no difference.

Turning on solverSplitImpulse made no difference.

So in conclusion I think objects of this scale are feasible if one is prepare to use a small fixed time step. There are still artifacts that can be eliminated. I tried tweaking all the internal parameters I know about but I couldn't make the "twitching" go away except with this linearSlop thing which I don't understand.
sparkprime
Posts: 508
Joined: Fri May 30, 2008 2:51 am
Location: Ossining, New York
Contact:

Re: Experimenting with sub0.2 spheres and boxes

Post by sparkprime »

It's possible to get a simulation of 0.02 radius spheres with 9.8 gravity running nicely even at 60hz. This allows 100 balls to be simulated very comfortably (35% CPU including graphics). There is tunneling if you hit the balls too fast, but that's to be expected.

This only works if there is no restitution involved with the ground (other interactions can have restitution).

Similarly-sized boxes are OK too but only if they are stationary. When they slide they "jiggle" quite a lot.

gContactBreakingThreshold needs to be less than the width of the smallest box but otherwise doesn't do much.

linearSlop works best at 0.00001 and doesn't seem to affect the simulation negatively.

The boxes behave a bit better with a higher erp, e.g. 0.3 or 0.4. I think this compensates somewhat for the sinking side-effect of linearSlop.

Any artiifacts are reduced when using a higher frequency e.g. 500hz.

If anyone has any suggestions about other things to try, please tell me :) I'll report the results back and eventually write a wiki article. Small-scale simulations in Bullet are beginning to look feasable!
gfm
Posts: 16
Joined: Tue Sep 09, 2008 8:56 am
Contact:

Re: Experimenting with sub0.2 spheres and boxes

Post by gfm »

Hey sparkprime,

I've been trying to do kinda the same thing.. get small(ish) objects falling onto a trimesh. I tried adding spheres of size 0.2 but they frequently fall through the trimesh. Stepping through SphereTriangleDetector::collide() it looks like what's happening is the ball is completely above a triangle one frame and then completely through it on the next frame.

The only way I've been able to get a sphere of size 0.2 to collide with the terrain properly is to call stepSimulation() with a time interval of at least 300Hz.

gContactBreakingThreshold doesn't matter in this case because the sphere is literally out of contact with the trimesh both frames. Even if I force a contact by setting isInsideShellPlane=true it still misses the poly test.

When is btContinuousDynamicsWorld gonna be ready? :-)
Ahigh
Posts: 1
Joined: Wed Jan 26, 2011 11:04 pm

Re: Experimenting with sub0.2 spheres and boxes

Post by Ahigh »

I'm working on something very similar. The only thing is that I hadn't figured out the right parameters to StepSimulation yet. I tried some things but I didn't get the results that I was hoping for.
Post Reply