Controlling pitch , yaw and roll of an airplane

Started by
4 comments, last by jeskeca 8 years, 11 months ago

So i have been trying to rotate an airplane in UNITY along the x y z axes such that it has a free rotation in the x(pitch) and y(yaw/turn) axes but a limited lean/roll in the z axis.. I have written the following script , but it suffers from gimbal lock... pleaseee help...clear.pngclear.png
please suggest some alternative methods to get the desired results without gimbal lock.


using UnityEngine;
using System.Collections;
 
public class TestScript : MonoBehaviour {
 
    public float rollAngle = 90f;
    public float pitchSpeed = 2f;
    public float turnSpeed = 3f;
    private Rigidbody rigidBody;
 
    void Start()
    {
        rigidBody = GetComponent<Rigidbody>();
    }
 
    void Update()
    {
        Vector3 euler = transform.eulerAngles;
        float turnTorque = 0;
 
        euler.z = Mathf.Lerp(euler.z , -Input.GetAxis("Horizontal")*rollAngle , 1.0f);
        Quaternion addRot = Quaternion.Euler(euler);
 
        transform.rotation = Quaternion.Lerp(transform.rotation , addRot , 0.2f);
        transform.Rotate(new Vector3(Input.GetAxis("Vertical")*pitchSpeed,0,0));
 
        turnTorque = turnSpeed*Input.GetAxis("Horizontal");
        rigidBody.AddTorque(Vector3.up*turnTorque);
 
        rigidBody.angularDrag = (turnTorque==0)?10:3;//Prevents rotation due to inertia.
 
    }
}
Advertisement

If you are working with Euler angles you will ALWAYS have the potential for Gimbal lock.

That is, using three rotation values where each one is unconstrained, there are orientations that cause two axis to become parallel, degenerating all future rotation into a two dimensional space.

As long as you stick with Euler angles the problem will never go away. While it is not as convenient, it is important to grow beyond the need for Euler angle representations. That normally means matrix representations for the full transformation and quaternions for changes in orientation.

Fortunately for you, Unity already offers this with many different variations.

Since it looks like you are using forces and game physics (normally pretty icky for game controls, but whatever) you can apply the forces relative to the local transformation. That's just a matter of replacing your AddTorque() with AddRelativeTorque(). Similarly for other forces, AddRelativeForce() instead of AddForce(). The "relative" versions work in the object's local orientation rather than world's orientation. So "up" becomes the object-relative up, not the world-relative up.

For other rotations, if you are trying to rotate toward a location rather than apply forces, that should go through quaternions. For example: theThing.transform.rotation = Quaternion.LookRotation( Vector3.RotateTowards( theThing.transform.forward, desired, rate*Time.deltaTime, 1)); or perhaps for other needs: theThing.transform.rotation = Quaternion.LookRotation(relativeTargetPosition); or whatever else you need for your specific situation.

For a plane sim, I'd imagine using forces and game physics wouldn't be that bad? Depending on how simmy he's trying to go.

For a plane sim, I'd imagine using forces and game physics wouldn't be that bad? Depending on how simmy he's trying to go.

actually this not for a flight sim game ... i m trying to develop controls for an airplane racing game

thats why my code is complex and messed up mellow.png

If you are working with Euler angles you will ALWAYS have the potential for Gimbal lock.

That is, using three rotation values where each one is unconstrained, there are orientations that cause two axis to become parallel, degenerating all future rotation into a two dimensional space.

As long as you stick with Euler angles the problem will never go away. While it is not as convenient, it is important to grow beyond the need for Euler angle representations. That normally means matrix representations for the full transformation and quaternions for changes in orientation.

Fortunately for you, Unity already offers this with many different variations.

Since it looks like you are using forces and game physics (normally pretty icky for game controls, but whatever) you can apply the forces relative to the local transformation. That's just a matter of replacing your AddTorque() with AddRelativeTorque(). Similarly for other forces, AddRelativeForce() instead of AddForce(). The "relative" versions work in the object's local orientation rather than world's orientation. So "up" becomes the object-relative up, not the world-relative up.

For other rotations, if you are trying to rotate toward a location rather than apply forces, that should go through quaternions. For example: theThing.transform.rotation = Quaternion.LookRotation( Vector3.RotateTowards( theThing.transform.forward, desired, rate*Time.deltaTime, 1)); or perhaps for other needs: theThing.transform.rotation = Quaternion.LookRotation(relativeTargetPosition); or whatever else you need for your specific situation.

well i had tried smthng lik that .. but still there were sum issues.. any ways spefically i want my plane to roll to 0 degs automatically when the horizontal input goes to zero, problem is i cant figure out how to use the functions you suggested to do that... thanx

One method to roll to zero is to extract the current orientation as a quaternion, then create the desired orientation as a quaternion, do a SLERP between them and set the result as the current orientation.

Another possibility is to extract the roll angle, calxulate a "roll up bouyancy" angle, create a transformaion from that angle and apply.

This topic is closed to new replies.

Advertisement