Links: Hinges and Sliders
-
- Posts: 33
- Joined: Tue Jul 26, 2005 2:28 pm
Links: Hinges and Sliders
Hi,
Does someone have an example of how to use the btHingeConstraint?
Specifically, what should the axis values be?
(I would like to have a hing constrait like a door's: one pivot point for both bodies with one axis of rotation)
(ie: just like ODE's hinge: http://www.ode.org/ode-latest-userguide.html#sec_7_3_2)
Also, how does one set a prismatic links axis?
(ie: just like ODE's slider axis: http://www.ode.org/ode-latest-userguide.html#sec_7_3_3)
(I created the slider via the btGeneric6DofConstraint, and added setLinearLowerLimit/upper)
Thanks!
Does someone have an example of how to use the btHingeConstraint?
Specifically, what should the axis values be?
(I would like to have a hing constrait like a door's: one pivot point for both bodies with one axis of rotation)
(ie: just like ODE's hinge: http://www.ode.org/ode-latest-userguide.html#sec_7_3_2)
Also, how does one set a prismatic links axis?
(ie: just like ODE's slider axis: http://www.ode.org/ode-latest-userguide.html#sec_7_3_3)
(I created the slider via the btGeneric6DofConstraint, and added setLinearLowerLimit/upper)
Thanks!
-
- Site Admin
- Posts: 4221
- Joined: Sun Jun 26, 2005 6:43 pm
- Location: California, USA
Re: Links: Hinges and Sliders
See Bullet/Demos/ConstraintDemo/ConstraintDemo.cpp, and add those 2 lines for a hinge:aboeing wrote:Hi,
Does someone have an example of how to use the btHingeConstraint?
Specifically, what should the axis values be?
(I would like to have a hing constrait like a door's: one pivot point for both bodies with one axis of rotation)
(ie: just like ODE's hinge: http://www.ode.org/ode-latest-userguide.html#sec_7_3_2)
Code: Select all
{
btRigidBody* body0 = localCreateRigidBody( mass,trans,shape);
trans.setOrigin(btVector3(2*CUBE_HALF_EXTENTS,20,0));
mass = 1.f;
btRigidBody* body1 = localCreateRigidBody( mass,trans,shape); body1->setActivationState(DISABLE_DEACTIVATION);
body1->setDamping(0.3,0.3);
btVector3 pivotInA(CUBE_HALF_EXTENTS,-CUBE_HALF_EXTENTS,-CUBE_HALF_EXTENTS);
btVector3 axisInA(0,0,1);
btVector3 pivotInB = body1 ? body1->getCenterOfMassTransform().inverse()(body0->getCenterOfMassTransform()(pivotInA)) : pivotInA;
btVector3 axisInB = body1?
(body1->getCenterOfMassTransform().getBasis().inverse()*(body1->getCenterOfMassTransform().getBasis() * axisInA)) :
body0->getCenterOfMassTransform().getBasis() * axisInA;
btTypedConstraint* p2p = new btPoint2PointConstraint(*body0,*body1,pivotInA,pivotInB);
btTypedConstraint* hinge = new btHingeConstraint(*body0,*body1,pivotInA,pivotInB,axisInA,axisInB);
m_dynamicsWorld->addConstraint(hinge);//p2p);
}
Which constraint do you want to build exactly? Ah, the slider in ConstraintDemo.cpp has been modified into a ragdoll rotational joint, for testing: using the btGeneric6DofConstraint, you can lock/free/limit the 3 linear and 3 angular axis independently.Also, how does one set a prismatic links axis?
(ie: just like ODE's slider axis: http://www.ode.org/ode-latest-userguide.html#sec_7_3_3)
(I created the slider via the btGeneric6DofConstraint, and added setLinearLowerLimit/upper)
Thanks!
To make it a slider with translation along the x-axis and rotation along the same x-axis, make following changes to the ConstraintDemo.cpp:
Code: Select all
btVector3 lowerSliderLimit = btVector3(-10,0,0);
btVector3 hiSliderLimit = btVector3(10,0,0);
Code: Select all
//create a slider, using the generic D6 constraint
{
mass = 1.f;
btVector3 sliderWorldPos(0,10,0);
btVector3 sliderAxis(1,0,0);
btScalar angle=0.f;//SIMD_RADS_PER_DEG * 10.f;
btMatrix3x3 sliderOrientation(btQuaternion(sliderAxis ,angle));
trans.setIdentity();
trans.setOrigin(sliderWorldPos);
//trans.setBasis(sliderOrientation);
sliderTransform = trans;
d6body0 = localCreateRigidBody( mass,trans,shape);
d6body0->setActivationState(DISABLE_DEACTIVATION);
btRigidBody* fixedBody1 = localCreateRigidBody(0,trans,0);
btTransform frameInA, frameInB;
frameInA = btTransform::getIdentity();
frameInB = btTransform::getIdentity();
btGeneric6DofConstraint* slider = new btGeneric6DofConstraint(*d6body0,*fixedBody1,frameInA,frameInB);
slider->setLinearLowerLimit(lowerSliderLimit);
slider->setLinearUpperLimit(hiSliderLimit);
//range should be small, otherwise singularities will 'explode' the constraint
slider->setAngularLowerLimit(btVector3(10,0,0));
slider->setAngularUpperLimit(btVector3(0,0,0));
m_dynamicsWorld->addConstraint(slider);
}
Thanks,
Erwin
-
- Posts: 33
- Joined: Tue Jul 26, 2005 2:28 pm
Hi Erwin,
Thanks again for the fast replies!
I got the hinge working, but my question for the slider was how to set the axis along which the slider translates?
Edit: PS: I noticed some strange behaviour with the slider, if the two bodies of the slider have another body inbetween them (that does not belong to the set of constraints) they respond unpredictably.
Thanks again for the fast replies!
I got the hinge working, but my question for the slider was how to set the axis along which the slider translates?
I would like to make it slide along an arbitrary axis - is there a way to do this?To make it a slider with translation along the x-axis and rotation along the same x-axis, make following changes to the ConstraintDemo.cpp:
Edit: PS: I noticed some strange behaviour with the slider, if the two bodies of the slider have another body inbetween them (that does not belong to the set of constraints) they respond unpredictably.
-
- Site Admin
- Posts: 4221
- Joined: Sun Jun 26, 2005 6:43 pm
- Location: California, USA
Yes. Just choose a different local frame in A (and the appropriate local frame in B).aboeing wrote:I would like to make it slide along an arbitrary axis - is there a way to do this?
Do you have some modified Bullet Demo that demonstrates this? Note that the current mouse picking in Bullet violates all constraints, it's too strong (a spring would be better).Edit: PS: I noticed some strange behaviour with the slider, if the two bodies of the slider have another body inbetween them (that does not belong to the set of constraints) they respond unpredictably.
Right now, the constraints are all solved before collision contacts. This means their effect is less then a collision. In a future version I will interleave regular joint constants with contact constraints, that should improve/fix this.
Erwin
-
- Posts: 33
- Joined: Tue Jul 26, 2005 2:28 pm
-
- Posts: 2
- Joined: Sat Dec 02, 2006 2:56 pm
Hi Erwin,
Bullet is a terrific library thanks for making it freely available.
Have you resolve the ?arbitrary axis? issue mentioned above and if so could you explain it here? I am currently trying to construct a ragdoll with btGeneric6DofConstraint (because of its rotational limits feature) and is experiencing a similar problem.
For example, the torso is represented by a big box and an upper left arm by a smaller box towards the top. I would want the pivot axis (where the 6 dof limits are referenced from) between these two to be the the shoulder bone (which is an arbitrary axis). However, my unsuccessful attempts had the pivot axis as the the segment between the pivot point and torso's center of mass.
Also a more general question is how to use the ?frameInA? and ?frameInB?variables in the btGeneric6DofConstraint constructor. I tried to set my own reference frames in my above attempts. For instance could you describe how to build a hinge from a btGeneric6DofConstraint that has an angle between the two attached bodies.
Thanks.
Bullet is a terrific library thanks for making it freely available.
Have you resolve the ?arbitrary axis? issue mentioned above and if so could you explain it here? I am currently trying to construct a ragdoll with btGeneric6DofConstraint (because of its rotational limits feature) and is experiencing a similar problem.
For example, the torso is represented by a big box and an upper left arm by a smaller box towards the top. I would want the pivot axis (where the 6 dof limits are referenced from) between these two to be the the shoulder bone (which is an arbitrary axis). However, my unsuccessful attempts had the pivot axis as the the segment between the pivot point and torso's center of mass.
Also a more general question is how to use the ?frameInA? and ?frameInB?variables in the btGeneric6DofConstraint constructor. I tried to set my own reference frames in my above attempts. For instance could you describe how to build a hinge from a btGeneric6DofConstraint that has an angle between the two attached bodies.
Thanks.
-
- Site Admin
- Posts: 4221
- Joined: Sun Jun 26, 2005 6:43 pm
- Location: California, USA
I just upgraded the Bullet Physics integration in Blender 3D modeler to version 2.37, and added compound and generic D6 joint support. This way, I found out that indeed, there is some issue with using arbitrary joint frames for the generic D6 joint. I will look into it, and let you know when its fixed.
Thanks,
Erwin
Thanks,
Erwin
par4 wrote:Hi Erwin,
Bullet is a terrific library thanks for making it freely available.
Have you resolve the ?arbitrary axis? issue mentioned above and if so could you explain it here? I am currently trying to construct a ragdoll with btGeneric6DofConstraint (because of its rotational limits feature) and is experiencing a similar problem.
For example, the torso is represented by a big box and an upper left arm by a smaller box towards the top. I would want the pivot axis (where the 6 dof limits are referenced from) between these two to be the the shoulder bone (which is an arbitrary axis). However, my unsuccessful attempts had the pivot axis as the the segment between the pivot point and torso's center of mass.
Also a more general question is how to use the ?frameInA? and ?frameInB?variables in the btGeneric6DofConstraint constructor. I tried to set my own reference frames in my above attempts. For instance could you describe how to build a hinge from a btGeneric6DofConstraint that has an angle between the two attached bodies.
Thanks.
-
- Posts: 4
- Joined: Wed May 09, 2007 1:37 pm
- Location: Brest, France
Hello,
I'm a newbie in Bullet.
I'm trying to create a slider joint between two objects along an arbitrary axis using a btGeneric6DofConstraint.
To do this, I saw the constraintDemo.cpp, the forum and also the blender source code.
When I create the slider, it is only along the X-axis of the object ....
what I expect is that the child moves along the X-axis of the joint frame and not along its own X-Axis.
Can someone explain why it doesn't work ?
Is my interpretation of frameInA and frameInB or/and my interpretation of the axis which allow the degrees of freedom which are false?
Thanks for your help
I'm a newbie in Bullet.
I'm trying to create a slider joint between two objects along an arbitrary axis using a btGeneric6DofConstraint.
To do this, I saw the constraintDemo.cpp, the forum and also the blender source code.
When I create the slider, it is only along the X-axis of the object ....
Code: Select all
//create 2 rigid bodies : the parent and the child
//create the frame attached to the joint
btTransform sliderFrame( 0.707,0.707,0,
-0,707,0.707,0,
0,0,1);
sliderFrame.setOrigin(btVector3(0,0,0));
btTransform sliderInParent = sliderFrame //the origin of the joint is the origin of the parent
//the frame of the joint is the frame of the parent with a rotation of PI/4 around the Z-axis
btTransform sliderInWorld = parent.getCenterOfMassTransform()*sliderInParent;
btTransform sliderInChild = (child.getCenterOfmassTransform().inverse())*sliderInworld;
btGeneric6DofConstraint slider = new btGeneric6DofConstraint(parent, child, jointInParent, jointInChild);
//there is only one translation along the X-axis of joint frame
slider->setLinearLowerLimit(btVector3(1,0,0));
slider->setLinearUpperLimit(btVector3(0,0,0));
//there is no rotation
slider->setAngularLowerLimit(btVector3(0,0,0));
slider->setAngularUpperLimit(btVector3(0,0,0));
world->addConstraint(slider);
Can someone explain why it doesn't work ?
Is my interpretation of frameInA and frameInB or/and my interpretation of the axis which allow the degrees of freedom which are false?
Thanks for your help
Last edited by lolo on Sat May 12, 2007 9:45 pm, edited 1 time in total.
-
- Posts: 3
- Joined: Mon Apr 16, 2007 2:41 pm
Perhaps the linear constraints are specified in global space and need transforming first. I don't know if that's a bug or a feature but this code made joints work for me :
Use that snippet only with linear limits. Angular limits do not seem to be affected and work as expected.
PS: Sorry about my crappy english.
Code: Select all
// The linear limit desired
btVector3 old_limit;
// The frame of reference of the joint, in global space
btTransform jointFrame;
btTransform globaltransform;
globaltransform.setIdentity();
globaltransform.setOrigin(old_limit);
btVector3 new_limit = (jointframe.inverse() * globaltransform).getOrigin();
PS: Sorry about my crappy english.
-
- Posts: 4
- Joined: Wed May 09, 2007 1:37 pm
- Location: Brest, France
Hi Rawsock,
Thanks for answering so fast.
I try to integrate your code into mine, but it doesn't work.
When I execute the program, the slider joint is totally broken => translation along all the axis
So I modify it a bit :
When you say that your snippet works, does it works in all cases? I mean does it work only when you have to create a limited translation or when you have to create an infinit translation(in this case what do you put in the upper and lower limits) ?
Thanks.
Thanks for answering so fast.
I try to integrate your code into mine, but it doesn't work.
When I execute the program, the slider joint is totally broken => translation along all the axis
So I modify it a bit :
Code: Select all
// The frame of reference of the joint, in global space
btTransform jointFrame;
//I want the axis totally free, so in the local space attached to the joint
//I got :
btVector3 lowerLimit=btVector3(1,0,0);
//and
btVector3 upperLimit=btVector3(0,0,0);
//so in global space all of this become
lowerLimit = jointFrame.inverse().getBasis().inverse() * lowerLimit;
// the upper limit is unchanged because it's a null vector
//and finally
sliderJoint.setLowerLimit(lowerLimit);
sliderJoint.setUpperLimit(upperLimit);
Thanks.
-
- Posts: 3
- Joined: Mon Apr 16, 2007 2:41 pm
-
- Posts: 4
- Joined: Wed May 09, 2007 1:37 pm
- Location: Brest, France
Hi Rawsock,
I'm sorry to bother you one more time, but I try to do what you've said (big limit) and it doesn't work.
In my example, I want to compute a slider joint whose frame was turned PI/4 around Z-axis of the world frame. The slider is along the X-axis of the slider frame. The result is that my object can move along the X-axis and Y-axis of the world : it can move in a squared surface.
here is my code
Can tell me what's wrong into my code ?
Thanks a lot
I'm sorry to bother you one more time, but I try to do what you've said (big limit) and it doesn't work.
In my example, I want to compute a slider joint whose frame was turned PI/4 around Z-axis of the world frame. The slider is along the X-axis of the slider frame. The result is that my object can move along the X-axis and Y-axis of the world : it can move in a squared surface.
here is my code
Code: Select all
btTransform sliderFrame( 0.707,0.707,0,
-0,707,0.707,0,
0,0,1);
sliderFrame.setOrigin(btVector3(0,0,0));
btTransform sliderInParent = sliderFrame //the origin of the joint is the origin of the parent
//the frame of the joint is the frame of the parent with a rotation of PI/4 around the Z-axis
btTransform sliderInWorld = parent.getCenterOfMassTransform()*sliderInParent;
btTransform sliderInChild = (child.getCenterOfmassTransform().inverse())*sliderInworld;
btGeneric6DofConstraint slider = new btGeneric6DofConstraint(parent, child, jointInParent, jointInChild);
//I think this above part is good
btVector3 upperLimit(10,0,0);
btVector3 lowerLimit(-10,0,0);
upperLimit = sliderInWorld.getCenterOfMassTransform().getBasis()*upperLimit; // upperLimit = (0.707*10, 0.707*10,0);
lowerLimit = sliderInWorld.getCenterOfMassTransform().getBasis()*lowerLimit; // lowerLimit = (-0.707*10, -707*10,0);
//Is it what you explain in your last reply ?
Thanks a lot