# 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 = fixedWingSurface("Elevator", "on","Symmetric",[-20,20])

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

`elevator.Coefficients = fixedWingCoefficient("Elevator")`

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

horizontalStabilizer = fixedWingSurface("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]

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 = fixedWingSurface("Aileron", "on", "Asymmetric", [-20,20], ... "Coefficients", fixedWingCoefficient("Aileron")); rudder = fixedWingSurface("Rudder", "on", "Symmetric", [-20,20], ... "Coefficients", fixedWingCoefficient("Rudder")); wing = fixedWingSurface("Wing","Surfaces", aileron); verticalStabilizer = fixedWingSurface("VerticalStabilizer","Surfaces", rudder);

### 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 = fixedWingThrust("Propeller","Coefficients", fixedWingCoefficient("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 Properties: [1x1 Aero.Aircraft.Properties] UnitSystem: "English (ft/s)" TemperatureSystem: "Fahrenheit" AngleSystem: "Radians"

### 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 Analyze State-Space Model for Linear Control and Static Stability Analysis 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",C182.UnitSystem,... "AngleSystem",C182.AngleSystem, ... "TemperatureSystem",C182.TemperatureSystem, ... "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 = aircraftEnvironment(C182,"ISA",CruiseState.AltitudeMSL);

### 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.6488e+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] BodyToStabilityMatrix: [3x3 double] StabilityToBodyMatrix: [3x3 double] DynamicPressure: 49.6090 Environment: [1x1 Aero.Aircraft.Environment] ControlStates: [1x6 Aero.Aircraft.ControlState] OutOfRangeAction: "Limit" DiagnosticAction: "Warning" Properties: [1x1 Aero.Aircraft.Properties] UnitSystem: "English (ft/s)" TemperatureSystem: "Fahrenheit" AngleSystem: "Radians"

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.0633
0
-1.2484

M =3×110^{3}× 0 1.5101 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:

`load("astFixedWingDOFtable.mat").DOFtable`

`ans=`*12×4 table*
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.8319
0
-0.0152
0
1.1219
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 "" "Unstable" "" "" "" "" "" ""
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.1178 -7.2191e-07 7.2946 1605.9 -0.035089 0 0 0
FY 0 14.354 0 0 3159.3 52.945 0 -151.07
FZ -24.08 -5.0022e-07 -174.01 -38300 -0.0265 0 -374.73 0
L 0 -138 0 0 -30374 -12300 0 2028
M 13.722 -5.8208e-06 -129.74 -28555 -0.28018 0 -5863.8 0
N 0 81.892 0 0 18024 -710.13 0 -2370.9

### References

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