Page 2 of 2
Re: Keeping two Entities at the same position.
Posted: Fri Feb 04, 2011 9:13 pm
by Jonno2343
I've decided to first get the hands working on their own before adding the arms. Rather keep it simple and finish it and then add it on later then get stuck on this and not move forward.
I definitely want to try this later on and so thanks for the help regarding it.
I had another question regarding Box sizes. Is there a minimum size that a box can be? I've adopted a scale of 1f in game = 1m in real life and am therefore modelling and positioning accordingly:
https://www.facebook.com/gra.moonstars
I've tried implementing fingers but I cannot get a box to go smaller than 0.1f when drawn by the ModelDrawer.
The Entity is definitely showing the correct bounding box numbers for the small size but when drawn nothing goes smaller than 0.1f or 10cm.
I have some convex hulls that go down to 0.01f or 1cm and that's what I'm wanting with the Fingers. Is this a limitation of the ModelDrawer or of the actual Box Entity?
Re: Keeping two Entities at the same position.
Posted: Fri Feb 04, 2011 9:15 pm
by Jonno2343
Ah, lol, nevermind that post. I changed the collision margin to 0.001f and now it goes smaller.
Will just need to watch it for problems later on.
Re: Keeping two Entities at the same position.
Posted: Mon Feb 07, 2011 7:38 pm
by Jonno2343
Hey again,
I've implement the fingers using two box entities with RevoluteJoints connect the bottom part of the finger to the palm of the hand and the top part of the finger to the bottom part of the finger.
I've also added RevoluteLimits limiting the angles between 0 and 135 degree.
Then to control the angle of the finger parts I've added a RevoluteMotor which is in Servo mode. I then set the GoalOrientation of the motor and it adjusts the fingers nicely
MMORPG.
I am having two problems with this though:
1.) The RevoluteJoint does not always remove the 2 degrees of freedom and it is possible for the fingers to bend outwards. Is there a way to set the strength of the joint?
2.) The RevoluteLimit does not restrict the angles of rotation correctly. Once it gets to the outer ends of the limit's angle the motor slows down but still marches through and I end up with a mess of fingers.
Thanks again,
Jonno
Re: Keeping two Entities at the same position.
Posted: Mon Feb 07, 2011 8:34 pm
by Norbo
Getting constraint bases configured correctly can be a little tricky. It sounds a lot like there's a problem in their configuration that's allowing the limits/constraint to be broken.
Constraints try to make a guess about what they should be configured like, but with fine-tuned systems, this guess can often be quite wrong and it's up to the user to do it.
If you post a chunk of code showing the hand setup, I'll see if I can get it configured properly for you (or at least one finger, I'll leave the rest to you

).
Is there a way to set the strength of the joint?
Yes. A RevoluteJoint's AngularJoint (and all Joints) have a SpringSettings property. However, the default is very nearly rigid. Increasing it more will probably not fix the problem. It's probably related to constraint configuration and possibly the interacting objects' masses.
Re: Keeping two Entities at the same position.
Posted: Mon Feb 07, 2011 9:11 pm
by Jonno2343
Hi
Thanks for the offer to help.
I've posted the
code bellow but in this latest version I've tried using the limits and motor from the RevoluteJoint itself, the old way is commented out.
Code: Select all
public Finger(Entity palm, float width, float depth, float bottomHeight, float topHeight, float xOffset)
{
Palm = palm;
Angle = MathHelper.PiOver4;
constraints = new List<SolverUpdateable>();
#region Bottom Part
//
float YOffset = ((Box)Palm).HalfHeight; // Move to top of palm.
YOffset += bottomHeight / 2; // Move up to center pos of bottom part.
Vector3 offset = new Vector3(xOffset, YOffset, 0);
Bottom = new Box(palm.CenterPosition + offset, width, bottomHeight, depth, 0.1f);
var BottomPalmJoint = new RevoluteJoint(Palm, Bottom, Bottom.CenterPosition - new Vector3(0, Bottom.HalfHeight, 0), Vector3.UnitX);
BottomPalmJoint.Limit.MinimumAngle = -MathHelper.PiOver2;
BottomPalmJoint.Limit.MaximumAngle = 0;
BottomPalmJoint.Limit.IsActive = true;
BottomMotor = BottomPalmJoint.Motor;
BottomMotor.IsActive = true;
BottomMotor.Settings.Mode = MotorMode.Servomechanism;
BottomMotor.Settings.Servo.Goal = -MathHelper.PiOver4;
//BottomPalmLimit.Bounciness = 0f;
constraints.Add(BottomPalmJoint);
//constraints.Add(BottomPalmLimit);
//BottomMotor = new RevoluteMotor(Palm, Bottom, Vector3.UnitX);
//BottomMotor.Settings.Mode = MotorMode.Servomechanism;
//BottomMotor.Settings.Servo.Goal = -MathHelper.PiOver4;
//
#endregion
#region Top Part
//
YOffset = bottomHeight / 2; // Move to top of bottom part.
YOffset += topHeight / 2; // Move to center pos of top part.
offset = new Vector3(0, YOffset, 0);
Top = new Box(Bottom.CenterPosition + offset, width, topHeight, depth, 0.1f);
var TopBottomJoint = new RevoluteJoint(Bottom, Top, Top.CenterPosition - new Vector3(0, Top.HalfHeight, 0), Vector3.UnitX);
TopBottomJoint.Limit.MinimumAngle = -MathHelper.PiOver2;
TopBottomJoint.Limit.MaximumAngle = 0;
TopBottomJoint.Limit.IsActive = true;
TopMotor = TopBottomJoint.Motor;
TopMotor.IsActive = true;
TopMotor.Settings.Mode = MotorMode.Servomechanism;
TopMotor.Settings.Servo.Goal = -MathHelper.PiOver4;
//var TopBottomLimit = new RevoluteLimit(Bottom, Top, Vector3.UnitX, Vector3.UnitY, -MathHelper.PiOver2, 0);
//BottomPalmLimit.Bounciness = 0f;
constraints.Add(TopBottomJoint);
//constraints.Add(TopBottomLimit);
//TopMotor = new RevoluteMotor(Bottom, Top, Vector3.UnitX);
TopMotor.Settings.Mode = MotorMode.Servomechanism;
TopMotor.Settings.Servo.Goal = -MathHelper.PiOver4;
//
#endregion
#region Collision Rules
Top.CollisionRules.SpecificEntities.Add(Bottom, CollisionRule.NoPair);
//Top.CollisionRules.SpecificEntities.Add(Palm, CollisionRule.NoPair);
Bottom.CollisionRules.SpecificEntities.Add(Palm, CollisionRule.NoPair);
//Bottom.CollisionRules.SpecificEntities.Add(Top, CollisionRule.NoPair);
#endregion
Top.CollisionMargin = 0.001f;
Bottom.CollisionMargin = 0.001f;
}
Also available at
http://pastebin.com/vkn4MJJy
Re: Keeping two Entities at the same position.
Posted: Mon Feb 07, 2011 11:04 pm
by Norbo
It looks like it is configured properly. I've attached demo-ized version that you can pop into the BEPUphysicsDemos to see exactly what I see. The limits seem appropriate, the correct degree of freedoms are being controlled, and the motors appear to be functioning properly.
A couple of things you might have been seeing:
-If the motor has a goal that violates the joint limit, motor will try its hardest to still get there. On a revolute joint, this usually manifests as the fingers going sideways and jostling around a bunch. There are two easy solutions: target only in-limit goals, or weaken the motor such that it won't freak out.
-The fingers, which appear to be very light, are attempting to interact with other objects using very large forces relative to their mass. The solver has a hard time with such a configuration. Increasing the solver iterations would be one way to help this, but it will only go so far. The best way to avoid it is to avoid having extreme forces working through low-mass objects. Weakening the motors to prevent them from trying to apply rigid forces would help some, and decreasing the mass ratio between objects would help the most. This would probably mean the fingers would need to get heavier.
Re: Keeping two Entities at the same position.
Posted: Tue Feb 08, 2011 1:26 pm
by Jonno2343
Thanks for that.
I can't believe I was being so dense and just expecting the limit to withstand the motor if the angle was set to a high number. I've now made the angle stay within the constraints as well and all seems good.
I've increased the mass a bit but by decreasing the motor spring stiffness of the motor, it moves very slowly
translator:
http://translator.telewizor.eu/
Must I change the stiffness of the joints or limits as well and make them lower? Is there a relationship between the mass and stiffness?
Re: Keeping two Entities at the same position.
Posted: Tue Feb 08, 2011 8:46 pm
by Norbo
I've increased the mass a bit but by decreasing the motor spring stiffness of the motor, it moves very slowly.
Must I change the stiffness of the joints or limits as well and make them lower? Is there a relationship between the mass and stiffness?
The spring constant and damping constant are like those in a normal spring. Weakening the spring constant while keeping a strong damping constant results in slow, 'overdamped' movement. Weakening both the spring constant and damping constant will make the motor overall weaker, but maintaining a similar overall behavior (close to 'critically damped'). If damping is reduced and the spring constant is not, the joint will be 'underdamped' and will tend to oscillate back and forth while converging to the goal.
A more thorough description of the above can be found here:
http://en.wikipedia.org/wiki/Damping
Using a larger mass will require higher spring/damping constants to maintain the same behavior, in the same way that switching the mass on an object attached to a real world spring will behave differently.