xiangaodielian / bullet

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

Softbody friction probably wrong #613

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
CollideSDF_RS calculates the friction between a softbody and rigidbody as:

c.m_c3      =   fv.length2()<(btFabs(dn)*fc)?0:1-fc;

From the way this value is later used, the intent of the condition appears to 
be to select between static friction (setting c3 = 0) and kinetic (a.k.a. 
dynamic) friction (c3 = 1-fc). Static friction is when an object remains in 
place due to friction, while kinetic friction occurs when the object is sliding.

But this threshold at which an object begins to slide is typically defined as:

  threshold = tan(theta_threshold)

where theta_threshold is the angle between the surface normal and the direction 
opposite to which the object is pressing on the surface at which sliding starts 
to occur. If the angle is greater than that, then the object will slide using 
kinetic friction.

In the context of the c3 calculation, fv is the projection of the node's motion 
vector onto the surface, while dn is the length of the motion projected onto 
the surface normal. Thus:

  tan(theta) = fv.length() / abs(dn)

(using an abs() on dn for symmetry sake). The threshold is the combined 
friction fc. One would therefore expect static friction when:

  fv.length() / abs(dn) < fc

which, rearranged a bit, gives:

  fv.length() < abs(dn) * fc

However the implementation uses fv.length2(), possibly to avoid the square 
root, but doesn't square the right hand side to match.

That effectively makes the threshold also dependent on the speed at which the 
node hits the surface, which is contrary to the usual treatment of friction.
Also, the units in the inequality wouldn't match. fv.length2() is metres^2, dn 
is in metres, and friction fc is unitless. It ends up comparing square metres 
to metres, which doesn't make much sense physically.

The same issue is in the ClusterBase collision code to calculate 
joint.m_friction.

Original issue reported on code.google.com by ja...@orcon.net.nz on 29 Mar 2012 at 2:02

GoogleCodeExporter commented 9 years ago
That sounds reasonable.

I suppose 
c.m_c3 = fv.length()<(btFabs(dn)*fc)?0:1-fc;
or
btScalar tmp = (btFabs(dn)*fc);
c.m_c3 = fv.length2()<tmp*tmp?0:1-fc;

Do you mind creating a suggested patch for both?

Original comment by erwin.coumans on 30 Mar 2012 at 7:25

GoogleCodeExporter commented 9 years ago
Patch attached. It squares the RHS. Tested with the SoftDemo demos.

Original comment by ja...@orcon.net.nz on 5 Apr 2012 at 8:29

Attachments:

GoogleCodeExporter commented 9 years ago
I finally got to apply the patch:
http://code.google.com/p/bullet/source/detail?r=2545

Thanks for your help!

Original comment by erwin.coumans on 31 Jul 2012 at 5:03