# PID controller error value for heading correction

The above example uses the cross-product of the two headings as the error value for the PID controller. This works great if the angle between the desired and current headings is less than 90 degrees but if the angle is greater than that, the PID controller corrects to the opposite direction than I want (as it tries to correct to zero)!

What is a good error value between two vectors to pass into a PID controller that works no matter what the angle between the desired, and current heading?

Note: because the PID controller returns the correction as a vec3, the error value must also be a vec3

Assuming v1 & v2 are unit length, acos(dot(v1, v2)) will vary between 0 when they are identical to pi when they are opposite.

To turn this into a vector, we can use...

Vector3 error = Vector3.Cross(v1, v2);
float dot = Vector3.Dot(v1, v2);
float length = error.magnitude;

if(length > 0f)
{
error *= Mathf.acos(dot)/length;
// equivalently, you can use error *= Vector3.angle(v1, v2)/length; but this will be in degrees.
}
else if(dot < 0f)
{
error = axis * Mathf.PI;
}

return error;


...where axis is your rotation axis (we can't infer it from v1 & v2 when they are parallel)

• Thanks, but the trouble is that for the PID controller I need to provide a vector as an error value to get a vector back out. :( – Kazade Dec 13 '13 at 8:14
• That's easy then - just rescale the cross product to have the magnitude of the arc cosine of the dot product. You'll need to apply a fixup in the 180-degree case where the cross product becomes zero - so send your axis vector times pi in that case. – DMGregory Dec 13 '13 at 13:21
• Edited the answer to provide a vector. – DMGregory Dec 13 '13 at 17:13