Main Content

Determine Nonlinear Dynamics and Static Stability of Fixed-Wing Aircraft

This example shows the process of creating and analyzing a fixed-wing aircraft in MATLAB using Cessna C182 geometry and coefficient data.

The data used to create the aircraft is taken from Airplane Flight Dynamics and Controls by Jan Roskam [1].

This example describes:

  • Setting up fixed-wing aerodynamic and control surfaces by creating and nesting an elevator control surface and then creating the aileron, rudder, wing, and vertical stabilizer.

  • Creating the propulsion models on the fixed-wing aircraft models similar to control surfaces.

  • Defining the full aircraft.

  • Defining the coefficients on the aircraft.

  • Preparing the aircraft for numerical analysis.

  • Performing numerical analysis.

Setting Up Fixed-Wing Aerodynamic and Control Surfaces

The Aero.FixedWing.Surface class can serve as both an aerodynamic and control surface.

This behavior is controlled by the Controllable property on the class.

Setting Controllable to on creates a control surface and a ControlState variable.

Nesting a control surface on an aerodynamic surface mimics the actual construction of the aircraft.

Below, the example creates an elevator control surface and nests it on the horizontal stabilizer.

elevator = Aero.FixedWing.Surface()
elevator = 
  Surface with properties:

            Surfaces: [1x0 Aero.FixedWing.Surface]
        Coefficients: [1x1 Aero.FixedWing.Coefficient]
        MaximumValue: Inf
        MinimumValue: -Inf
        Controllable: off
            Symmetry: "Symmetric"
    ControlVariables: [0x0 string]
          Properties: [1x1 Aero.Aircraft.Properties]

elevator.MaximumValue = deg2rad(20);
elevator.MinimumValue = deg2rad(-20);
elevator.Properties = Aero.Aircraft.Properties("Name", "Elevator");
elevator.Controllable = "on";
elevator.Coefficients = Aero.FixedWing.Coefficient("StateVariables", "Elevator")
elevator = 
  Surface with properties:

            Surfaces: [1x0 Aero.FixedWing.Surface]
        Coefficients: [1x1 Aero.FixedWing.Coefficient]
        MaximumValue: 0.3491
        MinimumValue: -0.3491
        Controllable: on
            Symmetry: "Symmetric"
    ControlVariables: "Elevator"
          Properties: [1x1 Aero.Aircraft.Properties]

horizontalStabilizer = Aero.FixedWing.Surface()
horizontalStabilizer = 
  Surface with properties:

            Surfaces: [1x0 Aero.FixedWing.Surface]
        Coefficients: [1x1 Aero.FixedWing.Coefficient]
        MaximumValue: Inf
        MinimumValue: -Inf
        Controllable: off
            Symmetry: "Symmetric"
    ControlVariables: [0x0 string]
          Properties: [1x1 Aero.Aircraft.Properties]

horizontalStabilizer.Surfaces = elevator
horizontalStabilizer = 
  Surface with properties:

            Surfaces: [1x1 Aero.FixedWing.Surface]
        Coefficients: [1x1 Aero.FixedWing.Coefficient]
        MaximumValue: Inf
        MinimumValue: -Inf
        Controllable: off
            Symmetry: "Symmetric"
    ControlVariables: [0x0 string]
          Properties: [1x1 Aero.Aircraft.Properties]

horizontalStabilizer.Properties = Aero.Aircraft.Properties("Name", "HorizontalStabilizer")
horizontalStabilizer = 
  Surface with properties:

            Surfaces: [1x1 Aero.FixedWing.Surface]
        Coefficients: [1x1 Aero.FixedWing.Coefficient]
        MaximumValue: Inf
        MinimumValue: -Inf
        Controllable: off
            Symmetry: "Symmetric"
    ControlVariables: [0x0 string]
          Properties: [1x1 Aero.Aircraft.Properties]

Each property on the fixed-wing objects can also be set through Name,Value arguments on construction. This method of creation will be used in the rest of the example.

Next, construct the ailerons, rudder, wing, and vertical stabilizer.

aileron = Aero.FixedWing.Surface(...
    "MaximumValue", deg2rad(20), ...
    "MinimumValue", deg2rad(-20), ...
    "Properties"  , Aero.Aircraft.Properties(1, "Name", "Aileron"), ...
    "Controllable", "on", ...
    "Coefficients", Aero.FixedWing.Coefficient("StateVariables", "Aileron"));

rudder = Aero.FixedWing.Surface(...
    "MaximumValue", deg2rad(20), ...
    "MinimumValue", deg2rad(-20), ...
    "Properties"  , Aero.Aircraft.Properties("Name", "Rudder"), ...
    "Controllable", "on", ...
	"Coefficients", Aero.FixedWing.Coefficient("StateVariables", "Rudder"));

wing = Aero.FixedWing.Surface(...
    "Surfaces"  , aileron, ...
    "Properties", Aero.Aircraft.Properties("Name", "Wing"));

verticalStabilizer = Aero.FixedWing.Surface(...
    "Surfaces"  , rudder, ...
    "Properties", Aero.Aircraft.Properties("Name", "VerticalStabilizer"));

Defining Propulsion

Use the Aero.FixedWing.Thrust object to create the propulsion models on the fixed-wing aircraft models similar to control surfaces.

The Aero.FixedWing.Thrust object is always controllable. It cannot be nested like aerodynamic and control surfaces.

propeller = Aero.FixedWing.Thrust(...
    "Properties"  , Aero.Aircraft.Properties("Name","Propeller"), ...
    "Coefficients", Aero.FixedWing.Coefficient("StateVariables", "Propeller"))
propeller = 
  Thrust with properties:

        Coefficients: [1x1 Aero.FixedWing.Coefficient]
        MaximumValue: 1
        MinimumValue: 0
        Controllable: on
            Symmetry: "Symmetric"
    ControlVariables: "Propeller"
          Properties: [1x1 Aero.Aircraft.Properties]

Constructing the Aircraft

With the aerodynamic surfaces, control surface, and thrust components defined, define the full aircraft.

First, define a separate Aero.Aircraft.Properties class for the aircraft. Use this class to keep track of versions on components and which components a given aircraft is using.

All Aero.FixedWing and Aero.Aircraft classes contain this property.

C182Properties = Aero.Aircraft.Properties(...
    "Name"       , "Cessna C182", ...
    "Type"       , "General Aviation", ...
    "Version"    , "1.0", ...
    "Description", "Cessna 182 Example")
C182Properties = 
  Properties with properties:

           Name: "Cessna C182"
    Description: "Cessna 182 Example"
           Type: "General Aviation"
        Version: "1.0"

C182 = Aero.FixedWing(...
    "Properties"       , C182Properties, ...
    "UnitSystem"       , "English (ft/s)", ...
    "AngleSystem"      , "Radians", ...
    "TemperatureSystem", "Fahrenheit", ...
    "ReferenceArea"    , 174, ...
    "ReferenceSpan"    , 36, ...
    "ReferenceLength"  , 4.9, ...
    "Surfaces"         , [wing, horizontalStabilizer, verticalStabilizer], ...
    "Thrusts"          , propeller)
C182 = 
  FixedWing with properties:

        ReferenceArea: 174
        ReferenceSpan: 36
      ReferenceLength: 4.9000
         Coefficients: [1x1 Aero.FixedWing.Coefficient]
     DegreesOfFreedom: "6DOF"
             Surfaces: [1x3 Aero.FixedWing.Surface]
              Thrusts: [1x1 Aero.FixedWing.Thrust]
          AspectRatio: 7.4483
           UnitSystem: "English (ft/s)"
          AngleSystem: "Radians"
    TemperatureSystem: "Fahrenheit"
           Properties: [1x1 Aero.Aircraft.Properties]

Setting the Aircraft Coefficients

Next, define the coefficients on the aircraft.

These coefficients describe the dynamic behavior of the aircraft. This example defines scalar constant coefficients, which define the linear behavior of the aircraft.

To define non-linear dynamic behavior of a fixed-wing aircraft, define Simulink.LookupTable coefficients. Simulink.LookupTables are not used in this example. To see an example using Simulink.LookupTables, open the Perform Controls and Static Stability Analysis with Linearized Fixed-Wing Aircraft example.

By default, all coefficients are 0.

BodyCoefficients = {
    'CD', 'Zero', 0.027;
    'CL', 'Zero', 0.307;
    'Cm', 'Zero', 0.04;
    'CD', 'Alpha', 0.121;
    'CL', 'Alpha', 4.41;
    'Cm', 'Alpha', -0.613;
    'CD', 'AlphaDot', 0
    'CL', 'AlphaDot',  1.7;
    'Cm', 'AlphaDot', -7.27;
    'CD', 'Q', 0;
    'CL', 'Q', 3.9;
    'Cm', 'Q', -12.4;
    'CY', 'Beta', -0.393;
    'Cl', 'Beta', -0.0923;
    'Cn', 'Beta', 0.0587;
    'CY', 'P', -0.075;
    'Cl', 'P', -0.484;
    'Cn', 'P', -0.0278;
    'CY', 'R', 0.214;
    'Cl', 'R', 0.0798;
    'Cn', 'R', -0.0937;
    };
 
C182 = setCoefficient(C182, BodyCoefficients(:, 1), BodyCoefficients(:, 2), BodyCoefficients(:, 3));

Coefficients can be defined on any component on the aircraft. These components can include any Aero.FixedWing.Surface or Aero.FixedWing.Thrust.

The setCoefficient method provides a Component Name,Value argument, which takes the coefficients on the desired component name, obviating the need to know exactly where the component is on the aircraft.

Valid component names depend on the Name property on the component.

AileronCoefficients = {
    'CY', 'Aileron', 0;
    'Cl', 'Aileron', 0.229;
    'Cn', 'Aileron', -0.0504;
    };
ElevatorCoefficients = {
    'CY', 'Elevator', 0.187;
    'Cl', 'Elevator', 0.0147;
    'Cn', 'Elevator', -0.0805;
    };
RudderCoefficients = {
    'CD', 'Rudder', 0;
    'CL', 'Rudder', 0.43;
    'Cm', 'Rudder', -1.369;
    };
PropellerCoefficients = {
    'CD', 'Propeller', -21.1200;
    };

C182 = setCoefficient(C182, AileronCoefficients(:, 1), AileronCoefficients(:, 2), AileronCoefficients(:, 3), "Component", "Aileron");
C182 = setCoefficient(C182, ElevatorCoefficients(:, 1), ElevatorCoefficients(:, 2), ElevatorCoefficients(:, 3), "Component", "Elevator");
C182 = setCoefficient(C182, RudderCoefficients(:, 1), RudderCoefficients(:, 2), RudderCoefficients(:, 3), "Component", "Rudder");
C182 = setCoefficient(C182, PropellerCoefficients(:, 1), PropellerCoefficients(:, 2), PropellerCoefficients(:, 3), "Component", "Propeller");

Defining the Current State

The fixed-wing aircraft is fully constructed and ready for numerical analysis.

To perform numerical analysis on a fixed-wing aircraft, define an Aero.FixedWing.State object.

The Aero.FixedWing.State object defines the current state of the Aero.FixedWing object at an instance in time. The Aero.FixedWing.State is also where dynamic physical properties of the aircraft, including the mass and inertia, are defined.

In this example, we analyze the cruise state.

CruiseState = Aero.FixedWing.State(...
    "UnitSystem","English (ft/s)",...
    "AngleSystem","Radians", ...
    "TemperatureSystem","Fahrenheit", ...
    "Mass",82.2981, ...
    "U", 220.1, ...
    "AltitudeMSL",5000);

CruiseState.Inertia.Variables = [
    948, 0,    0   ;
    0  , 1346, 0   ;
    0  , 0   , 1967;
    ];

CruiseState.CenterOfGravity = [0.264, 0 , 0] .* C182.ReferenceLength;
CruiseState.CenterOfPressure = [0.25, 0, 0] .* C182.ReferenceLength;
CruiseState.Environment = Aero.Aircraft.Environment(...
    "Temperature", 500.839, ...
    "Density", 0.00204834, ...
    "SpeedOfSound", 1097.09, ...
    "Pressure", 84307.3, ...
    "Gravity", 32.2);

Setting Up the Control States

In addition to the environment and dynamic physical properties, the Aero.FixedWing.State class also holds the current control surface deflections and thrust positions. These positions are held in the ControlStates property. Use this class to set up the control states.

By default, this property is empty. Initialize the property from the control surface and thrust information on the aircraft.

To set up these control states, use the setupControlStates method below.

CruiseState = setupControlStates(CruiseState, C182)
CruiseState = 
  State with properties:

                   Alpha: 0
                    Beta: 0
                AlphaDot: 0
                 BetaDot: 0
                    Mass: 82.2981
                 Inertia: [3x3 table]
         CenterOfGravity: [1.2936 0 0]
        CenterOfPressure: [1.2250 0 0]
             AltitudeMSL: 5000
            GroundHeight: 0
                      XN: 0
                      XE: 0
                      XD: -5000
                       U: 220.1000
                       V: 0
                       W: 0
                     Phi: 0
                   Theta: 0
                     Psi: 0
                       P: 0
                       Q: 0
                       R: 0
                  Weight: 2.6500e+03
             AltitudeAGL: 5000
                Airspeed: 220.1000
             GroundSpeed: 220.1000
              MachNumber: 0.2006
            BodyVelocity: [220.1000 0 0]
          GroundVelocity: [220.1000 0 0]
                      Ur: 220.1000
                      Vr: 0
                      Wr: 0
         FlightPathAngle: 0
             CourseAngle: 0
    InertialToBodyMatrix: [3x3 double]
    BodyToInertialMatrix: [3x3 double]
        BodyToWindMatrix: [3x3 double]
        WindToBodyMatrix: [3x3 double]
         DynamicPressure: 49.6149
             Environment: [1x1 Aero.Aircraft.Environment]
              UnitSystem: "English (ft/s)"
             AngleSystem: "Radians"
       TemperatureSystem: "Fahrenheit"
           ControlStates: [1x4 Aero.Aircraft.ControlState]
        OutOfRangeAction: "Limit"
        DiagnosticAction: "Warning"
              Properties: [1x1 Aero.Aircraft.Properties]

Perform this only once per aircraft configuration. If no control surfaces or thrusts have been added or removed to the aircraft, skip this step.

Performing Numerical Analysis

At this point, the aircraft and state are now fully constructed and defined.

A number of numerical analysis methods come with the fixed-wing aircraft, including forces and moments, non-linear dynamics, and static stability.

Forces and Moments

To calculate the forces and moments on the aircraft at an instance in time, use the forcesAndMoments method.

These forces and moments are in the aircraft body frame. Coefficients defined in a different frame have the appropriate transformation matrices applied to translate them to the body frame.

[F, M] = forcesAndMoments(C182, CruiseState)
F = 3×1

 -233.0908
         0
   -0.3300

M = 3×1
103 ×

         0
    1.8739
         0

Nonlinear Dynamics

To calculate the aircraft dynamic behavior, use the nonlinearDynamics method.

The nonlinearDynamics method returns a vector of the rates of change of the selected degrees of freedom on the aircraft. The size of the vector depends on the degrees of freedom. To calculate the aircraft dynamic behavior over time, use the vector in conjunction with an ode solver, such as ode45.

To quickly iterate between the fidelities of different aircraft designs, or trim unnecessary states from the output vector, change the selected degrees of freedom. These rates of change are defined below:

disp(load("astFixedWingDOFtable.mat").DOFtable)
                  PM4    PM6    3DOF    6DOF
                  ___    ___    ____    ____

    dXN /dt       "X"    "X"    "X"     "X" 
    dXE /dt       ""     "X"    ""      "X" 
    dXD /dt       "X"    "X"    "X"     "X" 
    dU /dt        "X"    "X"    "X"     "X" 
    dV /dt        ""     "X"    ""      "X" 
    dW /dt        "X"    "X"    "X"     "X" 
    dP /dt        ""     ""     ""      "X" 
    dQ /dt        ""     ""     "X"     "X" 
    dR /dt        ""     ""     ""      "X" 
    dPhi /dt      ""     ""     ""      "X" 
    dTheta /dt    ""     ""     "X"     "X" 
    dPsi /dt      ""     ""     ""      "X" 
dydt = nonlinearDynamics(C182, CruiseState)
dydt = 12×1

  220.1000
         0
         0
   -2.8323
         0
   -0.0040
         0
    1.3922
         0
         0
      ⋮

Static Stability

Static stability is the tendency of an aircraft to return to its original state after a small perturbation from an initial state. It is an important feature of aircraft for civilian use and reduces the need for complex controllers to maintain dynamic stability. Under some conditions, aircraft that require advanced maneuverability might opt for static instability.

The Aero.FixedWing object static stability method calculates from changes in forces and moments due to perturbations at the current state of an aircraft.

The method compares the perturbations against a predefined set of criteria as less-than, greater-than, or equal-to zero. You can also specify custom criteria. The method then evaluates the static stability as:

  • If the criteria is satisfied, then the perturbation is statically stable.

  • If the criteria is not satisfied, then the perturbation is statically unstable.

  • If the perturbation is 0, the perturbation is statically neutral.

The staticStability method does not perform a requirements-based analysis. Only use this method in the preliminary design phase.

[stability, derivatives] = staticStability(C182, CruiseState)
stability=6×8 table
             U           V           W         Alpha        Beta         P           Q           R    
          ________    ________    ________    ________    ________    ________    ________    ________

    FX    "Stable"    ""          ""          ""          ""          ""          ""          ""      
    FY    ""          "Stable"    ""          ""          ""          ""          ""          ""      
    FZ    ""          ""          "Stable"    ""          ""          ""          ""          ""      
    L     ""          ""          ""          ""          "Stable"    "Stable"    ""          ""      
    M     "Stable"    ""          ""          "Stable"    ""          ""          "Stable"    ""      
    N     ""          ""          ""          ""          "Stable"    ""          ""          "Stable"

derivatives=6×8 table
             U            V            W       Alpha        Beta            P              Q           R   
          _______    ___________    _______    ______    __________    ___________    ___________    ______

    FX     -2.118    -5.4001e-08     7.2955    1606.1    -0.0023309              0              0         0
    FY          0        -15.415          0         0       -3392.8        -647.47              0    1847.5
    FZ    -24.083    -5.9117e-07    -174.03    -38305     -0.026503              0         -33669         0
    L           0        -130.33          0         0        -28686    -1.5042e+05              0     24801
    M      17.028     4.5475e-07    -105.88    -23303      0.018739              0    -5.2223e+05         0
    N           0         83.944          0         0         18476        -8595.5              0    -29248

References

  1. Roskam, J., "Airplane Flight Dynamics and Automatic Flight Controls (Part 1)", DAR Corporation, 2003.