Пример #1
0
    def __init__(self, icao_code=None, rwyno=0,
                 elevation_ft=0, heading=0, surf='ASP',
                 length_ft=10000, width_ft=100):
        if icao_code:
            # Read relevant runway data from the ourairports.com database
            # le_... / he_... - numbers referring to the low/high end respectively
            rwy_file = os.path.join(os.path.dirname(__file__), "data", "runways.csv")
            with open(rwy_file, newline='') as rwyfile:
                runwaydata = csv.reader(rwyfile, delimiter=',')
                runwaylist = []
                for row in runwaydata:
                    runwaylist.append(row)
            rindlst = [i for i, rwy in enumerate(runwaylist) if rwy[2] == icao_code]
            self.nrways = len(rindlst)
            if rwyno > self.nrways - 1:
                print('Requested rwy. nr. exceeds the nr. of runways at ',
                      icao_code, '(', self.nrways, ')')
                raise ValueError('Incorrect runway number.')
            rind = rindlst[0]
            self.ident = runwaylist[rind + rwyno][0]
            self.airport_ref = runwaylist[rind + rwyno][1]
            self.airport_ident = runwaylist[rind + rwyno][2]
            self.length_ft = float(runwaylist[rind + rwyno][3])
            self.width_ft = float(runwaylist[rind + rwyno][4])
            self.surface = runwaylist[rind + rwyno][5]
            self.lighted = runwaylist[rind + rwyno][6]
            self.closed = runwaylist[rind + rwyno][7]
            self.le_ident = runwaylist[rind + rwyno][8]
            self.le_latitude_deg = runwaylist[rind + rwyno][9]
            self.le_longitude_deg = runwaylist[rind + rwyno][10]
            self.le_elevation_ft = float(runwaylist[rind + rwyno][11])
            self.le_heading_degt = float(runwaylist[rind + rwyno][12])
            try:
                self.le_displaced_threshold_ft = float(runwaylist[rind + rwyno][13])
            except ValueError:
                self.le_displaced_threshold_ft = float('nan')
            self.he_ident = runwaylist[rind + rwyno][14]
            self.he_latitude_deg = runwaylist[rind + rwyno][15]
            self.he_longitude_deg = runwaylist[rind + rwyno][16]
            self.he_elevation_ft = float(runwaylist[rind + rwyno][17])
            self.he_heading_degt = float(runwaylist[rind + rwyno][18])
            try:
                self.he_displaced_threshold_ft = float(runwaylist[rind + rwyno][19])
            except ValueError:
                self.he_displaced_threshold_ft = float('nan')
        else:
            # Define a custom runway based on the data provided
            self.ident = '0000000'
            self.airport_ref = '0000'
            self.airport_ident = 'CUST'
            self.length_ft = length_ft
            self.width_ft = width_ft
            self.surface = surf
            self.lighted = 1
            self.closed = 0
            self.le_ident = str(int(heading/10))
            self.le_latitude_deg = 0
            self.le_longitude_deg = 0
            self.le_elevation_ft = elevation_ft
            self.le_heading_degt = heading
            self.le_displaced_threshold_ft = 0
            self.he_ident = str(int(reciprocalhdg(heading)/10))
            self.he_latitude_deg = 0
            self.he_longitude_deg = 0
            self.he_elevation_ft = elevation_ft
            self.he_heading_degt = reciprocalhdg(heading)
            self.he_displaced_threshold_ft = 0

        # Metric versions of the imperial fields listed above
        self.length_m = co.feet2m(self.length_ft)
        self.width_m = co.feet2m(self.width_ft)
        self.le_elevation_m = co.feet2m(self.le_elevation_ft)
        self.le_displaced_threshold_m = co.feet2m(self.le_displaced_threshold_ft)
        self.he_elevation_m = co.feet2m(self.he_elevation_ft)
        self.he_displaced_threshold_m = co.feet2m(self.he_displaced_threshold_ft)
Пример #2
0
    def _paragraph333(self):
        """Flight envelope, as defined by CS-23.

        For normal, utility, commuter, and aerobatic categories of aircraft, returns the maximum
        and minimum limit loads from symmetrical manoeuvres, as well as gust types each category
        must be designed to withstand.

        **Outputs:**

        manoeuvre_dict
            dictionary, with aircraft categories :code:`'norm'`,:code:`'util'`, :code:`'comm'`,
            and :code:`'aero'`. Embedded within each category is a dictionary of minimum and
            maximum manoeuvre limit loads the aircraft should be designed to withstand, in
            different flight conditions. Limit loads in each category are :code:`'npos_D'`,
            :code:`'nneg_C'`, and :code:`'nneg_D'`, relating to cruise and dive speed limits.

        gustmps_dict
            dictionary, with aircraft categories :code:`'norm'`,:code:`'util'`, :code:`'comm'`,
            and :code:`'aero'`. Embedded within each category is a dictionary of derived gust
            velocities U_de, that each category is expected to encounter and must be designed to
            withstand. As per CS-23.333, only :code:`'Ub_mps'` is pertinent to commuter category
            aircraft (rough gusts), whereas :code:`'Uc_mps'` and :code:`'Ud_mps'` apply to all.
        """

        altitude_m = self.altitude_m

        # Create a dictionary of empty dictionaries for each aircraft category
        cs23categories_list = ['norm', 'util', 'comm', 'aero']
        manoeuvre_dict = dict(
            zip(cs23categories_list,
                [{} for _ in range(len(cs23categories_list))]))
        gustmps_dict = dict(
            zip(cs23categories_list,
                [{} for _ in range(len(cs23categories_list))]))

        # (b) Manoeuvring Envelope

        # (b)(1, 2)
        manoeuvrelimitloads = self._paragraph337()

        for category in cs23categories_list:
            # The aeroplane is to be subjected to sym. manoeuvres that result in +ve limit load for speeds up to V_D
            manoeuvre_dict[category].update(
                {'npos_D': manoeuvrelimitloads[category]['npos_min']})
            # The aeroplane is to be subjected to sym. manoeuvres that result in -ve limit load for speeds up to V_C
            manoeuvre_dict[category].update(
                {'nneg_C': manoeuvrelimitloads[category]['nneg_max']})

        # (b)(3)
        manoeuvre_dict['norm'].update({'nneg_D': 0})
        manoeuvre_dict['util'].update({'nneg_D': -1})
        manoeuvre_dict['comm'].update({'nneg_D': 0})
        manoeuvre_dict['aero'].update({'nneg_D': -1})

        # (c) Gust Envelope

        # (c)(1)
        gustb_mps = np.interp(
            altitude_m, [co.feet2m(15000), co.feet2m(60000)],
            [co.feet2m(44), co.feet2m(20.86)]),
        gustc_mps = np.interp(
            altitude_m, [co.feet2m(15000), co.feet2m(60000)],
            [co.feet2m(44), co.feet2m(20.86)]),
        gustd_mps = np.interp(
            altitude_m, [co.feet2m(15000), co.feet2m(60000)],
            [co.feet2m(22), co.feet2m(20.86 / 2)])

        gustmps_dict['norm'].update({
            'Uc_mps': gustc_mps[0],
            'Ud_mps': gustd_mps
        })

        gustmps_dict['util'].update({
            'Uc_mps': gustc_mps[0],
            'Ud_mps': gustd_mps
        })

        gustmps_dict['comm'].update({
            'Ub_mps': gustb_mps[0],
            'Uc_mps': gustc_mps[0],
            'Ud_mps': gustd_mps
        })

        gustmps_dict['aero'].update({
            'Uc_mps': gustc_mps[0],
            'Ud_mps': gustd_mps
        })

        # (c)(2) Gust loading assumptions and load factor variation with speed

        return manoeuvre_dict, gustmps_dict