Jump to content
  • Advertisement
Axiverse

Spaceship Autopilot to face direction ignoring roll.

Recommended Posts

I'm working on a spaceship simulation and am working on implementing autopilot. Setting the right torque in order to make the ship's heading in the right direction has been tricky. The parts I'm not sure about are how to properly translate the quaternion difference to torque and how to do it ignoring the roll of the ship. When I set the target to a identity quaternion, it seems to align just fine, but anything else, and it goes haywire. The simulation starts with a random quaternion normalized.

The steps I'm currently taking are:

  1. Compute the target heading (forward is unit Y, I want it to point to unit X, I get {[ 0, 0, -0.7071068, 0.7071068 ]} in xyzw)
  2. Compute the delta orientation (I don't know how to tell it to ignore roll or choose the closet roll with this rotation).
  3. Covert it to euler.
  4. Subtract the current velocity from the euler velocity, The euler velocity is the target we are aiming for.
  5. Apply it as torque.
Quaternion target = Quaternion.FromVectors(Vector3.UnitY, Vector3.UnitX); //Quaternion.Identity;
Quaternion current = Entity.AngularPosition;

Quaternion deltaOrientation = target * current.Inverse();
Vector3 euler = Quaternion.ToEuler(deltaOrientation);

Vector3 difference = euler - Entity.AngularVelocity;
//Quaternion deltaVelocity = deltaOrientation * Quaternion.FromEuler(Entity.AngularVelocity).Inverse();
//difference = Quaternion.ToEuler(deltaOrientation);

//Entity.AngularVelocity = new Vector3();
Entity.ResetForces();
Entity.ApplyTorque(difference);

// Primary thrusters
var heading = Entity.AngularPosition.Transform(Vector3.UnitY);
Entity.ApplyCentralForce(heading);

base.Step(delta);
Console.WriteLine($"\tNavigating {euler}\n\tHeading {heading}");

The integration code is based on bullet physics. I think that the angularVelocity is convertable to euler rotation, but I'm not sure. Also generally euler is clamped, which doesn't work here. But since the equations I've come across all seem to expect the clamp, I don't know if it works correctly with unclamped values.

float angle = angularVelocity.Length();
Vector3 axis;

if (angle < 0.001f)
{
  // use Taylor's expansions of sync function
  axis = angularVelocity * (0.5f * delta - (delta * delta * delta) * 0.020833333333f) * angle * angle;
}
else
{
  axis = angularVelocity * ((float)Math.Sin(0.5f * angle * delta) / angle);
}

Quaternion deltaOrientation = new Quaternion(axis, (float)Math.Cos(0.5f * angle * delta));
angularPosition = angularPosition * deltaOrientation;
angularPosition = angularPosition.Normalize();

 

Share this post


Link to post
Share on other sites
Advertisement

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!