Ejemplo n.º 1
0
 def derive(self,
            alt_aal=P('Altitude AAL'),
            alt_agl=P('Altitude AGL'),
            ac_type=A('Aircraft Type'),
            app=S('Approach And Landing'),
            hdg=P('Heading Continuous'),
            lat=P('Latitude Prepared'),
            lon=P('Longitude Prepared'),
            ils_loc=P('ILS Localizer'),
            ils_gs=S('ILS Glideslope'),
            ils_freq=P('ILS Frequency'),
            land_afr_apt=A('AFR Landing Airport'),
            land_afr_rwy=A('AFR Landing Runway'),
            lat_land=KPV('Latitude At Touchdown'),
            lon_land=KPV('Longitude At Touchdown'),
            precision=A('Precise Positioning'),
            fast=S('Fast'),
            u=P('Airspeed'),
            gspd=P('Groundspeed'),
            height_from_rig=P('Altitude ADH'),
            hdot=P('Vertical Speed'),
            roll=P('Roll'),
            heading=P('Heading'),
            distance_land=P('Distance To Landing'),
            tdwns=KTI('Touchdown'),
            offshore=M('Offshore'),
            takeoff=S('Takeoff')):
     pass
Ejemplo n.º 2
0
 def derive(self,
            ac_type=A('Aircraft Type'),
            alt_aal=P('Altitude AAL For Flight Phases'),
            level_flights=S('Level Flight'),
            apps=S('Approach'),
            landings=S('Landing')):
     pass
Ejemplo n.º 3
0
 def test_derive_without_turning(self):
     # Empty 'Turning'.
     turning = S('Turning On Ground')
     start_datetime = A(name='Start Datetime', value=datetime.now())
     off_blocks_datetime = OnBlocksDatetime()
     off_blocks_datetime.set_flight_attr = Mock()
     off_blocks_datetime.derive(turning, start_datetime)
     off_blocks_datetime.set_flight_attr.assert_called_once_with(None)
     # 'Turning On Ground'.
     turning = S('Turning On Ground',
                 items=[KeyPointValue(name='Turning On Ground',
                                      slice=slice(20, 60))])
     off_blocks_datetime.set_flight_attr = Mock()
     off_blocks_datetime.derive(turning, start_datetime)
     off_blocks_datetime.set_flight_attr.assert_called_once_with(
         start_datetime.value + timedelta(seconds=60))
     turning = S('Turning', items=[KeyPointValue(name='Turning On Ground',
                                                 slice=slice(10, 20)),
                                   KeyPointValue(name='Turning In Air',
                                                 slice=slice(20, 60)),
                                   KeyPointValue(name='Turning On Ground',
                                                 slice=slice(70, 90))])
     off_blocks_datetime.set_flight_attr = Mock()
     off_blocks_datetime.derive(turning, start_datetime)
     off_blocks_datetime.set_flight_attr.assert_called_once_with(
         start_datetime.value + timedelta(seconds=90))
 def derive(self,
            takeoff=S('Takeoff'),
            initial_climb=S('Initial Climb'),
            climb=S('Climb'),
            alt_aal=P('Altitude AAL'),
            alt_std=P('Altitude STD Smoothed')):
     pass
Ejemplo n.º 5
0
    def derive(self,
               alt_agl=P('Altitude AGL'),
               airs=S('Airborne'),
               hovers=S('Hover'),
               trans_hfs=S('Transition Hover To Flight'),
               trans_fhs=S('Transition Flight To Hover')):

        air_taxis = []
        taxis = []

        if airs:
            for air in airs:
                lows = slices_below(alt_agl.array[air.slice],
                                    HOVER_TAXI_HEIGHT)[1]
                taxis = shift_slices(lows, air.slice.start)
        # Remove periods identified already as transitions.
        if taxis:
            for taxi in slices_and_not(taxis, [h.slice for h in hovers]):
                if trans_fhs:
                    for trans_fh in trans_fhs:
                        if slices_overlap(taxi, trans_fh.slice):
                            taxi = slice(trans_fh.slice.stop, taxi.stop)

                if trans_hfs:
                    for trans_hf in trans_hfs:
                        if slices_overlap(taxi, trans_hf.slice):
                            taxi = slice(taxi.start, trans_hf.slice.start)

                air_taxis.extend([taxi])

        self.create_phases(air_taxis)
Ejemplo n.º 6
0
 def derive(self,
            alt_agl=P('Altitude AGL'),
            airs=S('Airborne'),
            hovers=S('Hover'),
            trans_hfs=S('Transition Hover To Flight'),
            trans_fhs=S('Transition Flight To Hover')):
     pass
Ejemplo n.º 7
0
    def derive(self,
               pilot_flying=M('Pilot Flying'),
               pitch_capt=P('Pitch (Capt)'),
               pitch_fo=P('Pitch (FO)'),
               roll_capt=P('Roll (Capt)'),
               roll_fo=P('Roll (FO)'),
               cc_capt=P('Control Column Force (Capt)'),
               cc_fo=P('Control Column Force (FO)'),
               ap1_eng=M('AP (1) Engaged'),
               ap2_eng=M('AP (2) Engaged'),
               takeoffs=S('Takeoff'),
               liftoffs=KTI('Liftoff'),
               rejected_toffs=S('Rejected Takeoff')):

        #TODO: Tidy
        phase = takeoffs or rejected_toffs or None
        if phase is None:
            # Nothing to do as no attempt to takeoff
            return
        lift = liftoffs.get_first() if liftoffs else None
        if lift and ap1_eng and ap2_eng:
            # check AP state at the floored index (just before lift)
            ap1 = ap1_eng.array[lift.index] == 'Engaged'
            ap2 = ap2_eng.array[lift.index] == 'Engaged'
        else:
            ap1 = ap2 = None
        args = (pilot_flying, pitch_capt, pitch_fo, roll_capt, roll_fo,
                cc_capt, cc_fo, phase.get_first(), ap1, ap2)
        self.set_flight_attr(self._determine_pilot(*args))
 def derive(self,
            offshores=M('Offshore'),
            liftoffs=KTI('Liftoff'),
            hovers=S('Hover'),
            nose_downs=S('Nose Down Attitude Adoption'),
            rad_alt=P('Altitude Radio'),
            alt_aal=P('Altitude AAL For Flight Phases')):
     pass
Ejemplo n.º 9
0
 def derive(self,
            ac_type=A('Aircraft Type'),
            alt_aal=P('Altitude AAL For Flight Phases'),
            level_flights=S('Level Flight'),
            landings=S('Landing'),
            alt_agl=P('Altitude AGL'),
            alt_std=P('Altitude STD')):
     pass
Ejemplo n.º 10
0
 def derive(
         self,
         head=P('Heading Continuous'),
         alt_aal=P('Altitude AAL For Flight Phases'),
         fast=S('Fast'),
         airs=S('Airborne'),
 ):
     pass
Ejemplo n.º 11
0
 def derive(
         self,
         rot=P('Heading Rate'),
         gspd=P('Groundspeed'),
         airs=S('Airborne'),
         fast=S('Fast'),
 ):
     pass
Ejemplo n.º 12
0
 def derive(self,
            mobiles=S('Mobile'),
            gspd=P('Groundspeed'),
            toffs=S('Takeoff'),
            lands=S('Landing'),
            rtos=S('Rejected Takeoff'),
            airs=S('Airborne')):
     pass
Ejemplo n.º 13
0
    def derive(self, afr_type=A('AFR Type'), fast=S('Fast'),
               liftoffs=KTI('Liftoff'), touchdowns=KTI('Touchdown'),
               touch_and_gos=S('Touch And Go'), groundspeed=P('Groundspeed')):
        '''
        TODO: Detect MID_FLIGHT.
        '''
        afr_type = afr_type.value if afr_type else None

        if liftoffs and not touchdowns:
            # In the air without having touched down.
            self.warning("'Liftoff' KTI exists without 'Touchdown'.")
            raise InvalidFlightType('LIFTOFF_ONLY')
            #self.set_flight_attr('LIFTOFF_ONLY')
            #return
        elif not liftoffs and touchdowns:
            # In the air without having lifted off.
            self.warning("'Touchdown' KTI exists without 'Liftoff'.")
            raise InvalidFlightType('TOUCHDOWN_ONLY')
            #self.set_flight_attr('TOUCHDOWN_ONLY')
            #return

        if liftoffs and touchdowns:
            first_touchdown = touchdowns.get_first()
            first_liftoff = liftoffs.get_first()
            if first_touchdown.index < first_liftoff.index:
                # Touchdown before having lifted off, data must be INCOMPLETE.
                self.warning("'Touchdown' KTI index before 'Liftoff'.")
                raise InvalidFlightType('TOUCHDOWN_BEFORE_LIFTOFF')
                #self.set_flight_attr('TOUCHDOWN_BEFORE_LIFTOFF')
                #return
            last_touchdown = touchdowns.get_last()  # TODO: Delete line.
            if touch_and_gos:
                last_touchdown = touchdowns.get_last()
                last_touch_and_go = touch_and_gos.get_last()
                if last_touchdown.index <= last_touch_and_go.index:
                    self.warning("A 'Touch And Go' KTI exists after the last "
                                 "'Touchdown'.")
                    raise InvalidFlightType('LIFTOFF_ONLY')
                    #self.set_flight_attr('LIFTOFF_ONLY')
                    #return

            if afr_type in [FlightType.Type.FERRY,
                            FlightType.Type.LINE_TRAINING,
                            FlightType.Type.POSITIONING,
                            FlightType.Type.TEST,
                            FlightType.Type.TRAINING]:
                flight_type = afr_type
            else:
                flight_type = FlightType.Type.COMPLETE
        elif fast:
            flight_type = FlightType.Type.REJECTED_TAKEOFF
        elif groundspeed and groundspeed.array.ptp() > 10:
            # The aircraft moved on the ground.
            flight_type = FlightType.Type.GROUND_RUN
        else:
            flight_type = FlightType.Type.ENGINE_RUN_UP
        self.set_flight_attr(flight_type)
 def derive(
         self,
         collective=P('Collective'),
         nr=P('Nr'),
         grounded=S('Grounded'),
         stationary=S('Stationary'),
         pedal=P('Tail Rotor Pedal'),
 ):
     pass
Ejemplo n.º 15
0
 def derive(
         self,
         tcas_ops=S('TCAS Operational'),
         tcas_ta1=M('TCAS TA'),
         tcas_ta2=M('TCAS All Threat Traffic'),
         tcas_ta3=M('TCAS Traffic Alert'),
         tcas_ta4=M('TCAS TA (1)'),
         tcas_ras=S('TCAS Resolution Advisory'),
 ):
     pass
Ejemplo n.º 16
0
 def derive(self,
            accel_lon=P('Acceleration Longitudinal Offset Removed'),
            eng_running=M('Eng (*) All Running'),
            groundeds=S('Grounded'),
            eng_n1=P('Eng (*) N1 Max'),
            toff_acc=KTI('Takeoff Acceleration Start'),
            toff_rwy_hdg=S('Takeoff Runway Heading'),
            seg_type=A('Segment Type'),
            toga=M('Takeoff And Go Around')):
     pass
Ejemplo n.º 17
0
 def derive(self,
            ac_type=A('Aircraft Type'),
            head=P('Heading Continuous'),
            alt_aal=P('Altitude AAL For Flight Phases'),
            fast=S('Fast'),
            mobile=S('Mobile'),
            alt_agl=P('Altitude AGL'),
            coll=P('Collective'),
            airs=S('Airborne')):
     pass
 def derive(self,
            afr_type=A('AFR Type'),
            fast=S('Fast'),
            mobile=S('Mobile'),
            liftoffs=KTI('Liftoff'),
            touchdowns=KTI('Touchdown'),
            touch_and_gos=S('Touch And Go'),
            rejected_to=S('Rejected Takeoff'),
            eng_start=KTI('Eng Start'),
            seg_type=A('Segment Type')):
     pass
 def derive(self,
            acc_norm=P('Acceleration Normal'),
            acc_long=P('Acceleration Longitudinal Offset Removed'),
            alt=P('Altitude AAL'),
            alt_rad=P('Altitude Radio'),
            gog=M('Gear On Ground'),
            lands=S('Landing'),
            flap=P('Flap'),
            manufacturer=A('Manufacturer'),
            family=A('Family'),
            airs=S('Airborne'),
            ac_type=A('Aircraft Type'),
            accel=P('Acceleration Longitudinal')):
     pass
 def derive(self,
            pilot_flying=M('Pilot Flying'),
            pitch_capt=P('Pitch (Capt)'),
            pitch_fo=P('Pitch (FO)'),
            roll_capt=P('Roll (Capt)'),
            roll_fo=P('Roll (FO)'),
            cc_capt=P('Control Column Force (Capt)'),
            cc_fo=P('Control Column Force (FO)'),
            ap1_eng=M('AP (1) Engaged'),
            ap2_eng=M('AP (2) Engaged'),
            takeoffs=S('Takeoff'),
            liftoffs=KTI('Liftoff'),
            rejected_toffs=S('Rejected Takeoff'),
            afr_takeoff_pilot=A('AFR Takeoff Pilot')):
     pass
Ejemplo n.º 21
0
    def derive(self,
               ils_localizer=P('ILS Localizer'),
               alt_aal=P('Altitude AAL For Flight Phases'),
               approaches=S('Approach And Landing'),
               runway=A('FDR Landing Runway')):

        if 'glideslope' in runway.value:
            for app in approaches:
                if ils_localizer:
                    alt_bands = alt_aal.slices_from_to(1000, 500)
                    ils_run = sustained_max_abs(ils_localizer,
                                                window=5,
                                                _slice=app)
                    x = np.ma.zeros(len(ils_localizer.array))
                    x.data[app.slice] = ils_run
                    self.create_kpvs_within_slices(
                        abs(x),
                        alt_bands,
                        max_abs_value,
                    )
                else:
                    self.warning("ILS Localizer not measured on approach")
                    return
        else:
            self.warning("Runway not equipped with ILS Localizer")
            return
Ejemplo n.º 22
0
    def get_params(self, hdf_path, _slice, phase_name):
        import shutil
        import tempfile
        from hdfaccess.file import hdf_file

        with tempfile.NamedTemporaryFile() as temp_file:
            shutil.copy(hdf_path, temp_file.name)

            with hdf_file(hdf_path) as hdf:
                pitch_capt = hdf.get('Pitch (Capt)')
                pitch_fo = hdf.get('Pitch (FO)')
                roll_capt = hdf.get('Roll (Capt)')
                roll_fo = hdf.get('Roll (FO)')
                cc_capt = hdf.get('Control Column Force (Capt)')
                cc_fo = hdf.get('Control Column Force (FO)')

                for par in pitch_capt, pitch_fo, roll_capt, roll_fo, cc_capt, \
                        cc_fo:
                    if par is not None:
                        ref_par = par
                        break

        phase = S(name=phase_name, frequency=1)
        phase.create_section(_slice)
        phase = phase.get_aligned(ref_par)[0]

        # Align the arrays, usually done in the Nodes
        for par in pitch_fo, roll_capt, roll_fo, cc_capt, cc_fo:
            if par is None:
                continue
            par.array = align(par, ref_par)
            par.hz = ref_par.hz

        return pitch_capt, pitch_fo, roll_capt, roll_fo, cc_capt, cc_fo, phase
Ejemplo n.º 23
0
    def derive(self,
               liftoff=KTI('Liftoff'),
               rto=S('Rejected Takeoff'),
               off_blocks=KTI('Off Blocks'),
               start_dt=A('Start Datetime')):

        if liftoff:
            # Flight - use first liftoff index
            first_liftoff = liftoff.get_first()
            liftoff_index = first_liftoff.index
            frequency = liftoff.frequency
        elif rto:
            # RTO - use start index of first RTO
            first_rto = rto.get_first()
            liftoff_index = first_rto.slice.start
            frequency = rto.frequency
        elif off_blocks:
            # Ground Only - use first off blocks index
            first_off_blocks = off_blocks.get_first()
            liftoff_index = first_off_blocks.index
            frequency = off_blocks.frequency
        else:
            # Incomplete - use start of data
            liftoff_index = 0
            frequency = 1

        takeoff_dt = datetime_of_index(start_dt.value,
                                       liftoff_index,
                                       frequency=frequency)
        self.set_flight_attr(takeoff_dt)
Ejemplo n.º 24
0
    def setUp(self):
        self.node_class = ApproachInformation
        self.alt_aal = P(name='Altitude AAL', array=np.ma.array([
            10, 5, 0, 0, 5, 10, 20, 30, 40, 50,      # Touch & Go
            50, 45, 30, 35, 30, 30, 35, 40, 40, 40,  # Go Around
            30, 20, 10, 0, 0, 0, 0, 0, 0, 0,         # Landing
        ]))
        self.app = ApproachAndLanding()
        self.fast = S(name='Fast', items=[
            Section(name='Fast', slice=slice(0, 22), start_edge=0,
                    stop_edge=22.5),
        ])

        self.land_hdg = KPV(name='Heading During Landing', items=[
            KeyPointValue(index=22, value=60),
        ])
        self.land_lat = KPV(name='Latitude At Touchdown', items=[
            KeyPointValue(index=22, value=10),
        ])
        self.land_lon = KPV(name='Longitude At Touchdown', items=[
            KeyPointValue(index=22, value=-2),
        ])
        self.appr_hdg = KPV(name='Heading At Lowest Altitude During Approach', items=[
            KeyPointValue(index=5, value=25),
            KeyPointValue(index=12, value=35),
        ])
        self.appr_lat = KPV(name='Latitude At Lowest Altitude During Approach', items=[
            KeyPointValue(index=5, value=8),
        ])
        self.appr_lon = KPV(name='Longitude At Lowest Altitude During Approach', items=[
            KeyPointValue(index=5, value=4),
        ])
        self.land_afr_apt_none = A(name='AFR Landing Airport', value=None)
        self.land_afr_rwy_none = A(name='AFR Landing Runway', value=None)
Ejemplo n.º 25
0
 def derive(self,
            eng2_np=P('Eng (2) Np'),
            eng1_n1=P('Eng (1) N1'),
            eng2_n1=P('Eng (2) N1'),
            groundeds=S('Grounded'),
            prop_brake=M('Propeller Brake')):
     pass
Ejemplo n.º 26
0
 def derive(self,
            alt_agl=P('Altitude AGL'),
            ias=P('Airspeed'),
            airs=S('Airborne'),
            pitch_rate=P('Pitch Rate')):
     for air in airs:
         lows = np.ma.clump_unmasked(
             np.ma.masked_greater(alt_agl.array[air.slice],
                                  ROTOR_TRANSITION_ALTITUDE))
         for low in lows:
             trans_slices = slices_from_to(ias.array[air.slice][low],
                                           ROTOR_TRANSITION_SPEED_LOW,
                                           ROTOR_TRANSITION_SPEED_HIGH,
                                           threshold=1.0)[1]
             if trans_slices:
                 for trans in trans_slices:
                     base = air.slice.start + low.start
                     ext_start = int(base + trans.start -
                                     20 * ias.frequency)
                     if alt_agl.array[ext_start] == 0.0:
                         trans_start = index_at_value(
                             ias.array,
                             0.0,
                             _slice=slice(base + trans.start, ext_start,
                                          -1),
                             endpoint='first_closing')
                     else:
                         trans_start = np.ma.argmin(
                             pitch_rate.array[ext_start:base +
                                              trans.start]) + ext_start
                     self.create_phase(slice(trans_start,
                                             trans.stop + base))
Ejemplo n.º 27
0
    def derive(self,
               alt_rad=P('Altitude Radio'),
               alt_agl=P('Altitude AGL'),
               gog=M('Gear On Ground'),
               rtr=S('Rotors Turning')):
        # When was the gear in the air?
        gear_off_grounds = runs_of_ones(gog.array == 'Air')

        if alt_rad and alt_agl and rtr:
            # We can do a full analysis.
            # First, confirm that the rotors were turning at this time:
            gear_off_grounds = slices_and(gear_off_grounds, rtr.get_slices())

            # When did the radio altimeters indicate airborne?
            airs = slices_remove_small_gaps(
                np.ma.clump_unmasked(
                    np.ma.masked_less_equal(alt_agl.array, 1.0)),
                time_limit=AIRBORNE_THRESHOLD_TIME_RW,
                hz=alt_agl.frequency)
            # Both is a reliable indication of being in the air.
            for air in airs:
                for goff in gear_off_grounds:
                    # Providing they relate to each other :o)
                    if slices_overlap(air, goff):
                        start_index = max(air.start, goff.start)
                        end_index = min(air.stop, goff.stop)

                        better_begin = index_at_value(
                            alt_rad.array,
                            1.0,
                            _slice=slice(
                                max(start_index - 5 * alt_rad.frequency, 0),
                                start_index + 5 * alt_rad.frequency))
                        if better_begin:
                            begin = better_begin
                        else:
                            begin = start_index

                        better_end = index_at_value(
                            alt_rad.array,
                            1.0,
                            _slice=slice(
                                max(end_index + 5 * alt_rad.frequency, 0),
                                end_index - 5 * alt_rad.frequency, -1))
                        if better_end:
                            end = better_end
                        else:
                            end = end_index

                        duration = end - begin
                        if (duration /
                                alt_rad.hz) > AIRBORNE_THRESHOLD_TIME_RW:
                            self.create_phase(slice(begin, end))
        else:
            # During data validation we can select just sensible flights;
            # short hops make parameter validation tricky!
            self.create_phases(
                slices_remove_small_gaps(
                    slices_remove_small_slices(gear_off_grounds,
                                               time_limit=30)))
Ejemplo n.º 28
0
    def derive(self, gnds=S('Grounded'), pitch=P('Pitch'), roll=P('Roll')):

        decks = []
        for gnd in gnds:
            # The fourier transform for pitching motion...
            p = pitch.array[gnd.slice]
            if np.all(p.mask):
                continue
            n = float(
                len(p))  # Scaling the result to be independet of data length.
            fft_p = np.abs(np.fft.rfft(p - moving_average(p))) / n

            # similarly for roll
            r = roll.array[gnd.slice]
            if np.all(r.mask):
                continue
            fft_r = np.abs(np.fft.rfft(r - moving_average(r))) / n

            # What was the maximum harmonic seen?
            fft_max = np.ma.max(fft_p + fft_r)

            # Values of less than 0.1 were on the ground, and 0.34 on deck for the one case seen to date.
            if fft_max > 0.2:
                decks.append(gnd.slice)
        if decks:
            self.create_sections(decks)
    def derive(self,
               pilot_flying=M('Pilot Flying'),
               pitch_capt=P('Pitch (Capt)'),
               pitch_fo=P('Pitch (FO)'),
               roll_capt=P('Roll (Capt)'),
               roll_fo=P('Roll (FO)'),
               cc_capt=P('Control Column Force (Capt)'),
               cc_fo=P('Control Column Force (FO)'),
               ap1_eng=M('AP (1) Engaged'),
               ap2_eng=M('AP (2) Engaged'),
               landings=S('Landing'),
               touchdowns=KTI('Touchdown'),
               afr_landing_pilot=A('AFR Landing Pilot')):

        if afr_landing_pilot and afr_landing_pilot.value:
            self.set_flight_attr(afr_landing_pilot.value.replace('_', ' ').title())
            return

        phase = landings.get_last() if landings else None
        tdwn = touchdowns.get_last() if touchdowns else None
        if tdwn and ap1_eng and ap2_eng:
            # check AP state at the floored index (just before tdwn)
            ap1 = ap1_eng.array[int(tdwn.index)] == 'Engaged'
            ap2 = ap2_eng.array[int(tdwn.index)] == 'Engaged'
        else:
            ap1 = ap2 = None
        args = (pilot_flying, pitch_capt, pitch_fo, roll_capt, roll_fo,
                cc_capt, cc_fo, phase, ap1, ap2)
        self.set_flight_attr(self._determine_pilot(*args))
Ejemplo n.º 30
0
 def derive(self,
            takeoffs=S('Takeoff'),
            climb_starts=KTI('Climb Start'),
            tocs=KTI('Top Of Climb'),
            alt=P('Altitude STD'),
            ac_type=A('Aircraft Type')):
     pass