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?
btGeneric6DofSpring2Constraint blows up for kinematic rotate
-
- Posts: 21
- Joined: Fri Oct 24, 2014 10:48 am
-
- Posts: 21
- Joined: Fri Oct 24, 2014 10:48 am
Re: btGeneric6DofSpring2Constraint blows up for kinematic ro
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.
-
- Posts: 21
- Joined: Fri Oct 24, 2014 10:48 am
Re: btGeneric6DofSpring2Constraint blows up for kinematic ro
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);
-
- Site Admin
- Posts: 4221
- Joined: Sun Jun 26, 2005 6:43 pm
- Location: California, USA
Re: btGeneric6DofSpring2Constraint blows up for kinematic ro
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
Thanks for reporting. Does the workaround work for you?
Thanks!
Erwin
-
- Site Admin
- Posts: 4221
- Joined: Sun Jun 26, 2005 6:43 pm
- Location: California, USA
Re: btGeneric6DofSpring2Constraint blows up for kinematic ro
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
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
-
- Site Admin
- Posts: 4221
- Joined: Sun Jun 26, 2005 6:43 pm
- Location: California, USA
Re: btGeneric6DofSpring2Constraint blows up for kinematic ro
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
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
-
- Posts: 21
- Joined: Fri Oct 24, 2014 10:48 am
Re: btGeneric6DofSpring2Constraint blows up for kinematic ro
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.
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.
-
- Site Admin
- Posts: 4221
- Joined: Sun Jun 26, 2005 6:43 pm
- Location: California, USA
Re: btGeneric6DofSpring2Constraint blows up for kinematic ro
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
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
-
- Posts: 18
- Joined: Tue Sep 24, 2013 12:29 pm
Re: btGeneric6DofSpring2Constraint blows up for kinematic ro
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~
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~