コード例 #1
0
    def __init__(self, arg):
        __class__.conexao = arg
        __class__.centro_espacial = conexao.space_center
        self.nave_atual = __class__.centro_espacial.active_vessel  # objeto da nave
        self.ponto_ref = self.nave_atual.orbit.body.reference_frame
        self.voo_nave = self.nave_atual.flight(self.ponto_ref)
        # Parâmetros da nave
        self.altitude_da_nave = conexao.add_stream(getattr, self.voo_nave,
                                                   "surface_altitude")
        self.vel_vert_nave = conexao.add_stream(getattr, self.voo_nave,
                                                "vertical_speed")
        self.massa_total_nave = conexao.add_stream(getattr, self.nave_atual,
                                                   "mass")
        self.ut = conexao.add_stream(getattr, __class__.centro_espacial, "ut")
        self.controle_acel = ControlePID()
        self.controle_pouso = ControlePID()
        self.nav = Navegacao()
        self.distancia_pouso = 50  # Altura pra começar o Hover
        self.forca_grav = self.nave_atual.orbit.body.surface_gravity
        self.exec_suicide_burn = False
        self.pode_pousar = False
        self.nave_twr_max = 1
        self.acel_max = 0
        self.empuxo_total = 0
        self.distancia_ate_queima = 0
        self.tempo_da_queima = 0

        self.construir_painel_info()
コード例 #2
0
class Navegacao:
      
    def __init__(self):
        self.alinhar_distancia_horizontal = Vetor.Vetor(0, 0)
        self.posicao_pouso_alvo = Vetor.Vetor(0.0, 0.0)
        self.vetorDaVelocidade = Vetor.Vetor(0, 0)
        self.controle_mag = ControlePID()
        self.retornar_vetor = Vetor.Vetor(0, 0)

    def navegacao(self, centro_espacial, nave_atual):
        self.centro_espacial = centro_espacial
        self.nave_atual = nave_atual
        self.ponto_ref = self.nave_atual.orbit.body.reference_frame
        self.voo_nave = self.nave_atual.flight(self.ponto_ref)
        self.controle_mag.tempo_amostragem(40)
        self.controle_mag.ajustar_pid(0.5, 0.001, 10)
        self.controle_mag.limitar_saida(-1, 1)
        self.mirar_nave()
        
    def mirar_nave(self):
        # Buscar Nó Retrógrado:
        self.posicao_pouso_alvo = \
            self.centro_espacial.transform_position(self.voo_nave.retrograde,
                                                    self.nave_atual.surface_velocity_reference_frame,
                                                    self.ponto_ref)
        self.alinhar_distancia_horizontal = \
            Vetor.vetor_distancia(self.centro_espacial.transform_position(self.posicao_pouso_alvo,
                                                                          self.ponto_ref,
                                                                          self.nave_atual.surface_reference_frame),
                                  self.nave_atual.position(self.nave_atual.surface_reference_frame))
        
        self.alinhar_direcao = self.get_elevacao_direcao_do_vetor(self.alinhar_distancia_horizontal)
 
        self.nave_atual.auto_pilot.target_pitch_and_heading(self.alinhar_direcao.y, self.alinhar_direcao.x)
        self.nave_atual.auto_pilot.target_roll = self.alinhar_direcao.x

    def get_elevacao_direcao_do_vetor(self, vetor):
        self.vel_relativa = self.centro_espacial.transform_position(self.voo_nave.velocity,
                                                                    self.ponto_ref,
                                                                    self.nave_atual.surface_reference_frame)
 
        self.vetorDaVelocidade.x = (self.vel_relativa[1])
        self.vetorDaVelocidade.y = (self.vel_relativa[2])

        vetor = vetor.subtrai(self.vetorDaVelocidade)

        self.retornar_vetor.x = Vetor.angulo_direcao(vetor)

        self.comprimento = math.pow(1 + vetor.magnitude(), 1) - 1
        self.controle_mag.entrada_pid(self.comprimento)
        self.controle_mag.limite_pid(self.vetorDaVelocidade.magnitude())
        self.retornar_vetor.y = max(60, (90 - int(self.comprimento) * 2))
 
#         print("Comprimento: " + str(self.comprimento))
#         print("Comprimento Vel: " + str(self.vetorDaVelocidade.magnitude()))
#         print("Inclinacao: " + str(self.retornar_vetor.elevacao))
#         print("PID: " + str(self.controle_mag.computar_pid()))
#  
        return self.retornar_vetor
コード例 #3
0
    def iniciar_decolagem(self):
        #Parametros padrao de decolagem:
        self.alt_inicio_curva = 150
        self.alt_fim_curva = 60000
        self.alt_final = 85000
        self.inclinacao = "Normal"
        self.programa = 0
        self.escudos_soltos = False
        #Parametros de voo:
        self.nave_atual = __class__.centro_espacial.active_vessel  # objeto da nave
        ponto_ref = self.nave_atual.orbit.body.reference_frame
        voo_nave = self.nave_atual.flight(ponto_ref)
        self.ut = __class__.conexao.add_stream(getattr,
                                               __class__.centro_espacial, "ut")
        self.controle_acel = ControlePID()

        #Variaveis da nave:
        self.altitude = __class__.conexao.add_stream(getattr, voo_nave,
                                                     "mean_altitude")
        self.max_q = __class__.conexao.add_stream(getattr, voo_nave,
                                                  "dynamic_pressure")
        self.apoastro = __class__.conexao.add_stream(getattr,
                                                     self.nave_atual.orbit,
                                                     "apoapsis_altitude")
        self.periastro = __class__.conexao.add_stream(getattr,
                                                      self.nave_atual.orbit,
                                                      "periapsis_altitude")
        self.tempo_ate_apoastro = __class__.conexao.add_stream(
            getattr, self.nave_atual.orbit, "time_to_apoapsis")

        self.construir_painel_info()  #<<< Mostrar painel de informacoes

        while True:
            if self.programa == 0:
                self.iniciar_lançamento()
            elif self.programa == 1:
                self.giro_gravitacional()
            elif self.programa == 2:
                self.circularizar()

            sleep(0.40)
コード例 #4
0
    def __init__(self, arg0):
        self.conexao_krpc = arg0  # Conexão com o KRPC
        self.centro_espacial = arg0.space_center  # Objeto do Centro Espacial
        self.marcadores = self.centro_espacial.waypoint_manager  # Gerenciador de Marcadores no mapa
        self.rover = self.centro_espacial.active_vessel  # Objeto do Rover (Nave Atual)
        self.ponto_ref_orbital = self.rover.orbit.body.reference_frame  # Ponto de Referência Orbital
        self.ponto_ref_superficie = self.rover.surface_reference_frame  # Ponto de Referência da Superfície
        self.ponto_ref_rover = self.rover.reference_frame  # Ponto de Referência do Rover
        self.parametros_rover = self.rover.flight(
            self.ponto_ref_orbital)  # Parâmetros de "voo" do Rover
        # Definindo Vetores de posição e direção:
        self.posicao_rover = Vetor.Vetor(0, 0)
        self.posicao_alvo = Vetor.Vetor(0, 0)
        self.direcao_rover = Vetor.Vetor(0, 0)
        self.distancia_entre_pontos = Vetor.Vetor(0, 0)
        # Variáveis de Angulo:
        self.angulo_alvo = 0.0
        self.angulo_rover = 0.0

        print("O nome do Rover é: {0:.30}".format(self.rover.name))
        self.alvo = self.definir_alvo()
        if self.alvo is not None:
            print("Está buscando o alvo: {0:.30}".format(str(self.alvo.name)),
                  "\n")

        self.ctrl_direcao = ControlePID()
        self.ctrl_direcao.ajustar_pid(0.01, 0.001, 0.01)
        self.ctrl_aceleracao = ControlePID()
        self.ctrl_aceleracao.ajustar_pid(0.5, 0.001, 0.1)
        self.ctrl_distancia_alvo = ControlePID()
        self.ctrl_distancia_alvo.ajustar_pid(0.1, 0.001, 5)
        self.ctrl_distancia_alvo.limitar_saida(-1, 1)
        self.limite_distancia_alvo = 50
        self.velocidade_maxima = 15
        self.velocidade_curva = 3
        self.construir_painel_info()
        self.controlar_rover()
コード例 #5
0
class SuicideBurn:
    margem_ui = 20
    conexao = None
    centro_espacial = None

    def __init__(self, arg):
        __class__.conexao = arg
        __class__.centro_espacial = conexao.space_center
        self.nave_atual = __class__.centro_espacial.active_vessel  # objeto da nave
        self.ponto_ref = self.nave_atual.orbit.body.reference_frame
        self.voo_nave = self.nave_atual.flight(self.ponto_ref)
        # Parâmetros da nave
        self.altitude_da_nave = conexao.add_stream(getattr, self.voo_nave,
                                                   "surface_altitude")
        self.vel_vert_nave = conexao.add_stream(getattr, self.voo_nave,
                                                "vertical_speed")
        self.massa_total_nave = conexao.add_stream(getattr, self.nave_atual,
                                                   "mass")
        self.ut = conexao.add_stream(getattr, __class__.centro_espacial, "ut")
        self.controle_acel = ControlePID()
        self.controle_pouso = ControlePID()
        self.nav = Navegacao()
        self.distancia_pouso = 50  # Altura pra começar o Hover
        self.forca_grav = self.nave_atual.orbit.body.surface_gravity
        self.exec_suicide_burn = False
        self.pode_pousar = False
        self.nave_twr_max = 1
        self.acel_max = 0
        self.empuxo_total = 0
        self.distancia_ate_queima = 0
        self.tempo_da_queima = 0

        self.construir_painel_info()

    def iniciar_suicide_burn(self):
        print("Nave Atual: ", self.nave_atual.name)
        print(str(self.nave_atual.situation))
        print("Força da Gravidade Atual: ", self.forca_grav, "Corpo Celeste: ",
              self.nave_atual.orbit.body.name)
        self.calcular_parametros()
        print("Força de TWR da Nave: ", self.nave_twr_max)
        self.controle_acel.tempo_amostragem(40)
        self.controle_pouso.tempo_amostragem(40)
        self.controle_acel.ajustar_pid(0.025, 0.001, 0.025)  # <== AJUSTES PID
        self.controle_pouso.ajustar_pid(0.1, 0.001, 0.1)  # <== AJUSTES PID
        # Limita a aceleração da nave:
        self.nave_atual.auto_pilot.engage()  # LIGAR O PILOTO
        self.decolagem_de_teste()
        self.calcular_parametros()
        self.controle_acel.limitar_saida(0, 1)
        self.controle_pouso.limitar_saida(0.75 / self.nave_twr_max, 1)
        self.controle_pouso.limite_pid(0)
        self.nav.navegacao(__class__.centro_espacial, self.nave_atual)

        while not self.exec_suicide_burn:  # LOOP esperando para executar o SuicideBurn
            self.calcular_parametros()
            self.pode_pousar = False
            self.nav.mirar_nave()
            # Ativa freios e RCS para melhorar o controle da descida:
            if 100 < self.altitude_da_nave() < 10000:
                self.nave_atual.control.brakes = True
            else:
                self.nave_atual.control.brakes = False
            if self.altitude_da_nave() < 4000:
                self.nave_atual.control.rcs = True
            # self.controle_acel.ajustar_pid(round(self.nave_twr_max, 1) / 200, 0.001, 1)

            if (0 > self.altitude_da_nave() - self.distancia_ate_queima -
                    self.distancia_pouso) and (self.vel_vert_nave() < -1):
                self.exec_suicide_burn = True
                print("Iniciando o Suicide Burn!")
            sleep(0.1)

        # -=-=- Loop Principal do Suicide Burn -=-=-
        while self.exec_suicide_burn:
            # Calcula os valores de aceleração e TWR do foguete:
            self.calcular_parametros()
            # Desce o trem de pouso da nave em menos de 100 metros
            if self.altitude_da_nave() < 100:
                self.nave_atual.control.gear = True
            # Informa aos PIDs a altitude, limite e velocidade da nave
            self.controle_acel.entrada_pid(self.altitude_da_nave())
            self.controle_acel.limite_pid(self.distancia_ate_queima)
            self.controle_pouso.entrada_pid(self.vel_vert_nave())

            # Aponta nave para o retrograde se a velocidade horizontal for maior que 1m/s
            if self.altitude_da_nave() > self.distancia_pouso:
                self.pode_pousar = False
            else:
                self.pode_pousar = True

            if self.voo_nave.horizontal_speed > 0.2:
                self.nav.mirar_nave()
            else:
                self.nave_atual.control.target_pitch = 0
            # Acelera o foguete de acordo com o PID:
            correcao_anterior = self.nave_atual.control.throttle
            try:
                if self.pode_pousar is False:
                    self.aceleracao(
                        float((correcao_anterior +
                               self.controle_acel.computar_pid() +
                               1 / self.nave_twr_max) / 3))
                    print("Valor Saída ACEL: ",
                          self.controle_acel.computar_pid())
                else:
                    self.aceleracao(float(self.controle_pouso.computar_pid()))
                    print("Valor Saída POUSO: ",
                          self.controle_pouso.computar_pid())

            except ZeroDivisionError:
                print("Erro no cálculo da aceleração. Usando valor antigo")
                self.aceleracao(correcao_anterior)

            # Verifica se o foguete pousou
            self.checar_pouso()

            sleep(0.05)

    def calcular_parametros(self):
        # Calcular TWR:
        try:
            if self.nave_atual.available_thrust == 0.0:
                self.empuxo_atual = self.nave_atual.available_thrust
            else:
                self.empuxo_atual = 0.0
                for motor in self.nave_atual.parts.engines:
                    self.empuxo_atual += motor.available_thrust

            self.nave_twr_max = self.empuxo_atual / (self.massa_total_nave() *
                                                     self.forca_grav)
            # Aceleração Máxima da Nave:
            self.acel_max = (self.nave_twr_max *
                             self.forca_grav) - self.forca_grav
            # Tempo de queima dessa aceleração e distancia até iniciar a queima de suicide burn com essa aceleração:
            self.tempo_da_queima = abs(self.vel_vert_nave()) / self.acel_max
            self.distancia_ate_queima = abs(self.vel_vert_nave()) * self.tempo_da_queima \
             + 1 / 2 * self.acel_max * (self.tempo_da_queima ** 2)

        except ZeroDivisionError:
            self.nave_twr_max = 1
            self.tempo_da_queima = 0
            self.distancia_ate_queima = 0
        # Mostrar dados:
        try:
            self.txt_altitude.content = str("Altitude: {0:.1f}{1}".format(
                self.altitude_da_nave(), "m"))
            self.txt_velocidade.content = str("Velocidade: {0:.1f}{1}".format(
                self.vel_vert_nave(), "m/s"))
            self.txt_suicide_dist.content = str(
                "Distância até Suicide: {0:>20.1f}{1}".format(
                    (self.altitude_da_nave() - self.distancia_ate_queima -
                     self.distancia_pouso), "m"))
        except ZeroDivisionError:
            self.txt_altitude.content = "Impossível buscar altitude"
            self.txt_velocidade.content = "Impossível buscar velocidade"
            self.txt_suicide_dist.content = "Impossível buscar distância"
        try:
            self.txt_twr.content = str("TWR: {0:.1f}".format(
                self.nave_twr_max))
        except ZeroDivisionError:
            self.txt_twr.content = "Impossível buscar TWR"

    def aceleracao(self, valor):
        """ Acelera a nave de acordo com o valor
		Se o valor for negativo, o resultado é 0, se for maior que 1, fica 1"""
        valor = valor if valor > 0 else 0
        valor = valor if valor < 1 else 1
        self.nave_atual.control.throttle = valor

    def decolagem_de_teste(self):
        situacao_da_nave = str(self.nave_atual.situation)
        # Se o veículo está pousado ou na base de lançamento, ele sobe:
        if situacao_da_nave == "VesselSituation.landed" or situacao_da_nave == "VesselSituation.pre_launch":
            if situacao_da_nave == "VesselSituation.pre_launch":
                self.nave_atual.control.activate_next_stage()
            self.nave_atual.control.gear = False
            self.calcular_parametros()
            self.aceleracao(1)
            while self.altitude_da_nave() <= self.distancia_pouso:
                self.nave_atual.control.target_pitch = 0
                sleep(0.1)
            self.aceleracao(0)
            sleep(0.1)
            self.nave_atual.control.target_pitch = 0  # mirar pra cima <<<
        else:
            self.aceleracao(0)

    def checar_pouso(self):
        situacao_da_nave = str(self.nave_atual.situation)
        if situacao_da_nave == "VesselSituation.landed" or \
         situacao_da_nave == "VesselSituation.splashed" and self.pode_pousar:
            while self.nave_atual.control.throttle > 0.1:
                acel = self.nave_atual.control.throttle - 0.1
                self.aceleracao(acel)
                sleep(0.1)
            print("Pouso finalizado.")
            self.aceleracao(0)
            self.nave_atual.auto_pilot.disengage()
            self.nave_atual.control.rcs = True
            self.nave_atual.control.sas = True
            self.nave_atual.control.brakes = False
            self.pode_pousar = False
            self.nave_atual.auto_pilot.disengage()  # DESLIGAR O PILOTO
            self.exec_suicide_burn = False

    def construir_painel_info(self):
        # Tela do jogo:
        self.tela_itens = __class__.conexao.ui.stock_canvas
        # Tamanho da tela de jogo
        tamanho_tela = self.tela_itens.rect_transform.size
        # Adicionar um painel para conter os elementos de UI
        painel_info = self.tela_itens.add_panel(True)

        # Posicionar o painel a esquerda da tela
        painel_transform = painel_info.rect_transform
        painel_transform.size = (400.0, 100.0)
        painel_transform.position = (-int(tamanho_tela[0] * 0.25),
                                     int(tamanho_tela[1] * 0.16))

        self.txt_altitude = painel_info.add_text("Altitude: ", True)
        self.txt_velocidade = painel_info.add_text("Velocidade: ", True)
        self.txt_twr = painel_info.add_text("TWR: ", True)
        self.txt_suicide_dist = painel_info.add_text("Distância Suicide: ",
                                                     True)
        self.txt_altitude.rect_transform.size = (400.0, __class__.margem_ui)
        self.txt_velocidade.rect_transform.size = (400.0, __class__.margem_ui)
        self.txt_twr.rect_transform.size = (400.0, __class__.margem_ui)
        self.txt_suicide_dist.rect_transform.size = (400.0,
                                                     __class__.margem_ui)
        self.txt_altitude.rect_transform.position = (__class__.margem_ui,
                                                     __class__.margem_ui)
        self.txt_velocidade.rect_transform.position = (__class__.margem_ui, 0)
        self.txt_twr.rect_transform.position = (__class__.margem_ui,
                                                -__class__.margem_ui)
        self.txt_suicide_dist.rect_transform.position = (
            __class__.margem_ui, -(__class__.margem_ui * 2))
        self.txt_altitude.color = (0.0, 0.0, 0.0)
        self.txt_altitude.size = 12
        self.txt_velocidade.color = (0.0, 0.0, 0.0)
        self.txt_velocidade.size = 12
        self.txt_twr.color = (1.0, 1.0, 1.0)
        self.txt_twr.size = 12
        self.txt_suicide_dist.color = (1.0, 1.0, 1.0)
        self.txt_suicide_dist.size = 12

        # Adicionar botões:
        bt_sburn = painel_info.add_button("Suicide Burn", True)
        bt_cancelar = painel_info.add_button("Cancelar", True)
        bt_sburn.rect_transform.position = (100.0, -__class__.margem_ui)
        bt_cancelar.rect_transform.position = (100.0, __class__.margem_ui)

        # stream para checar se o botao foi clicado
        bt_sburn_clk = __class__.conexao.add_stream(getattr, bt_sburn,
                                                    "clicked")
        bt_cancelar_clk = __class__.conexao.add_stream(getattr, bt_cancelar,
                                                       "clicked")
        cancelar = False
        # Esperar clique do botão:
        while not (bt_sburn_clk()):
            try:
                self.txt_altitude.content = str("Altitude: {0:.1f}{1}".format(
                    self.altitude_da_nave(), "m"))
                self.txt_velocidade.content = str(
                    "Velocidade: {0:.1f}{1}".format(self.vel_vert_nave(),
                                                    "m/s"))
            except:
                self.txt_altitude.content = "Impossível buscar altitude"
                self.txt_velocidade.content = "Impossível buscar velocidade"
            try:
                for motor in self.nave_atual.parts.engines:
                    self.empuxo_total += motor.max_thrust
                twr_atual = float(self.empuxo_total /
                                  (self.massa_total_nave() * self.forca_grav))
                self.txt_twr.content = str("TWR: {0:.1f}".format(twr_atual))
                self.empuxo_total = 0
            except:
                self.txt_twr.content = "Impossível buscar TWR"
            sleep(0.5)
            if bt_cancelar_clk():
                cancelar = True
                break
        if not cancelar:
            self.iniciar_suicide_burn()
            bt_sburn.clicked = False
            bt_sburn.remove()
コード例 #6
0
 def __init__(self):
     self.alinhar_distancia_horizontal = Vetor.Vetor(0, 0)
     self.posicao_pouso_alvo = Vetor.Vetor(0.0, 0.0)
     self.vetorDaVelocidade = Vetor.Vetor(0, 0)
     self.controle_mag = ControlePID()
     self.retornar_vetor = Vetor.Vetor(0, 0)
コード例 #7
0
class RoverPST:

    margem_ui = 20

    def __init__(self, arg0):
        self.conexao_krpc = arg0  # Conexão com o KRPC
        self.centro_espacial = arg0.space_center  # Objeto do Centro Espacial
        self.marcadores = self.centro_espacial.waypoint_manager  # Gerenciador de Marcadores no mapa
        self.rover = self.centro_espacial.active_vessel  # Objeto do Rover (Nave Atual)
        self.ponto_ref_orbital = self.rover.orbit.body.reference_frame  # Ponto de Referência Orbital
        self.ponto_ref_superficie = self.rover.surface_reference_frame  # Ponto de Referência da Superfície
        self.ponto_ref_rover = self.rover.reference_frame  # Ponto de Referência do Rover
        self.parametros_rover = self.rover.flight(
            self.ponto_ref_orbital)  # Parâmetros de "voo" do Rover
        # Definindo Vetores de posição e direção:
        self.posicao_rover = Vetor.Vetor(0, 0)
        self.posicao_alvo = Vetor.Vetor(0, 0)
        self.direcao_rover = Vetor.Vetor(0, 0)
        self.distancia_entre_pontos = Vetor.Vetor(0, 0)
        # Variáveis de Angulo:
        self.angulo_alvo = 0.0
        self.angulo_rover = 0.0

        print("O nome do Rover é: {0:.30}".format(self.rover.name))
        self.alvo = self.definir_alvo()
        if self.alvo is not None:
            print("Está buscando o alvo: {0:.30}".format(str(self.alvo.name)),
                  "\n")

        self.ctrl_direcao = ControlePID()
        self.ctrl_direcao.ajustar_pid(0.01, 0.001, 0.01)
        self.ctrl_aceleracao = ControlePID()
        self.ctrl_aceleracao.ajustar_pid(0.5, 0.001, 0.1)
        self.ctrl_distancia_alvo = ControlePID()
        self.ctrl_distancia_alvo.ajustar_pid(0.1, 0.001, 5)
        self.ctrl_distancia_alvo.limitar_saida(-1, 1)
        self.limite_distancia_alvo = 50
        self.velocidade_maxima = 15
        self.velocidade_curva = 3
        self.construir_painel_info()
        self.controlar_rover()

    def controlar_rover(self):
        while True:
            try:
                self.definir_vetor_direcao(self.definir_alvo())
                self.informar_ctrl_pid()
                # Com tudo calculado, pilotar o rover:
                if self.distancia_entre_pontos.magnitude(
                ) > self.limite_distancia_alvo:
                    self.acelerar_rover(self.ctrl_aceleracao.computar_pid())
                    self.pilotar_rover()
                else:
                    self.acelerar_rover(
                        self.ctrl_aceleracao.computar_pid() *
                        self.ctrl_distancia_alvo.computar_pid())

                self.atualizar_infos()
            except AttributeError:
                print("Sem alvo selecionado")
                sleep(1)

            sleep(0.05)

    def informar_ctrl_pid(self):
        # Informar ao PID de controle de direção os ângulos e tentar zerar a diferença entre eles:
        self.ctrl_direcao.entrada_pid(self.angulo_rover -
                                      abs(self.angulo_alvo))
        self.ctrl_direcao.limite_pid(0)
        # Informar ao PID de aceleração a velocidade horizontal e limitar:
        self.ctrl_aceleracao.entrada_pid(
            self.parametros_rover.horizontal_speed)
        self.ctrl_distancia_alvo.entrada_pid(
            self.limite_distancia_alvo -
            self.distancia_entre_pontos.magnitude())
        self.ctrl_distancia_alvo.limite_pid(0)
        diferenca_angulo = self.angulo_rover - abs(self.angulo_alvo)
        if abs(diferenca_angulo) > 30:
            self.ctrl_aceleracao.limite_pid(self.velocidade_curva)
        else:
            self.ctrl_aceleracao.limite_pid(self.velocidade_maxima)

    def definir_vetor_direcao(self, alvo):
        # Vetor de posição do Rover em relacão à superfície:
        self.posicao_rover = Vetor.Vetor(
            self.posicionar_vetor(
                self.rover.position(self.ponto_ref_superficie)))
        # Vetor de posição do Alvo em relacão ao rover e a órbita:
        self.posicao_alvo = Vetor.Vetor(
            self.posicionar_vetor(alvo.position(self.ponto_ref_rover)))
        # Vetor de posição do alvo em relacão à superfície e ao rover:
        self.direcao_rover = Vetor.Vetor(alvo.position(self.ponto_ref_rover))
        # Vetor de distância do alvo em relacão rover:
        self.distancia_entre_pontos = self.posicao_rover.subtrai(
            self.posicao_alvo)
        # Calculando angulos até o alvo e da direção do rover
        self.angulo_alvo = Vetor.angulo_direcao(self.distancia_entre_pontos)
        self.angulo_rover = Vetor.angulo_direcao(self.direcao_rover)

    def pilotar_rover(self):
        if not 0 < self.angulo_alvo - self.angulo_rover < 1:
            self.rover.control.wheel_steering = -self.ctrl_direcao.computar_pid(
            )
        else:
            self.rover.control.wheel_steering = 0

    def posicionar_vetor(self, arg):
        if type(arg) is Vetor.Vetor:
            vetor = (arg.x, arg.y, 0)
            vetor_retorno = self.centro_espacial.transform_position(
                vetor, self.ponto_ref_superficie, self.ponto_ref_orbital)
        else:
            vetor_retorno = self.centro_espacial.transform_position(
                arg, self.ponto_ref_superficie, self.ponto_ref_orbital)
        return round(vetor_retorno[0],
                     2), round(vetor_retorno[1],
                               2), round(vetor_retorno[2], 2)

    def acelerar_rover(self, arg0):
        self.rover.control.wheel_throttle = arg0

    def definir_alvo(self):
        try:
            self.alvo = self.centro_espacial.target_vessel
            return self.alvo
        except AttributeError:
            return None

    def construir_painel_info(self):
        # Tela do jogo:
        self.tela_itens = self.conexao_krpc.ui.stock_canvas
        # Tamanho da tela de jogo
        tamanho_tela = self.tela_itens.rect_transform.size
        # Adicionar um painel para conter os elementos de UI
        painel_info = self.tela_itens.add_panel(True)

        # Posicionar o painel a esquerda da tela
        painel_transform = painel_info.rect_transform
        painel_transform.size = (200.0, 100.0)
        painel_transform.position = (-int(tamanho_tela[0] * 0.25),
                                     int(tamanho_tela[1] * 0.16))

        self.txt_angulo_rover = painel_info.add_text("Angulo Rover: ", True)
        self.txt_angulo_alvo = painel_info.add_text("Angulo Alvo: ", True)
        self.txt_angulo_distancia = painel_info.add_text(
            "Angulo Distancia: ", True)
        self.txt_distancia_alvo = painel_info.add_text(
            "Distância até o alvo: ", True)
        self.txt_angulo_rover.rect_transform.size = (200.0,
                                                     __class__.margem_ui)
        self.txt_angulo_alvo.rect_transform.size = (200.0, __class__.margem_ui)
        self.txt_angulo_distancia.rect_transform.size = (200.0,
                                                         __class__.margem_ui)
        self.txt_distancia_alvo.rect_transform.size = (200.0,
                                                       __class__.margem_ui)
        self.txt_angulo_rover.rect_transform.position = (__class__.margem_ui,
                                                         __class__.margem_ui)
        self.txt_angulo_alvo.rect_transform.position = (__class__.margem_ui, 0)
        self.txt_angulo_distancia.rect_transform.position = (
            __class__.margem_ui, -__class__.margem_ui)
        self.txt_distancia_alvo.rect_transform.position = (
            __class__.margem_ui, -(__class__.margem_ui * 2))
        self.txt_angulo_rover.color = (0.0, 0.0, 0.0)
        self.txt_angulo_rover.size = 12
        self.txt_angulo_alvo.color = (0.0, 0.0, 0.0)
        self.txt_angulo_alvo.size = 12
        self.txt_angulo_distancia.color = (1.0, 1.0, 1.0)
        self.txt_angulo_distancia.size = 12
        self.txt_distancia_alvo.color = (1.0, 1.0, 1.0)
        self.txt_distancia_alvo.size = 12

    def atualizar_infos(self):
        self.txt_angulo_rover.content = "Correção de Ângulo: " + str(
            round(self.angulo_rover - abs(self.angulo_alvo), 2))
        self.txt_angulo_alvo.content = "Acelerador: " + str(
            round(self.ctrl_aceleracao.computar_pid(), 2))
        self.txt_angulo_distancia.content = "Angulo Distância: " + str(
            Vetor.angulo_direcao(self.distancia_entre_pontos))
        self.txt_distancia_alvo.content = "Distância: " + str(
            round(self.distancia_entre_pontos.magnitude(), 1)) + "m"
コード例 #8
0
class DecolagemOrbital():
    #Elementos da UI:
    margem_ui = 20
    #Parametros:
    GRAV = 9.81
    conexao = None
    centro_espacial = None

    def __init__(self, conexao):
        __class__.conexao = conexao
        __class__.centro_espacial = conexao.space_center
        self.iniciar_decolagem()

    def iniciar_decolagem(self):
        #Parametros padrao de decolagem:
        self.alt_inicio_curva = 150
        self.alt_fim_curva = 60000
        self.alt_final = 85000
        self.inclinacao = "Normal"
        self.programa = 0
        self.escudos_soltos = False
        #Parametros de voo:
        self.nave_atual = __class__.centro_espacial.active_vessel  # objeto da nave
        ponto_ref = self.nave_atual.orbit.body.reference_frame
        voo_nave = self.nave_atual.flight(ponto_ref)
        self.ut = __class__.conexao.add_stream(getattr,
                                               __class__.centro_espacial, "ut")
        self.controle_acel = ControlePID()

        #Variaveis da nave:
        self.altitude = __class__.conexao.add_stream(getattr, voo_nave,
                                                     "mean_altitude")
        self.max_q = __class__.conexao.add_stream(getattr, voo_nave,
                                                  "dynamic_pressure")
        self.apoastro = __class__.conexao.add_stream(getattr,
                                                     self.nave_atual.orbit,
                                                     "apoapsis_altitude")
        self.periastro = __class__.conexao.add_stream(getattr,
                                                      self.nave_atual.orbit,
                                                      "periapsis_altitude")
        self.tempo_ate_apoastro = __class__.conexao.add_stream(
            getattr, self.nave_atual.orbit, "time_to_apoapsis")

        self.construir_painel_info()  #<<< Mostrar painel de informacoes

        while True:
            if self.programa == 0:
                self.iniciar_lançamento()
            elif self.programa == 1:
                self.giro_gravitacional()
            elif self.programa == 2:
                self.circularizar()

            sleep(0.40)

    def iniciar_lançamento(self):
        #	Iniciar Lancamento:
        self.nave_atual.control.sas = False  # desligar SAS
        self.nave_atual.control.rcs = False  # desligar RCS

        #	Contagem regressiva...
        self.set_txt_titulo("Lançamento em:")
        for segundo in range(5, 0, -1):
            self.set_txt_status(segundo)
            sleep(1)

        #	Acertar aceleracao:
        motores = self.nave_atual.parts.engines
        empuxo_total_lancamento = motores[0].max_thrust
        massa_total_lancamento = self.nave_atual.mass  #	massa da nave
        try:
            acel_lancamento = float(
                (1.5 / (empuxo_total_lancamento /
                        (massa_total_lancamento * __class__.GRAV))))
        except:
            acel_lancamento = 1
        self.nave_atual.control.throttle = acel_lancamento  # ACELERAR COM 1.5 DE TWR

        #	Lançar e ativar piloto automático
        if (str(self.nave_atual.situation) == "VesselSituation.pre_launch"):
            self.nave_atual.control.activate_next_stage()
        self.nave_atual.auto_pilot.engage()  # ativa o piloto auto
        self.nave_atual.auto_pilot.target_pitch_and_heading(90, 90)  # direção
        self.programa = 1

    def giro_gravitacional(self):
        self.set_txt_titulo("Altitude em Relação ao Solo:")

        #Controle de Aceleração
        self.controle_acel.set_valor_limite(25000)  #Limite de pressão dinâmica
        self.controle_acel.limitar_saida(0.9, 3)  #Limite de controle do TWR
        self.controle_acel.ajustar_pid(0.001, 0.001, 0.0001)
        angulo_giro = 0  # angulo de giro

        while (True):  # loop do giro de gravidade
            self.set_txt_status(("{0:.1f}".format(self.altitude()) +
                                 " metros"))  #Mostra Altitude
            # Giro de Gravidade
            if (self.altitude() > float(self.alt_inicio_curva)
                    and self.altitude() < float(self.alt_fim_curva)):
                try:
                    incremento = math.sqrt(
                        (self.altitude() - self.alt_inicio_curva) /
                        (self.alt_fim_curva - self.alt_inicio_curva))
                except:
                    pass

                if self.inclinacao == "Rasa":
                    novo_angulo = math.sqrt(incremento * 0.8) * 90.0
                elif self.inclinacao == "Normal":
                    novo_angulo = (incremento) * 85.0
                elif self.inclinacao == "Aguda":
                    novo_angulo = math.pow(incremento, 1.2) * 80.0

                if (math.fabs(novo_angulo - angulo_giro) > 0.3):
                    angulo_giro = novo_angulo
                    self.nave_atual.auto_pilot.target_pitch_and_heading(
                        float(90 - angulo_giro), 90)

            #Controlar Aceleração para evitar o MaxQ:
            self.controle_acel.set_valor_entrada(self.max_q())
            try:
                nova_acel = float((self.controle_acel.computar_pid() /
                                   (self.nave_atual.available_thrust /
                                    (self.nave_atual.mass * __class__.GRAV))))
            except:
                nova_acel = 0
            self.nave_atual.control.throttle = nova_acel

            if (self.altitude() > 20000):
                self.controle_acel.set_valor_limite(20000)

            # Diminuir aceleracao ao chegar perto do apoastro alvo
            if (self.apoastro() >= self.alt_final * 0.95):
                self.set_txt_titulo("Aproximando-se do apoastro alvo")
                self.nave_atual.control.throttle = 0.20  # mudar aceleração pra 25%
                break

            self.soltar_escudos()
            sleep(0.40)

        # Desativa motores ao chegar no apoastro
        while (self.apoastro() < self.alt_final):
            self.set_txt_titulo("Altitude do Apoastro:")
            self.set_txt_status("{0:.1f}".format(self.apoastro()) +
                                "m, alvo: " +
                                "{0:.1f}".format(self.alt_final) + "m.")
            self.soltar_escudos()
            sleep(0.40)
        self.set_txt_titulo("Apoastro alvo alcançado")
        self.nave_atual.control.throttle = 0  # cortar motor
        sleep(1)
        # esperar ate sair da atmosfera
        self.set_txt_titulo("Esperando sair da atmosfera")
        while (self.altitude() < 65000):
            self.set_txt_status("Altitude: " +
                                "{0:.1f}".format(self.altitude()) + " metros")
            self.soltar_escudos()
            sleep(0.40)
        self.programa = 2

    def soltar_escudos(self):
        #	Soltar Fairings da nave:
        if (self.altitude() > 50000 and self.escudos_soltos == False):
            for escudo in self.nave_atual.parts.fairings:
                try:
                    if not (escudo.jettisoned):
                        self.set_txt_status("Soltando escudos...")
                        sleep(1)
                        escudo.jettison()
                        self.set_txt_status("Escudos soltos.")
                        self.escudos_soltos = True
                        sleep(1)
                except:
                    self.set_txt_status("Erro ao soltar escudos...")
                    sleep(1)

    def circularizar(self):
        # Planejar circularizacao
        self.set_txt_titulo("Planejando queima de circularização")
        gm = self.nave_atual.orbit.body.gravitational_parameter  # pegar parametro G
        apo = self.nave_atual.orbit.apoapsis  # apoastro da orbita
        sma = self.nave_atual.orbit.semi_major_axis  # semieixo da orbita
        v1 = math.sqrt(gm * ((2.0 / apo) - (1.0 / sma)))
        v2 = math.sqrt(gm * ((2.0 / apo) - (1.0 / apo)))
        delta_v = v2 - v1

        #Adicionar a manobra
        node = self.nave_atual.control.add_node(
            self.ut() + self.nave_atual.orbit.time_to_apoapsis,
            prograde=delta_v)

        # Calcular tempo de queima (equacao de foguete)
        massa_total = self.nave_atual.mass  # massa total do foguete
        isp = self.nave_atual.specific_impulse * __class__.GRAV  # isp multiplicado pela constante grav
        empuxo_total = self.nave_atual.available_thrust  # empuxo disponivel
        massa_seca = massa_total / math.exp(
            delta_v / isp)  # massa seca do foguete
        taxa_queima = empuxo_total / isp  # taxa de fluxo, empuxo / isp
        tempo_queima = (massa_total -
                        massa_seca) / taxa_queima  #tempo de queima

        # Orientar nave ao noh
        self.set_txt_status("Orientando nave para queima de circularização")
        self.nave_atual.control.rcs = True
        self.nave_atual.auto_pilot.reference_frame = node.reference_frame
        self.nave_atual.auto_pilot.target_direction = (0.0, 1.0, 0.0)

        # esperar ate a queima
        self.set_txt_titulo("Esperando até a queima de circularização")
        tempo_ate_queima = float(self.ut() +
                                 self.nave_atual.orbit.time_to_apoapsis -
                                 (tempo_queima / 2.0))
        self.set_txt_status(("Tempo de queima: " +
                             "{0:.1f}".format(tempo_queima) + " segundos"))
        espera = 5
        self.nave_atual.auto_pilot.wait()
        __class__.centro_espacial.warp_to(tempo_ate_queima - espera)
        self.nave_atual.auto_pilot.target_direction = (0.0, 1.0, 0.0)

        # executar queima
        self.set_txt_titulo("Pronto para executar queima")
        queima_restante = __class__.conexao.add_stream(
            node.remaining_burn_vector, node.reference_frame)
        while (self.tempo_ate_apoastro() - (tempo_queima / 2.0) > 0.1):
            self.set_txt_status(
                str("Ignição em " +
                    "{0:.1f}".format(self.tempo_ate_apoastro() -
                                     (tempo_queima / 2.0)) + " segundos..."))

        self.set_txt_titulo("Executando queima")
        self.nave_atual.control.throttle = 1
        while (queima_restante()[1] > 1):
            sleep(0.20)
            if (queima_restante()[1] < 50
                    and self.nave_atual.control.throttle > 0.1):
                self.set_txt_titulo("Ajustando...")
                self.nave_atual.control.throttle = 0.1
            self.set_txt_status("Delta V restante: " +
                                "{0:.1f}".format(queima_restante()[1]) + "m/s")
        self.nave_atual.control.throttle = 0
        node.remove()
        self.set_txt_titulo("Lançamento completo.")
        self.set_txt_status("Apoastro: " + "{0:.1f}".format(self.apoastro()) +
                            "m, Periastro: " +
                            "{0:.1f}".format(self.periastro()) + "m")
        self.nave_atual.auto_pilot.disengage()
        self.nave_atual.control.sas = True
        self.incremento = 0
        self.angulo_giro = 0
        self.novo_angulo = 0
        sleep(5)
        __class__.conexao.close()

    def construir_painel_info(self):
        # Tela do jogo:
        self.tela_itens = __class__.conexao.ui.stock_canvas
        # Tamanho da tela de jogo
        tamanho_tela = self.tela_itens.rect_transform.size
        # Adicionar um painel para conter os elementos de UI
        painel_info = self.tela_itens.add_panel(True)

        # Posicionar o painel a esquerda da tela
        painel_transform = painel_info.rect_transform
        painel_transform.size = (400.0, 100.0)
        painel_transform.position = (-int(tamanho_tela[0] * 0.25),
                                     int(tamanho_tela[1] * 0.16))

        # Adicionar caixa de texto para altitude
        cx_txt = painel_info.add_input_field(True)
        self.txt_titulo = painel_info.add_text("Digite a Altitude Final: ",
                                               True)
        self.txt_status = painel_info.add_text("", False)

        self.txt_titulo.rect_transform.size = (400.0, __class__.margem_ui)
        self.txt_status.rect_transform.size = (400.0, __class__.margem_ui)

        self.txt_titulo.rect_transform.position = (__class__.margem_ui,
                                                   __class__.margem_ui)
        self.txt_status.rect_transform.position = (__class__.margem_ui,
                                                   -__class__.margem_ui)

        self.txt_titulo.color = (0.0, 0.0, 0.0)
        self.txt_titulo.size = (14)

        self.txt_status.color = (1.0, 1.0, 1.0)
        self.txt_status.size = (18)
        cx_txt.rect_transform.position = (-100.0, -__class__.margem_ui)
        cx_txt.value = str(self.alt_final)

        # Adicionar botões:
        bt_decolar = painel_info.add_button("Decolar", True)
        bt_configurar = painel_info.add_button("Configurar", True)
        bt_ok = painel_info.add_button("OK", False)
        bt_inc_nor = painel_info.add_button("Normal", False)
        bt_inc_agu = painel_info.add_button("Aguda", False)
        bt_inc_ras = painel_info.add_button("Rasa", False)
        bt_decolar.rect_transform.position = (100.0, -__class__.margem_ui)
        bt_configurar.rect_transform.position = (100.0, __class__.margem_ui)
        bt_ok.rect_transform.position = (100.0, -__class__.margem_ui)
        bt_inc_nor.rect_transform.position = (-100.0, -__class__.margem_ui)
        bt_inc_agu.rect_transform.position = (-100.0, -__class__.margem_ui)
        bt_inc_ras.rect_transform.position = (-100.0, -__class__.margem_ui)

        # stream para checar se o botao foi clicado
        bt_decolar_clk = __class__.conexao.add_stream(getattr, bt_decolar,
                                                      "clicked")
        bt_ok_clk = __class__.conexao.add_stream(getattr, bt_ok, "clicked")
        bt_configurar_clk = __class__.conexao.add_stream(
            getattr, bt_configurar, "clicked")
        bt_inc_nor_clk = __class__.conexao.add_stream(getattr, bt_inc_nor,
                                                      "clicked")
        bt_inc_agu_clk = __class__.conexao.add_stream(getattr, bt_inc_agu,
                                                      "clicked")
        bt_inc_ras_clk = __class__.conexao.add_stream(getattr, bt_inc_ras,
                                                      "clicked")

        # Esperar clique do botão:
        while not (bt_decolar_clk()):
            numero = True
            if (cx_txt.changed):
                try:
                    self.alt_final = float(cx_txt.value)
                except Exception:
                    numero = False

                if (numero) and (self.alt_final > 70500.0):
                    self.set_txt_titulo("Digite a Altitude Final: ")
                    bt_decolar.visible = True
                    bt_configurar.visible = True
                else:
                    self.set_txt_titulo(
                        "Precisa ser um número, acima de 71km!")
                    bt_decolar.visible = False
                    bt_configurar.visible = False
            sleep(0.50)
            if bt_configurar_clk():
                self.set_txt_titulo("Escolha a inclinação de subida orbital:")
                bt_inc_nor.visible = True
                bt_ok.visible = True
                bt_configurar.visible = False
                bt_decolar.visible = False
                cx_txt.visible = False

                while (True):
                    if bt_inc_nor_clk():
                        self.inclinacao = "Aguda"
                        bt_inc_nor.clicked = False
                        bt_inc_nor.visible = False
                        bt_inc_agu.visible = True

                    if bt_inc_agu_clk():
                        self.inclinacao = "Rasa"
                        bt_inc_agu.clicked = False
                        bt_inc_agu.visible = False
                        bt_inc_ras.visible = True
                    if bt_inc_ras_clk():
                        self.inclinacao = "Normal"
                        bt_inc_ras.clicked = False
                        bt_inc_ras.visible = False
                        bt_inc_nor.visible = True

                    if bt_ok_clk():
                        bt_decolar.visible = True
                        bt_configurar.visible = True
                        bt_ok.visible = False
                        bt_inc_nor.visible = False
                        bt_inc_agu.visible = False
                        bt_inc_ras.visible = False
                        bt_ok.clicked = False
                        bt_configurar.clicked = False
                        cx_txt.visible = True
                        self.set_txt_titulo("Digite a Altitude Final: ")
                        break

        bt_inc_ras.remove()
        bt_inc_nor.remove()
        bt_inc_agu.remove()
        bt_ok.remove()
        bt_decolar.remove()
        bt_configurar.remove()
        cx_txt.remove()
        self.txt_status.visible = True

    def set_txt_titulo(self, texto):
        self.txt_titulo.content = texto

    def set_txt_status(self, texto):
        self.txt_status.content = ("Status: " + str(texto))
コード例 #9
0
class Navegacao:
    def __init__(self):
        self.alinhar_distancia_horizontal = Vetor(0, 0)
        self.posicao_pouso_alvo = (0.0, 0.0, 0.0)
        self.vetorDaVelocidade = Vetor(0, 0)
        self.controle_mag = ControlePID()
        self.alvo_ou_nao = False

    def navegacao(self, centro_espacial, nave_atual):
        self.centro_espacial = centro_espacial
        self.nave_atual = nave_atual
        self.ponto_ref = self.nave_atual.orbit.body.reference_frame
        self.voo_nave = self.nave_atual.flight(self.ponto_ref)
        self.controle_mag.set_tempo_amostra(25)
        self.controle_mag.ajustar_pid(0.5, 0.001, 10)
        self.controle_mag.limitar_saida(-1, 1)
        self.mirar_nave()

    def mirar_nave(self):
        self.posicao_pouso_alvo = self.centro_espacial.transform_position(
            self.voo_nave.retrograde,
            self.nave_atual.surface_velocity_reference_frame, self.ponto_ref)
        try:
            self.posicao_pouso_alvo = self.centro_espacial.target_vessel.position(
                self.ponto_ref)  #ALVO
            self.alvo_ou_nao = True
        except:
            self.alvo_ou_nao = False

        self.alinhar_distancia_horizontal = Vetor.vetor_distancia(
            self,
            self.centro_espacial.transform_position(
                self.posicao_pouso_alvo, self.ponto_ref,
                self.nave_atual.surface_reference_frame),
            self.nave_atual.position(self.nave_atual.surface_reference_frame))

        self.alinhar_direcao = self.get_elevacao_direcao_do_vetor(
            self.alinhar_distancia_horizontal)

        self.nave_atual.auto_pilot.target_pitch_and_heading(
            self.alinhar_direcao.elevacao, self.alinhar_direcao.direcao)
        self.nave_atual.auto_pilot.target_roll = self.alinhar_direcao.direcao

#       print(self.alinhar_direcao.toString())


#      # FIM DO METODO MAIN
#

    def get_elevacao_direcao_do_vetor(self, vetor):
        self.vec = vetor
        self.to_ret = DirElev(0, 0)
        self.vec_invertido = Vetor(0, 0)
        self.vel_relativa = self.centro_espacial.transform_position(
            self.voo_nave.velocity, self.ponto_ref,
            self.nave_atual.surface_reference_frame)

        self.vetorDaVelocidade.x = (self.vel_relativa[1])
        self.vetorDaVelocidade.y = (self.vel_relativa[2])
        self.vetorDaVelocidade = self.vetorDaVelocidade.inverte()

        self.vec = self.vec.subtrai(self.vetorDaVelocidade)
        if (self.alvo_ou_nao):
            self.vec_invertido = self.vec.multiplica(-1)  #ALVO
        else:
            self.vec_invertido = self.vec.multiplica(1)  #RETROCESSO

        self.to_ret.direcao = (
            (math.atan2(self.vec_invertido.x, self.vec_invertido.y) / math.pi)
            * 180)
        if (self.to_ret.direcao < 0):
            self.to_ret.direcao = 360 + self.to_ret.direcao

        self.comprimento = math.pow(1 + self.vec.magnitude(), 1) - 1
        self.controle_mag.set_valor_entrada(self.comprimento)
        self.controle_mag.set_valor_limite(self.vetorDaVelocidade.magnitude())
        self.to_ret.elevacao = max(60, (90 - self.comprimento * 2))

        #         print("Comprimento: " + str(self.comprimento))
        #         print("Comprimento Vel: " + str(self.vetorDaVelocidade.magnitude()))
        #         print("Inclinacao: " + str(self.to_ret.elevacao))
        #         print("PID: " + str(self.controle_mag.computar_pid()))
        #
        return self.to_ret