def __get_flight_conditions(t):
        data = Data(r'RefData.mat')
        mat_data = data.get_mat().get_data()
        time = mat_data['time']
        rh_fu = mat_data['rh_engine_FU']
        lh_fu = mat_data['lh_engine_FU']

        alt = mat_data['Dadc1_alt']

        for idx, t_i in enumerate(time):
            if time[idx] < t <= time[idx+1]:
                break

        m = get_weight_at_t(t, time, rh_fu, lh_fu)/9.80665

        ts_tool = TimeSeriesTool()
        specific_t_mdat_vals = ts_tool.get_t_specific_mdat_values(t)
        V = specific_t_mdat_vals['Dadc1_tas'][0]

        h = alt[idx]
        rho = ISA(h)[2]

        mub = m / (rho * S * b)
        muc = m / (rho * S * c)

        CL = 2 * m / (rho * V ** 2 * S)  # Lift coefficient [ ]

        # Cmalpha = -0.5669172330105713
        Cmalpha = -0.6405

        return mub, muc, CL, Cmalpha, V
示例#2
0
def get_cg(t):
    #Weight & Balance Values of Aircraft for CoG Calculations
    ZFW = 4852.17
    ZFW_arm = 34586.06
    init_fuel = 4050 * 0.453592
    xdata = list(
        reversed([
            4100, 4000, 3900, 3800, 3700, 3600, 3500, 3400, 3300, 3200, 3100,
            3000, 2900, 2800, 2700, 2600, 2500, 2400
        ]))
    xdata = [x * 0.453592 for x in xdata]
    ydata = list(
        reversed([
            7.2517, 7.25055, 7.24942, 7.2482, 7.2471, 7.246112, 7.2451, 7.2442,
            7.2433, 7.2428, 7.2423, 7.2424, 7.2425, 7.24293, 7.2433, 7.244207,
            7.2451, 7.24636
        ]))

    #Time Data for CoG Shift
    t_start = 2573
    t_end = 2659

    #CoG Shift Data
    x_old = 7.315
    x_new = 3.3
    m_shift = 87

    #Aircraft Geometry
    x_LEMAC = 6.643624
    MAC = 2.056892

    #Idx Location of CoG Shift
    ts_tool = TimeSeriesTool()
    idx = ts_tool.get_mdat_tstep_list_idx_for_matching_pdat_tstep(t)
    idx_start = ts_tool.get_mdat_tstep_list_idx_for_matching_pdat_tstep(
        t_start)
    idx_end = ts_tool.get_mdat_tstep_list_idx_for_matching_pdat_tstep(t_end)

    #Get Fuel Use Data
    data = Data('FlightData.mat')
    rhfu = data.get_mat().get_data()['rh_engine_FU'][idx]
    lhfu = data.get_mat().get_data()['lh_engine_FU'][idx]

    fu = rhfu + lhfu
    fuel = init_fuel - fu
    print(ZFW + fuel)

    x_fuel = linear_spline(fuel, xdata, ydata)

    # Calculate CoG for Passenger Shift
    if idx >= idx_start and idx <= idx_end:
        x_cg = (ZFW_arm + fuel * x_fuel - m_shift *
                (x_old - x_new)) / (ZFW + fuel)
        x_cg_LEMAC = (x_cg - x_LEMAC) / MAC
    else:
        x_cg = (ZFW_arm + fuel * x_fuel) / (ZFW + fuel)
        x_cg_LEMAC = (x_cg - x_LEMAC) / MAC

    return [x_cg, x_cg_LEMAC]
 def __init__(self, time_start, time_length, Cma, Cmde, maneuver_name):
     self.time_start = time_start
     self.time_length= time_length
     self.time_end = self.time_start + self.time_length
     self.Cma = Cma
     self.Cmde = Cmde
     self.ts_tool = TimeSeriesTool()
     self.maneuver_name = maneuver_name
示例#4
0
from data.Cit_par import *
from src.data_extraction.time_series_tool import TimeSeriesTool

from src.data_extraction.time_series_tool import TimeSeriesTool
from src.data_extraction.data_main import Data
from src.data_processing.get_weight import get_weight_at_t
from src.data_processing.aerodynamics import ISA

#These reference values are missing from Cit_par:

Cma = -0.5669
#Cmde = -1.1642
Cmde = -1.2312

#Import data for given time step
ts_tool = TimeSeriesTool()


def maneuver_vals(time_start, length, name):
    t = list(range(time_start, time_start + length))
    da = []
    dr = []
    phi = []
    p = []
    r = []
    V = []
    yawRate = []
    beta = [0.0]

    for time in t:
        specific_t_mdat_vals = ts_tool.get_t_specific_mdat_values(time)
class SymmetricalStateSpace:

    def __init__(self, time_start, time_length, Cma, Cmde, maneuver_name):
        self.time_start = time_start
        self.time_length= time_length
        self.time_end = self.time_start + self.time_length
        self.Cma = Cma
        self.Cmde = Cmde
        self.ts_tool = TimeSeriesTool()
        self.maneuver_name = maneuver_name
        # self.data_tool = Data()

    def maneuver_vals(self, t, dt):
        t = list(range(t, t + dt))
        de = []
        aoa = []
        pitch = []
        q = []
        V = []
        u = []
        w = []
        for time in t:
            specific_t_mdat_vals = self.ts_tool.get_t_specific_mdat_values(time)
            de.append(specific_t_mdat_vals['delta_e'][0])
            aoa.append(specific_t_mdat_vals['vane_AOA'][0])
            pitch.append(specific_t_mdat_vals['Ahrs1_Pitch'][0])
            V.append(specific_t_mdat_vals['Dadc1_tas'][0])
            q.append(specific_t_mdat_vals['Ahrs1_bPitchRate'][0])
            u.append(
                specific_t_mdat_vals['Dadc1_tas'][0] * math.cos(specific_t_mdat_vals['vane_AOA'][0] * np.pi / 180.0))
            w.append(
                specific_t_mdat_vals['Dadc1_tas'][0] * math.sin(specific_t_mdat_vals['vane_AOA'][0] * np.pi / 180.0))
        t = np.asarray(t)
        aoa = np.asarray(aoa)
        pitch = np.asarray(pitch)
        q = np.asarray(q)
        V = np.asarray(V)
        u = np.asarray(u)
        w = np.asarray(w)

        u = u - u[0]
        w = w - w[0]

        # Initial conditions
        x0 = np.array([[0.0], [0.0], [pitch[0]], [q[0]]])

        return t, de, aoa, pitch, q, x0, u, V[0], w

    def get_flight_conditions(self, t):
        data = Data(r'FlightData.mat')
        mat_data = data.get_mat().get_data()
        time = mat_data['time']
        rh_fu = mat_data['rh_engine_FU']
        lh_fu = mat_data['lh_engine_FU']

        alt = mat_data['Dadc1_alt']

        for idx, t_i in enumerate(time):
            if time[idx] < t <= time[idx + 1]:
                break

        m = get_weight_at_t(t, time, rh_fu, lh_fu) / 9.80665

        h = alt[idx]
        rho = ISA(h)[2]

        mub = m / (rho * S * b)
        muc = m / (rho * S * c)

        return mub, muc, m, h, rho

    def L2error(self, x_exact: np.array, x_numerical: np.array):
        error = 0.0
        if (x_exact.shape[0] != x_numerical.shape[0]):
            print("Vectors must be of the same size!")
            return 1
        for i in range(x_exact.shape[0]):
            error += (x_numerical[i] - x_exact[i]) * (x_numerical[i] - x_exact[i])

        error = math.sqrt(error) / x_exact.shape[0]
        return error

    def create_ss_rep_of_sym_eom(self):
        # Cmq = -14.32232691
        forced_response_inputs = self.maneuver_vals(self.time_start, self.time_length)
        g = 9.80665
        V0 = forced_response_inputs[7]
        # short = maneuver_vals(2760, 50)
        mub, muc, m, h, rho = self.get_flight_conditions(self.time_start)
        mub = float(mub[0])
        muc = float(muc[0])
        m = float(m[0])
        h = float(h[0])
        rho = float(rho[0])

        CX0 = m * g * sin(forced_response_inputs[3][0] * np.pi / 180.0) / (0.5 * rho * (V0 ** 2) * S)
        CZ0 = -m * g * cos(forced_response_inputs[3][0] * np.pi / 180.0) / (0.5 * rho * (V0 ** 2) * S)

        c = 2.0569

        C1 = np.array([[-2.0 * muc * c / V0, 0.0, 0.0, 0.0],
                       [0.0, (CZadot - 2.0 * muc) * c / V0, 0.0, 0.0],
                       [0.0, 0.0, -c / V0, 0.0],
                       [0.0, Cmadot * c / V0, 0.0, -2.0 * muc * KY2 * c / V0]])

        C2 = np.array([[CXu, CXa, CZ0, CXq],
                       [CZu, CZa, -CX0, (CZq + 2.0 * muc)],
                       [0.0, 0.0, 0.0, 1.0],
                       [Cmu, Cma, 0.0, Cmq]])

        C3 = np.array([[CXde],
                       [CZde],
                       [0.0],
                       [self.Cmde]])

        # x' = A*x + B*u
        # y  = C*x + D*u

        A = -np.matmul(np.linalg.inv(C1), C2)
        B = -np.matmul(np.linalg.inv(C1), C3)
        C = np.identity(4)  # y = x, meaning we output the state
        D = np.array([[0.0], [0.0], [0.0], [0.0]])

        # Make control.ss state-space

        system = control.ss(A, B, C, D)

        t, y, x = control.forced_response(system, forced_response_inputs[0], forced_response_inputs[1], forced_response_inputs[5], transpose=False)

        # Change dimensionless qc/V to q
        y[2, :] = y[2, :] + forced_response_inputs[3][0]
        y[3, :] = forced_response_inputs[7] * y[3, :] / c

        # y[1, 0] = phugoid[2][0]
        y[3, 0] = 0.0

        fig = plt.figure(figsize=(12, 9))
        # fig = plt.figure(figsize=(10, 12))
        # fig.suptitle(self.maneuver_name, fontsize=16)

        ax1 = fig.add_subplot(221)
        ax1.plot(t, y[0, :], label="Simulation Response") # simulation response curve plot
        ax1.plot(t, forced_response_inputs[6], label="Test Flight Data Response") # test flight data response curve plot
        plt.legend(loc="best")
        ax1.set_xlabel("Time [s]")
        ax1.set_ylabel("u (x-dir. disturbance in velocity) [m/s]")
        ax1.grid()
        print("{0} Error in u:".format(self.maneuver_name))
        eigen_motion_error_u = self.L2error(forced_response_inputs[6], y[0, :])
        print(eigen_motion_error_u)

        ax2 = fig.add_subplot(222)
        ax2.plot(t, y[1, :], label="Simulation Response")
        # alpha
        ax2.plot(t, forced_response_inputs[8], label="Test Flight Data Response")
        plt.legend(loc="best")
        ax2.set_xlabel("Time [s]")
        ax2.set_ylabel("w (z-dir. disturbance in velocity) [m/s]")
        ax2.grid()
        print("{0} Error in w:".format(self.maneuver_name))
        eigen_motion_error_w = self.L2error(forced_response_inputs[8], y[1, :])
        print(eigen_motion_error_w)

        ax3 = fig.add_subplot(223)
        ax3.plot(t, y[2, :], label="Simulation Response")
        # theta
        ax3.plot(t, forced_response_inputs[3], label="Test Flight Data Response")
        plt.legend(loc="best")
        ax3.set_xlabel("Time [s]")
        ax3.set_ylabel("Theta (Pitch Angle) [deg]")
        ax3.grid()
        print("{0} Error in Theta:".format(self.maneuver_name))
        eigen_motion_error_th = self.L2error(forced_response_inputs[3], y[2, :])
        print(eigen_motion_error_th)

        ax4 = fig.add_subplot(224)
        ax4.plot(t, y[3, :], label="Simulation Response")
        # q
        ax4.plot(t, forced_response_inputs[4], label="Test Flight Data Response")
        plt.legend(loc="best")
        ax4.set_xlabel("Time [s]")
        ax4.set_ylabel("q (Pitch Rate) [deg/s]")
        ax4.grid()
        print("{0} Error in q:".format(self.maneuver_name))
        eigen_motion_error_q = self.L2error(forced_response_inputs[4], y[3, :])
        print(eigen_motion_error_q)

        print("Avg. {0} Error:".format(self.maneuver_name))
        avg_eigen_motion_error = (eigen_motion_error_q + eigen_motion_error_th + eigen_motion_error_w + eigen_motion_error_u) / 4
        print(avg_eigen_motion_error)
        # fig.suptitle(self.maneuver_name, fontsize=16)
        fig.suptitle(self.maneuver_name)
        # plt.tight_layout()

        # plt.legend(loc="best")
        plt.show()

    def compute_ss_rep_of_sym_eom(self, array_input):
        forced_response_inputs = self.maneuver_vals(int(array_input[1]), int(array_input[2]))

        g = 9.80665
        V0 = forced_response_inputs[7]
        # short = maneuver_vals(2760, 50)
        mub, muc, m, h, rho = self.get_flight_conditions(int(array_input[1]))
        mub = float(mub[0])
        muc = float(muc[0])
        m = float(m[0])
        h = float(h[0])
        rho = float(rho[0])

        CX0 = m * g * sin(forced_response_inputs[3][0] * np.pi / 180.0) / (0.5 * rho * (V0 ** 2) * S)
        CZ0 = -m * g * cos(forced_response_inputs[3][0] * np.pi / 180.0) / (0.5 * rho * (V0 ** 2) * S)

        c = 2.0569

        C1 = np.array([[-2.0 * muc * c / V0, 0.0, 0.0, 0.0],
                       [0.0, (CZadot - 2.0 * muc) * c / V0, 0.0, 0.0],
                       [0.0, 0.0, -c / V0, 0.0],
                       [0.0, Cmadot * c / V0, 0.0, -2.0 * muc * KY2 * c / V0]])

        C2 = np.array([[CXu, CXa, CZ0, CXq],
                       [CZu, CZa, -CX0, (CZq + 2.0 * muc)],
                       [0.0, 0.0, 0.0, 1.0],
                       [Cmu, Cma, 0.0, array_input[0]]])

        C3 = np.array([[CXde],
                       [CZde],
                       [0.0],
                       [self.Cmde]])

        # x' = A*x + B*u
        # y  = C*x + D*u

        A = -np.matmul(np.linalg.inv(C1), C2)
        B = -np.matmul(np.linalg.inv(C1), C3)
        C = np.identity(4)  # y = x, meaning we output the state
        D = np.array([[0.0], [0.0], [0.0], [0.0]])

        # Make control.ss state-space

        system = control.ss(A, B, C, D)

        t, y, x = control.forced_response(system, forced_response_inputs[0], forced_response_inputs[1], forced_response_inputs[5], transpose=False)

        # Change dimensionless qc/V to q
        y[2, :] = y[2, :] + forced_response_inputs[3][0]
        y[3, :] = forced_response_inputs[7] * y[3, :] / c

        # y[1, 0] = phugoid[2][0]
        y[3, 0] = 0.0

        eigen_motion_error_u = self.L2error(forced_response_inputs[6], y[0, :])
        eigen_motion_error_w = self.L2error(forced_response_inputs[8], y[1, :])
        eigen_motion_error_th = self.L2error(forced_response_inputs[3], y[2, :])
        eigen_motion_error_q = self.L2error(forced_response_inputs[4], y[3, :])
        avg_eigen_motion_error = (eigen_motion_error_q + eigen_motion_error_th + eigen_motion_error_w + eigen_motion_error_u) / 4
        # eigen_motion_error_u = self.L2error(forced_response_inputs[6], y[0, :])
        # eigen_motion_error_u_array = np.array([eigen_motion_error_u])
        # return eigen_motion_error_u
        return avg_eigen_motion_error
class AsymmetricStateSpace:

    def __init__(self, time_start, time_length, Cma, Cmde, maneuver_name):
        self.time_start = time_start
        self.time_length= time_length
        self.time_end = self.time_start + self.time_length
        self.Cma = Cma
        self.Cmde = Cmde
        self.ts_tool = TimeSeriesTool()
        self.maneuver_name = maneuver_name
        # self.data_tool = Data()

    def maneuver_vals(self):
        t = list(range(self.time_start, self.time_start + self.time_length))
        da = []
        dr = []
        phi = []
        p = []
        r = []
        V = []
        yawRate = []
        beta = [0.0]

        for time in t:
            specific_t_mdat_vals = self.ts_tool.get_t_specific_mdat_values(time)
            da.append(specific_t_mdat_vals['delta_a'][0])
            dr.append(specific_t_mdat_vals['delta_r'][0])
            phi.append(specific_t_mdat_vals['Ahrs1_Roll'][0])
            p.append(specific_t_mdat_vals['Ahrs1_bRollRate'][0])
            r.append(specific_t_mdat_vals['Ahrs1_bYawRate'][0])
            V.append(specific_t_mdat_vals['Dadc1_tas'][0])
            yawRate.append(specific_t_mdat_vals['Ahrs1_bYawRate'][0])

        for i in range(len(yawRate) - 1):
            beta.append(beta[i] + yawRate[i])

        t = np.asarray(t)
        phi = np.asarray(phi)
        p = np.asarray(p)
        r = np.asarray(r)
        da = np.asarray(da)
        dr = np.asarray(dr)
        V = np.asarray(V)
        beta = np.asarray(beta)

        x0 = np.array([[0.0],  # beta
                       [phi[0]],  # phi
                       [p[0]],  # p
                       [r[0]]])  # r
        return t, phi, p, r, da, dr, x0, V[0], beta


    def get_flight_conditions(self):
        data = Data(r'FlightData.mat')
        mat_data = data.get_mat().get_data()
        time = mat_data['time']
        rh_fu = mat_data['rh_engine_FU']
        lh_fu = mat_data['lh_engine_FU']

        alt = mat_data['Dadc1_alt']

        for idx, t_i in enumerate(time):
            if time[idx] < self.time_start <= time[idx + 1]:
                break

        m = get_weight_at_t(self.time_start, time, rh_fu, lh_fu) / 9.80665

        h = alt[idx]
        rho = ISA(h)[2]

        mub = m / (rho * S * b)
        muc = m / (rho * S * c)

        return mub, muc, m, h, rho


    def L2error(self, x_exact: np.array, x_numerical: np.array):
        error = 0.0
        if (x_exact.shape[0] != x_numerical.shape[0]):
            print("Vectors must be of the same size!")
            return 1
        for i in range(x_exact.shape[0]):
            error += (x_numerical[i] - x_exact[i]) * (x_numerical[i] - x_exact[i])

        error = math.sqrt(error) / x_exact.shape[0]
        return error


    def create_assymetric_ss_representation(self):
        forced_response_inputs = self.maneuver_vals()

        g = 9.80665

        # DUTCH ROLL:
        # State-space representation of asymmetric EOM:

        # C1*x' + C2*x + C3*u = 0

        V0 = forced_response_inputs[7]

        mub, muc, m, h, rho = self.get_flight_conditions()
        mub = float(mub[0])
        muc = float(muc[0])
        m = float(m[0])
        h = float(h[0])
        rho = float(rho[0])

        CX0 = m * g * sin(forced_response_inputs[3][0] * np.pi / 180.0) / (0.5 * rho * (V0 ** 2) * S)
        CZ0 = -m * g * cos(forced_response_inputs[3][0] * np.pi / 180.0) / (0.5 * rho * (V0 ** 2) * S)

        c = 2.0569

        C1 = np.array([[(CYbdot - 2.0 * mub) * b / V0, 0.0, 0.0, 0.0],
                       [0.0, -0.5 * b / V0, 0.0, 0.0],
                       [0.0, 0.0, -4.0 * mub * KX2 * b / V0, 4.0 * mub * KXZ * b / V0],
                       [Cnbdot * b / V0, 0.0, 4.0 * mub * KXZ * b / V0, -4.0 * mub * KZ2 * b / V0]])

        C2 = np.array([[-CYb, -CL, -CYp, -(CYr - 4.0 * mub)],
                       [0.0, 0.0, -1.0, 0.0],
                       [-Clb, 0.0, -Clp, -Clr],
                       [-Cnb, 0.0, -Cnp, -Cnr]])

        C3 = np.array([[-CYda, -CYdr],
                       [0.0, 0.0],
                       [-Clda, -Cldr],
                       [-Cnda, -Cndr]])

        # x' = A*x + B*u
        # y  = C*x + D*u

        # now u = [da]
        #         [dr]

        A = np.matmul(np.linalg.inv(C1), C2)
        B = np.matmul(np.linalg.inv(C1), C3)
        C = np.identity(4)  # y = x, meaning we output the state
        D = np.array([[0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0]])

        # Make control.ss state-space

        system = control.ss(A, B, C, D)

        # t = np.linspace(0.0, 200.0, num = 201)

        # Input:
        # u = np.zeros((2, t.shape[0]))

        # for i in range(t.shape[0]):
        #    u[0, i] = da[i] #Insert magnitude of "da" (aileron deflection) or comment out if none
        #    u[1, i] = dr[i] #Insert magnitude of "dr" (rudder deflection) or comment out if none

        u = np.array([forced_response_inputs[4],
                      forced_response_inputs[5]])

        # Calculate response to arbitrary input
        t, y, x = control.forced_response(system, forced_response_inputs[0], u, forced_response_inputs[6], transpose=False)

        # Change dimensionless pb/(2V) and rb/(2V) to p and r
        y[1, :] = -y[1, :] + 2 * y[1, 0]
        y[2, :] = -(2 * abs(V0) * y[2, :] / b) + 2 * y[2, 0]
        y[3, :] = -(2 * abs(V0) * y[3, :] / b) + 2 * y[3, 0]

        control.damp(system, doprint=True)

        fig = plt.figure(figsize=(12, 9))
        # fig.suptitle(self.maneuver_name, fontsize=16, )

        ax1 = fig.add_subplot(221)
        ax1.plot(t, y[0, :], label='Simulated response')
        ax1.plot(t, forced_response_inputs[8], label='Test Flight Data Response', color='tab:orange', linestyle='--')
        ax1.legend(loc='upper right')
        ax1.set_xlabel("Time [s]")
        ax1.set_ylabel("beta (yaw angle) [deg]")
        print("{0} Error in Beta:".format(self.maneuver_name))
        eigen_motion_error_beta = self.L2error(forced_response_inputs[8], y[0, :])
        print(eigen_motion_error_beta)
        plt.grid("True")

        ax2 = fig.add_subplot(222)
        ax2.plot(t, y[1, :], label='Simulated response')
        ax2.plot(t, forced_response_inputs[1], label='Test Flight Data Response', color='tab:orange', linestyle='--')
        ax2.legend(loc='upper right')
        ax2.set_xlabel("Time [s]")
        ax2.set_ylabel("phi (roll angle) [deg]")
        print("{0} Error in Phi:".format(self.maneuver_name))
        eigen_motion_error_phi = self.L2error(forced_response_inputs[1], y[1, :])
        print(eigen_motion_error_phi)
        plt.grid("True")

        ax3 = fig.add_subplot(223)
        ax3.plot(t, y[2, :], label='Simulated response')
        ax3.plot(t, forced_response_inputs[2], label='Test Flight Data Response', color='tab:orange', linestyle='--')
        ax3.legend(loc='upper right')
        ax3.set_xlabel("Time [s]")
        ax3.set_ylabel("p (roll rate) [deg/sec]")
        print("{0} Error in p:".format(self.maneuver_name))
        eigen_motion_error_p = self.L2error(forced_response_inputs[2], y[2, :])
        print(eigen_motion_error_p)
        plt.grid("True")

        ax4 = fig.add_subplot(224)
        ax4.plot(t, y[3, :], label='Simulated response')
        ax4.plot(t, forced_response_inputs[3], label='Test Flight Data Response', color='tab:orange', linestyle='--')
        ax4.legend(loc='upper right')
        ax4.set_xlabel("Time [s]")
        ax4.set_ylabel("r (yaw rate) [deg/s]")
        print("{0} Error in r:".format(self.maneuver_name))
        eigen_motion_error_r = self.L2error(forced_response_inputs[3], y[3, :])
        print(eigen_motion_error_r)
        plt.grid("True")

        print("Avg. {0} Error:".format(self.maneuver_name))
        avg_eigen_motion_error = (eigen_motion_error_beta + eigen_motion_error_p + eigen_motion_error_phi + eigen_motion_error_r) / 4.0
        print(avg_eigen_motion_error)
        # plt.grid("True")
        plt.show()


    def compute_assymetric_ss_representation_error(self, stability_coeffs_array):
        """

        :param stability_coeffs_array: [Cnb, Cnr, CYb]
        :return:
        """
        forced_response_inputs = self.maneuver_vals()
        # spiral = maneuver_vals(3305, 30, 'Spiral')
        # aperiodic = maneuver_vals(3380, 30, 'Aperiodic')

        g = 9.80665
        # State-space representation of asymmetric EOM:
        V0 = forced_response_inputs[7]

        mub, muc, m, h, rho = self.get_flight_conditions()
        mub = float(mub[0])
        muc = float(muc[0])
        m = float(m[0])
        h = float(h[0])
        rho = float(rho[0])

        CX0 = m * g * sin(forced_response_inputs[3][0] * np.pi / 180.0) / (0.5 * rho * (V0 ** 2) * S)
        CZ0 = -m * g * cos(forced_response_inputs[3][0] * np.pi / 180.0) / (0.5 * rho * (V0 ** 2) * S)

        c = 2.0569

        C1 = np.array([[(CYbdot - 2.0 * mub) * b / V0, 0.0, 0.0, 0.0],
                       [0.0, -0.5 * b / V0, 0.0, 0.0],
                       [0.0, 0.0, -4.0 * mub * KX2 * b / V0, 4.0 * mub * KXZ * b / V0],
                       [Cnbdot * b / V0, 0.0, 4.0 * mub * KXZ * b / V0, -4.0 * mub * KZ2 * b / V0]])

        C2 = np.array([[-stability_coeffs_array[2], -CL, -CYp, -(CYr - 4.0 * mub)],
                       [0.0, 0.0, -1.0, 0.0],
                       [-Clb, 0.0, -Clp, -Clr],
                       [-stability_coeffs_array[0], 0.0, -Cnp, -stability_coeffs_array[1]]])

        C3 = np.array([[-CYda, -CYdr],
                       [0.0, 0.0],
                       [-Clda, -Cldr],
                       [-Cnda, -Cndr]])

        A = np.matmul(np.linalg.inv(C1), C2)
        B = np.matmul(np.linalg.inv(C1), C3)
        C = np.identity(4)  # y = x, meaning we output the state
        D = np.array([[0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0]])

        # Make control.ss state-space

        system = control.ss(A, B, C, D)

        # t = np.linspace(0.0, 200.0, num = 201)

        # Input:
        # u = np.zeros((2, t.shape[0]))

        # for i in range(t.shape[0]):
        #    u[0, i] = da[i] #Insert magnitude of "da" (aileron deflection) or comment out if none
        #    u[1, i] = dr[i] #Insert magnitude of "dr" (rudder deflection) or comment out if none

        u = np.array([forced_response_inputs[4],
                      forced_response_inputs[5]])

        # Calculate response to arbitrary input
        t, y, x = control.forced_response(system, forced_response_inputs[0], u, forced_response_inputs[6], transpose=False)

        # Change dimensionless pb/(2V) and rb/(2V) to p and r
        y[1, :] = -y[1, :] + 2 * y[1, 0]
        y[2, :] = -(2 * abs(V0) * y[2, :] / b) + 2 * y[2, 0]
        y[3, :] = -(2 * abs(V0) * y[3, :] / b) + 2 * y[3, 0]

        control.damp(system, doprint=True)

        eigen_motion_error_beta = self.L2error(forced_response_inputs[8], y[0, :])
        eigen_motion_error_phi = self.L2error(forced_response_inputs[1], y[1, :])
        eigen_motion_error_p = self.L2error(forced_response_inputs[2], y[2, :])
        eigen_motion_error_r = self.L2error(forced_response_inputs[3], y[3, :])
        avg_eigen_motion_error = (eigen_motion_error_beta + eigen_motion_error_p + eigen_motion_error_phi + eigen_motion_error_r) / 4.0

        print("The Average Error Computed for the {0} is: {1}".format(self.maneuver_name, avg_eigen_motion_error))
        return avg_eigen_motion_error