Spring constraints?

acron^
Posts: 6
Joined: Fri Jan 16, 2009 10:08 am

Spring constraints?

Post by acron^ »

What's the best combination of constraint type and settings to simulate springs? There doesn't appear to be a native constraint.

Cheers,
nethin
Posts: 2
Joined: Tue Mar 24, 2009 3:17 pm

Re: Spring constraints?

Post by nethin »

Hello All,

Recently, I've been looking into creating an axis-aligned spring constraint, and was hoping to gain some insight from the bullet community.

My specific project calls for a column of rigid bodies connected by springs. I've looked into simulating the springs with slider constraints and linear motors (mentioned here). Unfortunately, this doesn't completely solve the problem, as it requires a collision to translate a force up the chain. And it seems that multiple motors are required per rigid body to handle both the push and pull of a "spring".

Looking into the source code for btTypedConstraint, I see that constraints need jacobian matrices (which are new to me).

There is an interesting article on assembling the Jacobian matrix for a 2D spring here.

Am I headed in the right direction? Has anyone attempted implementing this yet?
Any help with generating the Jacobian matrix would be hugely appreciated.


Thanks,
Andy
nethin
Posts: 2
Joined: Tue Mar 24, 2009 3:17 pm

Re: Spring constraints?

Post by nethin »

After discussing this further with a friend, we've determined that the 2D spring article mentioned above is not for a dynamic system.

So, as a follow up:

1) How similar would a spring be to a two point soft body? Perhaps the soft body calculations could be applied here.

2) It seems that the desired motion could be similar to a swinging rope. Could those calculations be modified to work here?
User avatar
rponomarev
Posts: 56
Joined: Sat Mar 08, 2008 12:37 am

Re: Spring constraints?

Post by rponomarev »

Hello,

The current version of Bullet (2.74) does not have spring motors for constraints.
We plan to add them in future.

However as a workaround you could easily simulate the spring using existing constraint (e.g. slider) and motors
Here is an example:

Code: Select all

class btSliderSpringConstraint : public btSliderConstraint
{
public:
	btScalar	m_springStiffness;
	btScalar	m_equilibriumPoint;
	// constructor
    btSliderSpringConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA)
		: btSliderConstraint(rbA, rbB, frameInA, frameInB, useLinearReferenceFrameA)
	{
		// take the initial position as equilibrium point for spring (could be reset in future)
		calculateTransforms();
		testLinLimits();
		m_equilibriumPoint = getLinearPos();
		// set stiffness to (2*M_PI)*(2*M_PI) to get period 1 sec for mass 1.0 kg
		// it could be changed in future
		m_springStiffness = btScalar(39.478f);
		// enable motor
		setPoweredLinMotor(true);
		// disable linear limits
		setLowerLinLimit( 1.0f);
		setUpperLinLimit(-1.0f);
		// fix angular limits
		setLowerAngLimit(0.0f);
		setUpperAngLimit(0.0f);
	}
	void updateSpringMotor(btConstraintInfo2* info)
	{
		// get current position of constraint (actually X coordinate of frameB in frameA)
		btScalar currPos = getLinearPos();
		// calculate difference
		btScalar delta = currPos - m_equilibriumPoint;
		// spring force is (-delta * m_stiffness) according to Hooke's Law
		btScalar force = -delta * m_springStiffness;
		// use setTargetLinMotorVelocity() to set right-hand side of constraint equation
		setTargetLinMotorVelocity(force  * info->fps);
		// use setMaxLinMotorForce() to set limits for the constraint solver
		setMaxLinMotorForce(btFabs(force) / (info->fps * info->fps));
	}
	virtual void getInfo2 (btConstraintInfo2* info)
	{	// this will be called by constraint solver at the constraint setup stage
		// set current motor parameters
		updateSpringMotor(info);
		// do the rest of job for slider setup
		btSliderConstraint::getInfo2(info);
	}
};

Hope this will help,
Roman