# 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

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 on other sites

So, I've found that PID systems solves for what I'm trying to do. This thread seems to be a pretty good starting point. I'm still trying to figure out do velocity as I'm shooting through the target at max velocity at the moment.

## Create an account

Register a new account

1. 1
2. 2
3. 3
Rutin
18
4. 4
JoeJ
14
5. 5

• 14
• 9
• 23
• 9
• 32
• ### Forum Statistics

• Total Topics
632626
• Total Posts
3007509
• ### Who's Online (See full list)

There are no registered users currently online

×