Hi,
I want try to use a RevoluteJoint with ServoMechanism Motor to connect a tank-vehicle with its turret.
So far so good, I got it positioned right, and its rotation is restricted to the up vector.
But the turrets orientation is not aligned to the vehicle chassis. When the chassis is inclined to any side, it looks like the turret tried to follow, but sometimes inclines to the opposite direction or it looks like its trying to stay upright or jut weired. I noticed that RevoluteJoint has a BallSocketJoint, I think this is causing the behavior. Is there a way to make it 100% stiff, so that the turrets orientation is aligned to the vehicle chassis but still remains turnable by servomotor?
thx Grobi
Question about RevoluteJoint
Re: Question about RevoluteJoint
The BallSocketJoint removes 3 linear degrees of freedom. The RevoluteJoint removes 2 angular degrees of freedom. Provided that everything is configured right, that leaves only a single angular degree of freedom between the two bodies, which should do what you want. The problem probably lies in the configuration.
Constaints, particularly the SolverGroup combination constraints, make initial guesses to configure themselves. Sometimes they guess wrong and require additional work, which may be the case here.
However, in the following example, I attached a 'turret' to the default demos vehicle and it works as expected. Try comparing the configurations to see if anything is conceptually different.
Constaints, particularly the SolverGroup combination constraints, make initial guesses to configure themselves. Sometimes they guess wrong and require additional work, which may be the case here.
However, in the following example, I attached a 'turret' to the default demos vehicle and it works as expected. Try comparing the configurations to see if anything is conceptually different.
Code: Select all
Entity turret = new Box(body.InternalCenterPosition + new Vector3(0, 1f, -1), 1, .3f, 2, 5);
RevoluteJoint revoluteJoint = new RevoluteJoint(body, turret, body.InternalCenterPosition + new Vector3(0, .9f, -1), Vector3.Up);
revoluteJoint.Motor.IsActive = true;
revoluteJoint.Motor.Settings.Mode = MotorMode.Servomechanism;
revoluteJoint.Motor.Settings.Servo.Goal = 0;
Space.Add(turret);
Space.Add(revoluteJoint);
Re: Question about RevoluteJoint
my setup looks like this (nothing really different from yours) :
and that looks like the turret is connected to the vehicle with a spring.
Grobi
Code: Select all
modelMatrix = (Matrix.CreateRotationX(MathHelper.ToRadians(modelRotation.X)) * Matrix.CreateRotationY(MathHelper.ToRadians(modelRotation.Y)) * Matrix.CreateRotationZ(MathHelper.ToRadians(modelRotation.Z))) * Matrix.CreateTranslation(modelPosition);
modelBody = new CompoundBody(false);
List<Vector3> vertices = new List<Vector3>();
Matrix[] transforms = new Matrix[model.Bones.Count];
model.CopyAbsoluteBoneTransformsTo(transforms);
XNAutils.XNAutils.ExtractVectors(model.Meshes[0], vertices, transforms[model.Meshes[0].ParentBone.Index]);
ConvexHull cHull = new ConvexHull(vertices);
modelBody.AddBody(cHull);
modelBody.Mass = 400f;
modelVehicle = new Vehicle(modelBody);
... wheels...
modelVehicle.Body.WorldTransform = modelMatrix;
space.Add(modelVehicle);
Vector3 turretPosition = modelPosition;
turretPosition.Y += 4.0f;
vertices.Clear();
transforms = new Matrix[modelTurret.Bones.Count];
modelTurret.CopyAbsoluteBoneTransformsTo(transforms);
XNAutils.XNAutils.ExtractVectors(modelTurret.Meshes[0], vertices, transforms[modelTurret.Meshes[0].ParentBone.Index]);
modelTurretBody = new ConvexHull(vertices);
modelTurretBody.Mass = 10f;
modelMatrix = modelVehicle.Body.OrientationMatrix * Matrix.CreateTranslation(turretPosition);
modelTurretBody.WorldTransform = modelMatrix;
space.Add(modelTurretBody);
Vector3 turretRotationPoint = turretPosition;
turretRotationPoint.Y -= 2.0f;
turretJoint = new RevoluteJoint(modelVehicle.Body, modelTurretBody, turretRotationPoint, Vector3.Up);
turretJoint.Motor.Settings.Mode = MotorMode.Servomechanism;
turretJoint.Motor.IsActive = true;
/*turretJoint.Motor.Settings.MaximumForce = 300f;
turretJoint.Motor.Settings.Servo.BaseCorrectiveSpeed = 1f;
turretJoint.Motor.Settings.Servo.MaxCorrectiveVelocity = 1f;*/
turretJoint.Motor.Settings.Servo.Goal = 0f;
space.Add(turretJoint);
modelVehicle.Body.CollisionRules.SpecificEntities.Add(modelTurretBody, CollisionRule.NoPair);
modelVehicle.Body.ForceCollisionRuleRecalculation();
Grobi
Re: Question about RevoluteJoint
...i forgot the servor motor isn't working at all if i don't set a maximumforce and basecorrectionspeed etc.
Re: Question about RevoluteJoint
The one thing I notice is that your RevoluteJoint has a freed axis of Vector3.Up. If your vehicle isn't initially oriented in a certain way, that will not work. You could try to use your orientation.Up vector instead.
If that still doesn't work, I'd recommend just stepping through it and making sure all the relevant configuration values are what you expect them to be (relative positions, orientations, etc.).
If that still doesn't work, I'd recommend just stepping through it and making sure all the relevant configuration values are what you expect them to be (relative positions, orientations, etc.).
Re: Question about RevoluteJoint
I tried changing the RevoluteJoint :
but still the same effect as :
Code: Select all
turretJoint = new RevoluteJoint(modelVehicle.Body, modelTurretBody, turretRotationPoint, modelVehicle.Body.OrientationMatrix.Up);
Code: Select all
turretJoint = new RevoluteJoint(modelVehicle.Body, modelTurretBody, turretRotationPoint, Vector3.Up);