btGeneric6DofSpring2Constraint blows up for kinematic rotate

Post Reply
ratatouille
Posts: 21
Joined: Fri Oct 24, 2014 10:48 am

btGeneric6DofSpring2Constraint blows up for kinematic rotate

Post by ratatouille »

hey,

There seems to be an issue with btGeneric6DofSpring2Constraint in combination with rotating one of the bodies to which it is attached.

Everything goes well until a certain point, where the non-kinematic sphere starts twitching and then experiences a violent jump. So it seems as if the constraint internally accumulates some value, which at some point becomes too large and causes the instability/jump. After the jump, the system returns back to normal (damped spring) and continues rotating, until the next instability occurs, over and over.

This seems to be completely independent of simulation timestep (I'm using fixed timestep), solver, velocity at which the kinematic object is rotated, or solver m_numIterations. It goes away completely if I use a btGeneric6DofSpringConstraint.

Is this a bug in btGeneric6DofSpring2Constraint? Any potential workarounds?
ratatouille
Posts: 21
Joined: Fri Oct 24, 2014 10:48 am

Re: btGeneric6DofSpring2Constraint blows up for kinematic ro

Post by ratatouille »

forgot to mention, also played with CFM and ERP, had only a very minor effect on when exactly the instabilities occurred. Also tried calling btGeneric6DofSpring2Constraint->calculateTransforms() after each kinematic move step, no success.
ratatouille
Posts: 21
Joined: Fri Oct 24, 2014 10:48 am

Re: btGeneric6DofSpring2Constraint blows up for kinematic ro

Post by ratatouille »

Looks like the following sequence of code for performing the kinematic update (just before the call to btDynamicsWorld.stepSimulation()) works:

Code: Select all

m_dynamicsWorld->removeRigidBody(rb);

btTransform tr;
rb->getMotionState()->getWorldTransform(tr);

tr.setRotation(btQuaternion(btVector3(0.f, 0.f, 1.f), btScalar(ampl * SIMD_PI * sin(2*SIMD_PI*freq*t))));

rb->setCenterOfMassTransform(tr);
rb->getMotionState()->setWorldTransform(tr);

rb->setInterpolationWorldTransform(rb->getWorldTransform());
rb->setInterpolationLinearVelocity(btVector3(0,0,0));
rb->setInterpolationAngularVelocity(btVector3(0,0,0));
rb->clearForces();

pGen6DOFSpring2->calculateTransforms();

m_dynamicsWorld->addRigidBody(rb);
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA
Contact:

Re: btGeneric6DofSpring2Constraint blows up for kinematic ro

Post by Erwin Coumans »

It may be a bug, I have to check it (btGeneric6DofSpring2Constraint is fairly new code and needs more tests).

Thanks for reporting. Does the workaround work for you?
Thanks!
Erwin
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA
Contact:

Re: btGeneric6DofSpring2Constraint blows up for kinematic ro

Post by Erwin Coumans »

It may be a bug, I have to check it (btGeneric6DofSpring2Constraint is fairly new code and needs more tests).

I filed an issue to investigate/fix: https://github.com/bulletphysics/bullet3/issues/334

Thanks for reporting. Does the workaround work for you?
Thanks!
Erwin
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA
Contact:

Re: btGeneric6DofSpring2Constraint blows up for kinematic ro

Post by Erwin Coumans »

Hi ratatouille,

The mass (and inertia) of kinematic objects needs to be set to zero, otherwise all constraints don't work well.
Could that be the problem?

Thanks,
Erwin
ratatouille
Posts: 21
Joined: Fri Oct 24, 2014 10:48 am

Re: btGeneric6DofSpring2Constraint blows up for kinematic ro

Post by ratatouille »

Hi Erwin,

Thanks for taking the time to look into this. The mass of the kinematic object was set to zero, so that wasn't the source of the problem. The code I posted solved the problem for me.
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA
Contact:

Re: btGeneric6DofSpring2Constraint blows up for kinematic ro

Post by Erwin Coumans »

Hi ratatouille,

I am very surprised that setting the (inverse) mass of the kinematic objects to zero doesn't solve your problem.
It is better to solve the problem properly instead of using your workaround.

Is it possible to reproduce your problem by modifying a Bullet demo, such as the Bullet/Demos/ConstraintDemo?
Thanks for your help!
Erwin
IresomPCH
Posts: 18
Joined: Tue Sep 24, 2013 12:29 pm

Re: btGeneric6DofSpring2Constraint blows up for kinematic ro

Post by IresomPCH »

Hi,

I've also tried to use 6DOFSpring2 to connect two rigidbodies.
However, is it necessary to set both mass and inertial to zero?

My settings:
MLCP Dantzig solver, 1000Hz stepSimulation, OverrideNumSolverIterations=120
rigidbody A: 0.5kg on the top, BoxShape
rigidbody B: 5kg on the bottom, BoxShape
A and B are 1m apart.

(ps. I use the BulletSharp version 2.83)
//----------------------------------------------------------------------------------------------
Matrix transform_temp = Matrix::Translation(Vector3(1, 2, 1));

RigidBody^ bodyA = LocalCreateRigidBody(0.5, transform_temp*Matrix::Translation(Vector3(0.0f, 0.5f, 0.0f)), ...);
RigidBody^ bodyB = LocalCreateRigidBody(5, transform_temp*Matrix::Translation(Vector3(0.0f, -0.5f, 0.0f)), ...);
bodyA->ActivationState = ActivationState::DisableDeactivation;
bodyB->ActivationState = ActivationState::DisableDeactivation;

dof6S = gcnew Generic6DofSpring2Constraint(bodyA, bodyB, localA, localB);
dof6S->SetLinearLowerLimit(Vector3(0.0f, -0.1f, 0));
dof6S->SetLinearUpperLimit(Vector3(0.0f, 0.1f, 0));
dof6S->SetAngularLowerLimit(Vector3::Zero);
dof6S->SetAngularUpperLimit(Vector3::Zero);

dof6S->EnableSpring(1, true);
dof6S->SetStiffness(1, 3947.8f);
dof6S->SetDamping(1, 0.001f);
dof6S->SetEquilibriumPoint();

float cfm = 0.1f;
float erp = 0.1f;

dof6S->SetParam(ConstraintParam::StopCfm, cfm, 0);
dof6S->SetParam(ConstraintParam::StopCfm, cfm, 1);
dof6S->SetParam(ConstraintParam::StopCfm, cfm, 2);
dof6S->SetParam(ConstraintParam::StopCfm, cfm, 3);
dof6S->SetParam(ConstraintParam::StopCfm, cfm, 4);
dof6S->SetParam(ConstraintParam::StopCfm, cfm, 5);

dof6S->SetParam(ConstraintParam::StopErp, erp, 0);
dof6S->SetParam(ConstraintParam::StopErp, erp, 1);
dof6S->SetParam(ConstraintParam::StopErp, erp, 2);
dof6S->SetParam(ConstraintParam::StopErp, erp, 3);
dof6S->SetParam(ConstraintParam::StopErp, erp, 4);
dof6S->SetParam(ConstraintParam::StopErp, erp, 5);
//----------------------------------------------------------------------------------------------

I can pick either body up and move/swing/rotate without above mentioned issue.
(relation: [Mouse] <-P2Pconstraint-> [Body1] <-6DofSpring2-> [Body2] )

The only problem I got is that the spring will "saturate" when a havier body is on top, no matter how high the stiffness is.

ex: If the 0.5kg body is on top, it just vibrate like a normal spring-mass system.
For stiffness of 3947.8f, Body weighted 1.0kg is fine, but the problem shows up when like >1.5kg

For normal spring, higher stiffness should results smaller deformation, right?
In this case, stiffness of 5000000 and 5kg on top makes no difference in deformation compared to stiffness of 500.
The body on top just compress the spring down to the limited postion...

I'm trying to simulated a tiny force sensor according to the deformation*stiffness.
Is there a proper way to setup a usable spring in Bullet? Thanks~
Post Reply