[SOLVED]AngularMotor Makes Joined Entities Go Crazy
Posted: Thu Feb 23, 2012 8:36 pm
Greetings! I have a little problem that is driving me nuts. Basically, I have 4 objects joined together via ball socket joints. These 4 joints are driven by an angular motor on each one. The shape roughly resembles the ascii-art version below (a base on the bottom, 2 'legs', and a top on the top). The problem is that when I attempt to 'twist' the joints with the angular motors on the Vector3.Up axis (twisting the bottom joints one way and the top joints the opposite direction), the whole model just starts spinning out of control. It seems to work fine at very low twist values (like 1 degree), but the more twist you put on it, the faster it flies out of control.
I cannot for the life of me figure out why it is doing this. I do have the frictions on the models and ground turned down low, so this does sort of amplify the problem. I need low friction though for my particular simulation. I would be very grateful if anyone could either give my an idea why this might be happening. I think I know 'what' is happening, but I don't know 'why' it is happening or how to fix it.
Thanks!
----
| |
| |
----
Here is an example for what is going on. You should be able to add this to the BEPUPhysicsDemos project if you want to test it out. I was not sure how else to post it here.
AngularMotorDemo.cs
I cannot for the life of me figure out why it is doing this. I do have the frictions on the models and ground turned down low, so this does sort of amplify the problem. I need low friction though for my particular simulation. I would be very grateful if anyone could either give my an idea why this might be happening. I think I know 'what' is happening, but I don't know 'why' it is happening or how to fix it.
Thanks!
----
| |
| |
----
Here is an example for what is going on. You should be able to add this to the BEPUPhysicsDemos project if you want to test it out. I was not sure how else to post it here.
AngularMotorDemo.cs
Code: Select all
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework.Input;
using BEPUphysics.Entities.Prefabs;
using BEPUphysics.Entities;
using BEPUphysics.CollisionRuleManagement;
using BEPUphysics.Constraints;
using BEPUphysics.Constraints.TwoEntity.Joints;
using BEPUphysics.Constraints.TwoEntity.Motors;
using Microsoft.Xna.Framework;
namespace BEPUphysicsDemos.Demos
{
/// <summary>
/// Multiple entities connected via ball socket joint controlled by angular motors
/// </summary>
public class AngularMotorDemo : StandardDemo
{
Entity eGround, eBase, eBox1, eBox2, eTop;
BallSocketJoint bsBox1Base, bsBox1Top, bsBox2Base, bsBox2Top;
AngularMotor amBox1Base, amBox1Top, amBox2Base, amBox2Top;
CollisionGroup bodyGroup = new CollisionGroup();
List<CollisionGroup> cg = new List<CollisionGroup>();
float twist = 0f;
/// <summary>
/// Constructs a new demo.
/// </summary>
/// <param name="game">Game owning this demo.</param>
public AngularMotorDemo(DemosGame game)
: base(game)
{
cg.Add(bodyGroup);
CollisionGroup.DefineCollisionRulesInSet(cg, CollisionRule.NoBroadPhase, CollisionRule.NoBroadPhase);
//add some ground
eGround = new Box(Vector3.Down * 5f, 100f, 10f, 100f);
eGround.Material.Bounciness = 0f;
eGround.Material.KineticFriction = 0.25f;
eGround.Material.StaticFriction = 0.25f;
Space.Add(eGround);
//add the base ent
eBase = new Box(Vector3.Up * 0.5f, 10f, 1f, 10f, 1f);
eBase.Material.Bounciness = 0f;
eBase.Material.KineticFriction = 0.25f;
eBase.Material.StaticFriction = 0.25f;
eBase.CollisionInformation.CollisionRules.Group = bodyGroup;
Space.Add(eBase);
//add the 1st box ent
eBox1 = new Box(Vector3.Up * 5f + Vector3.Left * 3f, 2f, 8f, 2f, 1f);
eBox1.Material.Bounciness = 0f;
eBox1.Material.KineticFriction = 0.25f;
eBox1.Material.StaticFriction = 0.25f;
eBox1.CollisionInformation.CollisionRules.Group = bodyGroup;
Space.Add(eBox1);
//add the 2st box ent
eBox2 = new Box(Vector3.Up * 5f + Vector3.Right * 3f, 2f, 8f, 2f, 1f);
eBox2.Material.Bounciness = 0f;
eBox2.Material.KineticFriction = 0.25f;
eBox2.Material.StaticFriction = 0.25f;
eBox2.CollisionInformation.CollisionRules.Group = bodyGroup;
Space.Add(eBox2);
//add the top ent
eTop = new Box(Vector3.Up * 10f, 8f, 2f, 2f, 1f);
eTop.Material.Bounciness = 0f;
eTop.Material.KineticFriction = 0.25f;
eTop.Material.StaticFriction = 0.25f;
eTop.CollisionInformation.CollisionRules.Group = bodyGroup;
Space.Add(eTop);
//add the joints connecting it all together
bsBox1Base = new BallSocketJoint(eBox1, eBase, eBox1.Position + Vector3.Down * 4f);
bsBox1Top = new BallSocketJoint(eBox1, eTop, eBox1.Position + Vector3.Up * 4f);
bsBox2Base = new BallSocketJoint(eBox2, eBase, eBox2.Position + Vector3.Down * 4f);
bsBox2Top = new BallSocketJoint(eBox2, eTop, eBox2.Position + Vector3.Up * 4f);
//add the angular motors to the joints
amBox1Base = new AngularMotor(eBox1, eBase);
amBox1Base.Settings.Mode = MotorMode.Servomechanism;
amBox1Top = new AngularMotor(eBox1, eTop);
amBox1Top.Settings.Mode = MotorMode.Servomechanism;
amBox2Base = new AngularMotor(eBox2, eBase);
amBox2Base.Settings.Mode = MotorMode.Servomechanism;
amBox2Top = new AngularMotor(eBox2, eTop);
amBox2Top.Settings.Mode = MotorMode.Servomechanism;
Space.Add(bsBox1Base);
Space.Add(amBox1Base);
Space.Add(bsBox1Top);
Space.Add(amBox1Top);
Space.Add(bsBox2Base);
Space.Add(amBox2Base);
Space.Add(bsBox2Top);
Space.Add(amBox2Top);
game.Camera.Position = new Vector3(0f, 10f, 30f);
game.Camera.Pitch = MathHelper.ToRadians(-10f);
}
public override void Update(float dt)
{
if (Game.KeyboardInput.IsKeyDown(Keys.Left))
twist += -0.1f * dt;
if (Game.KeyboardInput.IsKeyDown(Keys.Right))
twist += 0.1f * dt;
twist = MathHelper.Clamp(twist, MathHelper.ToRadians(-15f), MathHelper.ToRadians(15f));
Quaternion q;
q = Quaternion.Identity;
q *= Quaternion.CreateFromAxisAngle(Vector3.Up, twist);
amBox1Base.Settings.Servo.Goal = q;
amBox2Base.Settings.Servo.Goal = q;
q = Quaternion.Identity;
q *= Quaternion.CreateFromAxisAngle(Vector3.Up, -twist);
amBox1Top.Settings.Servo.Goal = q;
amBox2Top.Settings.Servo.Goal = q;
base.Update(dt);
}
public override void DrawUI()
{
base.DrawUI();
Game.DataTextDrawer.Draw("Twist Controls:", new Vector2(50, 20));
Game.TinyTextDrawer.Draw("Left and Right Arrow Keys", new Vector2(60, 40));
Game.DataTextDrawer.Draw("Current Twist Angle: " + MathHelper.ToDegrees(twist).ToString("0.0") + " degrees", new Vector2(50, 70));
}
/// <summary>
/// Gets the name of the simulation.
/// </summary>
public override string Name
{
get { return "Angular Motor Test"; }
}
}
}