Questions about constraints

Post Reply
inzombiak
Posts: 16
Joined: Wed Nov 25, 2015 3:34 pm

Questions about constraints

Post by inzombiak »

Hi everyone, I'm currently trying to wrap bullet for a personal project and I have a few questions regarding constraints:

1. Are there any major performance differences between the different constraints? I want to make the wrapper as simple as possible and wanted to only use the btGeneric6DofConstraint and lock whatever axes I needed. Is this a good approach? Would I be better off creating cases and utilizing each of the constraints for special cases?

2. How do you stop or slow down a constrained object? I created a swinging box using the btGeneric6DofConstraint and applied a force and the swinging didn't stop (maybe I didn't wait long enough (~10-15 min)). Do I need to manually apply a counter force?

3. My next question is regarding the frameInA and frameInB parameters of the btGeneric6DofConstraint constructor. First I tried using the method in Dof6SpringSetup.cpp in \examples\Constraints

Code: Select all

btTransform frameInA, frameInB;
frameInA.setIdentity();
frameInA.getOrigin() = btVector3(0, -5, 0);
frameInB.setIdentity();
frameInB.setOrigin(btVector3(0, 4, 0));
While it works the movement of the object becomes unstable over time.

Next I tried rponomarev's suggestion in this discussion, which solved my problems, but I don't understand the following section very well:

Code: Select all

  btVector3 parentAxis(1.f, 0.f, 0.f);
   btVector3 childAxis(0.f, 0.f, 1.f);
   btVector3 anchor(0.f, 2.f, 0.f);
   // build frame basis
   // 6DOF constraint uses Euler angles and to define limits
   // it is assumed that rotational order is :
   // Z - first, allowed limits are (-PI,PI);
   // new position of Y - second (allowed limits are (-PI/2 + epsilon, PI/2 - epsilon), where epsilon is a small positive number
   // used to prevent constraint from instability on poles;
   // new position of X, allowed limits are (-PI,PI);
   // So to simulate ODE Universal joint we should use parent axis as Z, child axis as Y and limit all other DOFs
   // Build the frame in world coordinate system first
   btVector3 zAxis = parentAxis.normalize();
   btVector3 yAxis = childAxis.normalize();
   btVector3 xAxis = yAxis.cross(zAxis); // we want right coordinate system
   btTransform frameInW;
   frameInW.setIdentity();
   frameInW.getBasis().setValue(   xAxis[0], yAxis[0], zAxis[0],   
                           xAxis[1], yAxis[1], zAxis[1],
                           xAxis[2], yAxis[2], zAxis[2]);
   frameInW.setOrigin(anchor);
   // now get constraint frame in local coordinate systems
   btTransform frameInA = pBodyA->getCenterOfMassTransform().inverse() * frameInW;
   btTransform frameInB = pBodyB->getCenterOfMassTransform().inverse() * frameInW;
I dont understand how the "parentAxis" and "childAxis" are chosen. From what I gather they are used to create a matrix to transform obj1 and obj2 from world space to joint space. Is this correct? Where do the "parentAxis" and "childAxis" come from?

4. Finally, should I use btGeneric6DofSpring2Constraint instead? I know its more stable, but the documentation says its also slower.

I'd be grateful for any insight.
benelot
Posts: 350
Joined: Sat Jul 04, 2015 10:33 am
Location: Bern, Switzerland
Contact:

Re: Questions about constraints

Post by benelot »

inzombiak wrote:Hi everyone, I'm currently trying to wrap bullet for a personal project and I have a few questions regarding constraints:

1. Are there any major performance differences between the different constraints? I want to make the wrapper as simple as possible and wanted to only use the btGeneric6DofConstraint and lock whatever axes I needed. Is this a good approach? Would I be better off creating cases and utilizing each of the constraints for special cases?
There are mayor differences between the different constraints, performance and stability as well. You will be much better off by making cases and utilizing each of the constraint for special cases. Have a look at the constraints : http://bulletphysics.org/mediawiki-1.5. ... onstraints
inzombiak wrote: 2. How do you stop or slow down a constrained object? I created a swinging box using the btGeneric6DofConstraint and applied a force and the swinging didn't stop (maybe I didn't wait long enough (~10-15 min)). Do I need to manually apply a counter force?
Your object will not slow down, as there is no damping force. You can either use damping on a joint, which is available for some joint if I remember correctly. Alternatively, you can also apply a counter force yourself by taking the current velocity in vector form and then apply it as a force with a negative constant in front of it. By varying the constant, you vary the amount of damping.
damping_force = -c*current_velocity
inzombiak wrote: 3. My next question is regarding the frameInA and frameInB parameters of the btGeneric6DofConstraint constructor. First I tried using the method in Dof6SpringSetup.cpp in \examples\Constraints

Code: Select all

btTransform frameInA, frameInB;
frameInA.setIdentity();
frameInA.getOrigin() = btVector3(0, -5, 0);
frameInB.setIdentity();
frameInB.setOrigin(btVector3(0, 4, 0));
While it works, the movement of the object becomes unstable over time.
This might be because the rotation you set to identity might not match the orientation of your two constrained objects. Also, using a more specialized constraint might remove the instability.
inzombiak wrote: Next I tried rponomarev's suggestion in this discussion, which solved my problems, but I don't understand the following section very well:

Code: Select all

  btVector3 parentAxis(1.f, 0.f, 0.f); 
   btVector3 childAxis(0.f, 0.f, 1.f);
   btVector3 anchor(0.f, 2.f, 0.f);
   // build frame basis
   // 6DOF constraint uses Euler angles and to define limits
   // it is assumed that rotational order is :
   // Z - first, allowed limits are (-PI,PI);
   // new position of Y - second (allowed limits are (-PI/2 + epsilon, PI/2 - epsilon), where epsilon is a small positive number
   // used to prevent constraint from instability on poles;
   // new position of X, allowed limits are (-PI,PI);
   // So to simulate ODE Universal joint we should use parent axis as Z, child axis as Y and limit all other DOFs
   // Build the frame in world coordinate system first
   btVector3 zAxis = parentAxis.normalize();
   btVector3 yAxis = childAxis.normalize();
   btVector3 xAxis = yAxis.cross(zAxis); // we want right coordinate system
   btTransform frameInW;
   frameInW.setIdentity();
   frameInW.getBasis().setValue(   xAxis[0], yAxis[0], zAxis[0],   
                           xAxis[1], yAxis[1], zAxis[1],
                           xAxis[2], yAxis[2], zAxis[2]);
   frameInW.setOrigin(anchor);
   // now get constraint frame in local coordinate systems
   btTransform frameInA = pBodyA->getCenterOfMassTransform().inverse() * frameInW;
   btTransform frameInB = pBodyB->getCenterOfMassTransform().inverse() * frameInW;
I dont understand how the "parentAxis" and "childAxis" are chosen. From what I gather they are used to create a matrix to transform obj1 and obj2 from world space to joint space. Is this correct? Where do the "parentAxis" and "childAxis" come from?
The parentAxis and childAxis are chosen to be perpendicular, that is everything. Then he produces the third perpendicular axis using the cross product. Then he creates the matrix which represents the desired joint axes which he then transforms from world frame of reference to the local object frame of reference. That is how you fix your joint setup so that your frames of reference coincide in the world reference frame.
inzombiak wrote: 4. Finally, should I use btGeneric6DofSpring2Constraint instead? I know its more stable, but the documentation says its also slower.

I'd be grateful for any insight.
You should not use it, except if you really need the springs. It is more stable, but believe me, you are looking for something more simple.
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA
Contact:

Re: Questions about constraints

Post by Erwin Coumans »

benelot wrote:
inzombiak wrote: 4. Finally, should I use btGeneric6DofSpring2Constraint instead? I know its more stable, but the documentation says its also slower.

I'd be grateful for any insight.
You should not use it, except if you really need the springs. It is more stable, but believe me, you are looking for something more simple.
I would recommend using the btGeneric6DofSpring2Constraint whenever possible, or use the btMultibody with various links (hinge/revolute, slider/prismatic, fixed, spherical, planar).
benelot
Posts: 350
Joined: Sat Jul 04, 2015 10:33 am
Location: Bern, Switzerland
Contact:

Re: Questions about constraints

Post by benelot »

@Erwin:
So if I could use a simple hinge for my problem, I should still use the btGeneric6DofSpring2Constraint for it? That sounds weird somehow. In the sense of the representation of the constraint as well as in stability and performance of your own simulation. Usually specialized implementations are far more performant than generalized implementations. Is this not the case for the joints here?

Is it possible to limit and motorize the btMultibody joints now? I had to work around motorization by applying appropriate torques to make it bend. Especially for the spherical joint, this is a particularly hard task.
kuma
Posts: 3
Joined: Sun Nov 24, 2013 2:56 am

Re: Questions about constraints

Post by kuma »

If I can hazard a guess at an answer. I think using the btGeneric6DofSpring2Constraint is good since it combines several constraints into one and you can potentially use it to perform several functions at once. btGeneric6DofSpring2Constraint seems to perform very well in general, however I usually just use a regular hinge constraint if I just need a single hinge.
Post Reply