Page 1 of 1

SwivelHingeJoint can be wrenched out of its limits

Posted: Fri May 20, 2011 7:24 pm
by m.starkov
Hi again,

I'm tring to use SwivelHingeJoint between body and arm and it seems like it is working not as expectable.

Please see the pictures:

(Doll looks to +Z, Up is Y, X to the Right side - left for the doll)
Hinge is stable, all is fine
Hinge is stable, all is fine
1.PNG (20.35 KiB) Viewed 5695 times
Right arm (which is at the left side of the picture) is using ordinary hinge joint.
When we applying perpendicular force it remains in its limits as it should be.
Let's try the same with SwivelHingeJoint
Let's try the same with SwivelHingeJoint
2.PNG (22.4 KiB) Viewed 5695 times
Left arm (which is at the right side of the picture) is using SwivelHingeJoint joint having
HingeLimit.MinimumAngle = 0.0f * Pi;
HingeLimit.MaximumAngle = 0.0f * Pi;
HingeLimit.IsActive = true;
TwistLimit.MinimumAngle = -0.75f * Pi;
TwistLimit.MaximumAngle = 0.0f * Pi;
TwistLimit.IsActive = true;
Hinge axis is Y.
So it supposed to be rotated inside one plane only (or may be I'm mistaken here?)
The result is joint wrench out of its limits
The result is joint wrench out of its limits
3.PNG (24.37 KiB) Viewed 5695 times
However by applying similar force we can see that it is not so...

It is observed that it actually tries to hold it inside the limiting plane but... it can't (very low resistance).

Forces are the same (I have played a lot with that).

So could you please advise what is wrong here? Is it normal behavior for these settings or not?

Actually it can be wrenched at 0.75 * Pi only (exactly the twist limit) this makes me think that may it is as expected...
However it is not like it is shown on the picture:
http://bepuphysics.codeplex.com/wikipag ... umentation

Here is the code.
Arms are not colliding with body.

Code: Select all

// hinge
                rjoint_exp = new RevoluteJoint(ra.entity, body.entity,
                    raj, -body.entity.OrientationMatrix.Left); Game1.scene.physics.space.Add(rjoint_exp);
                rjoint_exp.Limit.IsActive = true;
                rjoint_exp.Limit.MinimumAngle = 0; rjoint_exp.Limit.MaximumAngle = Pi * 0.75f;
                rjoint_exp.Limit.LocalTestAxis = Vector3.UnitZ;
// Swivel
                sjoint_la = new SwivelHingeJoint(la.entity, body.entity,
                    laj, -body.entity.OrientationMatrix.Up); Game1.scene.physics.space.Add(sjoint_la);
                sjoint_la.HingeLimit.MinimumAngle = 0.0f * Pi; sjoint_la.HingeLimit.MaximumAngle = 0.0f * Pi; sjoint_la.HingeLimit.IsActive = true;
                sjoint_la.TwistLimit.MinimumAngle = -0.75f * Pi; sjoint_la.TwistLimit.MaximumAngle = 0.0f * Pi; sjoint_la.TwistLimit.IsActive = true;

                sjoint_la.HingeLimit.TestAxis = Vector3.UnitZ;
                sjoint_la.AngularJoint.WorldHingeAxis = -Vector3.UnitY;
                sjoint_la.AngularJoint.WorldTwistAxis = Vector3.UnitX;

Re: SwivelHingeJoint can be wrenched out of its limits

Posted: Fri May 20, 2011 7:45 pm
by m.starkov
Having code as following eleminates the possibility of wrenching out of the plane however this does not solve the problem because -0.2f * Pi and 0.2f * Pi limits does not work in this case.

Also it is observed that hinge joint behaves much more stable while Swivel joint is like a bit loose.

Code: Select all

                sjoint_la = new SwivelHingeJoint(la.entity, body.entity,
                    laj, body.entity.OrientationMatrix.Left); Game1.scene.physics.space.Add(sjoint_la);
                sjoint_la.HingeLimit.MinimumAngle = -0.2f * Pi; sjoint_la.HingeLimit.MaximumAngle = 0.2f * Pi; sjoint_la.HingeLimit.IsActive = true;
                sjoint_la.TwistLimit.MinimumAngle = -0.75f * Pi; sjoint_la.TwistLimit.MaximumAngle = 0.0f * Pi; sjoint_la.TwistLimit.IsActive = true;

                sjoint_la.HingeLimit.TestAxis = Vector3.UnitX;
                sjoint_la.AngularJoint.WorldHingeAxis = -Vector3.UnitY;
                sjoint_la.AngularJoint.WorldTwistAxis = Vector3.UnitX;

Re: SwivelHingeJoint can be wrenched out of its limits

Posted: Fri May 20, 2011 8:59 pm
by Norbo
Take a look at the UnfortunateGuyDemo in the BEPUphysicsDemos project. It shows a SwivelHingeJoint used to create an elbow. It looks like it does what you are trying to do. There appear to be some configuration issues in your version, though it's hard to pick them all out for sure without having the complete entity and constraint construction.

Re: SwivelHingeJoint can be wrenched out of its limits

Posted: Sat May 21, 2011 12:12 am
by m.starkov
Hi Norbo,

Unfortunate guy is looking good without external forces.
However if we will do something like that (right in the demo):

Code: Select all

        
public static Entity lowerArm;
public static CompoundBody torso;

        protected override void Update(GameTime gameTime)
        {

            if (hand != null)
            {
                Vector3 imp = Vector3.One * 5 - lowerArm.Position - Vector3.UnitX * 10 + Vector3.UnitY * 10;
                hand.ApplyImpulse(lowerArm.Position, imp * 0.1f);

                Vector3 imp2 = Vector3.One * 5 + Vector3.UnitY * 10 - torso.Position;
                hand.ApplyImpulse(torso.Position, imp2 * 0.1f);
            }
changing arm and torso in UnfortunateGuyDemo class to these static variables.
Then we will see that the system behaves a bit unstable. Lower arm is just revolving... (in spite of its twist limit)
Impulses are actually not very big. In a contrast if we will change elbow joint to the hinge then we will see that with the same external forces hinge is much more stable (just like an iron).
I understand that complex joint should be a bit less stable because of all these roundings etc. But this one is too unstable. I believe that there is some deficit in the code somewhere which might need to be fixed.
Could you check the same to proove or disproove my suggestion?
I can help investigating this as much as I can.

Re: SwivelHingeJoint can be wrenched out of its limits

Posted: Sat May 21, 2011 1:30 am
by Norbo
A couple of things:
First, the magnitude of the impulses being applied by those two lines is around 5x the strength of gravity. That's quite a bit of force all in one spot.

Second, the twist joints are intentionally made softer in the arm. Note these lines:

Code: Select all

            twistLimit.SpringSettings.StiffnessConstant = 100;
            twistLimit.SpringSettings.DampingConstant = 100;
Each twist limit is weakened to make it softer. This, under normal circumstances, tends to produce more realistic results than a hard "bang" that occurs when the joint is rigid.

Try commenting all of the lines which weaken the constraints. Even with 5x the strength gravity, the rigid version holds up.

Re: SwivelHingeJoint can be wrenched out of its limits

Posted: Sat May 21, 2011 2:02 am
by m.starkov
I'm agree,

default stiffness holds better.

But anyway under the same conditions Hinge holds much better than Swivel with twist limit set to min=0, max=0.

May be it is supposed to be so. I'm just wondering why...

Re: SwivelHingeJoint can be wrenched out of its limits

Posted: Sat May 21, 2011 2:53 am
by Norbo
The limits are designed to act as 'allowed ranges,' not complete degree of freedom locks. A RevoluteJoint hinge which has one native degree of freedom solves the 2 restricted angular degrees of freedom at once with a very direct equality relationship. A series of limits in a degenerate configuration are unable to use the assumptions that make the RevoluteJoint as stable as it is. A twist limit in particular has certain behaviors which simply do not exist in the fundamentals of a hinge- they are unique and separate formulations.

Basically, if the end result is a RevoluteJoint, it's best to use a RevoluteJoint. If it's a swivel hinge, use a swivel hinge.