Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unity aircraft physics

I want to make a simple aircraft controller, what looks like little realistic in unity. I watch some video from airplane physics. and make a simple script in unity, but if I start, my plane cant move or if I change drag to zero, it cant lift. I tried to use real data and get it from wiki(F22 Raptor). To my game object, I gave the rigidbody component mass = 19670 kg. Engine thrust = 2 * 116000.0f Newton.

    private void calculateEnginePower()
    {
        EnginePower = engineThrust * ThrottleInput;
    }

    private void calculateForces()
    {
        angleOfAttack = Vector3.Angle(Vector3.forward, rb.velocity);
        angleOfAttack = Mathf.Clamp(angleOfAttack, 0, 90);

        coefficient = Mathf.Pow(1225.04f * rb.velocity.magnitude, 2) - 1; //M^2-2 where: M is mach.         

        if (coefficient > 0.0f)
            coefficientLift = (4 * angleOfAttack) / Mathf.Sqrt(coefficient);
        lift = 1.2754f * 0.5f * Mathf.Pow(rb.velocity.magnitude, 2) * coefficientLift * 78.04f; // densy1.2754 kg/m3, speed m/s , (F22)Wing area: 840 ft² (78.04 m²)

        coefficientDrag = 0.021f;
        rb.drag = coefficientDrag * 0.5f * Mathf.Pow(rb.velocity.magnitude,2) * 1.2754f * 78.04f;

        rb.AddForce(transform.up * lift);
        rb.AddForce(transform.forward * EnginePower);
    }

used these formulas:

for Lift force: Lift formula for Lift coefficient: Cl formula for Drag: Drag formula and for Drag coefficient: I used data from wiki too (0.021f).

like image 790
Boyesz Avatar asked Apr 08 '18 10:04

Boyesz


People also ask

What is plane unity?

A plane is an infinitely large, flat surface that exists in 3D space and divides the space into two halves known as half-spaces. It is easy to determine which of the two half-spaces a particular point is in and also how far the point is from the plane.

What are the 4 physics of flight?

The four forces are lift, thrust, drag, and weight. As a Frisbee flies through the air, lift holds it up. You gave the Frisbee thrust with your arm. Drag from the air made the Frisbee slow down.

What kind of physics is used in aviation?

aerodynamics, branch of physics that deals with the motion of air and other gaseous fluids and with the forces acting on bodies passing through such a fluid. Aerodynamics seeks, in particular, to explain the principles governing the flight of aircraft, rockets, and missiles.


1 Answers

So there are a number of issues with your code. I've outlined them below;

Calculate Forces


Issue: angleOfAttack = Vector3.Angle(Vector3.forward, rb.velocity);

  • Vector3.forward and rb.velocity are both in world-space. AoA is the angle between the local chord-line of your wing and the aircraft's velocity.
  • Vector3.Angle will return an unsigned angle. AoA must work in both positive and negative directions otherwise negative pitch and inverted flight would not be possible.

Solution: Move rb.velocity to local-space and solve for AoA with trigonometry.

// *flip sign(s) if necessary*
var localVelocity = transform.InverseTransformDirection(rb.velocity);
var angleOfAttack = Mathf.Atan2(-localVelocity.y, localVelocity.z);

Issue: coefficient = Mathf.Pow(1225.04f * rb.velocity.magnitude, 2) - 1;

  • 4α/sqrt(M^2−1) is a supersonic wave coefficient for M > 1. At zero velocity this equation will reduce to sqrt(-1) which is an imaginary number that will produce NaN. Mach is expressed as M=V/C where V=velocity and C=the speed of sound. Your 1225.04f constant must be C in units of km/h and not m/s as required. You're also multiplying and not dividing as given in the equation.

Solution: Simplify your equations with Lifting Line Theory.

var aspectRatio = (wingSpan * wingSpan) / wingArea; 
var inducedLift = angleOfAttack * (aspectRatio / (aspectRatio + 2f)) * 2f * Mathf.PI;
var inducedDrag = (inducedLift * inducedLift) / (aspectRatio * Mathf.PI);

Source: Aerospaceweb.org


Issue: rb.drag = coefficientDrag * 0.5f * Pow(rb.velocity.mag,2) * 1.2754f * 78.04f;

  • rb.drag is not required since we're calculating and applying drag manually.

Solution: Set the rb.drag property to the smallest possible value.

rb.drag = Mathf.Epsilon; // set in Awake

Issue: rb.AddForce(transform.up * lift);

  • transform.up is not correct for lift. Lift acts perpendicular to velocity while drag acts parallel.

Solution: Compute the lift direction by crossing the normalized velocity vector with the aircraft's lateral direction and apply drag opposite to velocity.

// *flip sign(s) if necessary*
var dragDirection = -rb.velocity.normalized;
var liftDirection = Vector3.Cross(dragDirection, transform.right);
rb.AddForce(liftDirection * lift + dragDirection * drag);

Your lift equation looks OK, so putting it all together would look something like this; (Untested)

public float wingSpan = 13.56f;
public float wingArea = 78.04f;

private float aspectRatio;

private void Awake ()
{
    rb.drag = Mathf.Epsilon;
    aspectRatio = (wingSpan * wingSpan) / wingArea;
}

private void calculateForces ()
{
    // *flip sign(s) if necessary*
    var localVelocity = transform.InverseTransformDirection(rb.velocity);
    var angleOfAttack = Mathf.Atan2(-localVelocity.y, localVelocity.z);

    // α * 2 * PI * (AR / AR + 2)
    var inducedLift = angleOfAttack * (aspectRatio / (aspectRatio + 2f)) * 2f * Mathf.PI;

    // CL ^ 2 / (AR * PI)
    var inducedDrag = (inducedLift * inducedLift) / (aspectRatio * Mathf.PI);

    // V ^ 2 * R * 0.5 * A
    var pressure = rb.velocity.sqrMagnitude * 1.2754f * 0.5f * wingArea;

    var lift = inducedLift * pressure;
    var drag = (0.021f + inducedDrag) * pressure;

    // *flip sign(s) if necessary*
    var dragDirection = rb.velocity.normalized;
    var liftDirection = Vector3.Cross(dragDirection, transform.right);

    // Lift + Drag = Total Force
    rb.AddForce(liftDirection * lift - dragDirection * drag);
    rb.AddForce(transform.forward * EnginePower);
}
like image 94
Lece Avatar answered Sep 22 '22 13:09

Lece