예제 #1
0
def __check_cancel_orbita(f_atv):
    """
    checa condições de abandonar a orbita. A condição é executada pelo comando de pilotagem

    @param f_atv: pointer para aeronave

    @return True se condição de abandonar a orbita, senão False (condição de permanecer em orbita)
    """
    # check input
    assert f_atv

    # verifica condições para execução
    if (not f_atv.v_atv_ok) or (ldefs.E_ATIVA != f_atv.en_trf_est_atv):
        # aeronave não ativa. cai fora...
        return True

    # condição de cancelamento ?
    if f_atv.v_atv_cnl_esp:
        # coloca a aeronave na condição de abandonar a orbita
        abnd.abort_prc(f_atv)
                
        # return
        return True

    # return
    return False
예제 #2
0
def restaura_associado(f_atv, f_cine_data, f_stk_context):
    """
    restaura o procedimento associado e o contexto da pilha

    @param f_atv: pointer to aeronave
    @param f_cine_data: kinematics data
    @param f_stk_context: pointer to stack
    """
    # logger
    # M_LOG.info("restaura_associado:>>")

    # check input
    assert f_atv
    assert f_stk_context is not None

    # active flight ?
    if (not f_atv.v_atv_ok) or (ldefs.E_ATIVA != f_atv.en_trf_est_atv):
        # logger
        l_log = logging.getLogger("restaura_associado")
        l_log.setLevel(logging.ERROR)
        l_log.error(u"<E01: aeronave não ativa.")

        # abort procedure
        abnd.abort_prc(f_atv)

        # cai fora...
        return False

    # stack not empty ?
    if len(f_stk_context) > 0:
        # pop context
        # f_atv.en_atv_brk_ptr = f_stk_context.pop()
        f_atv.en_trf_fnc_ope, f_atv.en_atv_fase, f_atv.ptr_trf_prc, f_atv.ptr_atv_brk, f_cine_data.i_brk_ndx = f_stk_context.pop(
        )

        # M_LOG.debug("restaura_associado:fnc_ope/fase:[{}]/[{}]".format(ldefs.DCT_FNC_OPE[f_atv.en_trf_fnc_ope], ldefs.DCT_FASE[f_atv.en_atv_fase]))
        # M_LOG.debug("restaura_associado:ptr_trf_prc:[{}]".format(f_atv.ptr_trf_prc))
        # M_LOG.debug("restaura_associado:ptr_atv_brk:[{}]".format(f_atv.ptr_atv_brk))
        # M_LOG.debug("restaura_associado:i_brk_ndx:[{}]".format(f_cine_data.i_brk_ndx))

        # cai fora...
        return True

    # coloca a aeronave em manual
    f_atv.en_trf_fnc_ope = ldefs.E_MANUAL

    # volta a fase de verificar condições
    f_atv.en_atv_fase = ldefs.E_FASE_ZERO

    # logger
    # M_LOG.info("restaura_associado:<<")

    # cai fora...
    return False
예제 #3
0
def prc_dir_ponto(f_atv, ff_pto_x, ff_pto_y, f_cine_data):
    """
    procedimento de direcionamento a ponto
    
    @param f_atv: ponteiro para struct aeronaves
    @param ff_pto_x: coordenada x do ponto (longitude)
    @param ff_pto_y: coordenada y do ponto (latitude)
    @param f_cine_data: ponteiro para pilha
    
    @return True se aeronave atingiu ponto, senão False
    """
    # check input
    assert f_atv
    assert f_cine_data

    # active flight ?
    if (not f_atv.v_atv_ok) or (ldefs.E_ATIVA != f_atv.en_trf_est_atv):
        # logger
        l_log = logging.getLogger("prc_dir_ponto")
        l_log.setLevel(logging.ERROR)
        l_log.error("<E01: aeronave não ativa.")

        # abort procedure
        abnd.abort_prc(f_atv)

        # cai fora...
        return None

    # calcula raio do cone de tolerância
    lf_pto_rcone = f_atv.f_trf_alt_atu * math.tan(math.radians(10))

    # calcula distância da aeronave ao ponto (x, y)
    f_cine_data.f_dst_anv_pto_x = ff_pto_x - f_atv.f_trf_x
    f_cine_data.f_dst_anv_pto_y = ff_pto_y - f_atv.f_trf_y

    # calcula distância euclidiana da aeronave ao ponto (linha reta)
    lf_dst_anv_pto = math.sqrt((f_cine_data.f_dst_anv_pto_x**2) +
                               (f_cine_data.f_dst_anv_pto_y**2))

    # calcula distância euclidiana do passo da aeronave (linha reta)
    lf_passo_anv = math.sqrt((f_cine_data.f_delta_x**2) +
                             (f_cine_data.f_delta_y**2))

    # (distância ao ponto <= raio de tolerância) ou (distância ao ponto <= passo da aeronave) ? (aeronave vai ultrapassar o ponto)
    if (lf_dst_anv_pto <= lf_pto_rcone) or (lf_dst_anv_pto <= lf_passo_anv):
        # sinaliza que aeronave ATINGIU o ponto
        return True

    # calcula nova proa de demanda
    f_atv.f_atv_pro_dem = cpd.calc_proa_demanda(f_cine_data.f_dst_anv_pto_x,
                                                f_cine_data.f_dst_anv_pto_y)
    # M_LOG.debug("__ckeck_ok:f_atv_pro_dem:[{}]".format(f_atv.f_atv_pro_dem))

    # em curva ?
    if f_atv.f_atv_pro_dem != f_atv.f_trf_pro_atu:
        # calcula sentido de curva pelo menor ângulo
        scrv.sentido_curva(f_atv)

        # faz o bloqueio do ponto próximo
        razc.calc_razao_curva(f_atv, ff_pto_x, ff_pto_y, f_cine_data)

    # sinaliza que aeronave ainda NÂO atingiu o ponto
    return False
예제 #4
0
    def __cmd_pil_curva(self, f_atv, fo_cmd_pil, fen_cmd_ope):
        """
        comando de pilotagem de curva
        """
        # check input
        assert f_atv

        # força aeronave a abandonar qualquer procedimento
        abnd.abort_prc(f_atv)

        # coloca a aeronave em manual
        f_atv.en_trf_fnc_ope = ldefs.E_MANUAL

        cdbg.M_DBG.debug("__cmd_pil_curva: fo_cmd_pil.t_param_1[0]: {}".format(fo_cmd_pil.t_param_1[0]))
        cdbg.M_DBG.debug("__cmd_pil_curva: fo_cmd_pil.t_param_2[0]: {}".format(fo_cmd_pil.t_param_2[0]))
        cdbg.M_DBG.debug("__cmd_pil_curva: fo_cmd_pil.t_param_3[0]: {}".format(fo_cmd_pil.t_param_3[0]))

        # curva a direita ?
        if ldefs.E_CDIR == fen_cmd_ope:
            # graus ?
            if (fo_cmd_pil.t_param_1 is not None) and fo_cmd_pil.t_param_1[1]:
                # obtém a proa desejada (demanda)
                cdbg.M_DBG.debug("__cmd_pil_curva: f_atv.f_atv_pro_dem (A): {}".format(f_atv.f_atv_pro_dem))
                f_atv.f_atv_pro_dem = (360. + f_atv.f_trf_pro_atu + fo_cmd_pil.t_param_1[0]) % 360.
                cdbg.M_DBG.debug("__cmd_pil_curva: f_atv.f_atv_pro_dem (D): {}".format(f_atv.f_atv_pro_dem))

            # proa ?
            elif (fo_cmd_pil.t_param_2 is not None) and fo_cmd_pil.t_param_2[1]:
                # obtém a proa desejada (demanda)
                cdbg.M_DBG.debug("__cmd_pil_curva: f_atv.f_atv_pro_dem (A): {}".format(f_atv.f_atv_pro_dem))
                f_atv.f_atv_pro_dem = fo_cmd_pil.t_param_2[0] % 360.
                cdbg.M_DBG.debug("__cmd_pil_curva: f_atv.f_atv_pro_dem (D): {}".format(f_atv.f_atv_pro_dem))

            # senão, curva indefinida...
            else:
                # proa negativa
                f_atv.f_atv_pro_dem = -1.

            # razão ?
            if (fo_cmd_pil.t_param_3 is not None) and (fo_cmd_pil.t_param_3[1]) and (fo_cmd_pil.t_param_3[0] != 0.):
                # curva direita (razão positiva)
                f_atv.f_atv_raz_crv = abs(fo_cmd_pil.t_param_3[0])

            else:
                # curva direita (razão positiva)
                f_atv.f_atv_raz_crv = abs(f_atv.f_atv_raz_crv)

        # curva a esquerda ?
        elif ldefs.E_CESQ == fen_cmd_ope:
            # graus ?
            if (fo_cmd_pil.t_param_1 is not None) and fo_cmd_pil.t_param_1[1]:
                # obtém a proa desejada (demanda)
                f_atv.f_atv_pro_dem = (360. + f_atv.f_trf_pro_atu - fo_cmd_pil.t_param_1[0]) % 360.

            # proa ?
            elif (fo_cmd_pil.t_param_2 is not None) and fo_cmd_pil.t_param_2[1]:
                # obtém a proa desejada (demanda)
                f_atv.f_atv_pro_dem = fo_cmd_pil.t_param_2[0] % 360.

            # senão, curva indefinida...
            else:
                # proa negativa
                f_atv.f_atv_pro_dem = -1.

            # razão ?
            if (fo_cmd_pil.t_param_3 is not None) and (fo_cmd_pil.t_param_3[1]) and (fo_cmd_pil.t_param_3[0] != 0.):
                # curva esquerda (razão negativa)
                f_atv.f_atv_raz_crv = -abs(fo_cmd_pil.t_param_3[0])

            else:
                # curva esquerda (razão negativa)
                f_atv.f_atv_raz_crv = -abs(f_atv.f_atv_raz_crv)

        # curva pelo menor ângulo ?
        elif ldefs.E_CMNR == fen_cmd_ope:
            # graus ?
            if (fo_cmd_pil.t_param_1 is not None) and fo_cmd_pil.t_param_1[1]:
                # obtém a proa desejada (demanda)
                f_atv.f_atv_pro_dem = (360. + f_atv.f_trf_pro_atu + fo_cmd_pil.t_param_1[0]) % 360.

            # proa ?
            elif (fo_cmd_pil.t_param_2 is not None) and fo_cmd_pil.t_param_2[1]:
                # obtém a proa desejada (demanda)
                f_atv.f_atv_pro_dem = fo_cmd_pil.t_param_2[0] % 360.

            # senão, curva indefinida...
            else:
                # proa negativa
                f_atv.f_atv_pro_dem = -1.

            # razão ?
            if (fo_cmd_pil.t_param_3 is not None) and (fo_cmd_pil.t_param_3[1]) and (fo_cmd_pil.t_param_3[0] != 0.):
                # razão de curva
                f_atv.f_atv_raz_crv = abs(fo_cmd_pil.t_param_3[0])

            else:
                # razão de curva
                f_atv.f_atv_raz_crv = abs(f_atv.f_atv_raz_crv)

            # força a curva pelo menor ângulo
            scrv.sentido_curva(f_atv)

        # proa ?
        elif ldefs.E_PROA == fen_cmd_ope:
            # obtém a proa desejada (demanda)
            f_atv.f_atv_pro_dem = fo_cmd_pil.t_param_2[0] % 360.

            # força a curva pelo menor ângulo
            scrv.sentido_curva(f_atv)

        # senão,...
        else:
            # logger
            l_log = logging.getLogger("CFlightEngine::__cmd_pil_curva")
            l_log.setLevel(logging.CRITICAL)
            l_log.critical(u"<E01: comando operacional ({}) não existe.".format(fen_cmd_ope))
예제 #5
0
def __check_ok(f_atv, f_cine_data):
    """
    preparar a aeronave para decolagem

    @param f_atv: pointer to struct aeronaves
    @param f_cine_data: dados da cinemática
    """
    # check input
    assert f_atv

    # pointer to aerodrome
    l_aer = f_cine_data.ptr_aer

    # aerodrome ok ?
    if (l_aer is None) or (not l_aer.v_aer_ok):
        # logger
        l_log = logging.getLogger("__check_ok")
        l_log.setLevel(logging.ERROR)
        l_log.error("<E01: aeródromo de decolagem inexistente. aeronave:[{}/{}].".format(f_atv.i_trf_id, f_atv.s_trf_ind))

        # abort procedure
        abnd.abort_prc(f_atv)

        # cancel flight 
        f_atv.en_atv_est_atv = ldefs.E_CANCELADA

        # aeródromo de decolagem inexistente. cai fora...
        return

    # pointer to runway
    l_pst = f_cine_data.ptr_pis

    # runway ok ?
    if (l_pst is None) or (not l_pst.v_pst_ok):
        # logger
        l_log = logging.getLogger("__check_ok")
        l_log.setLevel(logging.ERROR)
        l_log.error("<E02: pista de decolagem inexistente. aeronave:[{}/{}].".format(f_atv.i_trf_id, f_atv.s_trf_ind))

        # abort procedure
        abnd.abort_prc(f_atv)

        # cancel flight 
        f_atv.en_atv_est_atv = ldefs.E_CANCELADA

        # pista de decolagem inexistente. cai fora...
        return

    # aceleração
    f_atv.f_atv_acel = f_atv.ptr_trf_prf.f_prf_raz_max_var_vel * ldefs.D_FATOR_ACEL

    # velocidade atual
    f_atv.f_trf_vel_atu = 0.

    # velocidade de decolagem
    f_atv.f_atv_vel_dem = f_atv.ptr_trf_prf.f_prf_vel_dec

    # rumo da pista
    # i_pst_rumo (mlabru)
    f_atv.f_trf_pro_atu = \
    f_atv.f_atv_pro_dem = l_pst.f_pst_true

    # elevação do aeródromo
    f_atv.f_trf_alt_atu = \
    f_atv.f_atv_alt_dem = l_aer.f_aer_elev

    # posiciona aeronave na cabeceira da pista em x/y
    f_atv.f_trf_x = l_pst.f_pst_x
    f_atv.f_trf_y = l_pst.f_pst_y

    # sinaliza a fase de processamento de decolagem
    f_atv.en_atv_fase = ldefs.E_FASE_DECOLAGEM
예제 #6
0
def prc_decolagem(f_atv, f_cine_data, fstk_context):
    """
    @param f_atv: ponteiro para struct aeronaves
    @param f_cine_data: ponteiro para pilha
    @param fstk_context: pilha de contexto
    """
    # check input
    assert f_atv
    assert f_cine_data
    assert fstk_context

    # active flight ?
    if (not f_atv.v_atv_ok) or (ldefs.E_ATIVA != f_atv.en_trf_est_atv):
        # logger
        l_log = logging.getLogger("prc_decolagem")
        l_log.setLevel(logging.ERROR)
        l_log.error("<E01: aeronave [{}/{}] não ativa.".format(f_atv.i_trf_id, f_atv.s_trf_ind))

        # abort procedure
        abnd.abort_prc(f_atv)

        # aeronave não ativa. cai fora...
        return

    # performance ok ?
    if (f_atv.ptr_trf_prf is None) or (not f_atv.ptr_trf_prf.v_prf_ok):
        # logger
        l_log = logging.getLogger("prc_decolagem")
        l_log.setLevel(logging.ERROR)
        l_log.error("<E02: performance não existe. aeronave:[{}/{}].".format(f_atv.i_trf_id, f_atv.s_trf_ind))

        # abort procedure
        abnd.abort_prc(f_atv)

        # performance não existe. cai fora...
        return

    # processa as fases

    # fase de preparação ?
    if ldefs.E_FASE_ZERO == f_atv.en_atv_fase:
        # verifica condição para execução
        __check_ok(f_atv, f_cine_data)

    # fase de decolagem ?
    elif ldefs.E_FASE_DECOLAGEM == f_atv.en_atv_fase:
        # realiza o processamento
        __do_dep(f_atv, f_cine_data, fstk_context)

    # fase estabilizada ?
    elif ldefs.E_FASE_ESTABILIZADA == f_atv.en_atv_fase:
        # verifica o término da decolagem
        if f_atv.f_trf_alt_atu == f_atv.f_atv_alt_dem:
            # obtém do contexto a função operacional anterior
            len_fnc_ope_tmp, _, _, _, _ = fstk_context[-1]

            # restaura a pilha de procedimento ou por comando de pilotagem
            if (ldefs.E_SUBIDA == f_atv.en_trf_fnc_ope_ant) or (ldefs.E_SUBIDA == len_fnc_ope_tmp):
                # restaura a pilha de procedimento
                tass.restaura_associado(f_atv, f_cine_data, fstk_context)

            # senão,...
            else:
                # decolagem incluida num tráfego, coloca em MANUAL
                f_atv.f_atv_alt_dem = f_atv.ptr_trf_prf.f_prf_teto_sv
                f_atv.en_trf_fnc_ope = ldefs.E_MANUAL

    # senão,...
    else:
        # logger
        l_log = logging.getLogger("prc_decolagem")
        l_log.setLevel(logging.ERROR)
        l_log.error("<E04: fase da decolagem não identificada. aeronave:[{}/{}].".format(f_atv.i_trf_id, f_atv.s_trf_ind))

        # abort procedure
        abnd.abort_prc(f_atv)
예제 #7
0
def __do_dep(f_atv, f_cine_data, fstk_context):
    """
    realizar o procedimento de decolagem

    @param f_atv: ponteiro para struct aeronaves
    @param f_cine_data: dados de cinemática
    @param fstk_context: ponteiro para pilha
    """
    # check input
    assert f_atv
    assert f_cine_data
    assert fstk_context

    # obtém do contexto a função operacional anterior
    len_fnc_ope_tmp, _, _, _, _ = fstk_context[-1]

    # atingiu a velocidade de decolagem ?
    if f_atv.f_trf_vel_atu != f_atv.ptr_trf_prf.f_prf_vel_dec:
        # não atingiu a velocidade de decolagem, cai fora...
        return

    # pointer aerodrome
    l_aer = f_cine_data.ptr_aer

    # aerodrome ok ?
    if (l_aer is None) or (not l_aer.v_aer_ok):
        # logger
        l_log = logging.getLogger("__do_dep")
        l_log.setLevel(logging.ERROR)
        l_log.error("<E01: aeródromo de decolagem inexistente. aeronave:[{}/{}].".format(f_atv.i_trf_id, f_atv.s_trf_ind))

        # abort procedure
        abnd.abort_prc(f_atv)

        # cancel flight 
        f_atv.en_atv_est_atv = ldefs.E_CANCELADA

        # aeródromo de decolagem inexistente. cai fora...
        return

    # verifica se é uma decolagem com subida ou decolagem pura
    if (ldefs.E_SUBIDA == f_atv.en_trf_fnc_ope_ant) or (ldefs.E_SUBIDA == len_fnc_ope_tmp):
        # pointer to subida
        l_sub = f_cine_data.ptr_sub

        # subida ok ?
        if (l_sub is None) or (not l_sub.v_prc_ok):
            # logger
            l_log = logging.getLogger("__do_dep")
            l_log.setLevel(logging.ERROR)
            l_log.error("<E02: decolagem/subida inexistente. aeronave:[{}/{}].".format(f_atv.i_trf_id, f_atv.s_trf_ind))

            # abort procedure
            abnd.abort_prc(f_atv)

            # cancel flight 
            f_atv.en_atv_est_atv = ldefs.E_CANCELADA

            # decolagem/subida inexistente. cai fora...
            return

        # pointer to first climb breakpoint
        l_brk = l_sub.lst_sub_brk[0]

        # breakpoint ok ?
        if (l_brk is None) or (not l_brk.v_brk_ok):
            # logger
            l_log = logging.getLogger("__do_dep")
            l_log.setLevel(logging.ERROR)
            l_log.error("<E03: decolagem/subida breakpoint inexistente. aeronave:[{}/{}].".format(f_atv.i_trf_id, f_atv.s_trf_ind))

            # abort procedure
            abnd.abort_prc(f_atv)

            # cancel flight 
            f_atv.en_atv_est_atv = ldefs.E_CANCELADA

            # decolagem/subida breakpoint inexistente. cai fora...
            return

        # pointer to runway
        l_pst = f_cine_data.ptr_pis

        # runway ok ?
        if (l_pst is None) or (not l_pst.v_pst_ok):
            # logger
            l_log = logging.getLogger("__do_dep")
            l_log.setLevel(logging.ERROR)
            l_log.error("<E04: pista de decolagem inexistente. aeronave:[{}/{}].".format(f_atv.i_trf_id, f_atv.s_trf_ind))

            # abort procedure
            abnd.abort_prc(f_atv)

            # cancel flight 
            f_atv.en_atv_est_atv = ldefs.E_CANCELADA

            # pista de decolagem inexistente. cai fora...
            return

        # calcula a radial entre o 1*brk da subida e a pista
        lf_delta_x = l_brk.f_brk_x - l_pst.f_pst_x
        lf_delta_y = l_brk.f_brk_y - l_pst.f_pst_y

        lf_radial_pstta_brk = cpd.calc_proa_demanda(lf_delta_x , lf_delta_y)

        # calcula o ângulo entre o rumo da pista e o 1*brk da subida
        # i_pst_rumo (mlabru)
        lf_ang_pista_brk = abs(l_pst.f_pst_true - lf_radial_pstta_brk)

        # regra de cálculo da altitude na decolagem com Subida:
        # livrar obstáculos na decolagem (montanhas, prédios, ...)
        # limites: ângulo limite de 15 graus entre rumo da pista e o primeiro ponto da subida
        # se a diferença dos ângulos (fAngPistaBkp) for maior que 15 graus, então a altitude
        # de demanda será 400ft (não é nível) acima da elevação do aeródromo
        # se a diferença dos ângulos (fAngPistaBkp) for menor ou igual a 15 graus, a altitude
        # de demanda será 50ft acima da elevação do aeródromo

        if lf_ang_pista_brk > 15.:
            # calcula 400ft acima da altitude da pista (converte ft -> m)
            f_atv.f_atv_alt_dem = (400. * cdefs.D_CNV_FT2M) + l_aer.f_aer_elev

        # senão,...
        else:
            # calcula 50ft acima da altitude da pista (converte ft -> m)
            f_atv.f_atv_alt_dem = (50. * cdefs.D_CNV_FT2M) + l_aer.f_aer_elev

        # determina a razão máxima de subida na decolagem para todos os casos
        #
        # PBN (casos de DEP no SBGL e SBRJ)
        # Descomentado este trecho para as seguintes considerações:
        # a) aeródromos com pistas curtas (caso SBGL) as aeronaves consigam aplicar a
        #    RazMaxSubDec, porém o gradiente tem que estar zerado no primeiro ponto da Subida.
        # b) aeródromos com pistas longas, a AnvRazSub possa ser aplicada mediante o cálculo do
        #    gradiente (se houver) para atingir o primeiro ponto da Subida.
        #
        # Obs_1: Com o retorno da verificação do gradiente, evitou-se que aeronaves decolando
        #        em pistas longas chegassem a subir como se fossem foguetes devido ao uso
        #        generalizado da prf_raz_max_sub_dec para todos os casos.
        # Obs_2: Ambos casos a aceleração na DEP tem que ser 4 vezes (campo do arquivo ".ini")

        if 0. == l_brk.f_brk_raz_vel:
            # razão de subida é a razão máxima de subida na decolagem
            f_atv.f_atv_raz_sub = f_atv.ptr_trf_prf.f_prf_raz_max_sub_dec

        # senão,...
        else:
            # calcula a razão de subida em função do gradiente
            f_atv.f_atv_raz_sub = f_atv.f_trf_vel_atu * l_brk.f_brk_raz_vel

    # decolagem pura, sem subida
    else:
        # regra de cálculo da altitude na decolagem pura:
        # livrar obstáculos na decolagem (montanhas, prédios, ...). A altitude de demanda será
        # 50ft acima da elevação do aeródromo

        # calcula 50ft acima da altitude da pista
        f_atv.f_atv_alt_dem = (50. * cdefs.D_CNV_FT2M) + l_aer.f_aer_elev

        # razão de subida é a razão máxima de subida na decolagem
        f_atv.f_atv_raz_sub = f_atv.ptr_trf_prf.f_prf_raz_max_sub_dec

    # regra da velocidade na decolagem:
    # velocidade limite de 250kt para as aeronaves que estiverem voando abaixo de 10000ft (FL100)

    # verifica a altitude atual da aeronave
    if (f_atv.f_trf_alt_atu * cdefs.D_CNV_M2FT) < ldefs.D_ALT_MAX_TMA:
        # determina a velocidade de subida na decolagem (limitada a 250kt)
        f_atv.f_atv_vel_dem = min(f_atv.ptr_trf_prf.f_prf_vel_sub_dec, ldefs.D_VEL_MAX_TMA)

    # ajusta aceleração
    f_atv.f_atv_acel = f_atv.ptr_trf_prf.f_prf_raz_var_vel

    # determina fase final da decolagem
    f_atv.en_atv_fase = ldefs.E_FASE_ESTABILIZADA
예제 #8
0
def trata_associado(f_atv, f_brk, fi_brk_ndx, f_stk_context):
    """
    armazena na pilha o procedimento associado
    
    @param f_atv: pointer to aeronave
    @param f_brk: pointer to breakpoint
    @param fi_brk_ndx: índice do breakpoint atual
    @param f_stk_context: pointer to stack
    
    @return True se armazenou dados da aeronave na pilha, senão False
    """
    # logger
    # M_LOG.info("trata_associado:>>")

    # check input
    assert f_atv
    assert f_stk_context is not None

    # active flight ?
    if not f_atv.v_atv_ok or (ldefs.E_ATIVA != f_atv.en_trf_est_atv):
        # logger
        l_log = logging.getLogger("trata_associado")
        l_log.setLevel(logging.ERROR)
        l_log.error(u"<E01: aeronave não ativa.")

        # abort procedure
        abnd.abort_prc(f_atv)

        # cai fora...
        return False

    # M_LOG.debug("trata_associado:: bkp:[{}] f_brk.ptr_brk_prc:[{}]".format(f_brk.i_brk_id, f_brk.ptr_brk_prc))

    # existe um procedimento associado ?
    if (f_brk.ptr_brk_prc is not None) and (ldefs.E_NOPROC != f_brk.ptr_brk_prc
                                            ):  # and (0 != f_brk.BkpNumProc):
        # push actual context
        f_stk_context.append(
            (f_atv.en_trf_fnc_ope, f_atv.en_atv_fase, f_atv.ptr_trf_prc,
             f_atv.ptr_atv_brk, fi_brk_ndx))

        # M_LOG.debug("trata_associado::fnc_ope/fase(A):[{}]/[{}]".format(ldefs.DCT_FNC_OPE[f_atv.en_trf_fnc_ope], ldefs.DCT_FASE[f_atv.en_atv_fase]))
        # M_LOG.debug("trata_associado::ptr_trf_prc(A):[{}]".format(f_atv.ptr_trf_prc))
        # M_LOG.debug("trata_associado::ptr_atv_brk(A):[{}]".format(f_atv.ptr_atv_brk))

        # load new context
        f_atv.en_trf_fnc_ope = f_brk.en_brk_fnc_ope
        f_atv.en_atv_fase = ldefs.E_FASE_ZERO
        f_atv.ptr_trf_prc = f_brk.ptr_brk_prc

        # M_LOG.debug("trata_associado::fnc_ope/fase(D):[{}]/[{}]".format(ldefs.DCT_FNC_OPE[f_atv.en_trf_fnc_ope], ldefs.DCT_FASE[f_atv.en_atv_fase]))
        # M_LOG.debug("trata_associado::ptr_trf_prc(D):[{}]".format(f_atv.ptr_trf_prc))
        # M_LOG.debug("trata_associado::ptr_atv_brk(D):[{}]".format(f_atv.ptr_atv_brk))

        # EXISTE procedimento associado ao breakpoint
        return True

    # logger
    # M_LOG.info("trata_associado:<<")

    # NÂO existe procedimento associado ao breakpoint
    return False
예제 #9
0
def prc_trajetoria(f_atv, f_cine_data, f_stk_context):
    """
    @param f_atv: pointer to struct aeronave
    @param f_cine_data: kinematics data
    @param f_stk_context: pointer to stack
    """
    # check input
    assert f_atv
    assert f_cine_data
    assert f_stk_context is not None

    # active flight ?
    if (not f_atv.v_atv_ok) or (ldefs.E_ATIVA != f_atv.en_trf_est_atv):
        # logger
        l_log = logging.getLogger("prc_trajetoria")
        l_log.setLevel(logging.ERROR)
        l_log.error(u"prc_trajetoria:<E01: aeronave não ativa.")

        # cai fora...
        return

    # pointer to trajetória
    l_trj = f_atv.ptr_trf_prc

    # trajetória ok ?
    if (l_trj is None) or (not l_trj.v_prc_ok):
        # logger
        l_log = logging.getLogger("prc_trajetoria")
        l_log.setLevel(logging.ERROR)
        l_log.error(u"<E02: trajetória inexistente. aeronave:[{}/{}].".format(
            f_atv.i_trf_id, f_atv.s_trf_ind))

        # trajetória not found, abort procedure
        abnd.abort_prc(f_atv)

        # return
        return

    # fase de iniciação ?
    if ldefs.E_FASE_ZERO == f_atv.en_atv_fase:
        # reseta o flag altitude/velocidade para iniciar uma nova trajetória
        f_atv.i_atv_change_alt_vel = 0

        # inicia o index de breakpoints
        f_cine_data.i_brk_ndx = 0

        # inicia com dados do primeiro breakpoint
        l_brk = f_atv.ptr_atv_brk = l_trj.lst_trj_brk[0]

        # breakpoint ok ?
        if (l_brk is None) or not l_brk.v_brk_ok:
            # logger
            l_log = logging.getLogger("prc_trajetoria")
            l_log.setLevel(logging.ERROR)
            l_log.error(
                u"<E03: trajetória/breakpoint inexistente. aeronave:[{}/{}] fase:[{}]."
                .format(f_atv.i_trf_id, f_atv.s_trf_ind,
                        ldefs.DCT_FASE[f_atv.en_atv_fase]))

            # não encontrou o breakpoint, abort procedure
            abnd.abort_prc(f_atv)

            # return
            return

        # obtém dados do breakpoint da trajetória
        obrk.obtem_brk(f_atv, l_brk, f_cine_data)

    # fase de direção ao ponto ?
    elif ldefs.E_FASE_DIRPONTO == f_atv.en_atv_fase:
        # obter dados do breakpoint da trajetória
        l_brk = f_atv.ptr_atv_brk

        # breakpoint ok ?
        if (l_brk is None) or not l_brk.v_brk_ok:
            # logger
            l_log = logging.getLogger("prc_trajetoria")
            l_log.setLevel(logging.ERROR)
            l_log.error(
                u"<E04: trajetória/breakpoint inexistente. aeronave:[{}/{}] fase:[{}]."
                .format(f_atv.i_trf_id, f_atv.s_trf_ind,
                        ldefs.DCT_FASE[f_atv.en_atv_fase]))

            # não encontrou o breakpoint, abort procedure
            abnd.abort_prc(f_atv)

            # return
            return

        # obtém as coordenadas do ponto a ser bloqueado
        lf_brk_x = f_cine_data.f_coord_x_brk
        lf_brk_y = f_cine_data.f_coord_y_brk
        # M_LOG.debug("prc_trajetoria:stk.f_brk_x:[{}] stk.f_brk_y:[{}]".format(f_cine_data.f_coord_x_brk, f_cine_data.f_coord_y_brk))
        '''# tratamento para vôo lateral

        # foi comandado na pilotagem vôo lateral ?
        if f_atv.f_atv_dst_vlat > 0.:
            lf_radial = 0.

            # calcula a radial
            if 'D' == f_atv.c_atv_dir_vlat:
                lf_radial = 180.

            else:
                lf_radial = 0.

            if lf_radial <= 90.:
                lf_radial = 90. - lf_radial

            else:
                lf_radial = 450. - lf_radial

            # converte para radianos
            lf_radial = math.radians(lf_radial)

            # calcula as coordenadas x e y relativo ao fixo
            lf_brk_x = f_atv.f_atv_dst_vlat * math.cos(lf_radial)
            lf_brk_y = f_atv.f_atv_dst_vlat * math.sin(lf_radial)

            # calcula a projeção do ponto a ser deslocado "nnn NM" à direita ou à esquerda
            lf_brk_x = lf_brk_x + l_brk.f_brk_x
            lf_brk_y = lf_brk_y + l_brk.f_brk_y
        '''
        # faz o direcionamento ao breakpoint
        if dp.prc_dir_ponto(f_atv, lf_brk_x, lf_brk_y, f_cine_data):
            # ao bloquear o breakpoint, tem um procedimento associado ?
            if not tass.trata_associado(f_atv, l_brk, f_cine_data.i_brk_ndx,
                                        f_stk_context):
                # não tem procedimento associado, muda de fase
                f_atv.en_atv_fase = ldefs.E_FASE_BREAKPOINT

    # fase rumo/altitude ?
    elif ldefs.E_FASE_RUMOALT == f_atv.en_atv_fase:
        # dados do breakpoint da trajetória
        l_brk = f_atv.ptr_atv_brk

        # breakpoint ok ?
        if (l_brk is None) or not l_brk.v_brk_ok:
            # logger
            l_log = logging.getLogger("prc_trajetoria")
            l_log.setLevel(logging.ERROR)
            l_log.error(
                u"<E05: trajetória/breakpoint inexistente. aeronave:[{}/{}] fase:[{}]."
                .format(f_atv.i_trf_id, f_atv.s_trf_ind,
                        ldefs.DCT_FASE[f_atv.en_atv_fase]))

            # não encontrou o breakpoint, abort procedure
            abnd.abort_prc(f_atv)

            # return
            return

        # proa e a altitude estão estabilizadas ?
        if (f_atv.f_trf_pro_atu
                == f_atv.f_atv_pro_dem) and (f_atv.f_trf_alt_atu
                                             == f_atv.f_atv_alt_dem):
            # não existe procedimento associado ?
            if not tass.trata_associado(f_atv, f_cine_data.i_brk_ndx,
                                        f_stk_context):
                # muda de fase
                f_atv.en_atv_fase = ldefs.E_FASE_BREAKPOINT

    # fase de breakpoint ?
    elif ldefs.E_FASE_BREAKPOINT == f_atv.en_atv_fase:
        # é o último breakpoint da trajetoria atual ?
        if f_atv.ptr_atv_brk == l_trj.lst_trj_brk[-1]:
            # reset flag altitude/velocidade
            f_atv.i_atv_change_alt_vel = 0

            # não tem dados na pilha ?
            if not tass.restaura_associado(f_atv, f_cine_data, f_stk_context):
                # qual a proa que a aeroanve deve seguir após bloquear o último breakpoint ?

                # trajetória tem proa ?
                if l_trj.f_trj_proa > 0.:
                    # demanda é a proa da trajetória
                    f_atv.f_atv_pro_dem = l_trj.f_trj_proa

                # otherwise, trajetória NÃO tem proa...
                else:
                    # demanda é a proa atual
                    f_atv.f_atv_pro_dem = f_atv.f_trf_pro_atu

                # força a curva pelo menor lado
                scrv.sentido_curva(f_atv)

            # otherwise, tem dados na pilha...
            else:
                # o procedimento restaurado NÃO é trajetória ?
                if ldefs.E_TRAJETORIA != f_atv.en_trf_fnc_ope:
                    # logger
                    # M_LOG.info(u"prc_trajetoria:<E06: procedimento restaurado NÃO é trajetória.")

                    # return
                    return

                # dados da trajetória anterior
                l_trj = f_atv.ptr_trf_prc

                # é o último ponto da trajetoria anterior ?
                if f_atv.ptr_atv_brk._pNext is None:
                    # bloqueou o último ponto da trajetória anterior, força procedimento manual
                    abnd.abort_prc(f_atv)

                    # qual proa a aeroanve deve seguir após bloquear o último breakpoint ?

                    # trajetória tem proa ?
                    if l_trj.f_trj_proa > 0.:
                        # demanda é a proa da trajetória
                        f_atv.f_atv_pro_dem = l_trj.f_trj_proa

                    # otherwise, trajetória NÃO tem proa...
                    else:
                        # demanda é a proa atual
                        f_atv.f_atv_pro_dem = f_atv.f_trf_pro_atu

                    # força a curva pelo menor lado
                    scrv.sentido_curva(f_atv)

                # otherwise, não é o último breakpoint da trajetória anterior
                else:
                    # aponta para o próximo breakpoint da trajetória
                    l_brk = f_atv.ptr_atv_brk = f_atv.ptr_atv_brk._pNext

                    # breakpoint ok ?
                    if (l_brk is None) or not l_brk.v_brk_ok:
                        # logger
                        l_log = logging.getLogger("prc_trajetoria")
                        l_log.setLevel(logging.ERROR)
                        l_log.error(
                            u"<E07: trajetória anterior não é último ponto. aeronave:[{}/{}] fase:[{}]."
                            .format(f_atv.i_trf_id, f_atv.s_trf_ind,
                                    ldefs.DCT_FASE[f_atv.en_atv_fase]))

                        # não encontrou o breakpoint, abort procedure
                        abnd.abort_prc(f_atv)

                        # return
                        return

                    # obtém dados do breakpoint da trajetória anterior
                    obrk.obtem_brk(f_atv, l_brk, f_cine_data)

        # otherwise, não é o último breakpoint
        else:
            # próximo breakpoint
            f_cine_data.i_brk_ndx += 1

            # aponta para o próximo breakpoint
            l_brk = f_atv.ptr_atv_brk = l_trj.lst_trj_brk[
                f_cine_data.i_brk_ndx]

            # breakpoint ok ?
            if (l_brk is None) or not l_brk.v_brk_ok:
                # logger
                l_log = logging.getLogger("prc_trajetoria")
                l_log.setLevel(logging.ERROR)
                l_log.error(
                    u"<E08: trajetória/breakpoint inexistente. aeronave:[{}/{}] fase:[{}]."
                    .format(f_atv.i_trf_id, f_atv.s_trf_ind,
                            ldefs.DCT_FASE[f_atv.en_atv_fase]))

                # não encontrou o breakpoint, abort procedure
                abnd.abort_prc(f_atv)

                # return
                return

            # obtém dados do breakpoint atual
            obrk.obtem_brk(f_atv, l_brk, f_cine_data)

    # fase de direcionamento a um fixo ?
    elif ldefs.E_FASE_DIRFIXO == f_atv.en_atv_fase:
        # reseta o flag altitude/velocidade para iniciar uma nova trajetória
        f_atv.i_atv_change_alt_vel = 0

        # aponta para o breakpoint
        l_brk = f_atv.ptr_atv_brk

        # breakpoint ok ?
        if (l_brk is None) or not l_brk.v_brk_ok:
            # logger
            l_log = logging.getLogger("prc_trajetoria")
            l_log.setLevel(logging.ERROR)
            l_log.error(
                u"<E09: trajetória/breakpoint inexistente. aeronave:[{}/{}] fase:[{}]."
                .format(f_atv.i_trf_id, f_atv.s_trf_ind,
                        ldefs.DCT_FASE[f_atv.en_atv_fase]))

            # não encontrou o breakpoint, abort procedure
            abnd.abort_prc(f_atv)

            # return
            return

        # obtém dados do breakpoint atual
        obrk.obtem_brk(f_atv, l_brk, f_cine_data)

    # otherwise, erro na valor da fase
    else:
        # logger
        l_log = logging.getLogger("prc_trajetoria")
        l_log.setLevel(logging.ERROR)
        l_log.error(
            u"<E10: fase na trajetória não identificada. fase:[{}].".format(
                ldefs.DCT_FASE[f_atv.en_atv_fase]))
예제 #10
0
def prc_espera(f_atv, f_cine_data, f_stk_context, ff_delta_t):
    """
    DOCUMENT ME!
    
    @param f_atv: pointer para struct aeronaves
    @param f_cine_data: dados da cinemática
    @param f_stk_context: pointer para pilha
    @param ff_delta_t: tempo decorrido desde a última atualização
    """
    # check input
    assert f_atv
    assert f_cine_data
    assert f_stk_context is not None

    # aeronave ativa ?
    if (not f_atv.v_atv_ok) or (ldefs.E_ATIVA != f_atv.en_trf_est_atv):
        # logger
        l_log = logging.getLogger("prc_espera")
        l_log.setLevel(logging.ERROR)
        l_log.error(u"<E01: aeronave não ativa.")

        # aeronave não ativa. cai fora...
        return

    # performance existe ?
    if (f_atv.ptr_trf_prf is None) or (not f_atv.ptr_trf_prf.v_prf_ok):
        # logger
        l_log = logging.getLogger("prc_espera")
        l_log.setLevel(logging.ERROR)
        l_log.error(u"<E02: performance não existe.")

        # performance não existe. cai fora...
        return

    # aponta para a espera planejada e valida pointer
    l_esp = f_atv.ptr_trf_prc

    if (l_esp is None) or (not l_esp.v_prc_ok):
        # logger
        l_log = logging.getLogger("prc_espera::prc_espera")
        l_log.setLevel(logging.ERROR)
        l_log.error("<E03: espera inexistente. aeronave:[%d/%s]",
                    f_atv.i_trf_id, f_atv.s_trf_ind)

        # não encontrou a espera, força a aeronave abandonar o procedimento
        abnd.abort_prc(f_atv)

        # espera inexistente. cai fora...
        return

    # aeronave abaixo de 14000ft ?
    if (f_atv.f_trf_alt_atu <= M_14000FT) and (f_atv.f_trf_vel_atu >
                                               M_VEL_MAX):
        # velocidade máxima é de 230KT
        f_atv.f_atv_vel_dem = M_VEL_MAX

    # preparação de dados ?
    if ldefs.E_FASE_ZERO == f_atv.en_atv_fase:
        # obtém dados do fixo de espera e valida pointer
        l_fix = l_esp.ptr_esp_fix

        if (l_fix is None) or (not l_fix.v_fix_ok):
            # logger
            l_log = logging.getLogger("prc_espera::prc_espera")
            l_log.setLevel(logging.ERROR)
            l_log.error("<E04: fixo da espera inexistente. aeronave:[%d/%s]",
                        f_atv.i_trf_id, f_atv.s_trf_ind)

            # não encontrou o fixo, força a aeronave abandonar o procedimento
            abnd.abort_prc(f_atv)

            # fixo da espera inexistente. cai fora...
            return

        # checa condição de cancelamento, caso tenha sido comandado pelo piloto
        if __check_cancel_espera(f_atv, l_esp):
            # break
            return

        # direciona ao fixo de espera                                                   !!!REVER!!!
        if dp.prc_dir_ponto(f_atv, l_fix.f_fix_x, l_fix.f_fix_y, f_cine_data):
            # determina qual o setor de entrada na espera
            f_atv.en_atv_fase = __setor_entrada(f_atv, l_esp)

            # valida proa para perna de afastamento
            # f_esp_rumo (mlabru)
            f_cine_data.f_afasta = l_esp.f_esp_true - 180.

            # normaliza proa para perna de afastamento
            if f_cine_data.f_afasta < 0.:
                f_cine_data.f_afasta += 360.

            # limita a razão de subida/descida na espera em no máximo 1000FT/MIN        !!!REVER!!!
            if f_atv.f_atv_raz_sub > M_RAZ_SUB:
                # salva a razão atual
                f_cine_data.f_raz_sub_des = f_atv.f_atv_raz_sub

                # limita a razão
                f_atv.f_atv_raz_sub = M_RAZ_SUB

    # seguir na perna de aproximação em direção oposta (perna de afastamento)
    elif ldefs.E_FASE_SETOR1 == f_atv.en_atv_fase:
        # ajusta a razão de curva em relação ao sentido da espera
        if ldefs.E_DIREITA == l_esp.en_esp_sentido_curva:
            # curva pela direita (positivo)
            f_atv.f_atv_raz_crv = -abs(f_atv.f_atv_raz_crv)

        # senão,...
        else:
            # curva pela esquerda (negativo)
            f_atv.f_atv_raz_crv = abs(f_atv.f_atv_raz_crv)

        # inicia dados da espera na pilha
        f_cine_data.i_setor_ent = 1
        f_cine_data.i_bloqueio_fixo = 1

        # seguir numa paralela no sentido "oposto" da perna de aproximação
        f_atv.f_atv_pro_dem = f_cine_data.f_afasta

        # obtém o tempo limite na perna de aproximação considerando o limite de 14000FT
        f_cine_data.h_tempo = 90. if (f_atv.f_trf_alt_atu > M_14000FT) else 50.

        # sinaliza nova fase
        f_atv.en_atv_fase = ldefs.E_FASE_TEMPO

    # seguir no rumo perna de afastamento defasado de 30 graus
    elif ldefs.E_FASE_SETOR2 == f_atv.en_atv_fase:
        # curva pela direita ?
        if ldefs.E_DIREITA == l_esp.en_esp_sentido_curva:
            # calcula a nova proa de demanda
            f_atv.f_atv_pro_dem = f_cine_data.f_afasta - 30.

            # normaliza
            if f_atv.f_atv_pro_dem < 0.:
                f_atv.f_atv_pro_dem += 360.

        # senão, curva pela esquerda
        else:
            # calcula a nova proa de demanda
            f_atv.f_atv_pro_dem = f_cine_data.f_afasta + 30.

            # normaliza
            if f_atv.f_atv_pro_dem > 360.:
                f_atv.f_atv_pro_dem -= 360.

        # razão de curva pelo menor lado
        scrv.sentido_curva(f_atv)

        # tempo na defasagem (1 minuto e meio no limite de 14000FT)
        f_cine_data.h_tempo = 90. if (f_atv.f_trf_alt_atu > M_14000FT) else 60.

        # sinaliza nova fase
        f_atv.en_atv_fase = ldefs.E_FASE_TEMPOSETOR

    # entrada pelo setor 3
    elif ldefs.E_FASE_SETOR3 == f_atv.en_atv_fase:
        # entrada pelo setor 3
        f_atv.f_atv_pro_dem = f_cine_data.f_afasta

        # entra na órbita
        f_atv.en_atv_fase = ldefs.E_FASE_CRVAFASTA

        # curva pela esquerda ?
        if ldefs.E_ESQUERDA == l_esp.en_esp_sentido_curva:
            # curva pela esquerda (negativa)
            f_atv.f_atv_raz_crv = -abs(f_atv.f_atv_raz_crv)

        # senão, curva pela direita
        else:
            # curva pela direita (positiva)
            f_atv.f_atv_raz_crv = abs(f_atv.f_atv_raz_crv)

    # permanência na perna de aproximação
    elif ldefs.E_FASE_TEMPO == f_atv.en_atv_fase:
        # permanece na perna de aproximação ?
        if f_cine_data.h_tempo > 0.:
            # decrementa o tempo na perna
            f_cine_data.h_tempo -= ff_delta_t

        # senão, estorou o tempo
        else:
            # nova fase
            f_atv.en_atv_fase = ldefs.E_FASE_VOLTA

    # permanência nos 30 graus do rumo para o setor 2
    elif ldefs.E_FASE_TEMPOSETOR == f_atv.en_atv_fase:
        # permanece nos 30 graus ?
        if f_cine_data.h_tempo > 0.:
            # decrementa o tempo na perna
            f_cine_data.h_tempo -= ff_delta_t

        # senão, estorou o tempo
        else:
            # nova fase
            f_atv.en_atv_fase = ldefs.E_FASE_VOLTA

    # fase volta ?
    elif ldefs.E_FASE_VOLTA == f_atv.en_atv_fase:
        # acessa dados do fixo de espera e valida parâmetro
        l_fix = l_esp.ptr_esp_fix

        if (l_fix is None) or not l_fix.v_fix_ok:
            # logger
            l_log = logging.getLogger("prc_espera::prc_espera")
            l_log.setLevel(logging.ERROR)
            l_log.error("<E05: fixo da espera inexistente. aeronave: [%d/%s]",
                        f_atv.i_trf_id, f_atv.s_trf_ind)

            # não encontrou o fixo, força a aeronave abandonar o procedimento
            abnd.abort_prc(f_atv)

            # fixo da espera inexistente. caifora...
            return

        # calcula distância da aeronave ao ponto (x, y)
        lf_coord_x = l_fix.f_fix_x - f_atv.f_trf_x
        lf_coord_y = l_fix.f_fix_y - f_atv.f_trf_y

        # calcula distância linear da aeronave ao ponto
        lf_dst_anv_pto = math.sqrt((lf_coord_x**2) + (lf_coord_y**2))

        # calcula nova proa de demanda
        f_atv.f_atv_pro_dem = cpd.calc_proa_demanda(lf_coord_x, lf_coord_y)

        # calcula novo sentido de curva
        scrv.sentido_curva(f_atv)

        # aeronave atingiu o fixo de espera ? (distância ao ponto <= passo da aeronave)
        if lf_dst_anv_pto <= math.sqrt((f_cine_data.f_delta_x**2) +
                                       (f_cine_data.f_delta_y**2)):
            # checa condição de cancelamento e ajusta a razão
            if __check_cancel_espera(f_atv, l_esp):
                # ajusta a razão de subida/descida
                f_atv.f_atv_raz_sub = f_atv.f_prf_raz_des_crz

                # break
                return

            # função operacional anterior era aproximação ?
            if ldefs.E_APROXIMACAO == f_atv.en_trf_fnc_ope_ant:
                # aeronave chegou na altitude do fixo de espera ?
                if f_atv.f_trf_alt_atu == f_atv.f_atv_alt_dem:
                    # existe algo na pilha ?
                    if len(f_stk_context) > 0:
                        # desempilha o contexto
                        f_atv.en_trf_fnc_ope, f_atv.en_atv_fase, f_atv.ptr_trf_prc, f_atv.ptr_atv_brk, f_cine_data.i_brk_ndx = f_stk_context.pop(
                        )

                        # velocidade e proa
                        f_atv.f_atv_vel_dem = f_atv.ptr_trf_prf.f_prf_vel_apx
                        # f_esp_rumo (mlabru)
                        f_atv.f_atv_pro_dem = l_esp.f_esp_true

                        # calcula novo sentido de curva
                        scrv.sentido_curva(f_atv)

                        # razão de subida
                        f_atv.f_atv_raz_sub = f_cine_data.f_raz_sub_des

                        # break
                        return

            # aprumar no rumo da espera (sentido afastamento)
            f_atv.f_atv_pro_dem = f_cine_data.f_afasta

            # entrar na órbita
            f_atv.en_atv_fase = ldefs.E_FASE_CRVAFASTA

            f_cine_data.i_setor_ent = 0
            f_cine_data.i_bloqueio_fixo = 0

        # espera a direita ?
        if ldefs.E_DIREITA == l_esp.en_esp_sentido_curva:
            if (1 == f_cine_data.i_setor_ent) and (
                    1 == f_cine_data.i_bloqueio_fixo):
                # ajusta a razão de curva
                f_atv.f_atv_raz_crv = -abs(f_atv.f_atv_raz_crv)

            else:
                # ajusta a razão de curva
                f_atv.f_atv_raz_crv = abs(f_atv.f_atv_raz_crv)

        # senão, espera a esquerda
        else:
            if (1 == f_cine_data.i_setor_ent) and (
                    1 == f_cine_data.i_bloqueio_fixo):
                # ajusta a razão de curva
                f_atv.f_atv_raz_crv = abs(f_atv.f_atv_raz_crv)

            else:
                # ajusta a razão de curva
                f_atv.f_atv_raz_crv = -abs(f_atv.f_atv_raz_crv)

    # fase curva de afastamento ?
    elif ldefs.E_FASE_CRVAFASTA == f_atv.en_atv_fase:
        # já aprumou ?
        if f_atv.f_trf_pro_atu == f_atv.f_atv_pro_dem:
            # obtém o tempo (limite de 14000FT)
            f_cine_data.h_tempo = 90. if (
                f_atv.f_trf_alt_atu > M_14000FT) else 50.

            # sinaliza nova fase
            f_atv.en_atv_fase = ldefs.E_FASE_TEMPO

    # senão,...
    else:
        # logger
        l_log = logging.getLogger("prc_espera::prc_espera")
        l_log.setLevel(logging.ERROR)
        l_log.error("<E06: fase [{}/{}] da espera não identificada.".format(
            f_atv.en_atv_fase, ldefs.DCT_FASE[f_atv.en_atv_fase]))
예제 #11
0
def __ckeck_ok(f_atv, f_cine_data):
    """
    verifica condições da aeronave para o direcionamento ao fixo
    
    @param f_atv: ponteiro para aeronave
    @param f_cine_data: ponteiro para pilha
    """
    # check input
    assert f_atv
    assert f_cine_data

    # active flight ?
    if (not f_atv.v_atv_ok) or (ldefs.E_ATIVA != f_atv.en_trf_est_atv):
        # logger
        l_log = logging.getLogger("prc_dir_fixo::__check_ok")
        l_log.setLevel(logging.ERROR)
        l_log.error("<E01: aeronave não ativa.")

        # cai fora...
        return

    # aponta para o fixo a ser interceptado e valida ponteiro
    l_fix = f_atv.ptr_atv_fix_prc
    # M_LOG.debug("prc_dir_fixo::ptr_atv_fix_prc:[{}/{}].".format(f_atv.ptr_atv_fix_prc.i_fix_id, f_atv.ptr_atv_fix_prc.s_fix_desc))

    if (l_fix is None) or (not l_fix.v_fix_ok):
        # logger
        l_log = logging.getLogger("prc_dir_fixo::__ckeck_ok")
        l_log.setLevel(logging.ERROR)
        l_log.error(u"<E02: fixo inexistente. aeronave:[{}/{}].".format(
            f_atv.i_trf_id, f_atv.s_trf_ind))

        # não encontrou o fixo, força a aeronave abandonar o procedimento
        abnd.abort_prc(f_atv)

        # return
        return

    # VOR ?
    if ldefs.E_VOR == l_fix.en_fix_tipo:
        # calcula raio do cone de tolerância
        l_fix.f_fix_rcone = f_atv.f_trf_alt_atu * math.tan(math.radians(30))

    # otherwise, outro tipo de fixo
    else:
        # calcula raio do cone de tolerância
        l_fix.f_fix_rcone = f_atv.f_trf_alt_atu * math.tan(math.radians(40))

    # distância ao fixo <= raio do cone (ver DadosDinâmicos)
    if f_atv.f_atv_dst_fix <= l_fix.f_fix_rcone:
        # sinaliza que aeronave atingiu o ponto através raio do cone
        f_cine_data.v_interceptou_fixo = True

        # coloca em manual
        f_atv.en_trf_fnc_ope = ldefs.E_MANUAL

        # volta a fase de verificar condições
        f_atv.en_atv_fase = ldefs.E_FASE_ZERO

        # return interceptou o fixo
        return

    # calcula distância da aeronave ao fixo (x, y)
    lf_dst_x = f_cine_data.f_dst_anv_fix_x**2
    lf_dst_y = f_cine_data.f_dst_anv_fix_y**2

    # calcula distância do "passo" da aeronave (x, y)
    lf_dlt_x = f_cine_data.f_delta_x**2
    lf_dlt_y = f_cine_data.f_delta_y**2

    # aeronave atingiu fixo ? (distância <= passo da aeronave)
    if math.sqrt(lf_dst_x + lf_dst_y) <= math.sqrt(lf_dlt_x + lf_dlt_y):
        # considera que a aeronave atingiu o fixo pelas coordenadas x, y
        f_cine_data.v_interceptou_fixo = True

        # coloca em manual
        f_atv.en_trf_fnc_ope = ldefs.E_MANUAL

        # volta a fase de verificar condições
        f_atv.en_atv_fase = ldefs.E_FASE_ZERO

        # return interceptou o fixo
        return

    # calcula nova proa de demanda
    f_atv.f_atv_pro_dem = cpd.calc_proa_demanda(f_cine_data.f_dst_anv_fix_x,
                                                f_cine_data.f_dst_anv_fix_y)

    # calcula sentido de curva pelo menor ângulo
    scrv.sentido_curva(f_atv)

    # ajusta a razão de curva da aeronave
    razc.calc_razao_curva(f_atv, l_fix.f_fix_x, l_fix.f_fix_y, f_cine_data)

    # nova fase de processamento
    f_atv.en_atv_fase = ldefs.E_FASE_DIRFIXO
예제 #12
0
def __direciona(f_atv, f_cine_data):
    """
    direcionar a aeronave a um fixo específico
    
    @param f_atv: ponteiro para struct aeronaves
    @param f_cine_data: ponteiro para pilha
    """
    # check input
    assert f_atv
    assert f_cine_data

    # active flight ?
    if (not f_atv.v_atv_ok) or (ldefs.E_ATIVA != f_atv.en_trf_est_atv):
        # logger
        l_log = logging.getLogger("prc_dir_fixo::__direciona")
        l_log.setLevel(logging.ERROR)
        l_log.error("<E01: aeronave não ativa.")

        # cai fora...
        return

    # pointer to beacon & check
    l_fix = f_atv.ptr_atv_fix_prc

    if (l_fix is None) or (not l_fix.v_fix_ok):
        # logger
        l_log = logging.getLogger("prc_dir_fixo::__direciona")
        l_log.setLevel(logging.ERROR)
        l_log.error(u"<E02: fixo inexistente. aeronave:[{}/{}].".format(
            f_atv.i_trf_id, f_atv.s_trf_ind))

        # não encontrou o fixo, força a aeronave abandonar o procedimento
        abnd.abort_prc(f_atv)

        # return
        return

    # VOR ?
    if ldefs.E_VOR == l_fix.en_fix_tipo:
        # calcula raio do cone de tolerância do fixo
        l_fix.f_fix_rcone = f_atv.f_trf_alt_atu * math.tan(math.radians(30))

    # otherwise, outro tipo...
    else:
        # calcula raio do cone de tolerância do fixo
        l_fix.f_fix_rcone = f_atv.f_trf_alt_atu * math.tan(math.radians(40))

    # distância ao fixo <= raio do cone (ver DadosDinamicos)
    if f_atv.f_atv_dst_fix <= l_fix.f_fix_rcone:
        # sinaliza que aeronave atingiu o ponto através raio do cone
        f_cine_data.v_interceptou_fixo = True

        # coloca em manual
        f_atv.en_trf_fnc_ope = ldefs.E_MANUAL

        # volta a fase de verificar condições
        f_atv.en_atv_fase = ldefs.E_FASE_ZERO

        # return interceptou o fixo
        return

    # calcula distância da aeronave ao fixo (x, y)
    lf_dst_x = f_cine_data.f_dst_anv_fix_x**2
    lf_dst_y = f_cine_data.f_dst_anv_fix_y**2

    # calcula distância do "passo" da aeronave (x, y)
    lf_dlt_x = f_cine_data.f_delta_x**2
    lf_dlt_y = f_cine_data.f_delta_y**2

    # aeronave atingiu fixo ? (distância <= passo da aeronave)
    if math.sqrt(lf_dst_x + lf_dst_y) <= math.sqrt(lf_dlt_x + lf_dlt_y):
        # considera que a aeronave atingiu o fixo pelas coordenadas x, y
        f_cine_data.v_interceptou_fixo = True

        # coloca em manual
        f_atv.en_trf_fnc_ope = ldefs.E_MANUAL

        # volta a fase de verificar condições
        f_atv.en_atv_fase = ldefs.E_FASE_ZERO

        # return interceptou o fixo
        return

    # calcula nova proa de demanda
    f_atv.f_atv_pro_dem = cpd.calc_proa_demanda(f_cine_data.f_dst_anv_fix_x,
                                                f_cine_data.f_dst_anv_fix_y)

    # verifica se mudou a proa (curvando...)
    if f_atv.f_atv_pro_dem != f_atv.f_trf_pro_atu:
        # bloqueia o fixo
        razc.calc_razao_curva(f_atv, l_fix.f_fix_x, l_fix.f_fix_y, f_cine_data)
예제 #13
0
파일: obtem_brk.py 프로젝트: mlabru/ptracks
def obtem_brk(f_atv, f_brk, f_cine_data):
    """
    @param f_atv: pointer to struct aeronaves
    @param f_brk: pointer to struct breakpoints
    @param f_cine_data: pointer to kinematic data
    """
    # logger
    # M_LOG.info("obtem_brk:>>")

    # check input
    assert f_atv
    assert f_cine_data

    # active flight ?
    if (not f_atv.v_atv_ok) or (ldefs.E_ATIVA != f_atv.en_trf_est_atv):
        # logger
        l_log = logging.getLogger("obtem_brk")
        l_log.setLevel(logging.ERROR)
        l_log.error(u"<E01: aeronave não ativa.")

        # cai fora...
        return

    # performance ok ?
    if (f_atv.ptr_trf_prf is None) or (not f_atv.ptr_trf_prf.v_prf_ok):
        # logger
        l_log = logging.getLogger("obtem_brk")
        l_log.setLevel(logging.ERROR)
        l_log.error(u"<E02: performance não existe.")

        # cai fora...
        return

    # breakpoint ok ?
    if (f_brk is None) or (not f_brk.v_brk_ok):
        # logger
        l_log = logging.getLogger("obtem_brk::obtem_brk")
        l_log.setLevel(logging.ERROR)
        l_log.error(u"<E03: breakpoint inexistente. aeronave:[{}/{}].".format(
            f_atv.i_trf_id, f_atv.s_trf_ind))

        # não encontrou o breakpoint, força a abandonar o procedimento
        abnd.abort_prc(f_atv)

        # cai fora...
        return

    # + se a altitude NÃO foi alterada (i_atv_change_alt_vel = 0 ou 2)
    #   - obtém a altitude do breakpoint

    # + se a altitude foi alterada (i_atv_change_alt_vel = 1 ou 3)
    #   - mantém a altitude inserida pelo piloto e despreza as altitudes dos próximos pontos

    # i_atv_change_alt_vel = 0 > normal (sem alteração velocidade/altitude)
    # i_atv_change_alt_vel = 1 > mudou apenas a altitude
    # i_atv_change_alt_vel = 2 > mudou apenas a velocidade
    # i_atv_change_alt_vel = 3 > mudou ambas

    # subida ou trajetória ?
    if f_atv.en_trf_fnc_ope in [ldefs.E_SUBIDA, ldefs.E_TRAJETORIA]:
        # checa de onde obter a altitude
        # do breakpoint, da altitude de trajetória do tráfego ou da performance da aeronave

        # altitude NÃO foi alterada ?
        if (0 == f_atv.i_atv_change_alt_vel) or (
                2 == f_atv.i_atv_change_alt_vel):
            # é uma subida ?
            if ldefs.E_SUBIDA == f_atv.en_trf_fnc_ope:
                # breakpoint tem altitude ?
                if f_brk.f_brk_alt > 0.:
                    # altitude do breakpoint maior (ou igual) ao teto de serviço ?
                    if f_brk.f_brk_alt >= f_atv.ptr_trf_prf.f_prf_teto_sv:
                        # demanda o teto de serviço
                        f_atv.f_atv_alt_dem = f_atv.ptr_trf_prf.f_prf_teto_sv

                    # otherwise, altitude abaixo do teto de serviço...
                    else:
                        # se altitude do ponto maior que altitude de trajetória do tráfego
                        if (f_brk.f_brk_alt > f_atv.f_trf_alt_trj) and (
                                f_atv.f_trf_alt_trj > 0.):
                            # demanda a altitude de trajetória do tráfego
                            f_atv.f_atv_alt_dem = f_atv.f_trf_alt_trj

                        # otherwise,...
                        else:
                            # demanda a altitude do breakpoint
                            f_atv.f_atv_alt_dem = f_brk.f_brk_alt

            # é uma trajetória ?
            elif ldefs.E_TRAJETORIA == f_atv.en_trf_fnc_ope:
                # M_LOG.debug("obtem_brk:f_brk_alt:[{}].".format(f_brk.f_brk_alt))

                # breakpoint tem altitude ?
                if f_brk.f_brk_alt > 0.:
                    # altitude do breakpoint maior (ou igual) ao teto de serviço ?
                    if f_brk.f_brk_alt >= f_atv.ptr_trf_prf.f_prf_teto_sv:
                        # demanda o teto de serviço
                        f_atv.f_atv_alt_dem = f_atv.ptr_trf_prf.f_prf_teto_sv

                    # otherwise, abaixo do teto de serviço
                    else:
                        # demanda a altitude do breakpoint
                        f_atv.f_atv_alt_dem = f_brk.f_brk_alt

                # otherwise, breakpoint não tem altitude
                else:
                    # altitude de trajetória tem dado ?
                    if f_atv.f_trf_alt_trj > 0.:
                        # demanda a altitude de trajetória do tráfego
                        f_atv.f_atv_alt_dem = f_atv.f_trf_alt_trj

    # otherwise, não é subida nem trajetória...
    else:
        # demanda a altitude do breakpoint ou o teto de serviço, quem for menor
        f_atv.f_atv_alt_dem = min(f_brk.f_brk_alt,
                                  f_atv.ptr_trf_prf.f_prf_teto_sv)

    # coordenada é do tipo 'T' (temporal) ?
    if f_brk.i_brk_t > 0:
        pass
        '''# aponta o fixo de referência
        # FIXO * l_pFix = None ; # &f_pAtm.AtmFix [ (int)f_brk.f_brk_x ] ;   # !!!REVER!!!

        # calcula a projeção do ponto
        f_cine_data.fCoordXBkp = l_pFix.fFixX + ( f_atv.f_trf_vel_atu * f_brk.i_brk_t * sinf ( f_brk.f_brk_y ))
        f_cine_data.fCoordYBkp = l_pFix.fFixY + ( f_atv.f_trf_vel_atu * f_brk.i_brk_t * cosf ( f_brk.f_brk_y ))
        '''
    # coordenada é do tipo 'R' (rumo e altitude)
    elif f_brk.i_brk_t < 0:
        pass
        '''# é razão ou gradiente ?
        if f_brk.f_brk_x <= 0.:
            # obtém a razão de subida
            f_atv.f_atv_raz_sub = f_atv.ptr_trf_prf.f_prf_raz_sub_crz

        # otherwise,...
        else:
            # o gradiente é uma porcentagem e uma razão de subida um valor inteiro. O
            # gradiente nunca é maior que 10%.  A razão de subida sempre é maior que
            # 100ft/min. Assumir que valores maiores que 10 é razão de subida e valores
            # menores ou iguais a 10 é gradiente.
            # ref: Tratamento do Gradiente de Subida conforme MMA 100-31, pag.108.

            # é gradiente ?
            if f_brk.f_brk_x <= 10.:
                # aplica a forma simplificada do gradiente    !!!REVER!!!
                li_val = int(f_atv.f_trf_vel_atu * f_brk.f_brk_x)

                # calcula o módulo 50
                li_mod = li_val % 50

                if li_mod > 0:
                    # se não for múltiplo de 50, arrendondar para o múltiplo mais próximo
                    if li_mod < 26:
                        li_val -= li_mod

                    else:
                        li_val += 50 - li_mod

                # armazena o gradiente aplicado o múltiplo de 50
                f_atv.f_atv_raz_sub = float(li_val)

            # otherwise, é uma razão de subida
            else:
                # armazena a razão de subida (ft/min -> m/s)
                f_atv.f_atv_raz_sub = f_brk.f_brk_x * cdefs.D_CNV_FT2M / 60.

        # obtém o rumo
        f_atv.f_atv_pro_dem = math.degrees(f_brk.f_brk_y)

        # calcula a curva pelo menor lado
        scrv.sentido_curva(f_atv)
        '''
    # otherwise, 0 == f_brk.i_brk_t
    else:
        # armazena na pilha as coordenadas cartesianas do breakpoint
        f_cine_data.f_coord_x_brk = f_brk.f_brk_x
        f_cine_data.f_coord_y_brk = f_brk.f_brk_y
        # M_LOG.debug("obtem_brk:f_cine_data.f_brk_x:[{}] f_cine_data.f_brk_y:[{}]".format(f_cine_data.f_coord_x_brk, f_cine_data.f_coord_y_brk))

    # trata o procedimento que chamou a rotina

    # trajetória ?
    if ldefs.E_TRAJETORIA == f_atv.en_trf_fnc_ope:
        # checks
        assert f_atv.ptr_trf_prc
        assert f_atv.ptr_trf_prc.v_prc_ok

        # + se a velocidade NÃO foi alterada (i_atv_change_alt_vel = 0 ou 1)
        #   - obtém a velocidade do breakpoint

        # + se a velocidade foi alterada (i_atv_change_alt_vel = 2 ou 3)
        #   - mantém a velocidade inserida pelo piloto e despreza as velocidades dos próximos pontos

        # i_atv_change_alt_vel = 0 > normal (sem alteração velocidade/altitude)
        # i_atv_change_alt_vel = 1 > mudou apenas a altitude,
        # i_atv_change_alt_vel = 2 > mudou apenas a velocidade
        # i_atv_change_alt_vel = 3 > mudou ambas

        # checa de onde obter a velocidade
        # do breakpoint, velocidade do tráfego ou performance

        # velocidade NÃO foi alterada ?
        if (0 == f_atv.i_atv_change_alt_vel) or (
                1 == f_atv.i_atv_change_alt_vel):
            # star ?
            if f_atv.ptr_trf_prc.v_trj_star:
                # breakpoint tem velocidade ?
                if f_brk.f_brk_vel > 0.:
                    # converte a VelMaxCrz para IAS
                    lf_vel = f_atv.ptr_trf_prf.f_prf_vel_max_crz  # calcIAS(f_atv.ptr_trf_prf.f_prf_vel_max_crz, f_atv.f_atv_alt_dem, Exercicio.fExeVarTempISA)

                    # demanda a velocidade do breakpoint ou VelMaxCrz (IAS) o que for menor
                    f_atv.f_atv_vel_dem = min(f_brk.f_brk_vel, lf_vel)

            # otherwise, é trajetória ACC...
            else:
                # velocidade de trajetória do tráfego tem dado ?
                if f_atv.f_trf_vel_trj > 0.:
                    # demanda a velocidade de trajetória do tráfego (convertido para IAS na conversão)
                    f_atv.f_atv_vel_dem = f_atv.f_trf_vel_trj

                # otherwise, não tem velocidade de trajetória do tráfego...
                else:
                    # breakpoint tem velocidade ?
                    if f_brk.f_brk_vel > 0.:
                        # velocidade do breakpoint extrapolou o limite da performance ?
                        if f_brk.f_brk_vel > f_atv.ptr_trf_prf.f_prf_vel_max_crz:
                            # demanda a VelMaxCrz convertida para IAS
                            f_atv.f_atv_vel_dem = f_atv.ptr_trf_prf.f_prf_vel_max_crz  # calcIAS(f_atv.ptr_trf_prf.fAtrPrfVelMaxCrz, f_atv.f_atv_alt_dem, Exercicio.fExeVarTempISA)

                        # velocidade do breakpoint abaixo do limite da performance...
                        else:
                            # demanda a velocidade do breakpoint convertida para IAS
                            f_atv.f_atv_vel_dem = f_brk.f_brk_vel  # calcIAS(f_brk.f_brk_vel, f_atv.f_atv_alt_dem, Exercicio.fExeVarTempISA)

                    # otherwise, breakpoint não tem velocidade...
                    else:
                        # demanda a velocidade atual do tráfego
                        f_atv.f_atv_vel_dem = f_atv.f_trf_vel_atu

            # força cálculo do MACH
            # f_atv.vAnvISOMACH = False

        # ajustar a razão de subida ou descida da aeronave em trajetória

        # aeronave descendo ?
        if f_atv.f_trf_alt_atu > f_atv.f_atv_alt_dem:
            # aplica a razão de descida em cruzeiro
            f_atv.f_atv_raz_sub = f_atv.ptr_trf_prf.f_prf_raz_des_crz

        # aeronave subindo ?
        elif f_atv.f_trf_alt_atu < f_atv.f_atv_alt_dem:
            # aplica a razão de subida em cruzeiro
            f_atv.f_atv_raz_sub = f_atv.ptr_trf_prf.f_prf_raz_sub_crz

        # aeronave nivelada ?
        elif f_atv.f_trf_alt_atu == f_atv.f_atv_alt_dem:
            # não aplica a razão de subida ou descida
            f_atv.f_atv_raz_sub = 0.

    # subida ?
    elif ldefs.E_SUBIDA == f_atv.en_trf_fnc_ope:
        # teste de altimetria para corrigir o caso em que a aeronave ao cumprir pontos sem o
        # valor da "altitude", ela possa manter o valor da última altitude de demanda. Com a
        # "altitude do breakpoint sem valor", forçava a aeronave a entrar na condição de vôo
        # abaixo de 10000FT, o que não é correto, pois, a mesma já cumpriu esta etapa do vôo

        # obtém altitude do ponto atual
        lf_brk_alt = f_brk.f_brk_alt

        # extrapolou o limite da performance ?
        if f_brk.f_brk_alt > f_atv.ptr_trf_prf.f_prf_teto_sv:
            # ajusta a altitude pela performance
            lf_brk_alt = f_atv.ptr_trf_prf.f_prf_teto_sv

        # breakpoint NÃO tem altitude ?
        if 0 == lf_brk_alt:
            # mantém a altitude de demanda do ponto anterior
            lf_brk_alt = f_atv.f_atv_alt_dem

        # converte a velocidade de cruzeiro da performance para IAS
        lf_vel = f_atv.ptr_trf_prf.f_prf_vel_crz  # calcIAS(f_atv.ptr_trf_prf.f_prf_vel_crz, f_atv.f_atv_alt_dem, Exercicio.fExeVarTempISA)

        # altitude do breakpoint é menor (ou igual) que altitude máxima na TMA ?
        if (lf_brk_alt * cdefs.D_CNV_M2FT) <= ldefs.D_ALT_MAX_TMA:
            # velocidade de subida na DEP é maior que 250KT ?
            if f_atv.ptr_trf_prf.f_prf_vel_sub_dec >= ldefs.D_VEL_MAX_TMA:
                # velocidade NÃO foi alterada ?
                if (0 == f_atv.i_atv_change_alt_vel) or (
                        1 == f_atv.i_atv_change_alt_vel):
                    # velocidade do breakpoint é valida ?
                    if 0. < f_brk.f_brk_vel <= ldefs.D_VEL_MAX_TMA:
                        # demanda a velocidade da performance ou a velocidade do breakpoint, o que for menor
                        f_atv.f_atv_vel_dem = min(lf_vel, f_brk.f_brk_vel)

                    # otherwise, inválida...
                    else:
                        # demanda a velocidade da performance ou a velocidade limite 250KT, o que for menor
                        f_atv.f_atv_vel_dem = min(lf_vel, ldefs.D_VEL_MAX_TMA)

            # otherwise, velocidade de subida na DEP está abaixo de 250KT
            else:
                # velocidade NÃO foi alterada ?
                if (0 == f_atv.i_atv_change_alt_vel) or (
                        1 == f_atv.i_atv_change_alt_vel):
                    # velocidade do breakpoint é valida ?
                    if 0. < f_brk.f_brk_vel <= ldefs.D_VEL_MAX_TMA:
                        # demanda a velocidade da performance ou a velocidade do breakpoint, o que for menor
                        f_atv.f_atv_vel_dem = min(lf_vel, f_brk.f_brk_vel)

                    # otherwise, inválida...
                    else:
                        # demanda a velocidade da performance ou a velocidade limite 250KT, o que for menor
                        f_atv.f_atv_vel_dem = min(lf_vel, f_brk.f_brk_vel)

        # otherwise, altitude do breakpoint é maior que a altitude máxima na TMA...
        else:
            # velocidade NÃO foi alterada ?
            if (0 == f_atv.i_atv_change_alt_vel) or (
                    1 == f_atv.i_atv_change_alt_vel):
                # breakpoint tem velocidade ?
                if f_brk.f_brk_vel > 0.:
                    # demanda a velocidade da performance ou velocidade do breakpoint, o que for menor
                    f_atv.f_atv_vel_dem = min(lf_vel, f_brk.f_brk_vel)

                # velocidade da performance maior que velocidade de demanda atual ?
                elif lf_vel > f_atv.f_atv_vel_dem:
                    # demanda a velocidade da performance (cruzeiro)
                    f_atv.f_atv_vel_dem = lf_vel

        # coordenada cartesiana ou temporal ?
        if f_brk.i_brk_t >= 0:
            # obtém a razão de subida de cruzeiro
            f_atv.f_atv_raz_sub = f_atv.ptr_trf_prf.f_prf_raz_sub_crz

        # tem gradiente entre os pontos ?
        if 0. != f_brk.f_brk_raz_vel:
            # calcula a razão de subida em função do gradiente
            f_atv.f_atv_raz_sub += f_atv.f_trf_vel_atu * f_brk.f_brk_raz_vel

        # otherwise, NÃO tem gradiente entre os pontos...
        else:
            # obtém a razão de subida da performance
            f_atv.f_atv_raz_sub = f_atv.ptr_trf_prf.f_prf_raz_sub_crz

    # aproximação ou aproximação perdida
    elif f_atv.en_trf_fnc_ope in [ldefs.E_APROXIMACAO, ldefs.E_APXPERDIDA]:
        # aproximação perdida ?
        if ldefs.E_APXPERDIDA == f_atv.en_trf_fnc_ope:
            # demanda a velocidade de subida na decolagem
            f_atv.f_atv_vel_dem = f_atv.ptr_trf_prf.f_prf_vel_sub_dec
            # former case, fall throught to next item

        # coordenada cartesiana ou temporal ?
        if f_brk.i_brk_t >= 0:
            # desacelerando ?
            if f_brk.f_brk_raz_vel <= 0.:
                # razão de desaceleração de descida na aproximação
                f_atv.f_atv_raz_sub = f_atv.ptr_trf_prf.f_prf_raz_des_apx

            # otherwise, acelerando...
            else:
                # razão de velocidade
                f_atv.f_atv_raz_sub = f_brk.f_brk_raz_vel

    # otherwise, função operacional não reconhecida...
    else:
        # logger
        l_log = logging.getLogger("obtem_brk::obtem_brk")
        l_log.setLevel(logging.ERROR)
        l_log.error(u"<E04: função operacional [{}] não reconhecida.".format(
            ldefs.DCT_FNC_OPE[f_atv.en_trf_fnc_ope]))

    # cooredenada coordenadas rumo/azimute ?
    if f_brk.i_brk_t < 0:
        # seleciona próxima fase
        f_atv.en_atv_fase = ldefs.E_FASE_RUMOALT

    # otherwise, outro tipo de coordenada...
    else:
        # seleciona próxima fase
        f_atv.en_atv_fase = ldefs.E_FASE_DIRPONTO
예제 #14
0
def prc_subida(f_atv, f_cine_data, f_stk_context):
    """
    realiza o procedimento de subida após o procedimento de decolagem
    
    @param f_atv: pointer to struct aeronaves
    @param f_cine_data: dados da cinemática
    @param f_stk_context: pointer to stack
    """
    # check input
    assert f_atv
    assert f_stk_context is not None

    # active flight ?
    if (not f_atv.v_atv_ok) or (ldefs.E_ATIVA != f_atv.en_trf_est_atv):
        # logger
        l_log = logging.getLogger("prc_subida")
        l_log.setLevel(logging.ERROR)
        l_log.error("<E01: aeronave [{}/{}] não ativa.".format(f_atv.i_trf_id, f_atv.s_trf_ind))

        # abort procedure
        abnd.abort_prc(f_atv)
                                                
        # aeronave não ativa. cai fora...
        return False

    # pointer to subida
    l_sub = f_atv.ptr_trf_prc

    # subida ok ?
    if (l_sub is None) or (not l_sub.v_prc_ok):
        # logger
        l_log = logging.getLogger("prc_subida")
        l_log.setLevel(logging.ERROR)
        l_log.error("<E02: subida inexistente. aeronave:[{}/{}].".format(f_atv.i_trf_id, f_atv.s_trf_ind))

        # abort procedure
        abnd.abort_prc(f_atv)

        # subida inexistente. cai fora...
        return

    # fase de iniciação ?
    if ldefs.E_FASE_ZERO == f_atv.en_atv_fase:
        # inicia o contador de breakpoints
        f_cine_data.i_brk_ndx = 0

        # empilha o contexto futuro
        f_stk_context.append((f_atv.en_trf_fnc_ope, ldefs.E_FASE_SUBIDA, l_sub, None, 0))

        # salva a subida
        f_cine_data.ptr_sub = l_sub

        # obtém o aeródromo e pista da subida
        f_cine_data.ptr_aer = l_sub.ptr_sub_aer
        f_cine_data.ptr_pis = l_sub.ptr_sub_pis

        # carrega o contexto atual
        f_atv.ptr_trf_prc = l_sub.ptr_sub_prc_dec

        f_atv.en_trf_fnc_ope = ldefs.E_DECOLAGEM
        f_atv.en_atv_fase = ldefs.E_FASE_ZERO

    # fase subida ?
    elif ldefs.E_FASE_SUBIDA == f_atv.en_atv_fase:
        # inicia com o número do breakpoint atual
        l_brk = f_atv.ptr_atv_brk = l_sub.lst_sub_brk[f_cine_data.i_brk_ndx]

        # breakpoint ok ?
        if (l_brk is None) or (not l_brk.v_brk_ok):
            # logger
            l_log = logging.getLogger("prc_subida")
            l_log.setLevel(logging.ERROR)
            l_log.error("<E03: subida/breakpoint inexistente. aeronave:[{}/{}].".format(f_atv.i_trf_id, f_atv.s_trf_ind))

            # abort procedure
            abnd.abort_prc(f_atv)

            # subida/breakpoint inexistente. cai fora...
            return

        # obtém dados do breakpoint da subida
        obrk.obtem_brk(f_atv, l_brk, f_cine_data)

    # fase direcionamento a ponto ?
    elif ldefs.E_FASE_DIRPONTO == f_atv.en_atv_fase:
        # chegou ao breakpoint ?
        if dp.prc_dir_ponto(f_atv, f_cine_data.f_coord_x_brk, f_cine_data.f_coord_y_brk, f_cine_data):
            # próxima fase
            f_atv.en_atv_fase = ldefs.E_FASE_BREAKPOINT

            # obtém o breakpoint atual
            l_brk = f_atv.ptr_atv_brk

            # breakpoint ok ?
            if (l_brk is None) or (not l_brk.v_brk_ok):
                # logger
                l_log = logging.getLogger("prc_subida")
                l_log.setLevel(logging.ERROR)
                l_log.error("<E04: subida/breakpoint inexistente. aeronave:[{}/{}].".format(f_atv.i_atv_id, f_atv.s_atv_ind))

                # abort procedure
                abnd.abort_prc(f_atv)

                # subida/breakpoint inexistente. cai fora...
                return

            # trata o procedimento associado
            tass.trata_associado(f_atv, l_brk, f_cine_data.i_brk_ndx, f_stk_context)

    # fase rumo e altitude ?
    elif ldefs.E_FASE_RUMOALT == f_atv.en_atv_fase:
        # altitude atual(ft) é maior que a altitude máxima da TMA(ft) ?
        if (f_atv.f_atv_alt_atu * cdefs.D_CNV_M2FT) > ldefs.D_ALT_MAX_TMA:
            # ajusta a velocidade de demanda em função do nível de vôo
            f_atv.f_atv_vel_dem = f_atv.f_ptr_prf.f_prf_vel_crz  # calcIAS(f_atv.f_ptr_prf.f_prf_vel_crz, f_atv.f_atv_alt_atu, ldefs.D_EXE_VAR_TEMP_ISA)

        # proa e a altitude estão estabilizadas ?
        if (f_atv.f_atv_pro_atu == f_atv.f_atv_pro_dem) and (f_atv.f_atv_alt_atu == f_atv.f_atv_alt_dem):
            # nova fase
            f_atv.en_atv_fase = ldefs.E_FASE_BREAKPOINT

            # trata o procedimento associado
            tass.trata_associado(f_atv, l_brk, f_cine_data.i_brk_ndx, f_stk_context)

    # fase breakpoints ?
    elif ldefs.E_FASE_BREAKPOINT == f_atv.en_atv_fase:
        # é o último breakpoint da subida ?
        if f_atv.ptr_atv_brk == l_sub.lst_sub_brk[-1]:
            # reseta o flag altitude/velocidade
            f_atv.i_atv_change_alt_vel = 0

            # restaura pilha, se necessário
            tass.restaura_associado(f_atv, f_cine_data, f_stk_context)

        # otherwise, NÃO é o último breakpoint da subida...
        else:
            # próximo breakpoint
            f_cine_data.i_brk_ndx += 1
                                            
            # aponta para o próximo breakpoint
            l_brk = f_atv.ptr_atv_brk = l_sub.lst_sub_brk[f_cine_data.i_brk_ndx]
                                                                    
            # breakpoint ok ?
            if (l_brk is None) or (not l_brk.v_brk_ok):
                # logger
                l_log = logging.getLogger("prc_subida")
                l_log.setLevel(logging.ERROR)
                l_log.error("<E05: subida/breakpoint inexistente. aeronave:[{}/{}].".format(f_atv.i_atv_id, f_atv.s_atv_ind))

                # abort procedure
                abnd.abort_prc(f_atv)

                # subida/breakpoint inexistente. cai fora...
                return

            # obtém dados do breakpoint atual
            obrk.obtem_brk(f_atv, l_brk, f_cine_data)

    # otherwise, fase não identificada
    else:
        # logger
        l_log = logging.getLogger("prc_subida")
        l_log.setLevel(logging.ERROR)
        l_log.error("<E06: fase na subida não identificada.")
                
        # abort procedure
        abnd.abort_prc(f_atv)
예제 #15
0
def prc_aproximacao(f_atv, f_cine_data, f_stk_context):
    """
    realiza o procedimento de aproximação

    @param f_atv: pointer to aeronave
    @param f_cine_data: dados da cinemática
    @param f_stk_context: pointer to stack
    """
    # check input
    assert f_atv

    # active flight ?
    if (not f_atv.v_atv_ok) or (ldefs.E_ATIVA != f_atv.en_trf_est_atv):
        # logger
        l_log = logging.getLogger("prc_aproximacao")
        l_log.setLevel(logging.ERROR)
        l_log.error(u"<E01: aeronave não ativa.")

        # abort procedure
        abnd.abort_prc(f_atv)

        # cai fora...
        return

    # performance ok ?
    if (f_atv.ptr_trf_prf is None) or (not f_atv.ptr_trf_prf.v_prf_ok):
        # logger
        l_log = logging.getLogger("prc_aproximacao")
        l_log.setLevel(logging.ERROR)
        l_log.error(u"<E02: performance não existe.")

        # abort procedure
        abnd.abort_prc(f_atv)

        # cai fora...
        return

    # pointer to aproximação
    l_apx = f_atv.ptr_trf_prc

    # aproximação ok ?
    if (l_apx is None) or (not l_apx.v_prc_ok):
        # logger
        l_log = logging.getLogger("prc_aproximacao")
        l_log.setLevel(logging.ERROR)
        l_log.error(u"<E03: aproximação inexistente. aeronave:[{}/{}].".format(
            f_atv.i_trf_id, f_atv.s_trf_ind))

        # abort procedure
        abnd.abort_prc(f_atv)

        # return
        return

    # variáveis locais
    l_brk = None

    # fase de preparação dos dados para o procedimento ?
    if ldefs.E_FASE_ZERO == f_atv.en_atv_fase:
        # inicia o index de breakpoints
        f_cine_data.i_brk_ndx = 0

        # inicia com dados do primeiro breakpoint
        l_brk = f_atv.ptr_atv_brk = l_apx.lst_apx_brk[0]

        # breakpoint ok ?
        if (l_brk is None) or (not l_brk.v_brk_ok):
            # logger
            l_log = logging.getLogger("prc_aproximacao")
            l_log.setLevel(logging.ERROR)
            l_log.error(
                u"<E04: fase zero. apx/breakpoint inexistente. aeronave:[{}/{}]."
                .format(f_atv.i_trf_id, f_atv.s_trf_ind))

            # abort procedure
            abnd.abort_prc(f_atv)

            # return
            return

        # obtém dados do breakpoint
        obrk.obtem_brk(f_atv, l_brk, f_cine_data)

    # fase de direcionamento aos breakpoints do procedimento ?
    elif ldefs.E_FASE_DIRPONTO == f_atv.en_atv_fase:
        # interceptou o breakpoint ?
        if dp.prc_dir_ponto(f_atv, f_cine_data.f_coord_x_brk,
                            f_cine_data.f_coord_y_brk, f_cine_data):
            # se não houver um procedimento associado, faz uma espera, senão executa o procedimento
            f_atv.en_atv_fase = ldefs.E_FASE_ESPERA if f_atv.ptr_atv_brk is not None else ldefs.E_FASE_ASSOCIADO

    # fase rumo e altitude ?
    elif ldefs.E_FASE_RUMOALT == f_atv.en_atv_fase:
        # atingiu a proa e a altitude de demanda estabelecidas ?
        if (f_atv.f_trf_pro_atu
                == f_atv.f_atv_pro_dem) and (f_atv.f_trf_alt_atu
                                             == f_atv.f_atv_alt_dem):
            # se não houver um procedimento associado, faz uma espera, senão executa o procedimento
            f_atv.en_atv_fase = ldefs.E_FASE_ESPERA if f_atv.ptr_atv_brk is not None else ldefs.E_FASE_ASSOCIADO

    # fase de espera ? (mantém a aeronave em orbita até alcançar a altitude do breakpoint)
    elif ldefs.E_FASE_ESPERA == f_atv.en_atv_fase:
        # dados do breakpoint
        l_brk = f_atv.ptr_atv_brk
        assert l_brk

        # NÃO atingiu a altitude do breakpoint ?
        if f_atv.f_trf_alt_atu != l_brk.f_brk_alt:
            # obtém dados do breakpoint (Espera com altitude de demanda)
            obrk.obtem_brk(f_atv, l_brk, f_cine_data)

            # empilha o contexto atual devido a mudança na função operacional
            f_stk_context.append(
                (f_atv.en_trf_fnc_ope, ldefs.E_FASE_ASSOCIADO,
                 f_atv.ptr_trf_prc, f_atv.ptr_atv_brk, f_cine_data.i_brk_ndx))

            # salva a função operacional atual
            f_atv.en_trf_fnc_ope_ant = ldefs.E_APROXIMACAO

            # estabelece a nova função operacional e a nova fase por não ter atingido a altitude do breakpoint
            f_atv.en_trf_fnc_ope = ldefs.E_ESPERA
            f_atv.en_atv_fase = ldefs.E_FASE_ZERO
            f_atv.ptr_trf_prc = l_apx.ptr_apx_prc_esp

        # otherwise, atingiu a altitude do breakpoint...
        else:
            # estabelece nova velocidade de demanda e sinaliza nova fase
            f_atv.f_atv_vel_dem = f_atv.ptr_trf_prf.f_prf_vel_apx
            f_atv.en_atv_fase = ldefs.E_FASE_ASSOCIADO

    # fase associado ? (identifica se houve encadeamento de outros procedimentos)
    elif ldefs.E_FASE_ASSOCIADO == f_atv.en_atv_fase:
        # dados do breakpoint
        l_brk = f_atv.ptr_atv_brk
        assert l_brk

        # sinaliza nova fase
        f_atv.en_atv_fase = ldefs.E_FASE_BREAKPOINT

        # existe procedimento associado (APX, APE, TRJ, ESP...) ao breakpoint ?
        if tass.trata_associado(f_atv, l_brk, f_cine_data.i_brk_ndx,
                                f_stk_context):
            # é o último breakpoint da aproximação atual ?
            if f_atv.ptr_atv_brk == l_apx.lst_apx_brk[-1]:
                f_cine_data.i_brk_ndx -= 1

    # já passou por todos os breakpoints ?
    elif ldefs.E_FASE_BREAKPOINT == f_atv.en_atv_fase:
        # é o último breakpoint da aproximação atual ?
        if f_atv.ptr_atv_brk == l_apx.lst_apx_brk[-1]:
            # possível ILS ?
            if l_apx.ptr_apx_prc_ils is not None:
                # ils ok ?
                if __obtem_ils(f_atv, l_apx):
                    # coloca em procedimento de ILS
                    f_atv.en_trf_fnc_ope = ldefs.E_ILS
                    f_atv.en_atv_fase = ldefs.E_FASE_ZERO

                # otherwise, ils not ok...
                else:
                    # coloca em manual
                    f_atv.en_trf_fnc_ope = ldefs.E_MANUAL

            # pode fazer aproximação perdida caso não esteja em condições para aproximação ?
            if l_apx.ptr_apx_prc_ape is not None:
                # dados do breakpoint
                l_brk = f_atv.ptr_atv_brk
                assert l_brk

                # está em condição de pouso ?
                if (abs(f_atv.f_trf_alt_atu - l_brk.f_brk_alt) <= 0.01) and (
                        abs(f_atv.f_trf_vel_atu -
                            f_atv.ptr_trf_prf.f_prf_vel_apx) <= 0.01):
                    # pouso ok ?
                    if not __obtem_pouso(f_atv, l_apx):
                        # coloca em manual
                        f_atv.en_trf_fnc_ope = ldefs.E_MANUAL

                # otherwise, NÃO está em condição de pouso...
                else:
                    # aproximação perdida ok ?
                    if __obtem_apx_per(f_atv, l_apx):
                        # prepara para procedimento de aproximação perdida
                        f_atv.en_trf_fnc_ope = ldefs.E_APXPERDIDA
                        f_atv.en_atv_fase = ldefs.E_FASE_ZERO

                    # otherwise, aproximação perdida not ok...
                    else:
                        # coloca em manual
                        f_atv.en_trf_fnc_ope = ldefs.E_MANUAL

            # otherwise, NÃO pode fazer aproximação perdida nem ILS, faz pouso forçado...
            else:
                # pouso ok ?
                if not __obtem_pouso(f_atv, l_apx):
                    # coloca em manual
                    f_atv.en_trf_fnc_ope = ldefs.E_MANUAL

        # otherwise, não é o último breakpoint
        else:
            # próximo breakpoint
            f_cine_data.i_brk_ndx += 1

            # aponta para o próximo breakpoint
            l_brk = f_atv.ptr_atv_brk = l_apx.lst_apx_brk[
                f_cine_data.i_brk_ndx]

            # breakpoint ok ?
            if (l_brk is None) or (not l_brk.v_brk_ok):
                # logger
                l_log = logging.getLogger("prc_aproximacao")
                l_log.setLevel(logging.ERROR)
                l_log.error(
                    u"<E05: fase breakpoint. apx/breakpoint inexistente. aeronave:[{}/{}]."
                    .format(f_atv.i_trf_id, f_atv.s_trf_ind))

                # abort procedure
                abnd.abort_prc(f_atv)

                # apx/breakpoint inexistente. cai fora...
                return

            # obtém dados do breakpoint
            obrk.obtem_brk(f_atv, l_brk, f_cine_data)

    # otherwise,...
    else:
        # logger
        l_log = logging.getLogger("prc_aproximacao")
        l_log.setLevel(logging.ERROR)
        l_log.error(
            u"<E06: fase da aproximação não identificada. fase:[{}].".format(
                ldefs.DCT_FASE[f_atv.en_atv_fase]))