Spring daming in bullet

Post Reply
Ehsanizadi
Posts: 72
Joined: Mon Dec 02, 2013 4:13 pm

Spring daming in bullet

Post by Ehsanizadi »

Hi,

Does anyone know what formula bullet use for application of damping to an spring?

And what is the unit of damping paramter? or is it dimensionless? (the range of damping is between 0 and 1).

I tried to look at the source code in "btGeneric6DofSpringConstraint.cpp", however, I couldnt understand it.
e.g.

Code: Select all

for(i = 0; i < 3; i++)
	{
		if(m_springEnabled[i])
		{
			// get current position of constraint
			btScalar currPos = m_calculatedLinearDiff[i];
			// calculate difference
			btScalar delta = currPos - m_equilibriumPoint[i];
			// spring force is (delta * m_stiffness) according to Hooke's Law
			btScalar force = delta * m_springStiffness[i];
			btScalar velFactor = info->fps * m_springDamping[i] / btScalar(info->m_numIterations);
			m_linearLimits.m_targetVelocity[i] =  velFactor * force;
			m_linearLimits.m_maxMotorForce[i] =  btFabs(force) / info->fps;
		}
	}
What is the "velFactor" ?
why it is multiplied by force?
What is target velocity?
what is max motor force?
and finally what does btFabs() do?
Dirk Gregorius
Posts: 861
Joined: Sun Jul 03, 2005 4:06 pm
Location: Kirkland, WA

Re: Spring daming in bullet

Post by Dirk Gregorius »

I assume Bullet uses some kind of soft constraint to model springs. Maybe this explanation in the ODE gives you an idea:
http://www.ode.org/ode-latest-userguide.html#sec_3_8_0

Erin Catto gave a presentation about soft constraints here:
https://box2d.googlecode.com/files/GDC2 ... raints.pdf


HTH,
-Dirk
Ehsanizadi
Posts: 72
Joined: Mon Dec 02, 2013 4:13 pm

Re: Spring daming in bullet

Post by Ehsanizadi »

Dirk Gregorius wrote:I assume Bullet uses some kind of soft constraint to model springs. Maybe this explanation in the ODE gives you an idea:
http://www.ode.org/ode-latest-userguide.html#sec_3_8_0

Erin Catto gave a presentation about soft constraints here:
https://box2d.googlecode.com/files/GDC2 ... raints.pdf


HTH,
-Dirk
Thanks for the useful links. Actually I was completely unaware of existence of such method. I read it, however, there are some points that I dont understand:
If Bullet solves constraint springs based on the 'soft constraint' concept, it should solve such equation:
J*v + erp * C * x / h + cfm * Lambda= 0
J: impulse
v: velocity
erp: error reduction parameter
C: position error
h: time step
Lambda: constraint force
cfm: constraint force mixing

But in the code I appended in my previous post, something like this is going to be calculated:
-------------------
Force = Δx * K
K: spring stiffness
Δx: change in the spring length
-------------------
velFactor = D / (h * Nt)
D: damping
Nt: iteration number
-------------------
targetVelocity = Force * VelFactor = K * Δx * D / (h * Nt)
----------------------------------------------------

So my questions are:

Where is cfm?
How cfm and erp calculated?
Is that the whole process for solving soft constraints?

Sorry if my questions sound dumb, well, I am new to bullet, c++ and coding.
Thanks beforehand for your help.
Ehsan
Dirk Gregorius
Posts: 861
Joined: Sun Jul 03, 2005 4:06 pm
Location: Kirkland, WA

Re: Spring daming in bullet

Post by Dirk Gregorius »

Sorry, I don't know the internals of Bullet. I think there is a path in Bullet that calls into the ODE quickstep function. You can check there and see how the constraints/joints are setup.
Dirk Gregorius
Posts: 861
Joined: Sun Jul 03, 2005 4:06 pm
Location: Kirkland, WA

Re: Spring daming in bullet

Post by Dirk Gregorius »

I am wildly guessing now, but maybe Bullet uses motors. Essentially you can have a motor working on free axis of joint. The motor is defined by a target velocity and a maximum force to reach that velocity. E.g. you can define a target velocity of zero and a maximum force based on the joint geometry to model joint friction.

Kenny's PhD talks about motors: http://image.diku.dk/kenny/download/erl ... thesis.pdf
Helmut provides a good overview as well: http://www.digitalrune.com/portals/0/do ... namics.pdf
kingchurch
Posts: 28
Joined: Sun May 13, 2012 7:14 am

Re: Spring daming in bullet

Post by kingchurch »

Based on the quoted code from "btGeneric6DofSpringConstraint.cpp" in the original post, the 6Dof spring constraint in Bullet is just a spring force element. It's not soft constraint which is still implicit and still need a solver like the QuickStep to solve the equations. A force element is much simpler and he can just apply a spring force like f = P * d + D * vel every frame where P is the spring stiffness constant and D is the damping factor.
Dirk Gregorius
Posts: 861
Joined: Sun Jul 03, 2005 4:06 pm
Location: Kirkland, WA

Re: Spring daming in bullet

Post by Dirk Gregorius »

I don't think so. The code sets the target velocity and maximum force of the limit in the constraint. This indicates to me it goes through the constraint solver which will try to reach the target velocity. A PD controller would just compute the force and use the ApplyForce() interface of the body. I agree with you that you would either use a soft constraint or a PD controller. I have never seen this kind setup and it doesn't make sense to me. But it might work great in practice.
Ehsanizadi
Posts: 72
Joined: Mon Dec 02, 2013 4:13 pm

Re: Spring daming in bullet

Post by Ehsanizadi »

Thanks for your responses,
Actually what I am looking for, is the calculation loop (based on the Bullet code) for springs. For example in which files I can track the calculation loops of the springs.

What I am going to do is to compare the behaviour of hard constraint based springs with soft constraint ones.
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA
Contact:

Re: Spring daming in bullet

Post by Erwin Coumans »

Recently someone provided an improved spring implementation in a new btGeneric6DofSpring2Constraint file.

He started with the CFM/ERP conversion formula from the ODE manual (explained later by Erin Catto), but he had some issues.
So according to him his new implementation is better. You could try it.
Gabor Puhr wrote: Originaly I implemented what is in Erin Catto's "Soft Constraints" paper (thoug the original formula is from ODE).
Unfortunately there are a lot of usefull parameters where the result is not very good. (for example because the CFM is greater than 1)
Also the energy dissipation it very big, so I couldn't setup a spring that oscillates.

So with my colleague Tamas Umenhoffer we created a new algorithm that works with a wide variation of parameters and the energy loss is minimal.

For the new 6dof:

Pros:
- Much more accurate and stable in a lot of situation. (Especially when a sleeping chain of RBs connected with 6dof2 is pulled)
- Stable and accurate spring with minimal energy loss that works with all of the solvers. (latter is not true for the original 6dof spring)
- Servo motor functionality
- Much more accurate bouncing. 0 really means zero bouncing (not true for the original 6odf) and there is only a minimal energy loss when the value is 1 (because of the solvers' precision)
- Rotation order for the Euler system can be set. (One axis' freedom is still limited to pi/2)

Cons:
- It is slower than the original 6dof. There is no exact ratio, but half speed is a good estimation.
- At bouncing the correct velocity is calculated, but not the correct position. (it is because of the solver can correct position or velocity, but not both.)

What makes it stable that as we discussed it creates two solver constraint instead of one if the lo limit and the hi limits are not the same.
Each one is responsible only for one side. This makes possible to create the solver constraints even when the typed constraint is not violated.
This is important because when an outer force or constraint causes error in this constraint the old 6dof started to fix it only in the second step (not in the one where the error was generated)
When the hi and lo are the same it generates only one solver constraint, but similarly to the upper case it happens always so it can react to any error immediately.
Creating everything always may seems a bit overhead, but the fact is once one starts to move a chain of rigidbodies (connected with constraints) there will be a lot of error almost immediately so even the old 6dof would generate the solver constraints (just not from the very beginning).
When everything is calm the RBs are sleeping so nothing is calculated. (so no overhead)

The spring is considered as a damped harmonic oscillator. As such the balance of forces is: F = -kx - cx' . (where the k is the stiffness and c is the damping)
It is calculated that what would be the velocity of the affected body (bodies) if this much force affect it. A solver can correct velocity. So the m_constraintError is simply set to a value to try to correct the body(es) velocity to this value.
There are two fail safe "if" to not overdamp or oversample the spring. Over and above the maximum force that this solver constraint can cause is limited to the F for pulling and -cx' for pushing.
The logic here is that the spring pull the object with the force of F, but if there is dumping it can cause opposite force if the object is pushed to the equilibrium point with a big enough second force. The maximum of this is the component caused by the damping.

The servo is a very minor modification of the motor functionality. Instead of stopping it at the lo or hi limit this constraints stop it at the servo target. (that is defined by the user)
Obviously hi, lo and servo target can be positioned relative to each other in a various ways, but it can be handled with a few "if".

I felt the bounce was a small hack in the old 6odf, but it worked (more or less), so I used a similarly approach.
When the m_constraintError is calculated I check the relative velocity of the two bodies (connected with the current constraint).
If it would cause a violation of the limits in the next frame (without the correction of the solver) then I assume there is a bounce in the actual step so I just simply calculate an m_constraintError that causes a velocity flip.
(I have to admit though that it took me some time to find out the correct handling of the stopERP here.)

Changing the rotation order is very strait forward, just have to swap the axises correctly. :) Thanks for Tamas to deduce all the variations correctly.

There are a couple of new setter functions for the new functionalities at the end of the class definition. I hope the functions` name are self explaining.
See attached files. I will integrate this into the Bullet github repository soon (at http://github.com/bulletphysics/bullet3)
Thanks!
Erwin
Attachments
6dofnew.zip
(18.01 KiB) Downloaded 597 times
kingchurch
Posts: 28
Joined: Sun May 13, 2012 7:14 am

Re: Spring daming in bullet

Post by kingchurch »

This looks awesome!

Erwin: Is it straightforward to integrate one of these "soft constraint" springs into btMultiBody ? Or can we already simulate mobilizer springs (springs along the DoF permitted by the joint) with the current motor constraint for btMultiBody ?
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA
Contact:

Re: Spring daming in bullet

Post by Erwin Coumans »

kingchurch wrote:This looks awesome!

Erwin: Is it straightforward to integrate one of these "soft constraint" springs into btMultiBody ? Or can we already simulate mobilizer springs (springs along the DoF permitted by the joint) with the current motor constraint for btMultiBody ?
Only a few specific constraints are working with btMultiBody at the moment indeed.

I plan on adding support for other constraints for btMultiBody, such as btGeneric6DofSpring2Constraint.
The project just lacks resources/manpower so it could take a little while, hopefully later this year.
Post Reply