Esempio n. 1
0
    def _thrust_monitor(self):

        # recalculate accumulated delta-v so far
        self.accumulated_delta_v = self._calculate_accumulated_delta_v()
        current_velocity = get_telemetry("orbitalVelocity")
        #print("Accumulated dV: {:.2f}".format(self.accumulated_delta_v))
        #print("dV required: {:.2f}".format(self.delta_v_required))
        #print("Velocity at start: {:.2f}".format(self.initial_speed))
        #print("Current Velocity: {:.2f}".format(current_velocity))
        #print("Expected dV at cutoff: {}".format(self.velocity_at_cutoff))


        if current_velocity > (self.velocity_at_cutoff - 13.5) and not self._is_thrust_reduced:
            utils.log("Throttling back to 10%", log_level="DEBUG")
            telemachus.set_throttle(10)
            self._is_thrust_reduced = True
            telemachus.disable_smartass()
            telemachus.send_command_to_ksp("command=f.sas")

        if current_velocity > (self.velocity_at_cutoff - 3.5):  # the 3.5 a hack otherwise it overshoots, FIXME!
            telemachus.cut_throttle()
            utils.log("Closing throttle, burn complete!", log_level="DEBUG")
            computer.dsky.current_verb.terminate()
            computer.execute_verb(verb="06", noun="14")
            computer.main_loop_table.remove(self._thrust_monitor)
            #computer.burn_complete()
            self.terminate()
            computer.go_to_poo()
Esempio n. 2
0
def get_telemetry(data, body_number=None):
    """ Contacts telemachus for the requested data.

    :param data: The API call required
    :type data: str | float
    :param body_number: Specify which body to obtain data for
    :type body_number: string
    :rtype: string
    """

    # if telemetry is None:
    #     raise TelemetryNotAvailable
    try:
        query_string = data + "=" + telemetry[data]
    except KeyError:
        raise KSPNotConnected
        return
    if body_number:
        query_string += "[{}]".format(body_number)

    try:
        raw_response = urllib.request.urlopen(config.URL + query_string)
    except urllib.error.URLError:
        utils.log("Query string: {}".format(query_string), log_level="ERROR")
        utils.log("Caught exception urllib2.URLERROR", log_level="ERROR")
        raise KSPNotConnected
    response_string = raw_response.read().decode("utf-8)")
    json_response = json.loads(response_string)
    return json_response[data]
Esempio n. 3
0
 def _accept_enable_engine(self, data):
     if data == "proceed":
         utils.log("Go for burn!", log_level="INFO")
     else:
         return
     computer.main_loop_table.append(self._fine_start_time_monitor)
     computer.execute_verb(verb="16", noun="40")
Esempio n. 4
0
 def handle_data_register_load():
     """ Handles data register loading
     :return: None
     """
     if keypress.isdigit() == False:
         utils.log(
             "Expecting a digit for data load, got {}".format(keypress),
             log_level="ERROR")
         return
     display_register = state["display_location_to_load"]
     if state["register_index"] == 0:
         if keypress == "+":
             dsky.set_register("+", display_register)
         elif keypress == "-":
             dsky.set_register("-", display_register)
         else:
             dsky.set_register("b", display_register)
         state["register_index"] += 1
     if 1 <= state["register_index"] <= 5:
         dsky.set_register(keypress,
                           display_register,
                           digit=state["register_index"])
         if state["register_index"] >= 5:
             state["register_index"] = 0
         else:
             state["register_index"] += 1
     state["input_data_buffer"] += keypress
Esempio n. 5
0
def get_telemetry(data, body_number=None):
    """ Contacts telemachus for the requested data.

    :param data: The API call required
    :type data: str | float
    :param body_number: Specify which body to obtain data for
    :type body_number: string
    :rtype: string
    """
    
    # if telemetry is None:
    #     raise TelemetryNotAvailable
    try:
        query_string = data + "=" + telemetry[data]
    except KeyError:
        raise KSPNotConnected
        return
    if body_number:
        query_string += "[{}]".format(body_number)

    try:
        raw_response = urllib.request.urlopen(config.URL + query_string)
    except urllib.error.URLError:
        utils.log("Query string: {}".format(query_string), log_level="ERROR")
        utils.log("Caught exception urllib2.URLERROR", log_level="ERROR")
        raise KSPNotConnected
    response_string = raw_response.read().decode("utf-8)")
    json_response = json.loads(response_string)
    return json_response[data]
Esempio n. 6
0
    def execute(self):

        """ Executes the program.
        :return: None
        """

        super().execute()
        utils.log("Program 11 executing", log_level="INFO")

        # test if KSP is connected
        if check_connection() == False:
            return

        # --> call average G integration with ΔV integration
        # self.computer.run_average_g_routine = True

        # --> terminate gyrocompassing
        if "02" in self.computer.running_programs:
            self.computer.programs["02"].terminate()

        # --> compute initial state vector
        # self.computer.routines["average_g"]()

        # --> Display on DSKY:
        # --> V06 N62 (we are going to use V16N62 though, so we can have a updated display
        # --> R1: Velocity
        # --> R2: Rate of change of vehicle altitude
        # --> R3: Vehicle altitude in km to nearest .1 km
        self.computer.execute_verb(verb="16", noun="62")
Esempio n. 7
0
    def _fine_start_time_monitor(self):

        self.time_until_ignition = self.calculate_time_to_ignition()
        if float(self.time_until_ignition) < 1.1:  # ADJUSTED FROM 0.1 to 1.1 to dry fix start delay of approx 1 second
            utils.log("Engine Ignition", log_level="INFO")
            self._begin_burn()
            computer.main_loop_table.remove(self._fine_start_time_monitor)
Esempio n. 8
0
    def execute(self):
        """ Executes the program.
        :return: None
        """

        super().execute()
        utils.log("Program 11 executing", log_level="INFO")

        # test if KSP is connected
        if check_connection() == False:
            return

        # --> call average G integration with ΔV integration
        # self.computer.run_average_g_routine = True

        # --> terminate gyrocompassing
        if "02" in self.computer.running_programs:
            self.computer.programs["02"].terminate()

        # --> compute initial state vector
        # self.computer.routines["average_g"]()

        # --> Display on DSKY:
        # --> V06 N62 (we are going to use V16N62 though, so we can have a updated display
        # --> R1: Velocity
        # --> R2: Rate of change of vehicle altitude
        # --> R3: Vehicle altitude in km to nearest .1 km
        self.computer.execute_verb(verb="16", noun="62")
Esempio n. 9
0
def send_command_to_ksp(command_string):

    try:
        urllib.request.urlopen(config.URL + command_string)
    except urllib.error.URLError:
        utils.log("Query string: {}".format(command_string), log_level="ERROR")
        utils.log("Caught exception urllib2.URLERROR", log_level="ERROR")
        raise KSPNotConnected
Esempio n. 10
0
def send_command_to_ksp(command_string):
    
    try:
        urllib.request.urlopen(config.URL + command_string)
    except urllib.error.URLError:
        utils.log("Query string: {}".format(command_string), log_level="ERROR")
        utils.log("Caught exception urllib2.URLERROR", log_level="ERROR")
        raise KSPNotConnected
Esempio n. 11
0
    def receive_data(self, data):

        """ Allows the verb to receive requested data from the DSKY.
        :param data: the data sent by DSKY
        """

        utils.log("{} received data: {}".format(self, data))
        self.data = data
        self.execute()
Esempio n. 12
0
 def on(self):
     '''
     Turns the IMU on
     :returns: True if successful, False otherwise
     '''
     if check_connection() == False:
         utils.log("Cannot connect to KSP", "WARNING")
     else:
         self.set_coarse_align()
Esempio n. 13
0
    def set_annunciator(self, name, set_to=True):

        try:
            if set_to:
                self.annunciators[name].on()
            else:
                self.annunciators[name].off()
        except KeyError:
            utils.log("You tried to change a annunciator that doesnt exist :(", "WARNING")
Esempio n. 14
0
    def stop_blink(self):

        """ 
        THIS METHOD IS DEPRECIATED. It is left in here to catch any other usages.

        Stops the verb/noun flash
        :return: None
        """
        utils.log(message="Called depreciated method stop_blink(). Please use verb_noun_flash_off()", log_level="ERROR")
Esempio n. 15
0
    def disable_direction_autopilot(self):

        """ Disables the directional autopilot
        :return: None
        """

        telemachus.disable_smartass()
        self.is_direction_autopilot_engaged = False
        utils.log("Autopilot disabled", log_level="INFO")
Esempio n. 16
0
 def on(self):
     '''
     Turns the IMU on
     :returns: True if successful, False otherwise
     '''
     if check_connection() == False:
         utils.log("Cannot connect to KSP", "WARNING")
     else:
         self.set_coarse_align()
Esempio n. 17
0
    def set_annunciator(self, name, set_to=True):

        try:
            if set_to:
                self.annunciators[name].on()
            else:
                self.annunciators[name].off()
        except KeyError:
            utils.log("You tried to change a annunciator that doesnt exist :(",
                      "WARNING")
Esempio n. 18
0
    def execute(self):

        """ Executes the program.
        :return: None
        """

        utils.log("Executing Program {}: {}".format(self.number, self.description))
        self.computer.flash_comp_acty(500)
        self.computer.dsky.set_register(self.number, "program")
        self.computer.running_program = self
Esempio n. 19
0
    def check_for_liftoff(self):
        if get_telemetry("verticalSpeed") > 1:
            utils.log("Liftoff discrete")
            Program.computer.remove_from_mainloop(self.check_for_liftoff)

            # Clear display
            for register in ["verb", "noun", "program", "data_1", "data_2", "data_3"]:
                Program.computer.dsky.blank_register(register)
            # pause for 1 second, then run P11
            self.timer.start(1000)
Esempio n. 20
0
    def execute(self):
        """ Executes the program.
        :return: None
        """

        utils.log("Executing Program {}: {}".format(self.number,
                                                    self.description))
        self.computer.flash_comp_acty(500)
        self.computer.dsky.set_register(self.number, "program")
        self.computer.running_program = self
Esempio n. 21
0
    def operator_error(self, message=None):

        """ Called when the astronaut has entered invalid keyboard input.
        :param message: Optional message to send to log
        :return: None
        """

        if message:
            utils.log("OPERATOR ERROR: " + message, log_level="ERROR")
        self.dsky.annunciators["opr_err"].blink_timer.start(500)
Esempio n. 22
0
    def stop_blink(self):
        """ 
        THIS METHOD IS DEPRECIATED. It is left in here to catch any other usages.

        Stops the verb/noun flash
        :return: None
        """
        utils.log(
            message=
            "Called depreciated method stop_blink(). Please use verb_noun_flash_off()",
            log_level="ERROR")
Esempio n. 23
0
    def _send_output(self):

        """ Sends the requested output to the DSKY """

        # check if the display update interval needs to be changed
        if self.timer.interval() != config.DISPLAY_UPDATE_INTERVAL:
            # stop and start the timer to change the update interval
            self.timer.stop()
            self.timer.start(config.DISPLAY_UPDATE_INTERVAL)

        if self.noun is None:
            self.noun = Verb.computer.keyboard_state["requested_noun"]
        if self.noun in self.illegal_nouns:
            raise NounNotAcceptableError
        noun_function = Verb.computer.nouns[self.noun]()
        try:
            data = noun_function.return_data()
        except nouns.NounNotImplementedError:
            self.computer.operator_error("Noun {} not implemented yet. Sorry about that...".format(self.noun))
            self.terminate()
            return
        except KSPNotConnected:
            utils.log("KSP not connected, terminating V{}".format(self.number),
                      log_level="ERROR")
            Verb.computer.program_alarm(110)
            self.terminate()
            raise
        except TelemetryNotAvailable:
            utils.log("Telemetry not available, terminating V{}".format(self.number),
                      log_level="ERROR")
            Verb.computer.program_alarm(111)
            self.terminate()
            raise
        if not data:
            # if the noun returns False, the noun *should* have already raised a program alarm, so we just need to
            # terminate and return
            self.terminate()
            return
        output = self._format_output_data(data)
        
        # set tooltips
        if not self.is_tooltips_set:
            Verb.computer.dsky.set_tooltip("data_1", data["tooltips"][0])
            Verb.computer.dsky.set_tooltip("data_2", data["tooltips"][1])
            Verb.computer.dsky.set_tooltip("data_3", data["tooltips"][2])

            self.is_tooltips_set = True

        # display data on DSKY registers
        Verb.computer.dsky.set_register(output[0], "data_1")
        Verb.computer.dsky.set_register(output[1], "data_2")
        Verb.computer.dsky.set_register(output[2], "data_3")

        Verb.computer.dsky.flash_comp_acty()
Esempio n. 24
0
    def check_for_liftoff(self):
        if get_telemetry("verticalSpeed") > 1:
            utils.log("Liftoff discrete")
            Program.computer.remove_from_mainloop(self.check_for_liftoff)

            # Clear display
            for register in [
                    "verb", "noun", "program", "data_1", "data_2", "data_3"
            ]:
                Program.computer.dsky.blank_register(register)
            # pause for 1 second, then run P11
            self.timer.start(1000)
Esempio n. 25
0
    def display(self, number_to_display):

        # cast to string (but should be a string already, so log it
        if not isinstance(number_to_display, str):
            utils.log("You should pass a string to be displayed bu GUI!")
            number_to_display = str(number_to_display)

        # only change image if we arn't flashing, it will be changed next flash
        if self.blink_data["is_blinking"] == False:
            image = self.digit_pixmaps[number_to_display]
            self.setPixmap(image)
        self.blink_data["blink_value"] = number_to_display
Esempio n. 26
0
    def program_restart(self, alarm_code, message=None):

        """ Triggers a program restart.
        :param alarm_code: a 3 or 4 digit octal int of the alarm code to raise
        :param message: optional message to print to log
        :return: None
        """

        # TODO: insert terminate and restart program
        utils.log("Program fresh start not implemented yet... watch this space...")
        if message:
            utils.log(message, log_level="ERROR")
Esempio n. 27
0
    def display(self, number_to_display):

        # cast to string (but should be a string already, so log it
        if not isinstance(number_to_display, str):
            utils.log("You should pass a string to be displayed bu GUI!")
            number_to_display = str(number_to_display)

        # only change image if we arn't flashing, it will be changed next flash
        if self.blink_data["is_blinking"] == False:
            image = self.digit_pixmaps[number_to_display]
            self.setPixmap(image)
        self.blink_data["blink_value"] = number_to_display
Esempio n. 28
0
 def set_coarse_align(self):
     '''
     Sets coarse align mode.
     :returns: None
     '''
     self.is_fine_aligned = False
     self.is_course_aligned = True
     self.computer.dsky.set_annunciator("no_att")
     if self.update_gyro_angles in self.computer.main_loop_table:
         self.computer.main_loop_table.remove(self.update_gyro_angles)
     if self.check_for_gimbal_lock in self.computer.main_loop_table:
         self.computer.main_loop_table.remove(self.check_for_gimbal_lock)
     utils.log("IMU coarse align set")
Esempio n. 29
0
    def computer_restart(self, alarm_code, message=None):

        """ Triggers a guidance computer hardware restart. The most severe of the errors!
        :param alarm_code: a 3 or 4 digit octal int of the alarm code to raise
        :param message: optional message to print to log
        :return: None
        """

        # insert computer reboot
        # self.fresh_start()
        if message:
            utils.log(message, log_level="CRITICAL")
        pass
Esempio n. 30
0
    def execute(self):

        """ Executes the verb
        :return:
        """

        if self.noun in self.illegal_nouns:
            raise NounNotAcceptableError
        utils.log("Executing Verb {}: {}".format(self.number, self.name))
        self.dsky.current_verb = self
        if self.noun:
            Verb.computer.dsky.set_register(self.noun, "noun")
            utils.log(" With noun {}".format(self.noun)) # JRI
Esempio n. 31
0
    def program_alarm(self, alarm_code):

        """ Sets the program alarm codes in memory and turns the PROG annunciator on.
        :param alarm_code: a 3 or 4 digit octal int of the alarm code to raise
        :return: None
        """
        utils.log("PROGRAM ALARM {}: {}".format(str(alarm_code), config.ALARM_CODES[alarm_code]), log_level="ERROR")
        alarm_code += 1000
        if self.alarm_codes[0] != 0:
            self.alarm_codes[1] = self.alarm_codes[0]
        self.alarm_codes[0] = alarm_code
        self.alarm_codes[2] = self.alarm_codes[0]
        self.dsky.annunciators["prog"].on()
Esempio n. 32
0
 def set_coarse_align(self):
     '''
     Sets coarse align mode.
     :returns: None
     '''
     self.is_fine_aligned = False
     self.is_course_aligned = True
     self.computer.dsky.set_annunciator("no_att")
     if self.update_gyro_angles in self.computer.main_loop_table:
         self.computer.main_loop_table.remove(self.update_gyro_angles)
     if self.check_for_gimbal_lock in self.computer.main_loop_table:
         self.computer.main_loop_table.remove(self.check_for_gimbal_lock)
     utils.log("IMU coarse align set")
Esempio n. 33
0
    def return_data(self):

        utils.log("Noun 09 requested")
        alarm_codes = computer.alarm_codes
        data = {
            1: str(alarm_codes[0]),
            2: str(alarm_codes[1]),
            3: str(alarm_codes[2]),
            "is_octal": True,
            "tooltips": [
                "First alarm code",
                "Second alarm code",
                "Last alarm code",
            ],
        }
        return data
Esempio n. 34
0
    def request_data(self, requesting_object, display_location, is_proceed_available=False):

        """ Requests data entry from the user.
        :param requesting_object: the object requesting the data
        :param display_location: the register that entered data will be displayed in
        :param is_proceed_available: True if the user can key in PROCEED instead of data
        :return: None
        """
        # if is_proceed_available is set True, don't blank display as it should be showing data to proceed with
        if not is_proceed_available:
            self.blank_register(display_location)
        utils.log("{}, method {}() requesting data".format(requesting_object.__self__, requesting_object.__name__))
        self.verb_noun_flash_on()
        self.computer.keyboard_state["object_requesting_data"] = requesting_object
        self.computer.keyboard_state["is_expecting_data"] = True
        self.computer.keyboard_state["display_location_to_load"] = display_location
Esempio n. 35
0
 def set_fine_align(self):
     '''
     Sets fine align mode.
     :returns: None
     '''
     # if no connection to KSP, stop fine align and go back to coarse align
     if check_connection() == False:
         utils.log("IMU: cannot complete fine align, no connection to KSP", log_level="ERROR")
         return
     self.is_fine_aligned = True
     self.is_course_aligned = False
     self.computer.dsky.set_annunciator("gimbal_lock", False)
     self.computer.dsky.set_annunciator("no_att", False)
     #self.computer.main_loop_table.append(self.update_gyro_angles)
     #self.computer.main_loop_table.append(self.check_for_gimbal_lock)
     utils.log("IMU fine align set")
Esempio n. 36
0
 def set_fine_align(self):
     '''
     Sets fine align mode.
     :returns: None
     '''
     # if no connection to KSP, stop fine align and go back to coarse align
     if check_connection() == False:
         utils.log("IMU: cannot complete fine align, no connection to KSP",
                   log_level="ERROR")
         return
     self.is_fine_aligned = True
     self.is_course_aligned = False
     self.computer.dsky.set_annunciator("gimbal_lock", False)
     self.computer.dsky.set_annunciator("no_att", False)
     #self.computer.main_loop_table.append(self.update_gyro_angles)
     #self.computer.main_loop_table.append(self.check_for_gimbal_lock)
     utils.log("IMU fine align set")
Esempio n. 37
0
    def terminate(self):

        """ Terminates the verb
        :return: None
        """

        utils.log("Terminating V{}".format(self.number))
        Verb.computer.dsky.stop_annunciator_blink("key_rel")
        Verb.computer.keyboard_state["display_lock"] = None
        Verb.computer.keyboard_state["backgrounded_update"] = None
        self.timer.stop()
        self.noun = None
        # self.activity_timer.Stop()
        # reset tooltips to ""
        Verb.computer.dsky.set_tooltip("data_1", "")
        Verb.computer.dsky.set_tooltip("data_2", "")
        Verb.computer.dsky.set_tooltip("data_3", "")
Esempio n. 38
0
    def poodoo_abort(self, alarm_code, message=None):

        """ Terminates the faulty program, and executes Program 00 (P00)
        :param alarm_code: a 3 digit octal int of the alarm code to raise
        :return: None
        """

        # alarm_message = config.ALARM_CODES[alarm_code]
        alarm_code += 2000
        if self.alarm_codes[0] != 0:
            self.alarm_codes[1] = self.alarm_codes[0]
        self.alarm_codes[0] = alarm_code
        self.alarm_codes[2] = self.alarm_codes[0]
        self.dsky.annunciators["prog"].on()
        self.running_program.terminate()
        utils.log("P00DOO ABORT {}: {}".format(str(alarm_code), message), log_level="ERROR")
        poo = self.programs["00"]()
        poo.execute()
Esempio n. 39
0
    def handle_expected_data():
        """ Handles expected data entry.
        :return: None
        """
        #set_trace()
        if keypress == "P":
            dsky.verb_noun_flash_off()
            utils.log("Proceeding without input, calling {}".format(
                str(state["object_requesting_data"])))
            state["object_requesting_data"]("proceed")
            state["input_data_buffer"] = ""
            state["is_expecting_data"] = False
            return

        # if we receive ENTER, the load is complete and we will call the
        # program or verb requesting the data load

        elif keypress == "E":
            input_data = state["input_data_buffer"]
            state["input_data_buffer"] = ""
            state["is_expecting_data"] = False
            dsky.verb_noun_flash_off()
            data_requester = state["object_requesting_data"]
            utils.log("Data load complete, calling {}({})".format(
                data_requester.__self__, data_requester.__name__))
            data_requester(input_data)

            return
        if state["display_location_to_load"] in ["verb", "noun", "program"]:
            handle_control_register_load()
        else:
            handle_data_register_load()

        # if the user as entered anything other than a numeric d,
        # trigger a OPR ERR and recycle program
        if keypress.isalpha():
            # if a program is running, recycle it
            # INSERT TRY HERE!!!
            # computer.get_state("running_program").terminate()
            # INSERT EXCEPT HERE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
            # if a verb is running, recycle it
            # computer.get_state("running_verb").terminate()
            computer.operator_error("Expecting numeric input")
            return
Esempio n. 40
0
    def execute(self):

        self.calculate()
        time_to_node = HohmannTransfer.get_time_to_node(self.phase_angle_difference(),
                                                                     self.orbital_period,
                                                                     self.departure_body_period)
        if time_to_node <= 120:
            utils.log("Time of ignition less that 2 minutes in the future, starting burn during next orbit")
            time_to_node += self.orbital_period
        self.calculate_burn_timings()
        self.first_burn = Burn(delta_v=self.delta_v_1,
                               direction="node",
                               time_of_ignition=self.time_of_ignition_first_burn,
                               time_of_node=self.time_of_node,
                               burn_duration=self.duration_of_burn,
                               )
        if config.current_log_level == "DEBUG":
            self.print_maneuver_data()
        computer.add_burn(self.first_burn)
Esempio n. 41
0
 def phase_angle_difference(self):
     #set_trace()
     current_phase_angle = get_telemetry("body_phaseAngle", body_number=self.target_id)
     phase_angle_difference = current_phase_angle - self.phase_angle_required
     #if phase_angle_difference < 0:
         #phase_angle_difference = 180 + abs(phase_angle_difference)
         #utils.log("Adding 180 degrees to phase angle difference")
     utils.log()
     utils.log("Current Phase Angle: {} degrees".format(current_phase_angle))
     utils.log("Phase Angle Required: {} degrees".format(self.phase_angle_required))
     utils.log("Phase Angle Difference: {} degrees".format(phase_angle_difference))
     return phase_angle_difference
Esempio n. 42
0
    def handle_expected_data():
    
        """ Handles expected data entry.
        :return: None
        """
        #set_trace()
        if keypress == "P":
            dsky.verb_noun_flash_off()
            utils.log("Proceeding without input, calling {}".format(str(state["object_requesting_data"])))
            state["object_requesting_data"]("proceed")
            state["input_data_buffer"] = ""
            state["is_expecting_data"] = False
            return
    
        # if we receive ENTER, the load is complete and we will call the
        # program or verb requesting the data load

        elif keypress == "E":
            input_data = state["input_data_buffer"]
            state["input_data_buffer"] = ""
            state["is_expecting_data"] = False
            dsky.verb_noun_flash_off()
            data_requester = state["object_requesting_data"]
            utils.log("Data load complete, calling {}({})".format(data_requester.__self__, data_requester.__name__))
            data_requester(input_data)
            
            return
        if state["display_location_to_load"] in ["verb", "noun", "program"]:
            handle_control_register_load()
        else:
            handle_data_register_load()
    
        # if the user as entered anything other than a numeric d,
        # trigger a OPR ERR and recycle program
        if keypress.isalpha():
            # if a program is running, recycle it
            # INSERT TRY HERE!!!
            # computer.get_state("running_program").terminate()
            # INSERT EXCEPT HERE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
            # if a verb is running, recycle it
            # computer.get_state("running_verb").terminate()
            computer.operator_error("Expecting numeric input")
            return
Esempio n. 43
0
 def execute(self):
     '''
     Executes the program
     :returns: None
     '''
     super().execute()
     # if TIG < 2 mins away, abort burn
     if utils.seconds_to_time(self.burn.time_until_ignition)["minutes"] < 2:
         self.computer.remove_burn()
         self.computer.poodoo_abort(226)
         return
     # if time to ignition if further than a hour away, display time to ignition
     if utils.seconds_to_time(self.burn.time_until_ignition)["hours"] > 0:
         utils.log("TIG > 1 hour away")
         self.computer.execute_verb(verb="16", noun="33")
         self.computer.main_loop_table.append(self._ten_minute_monitor)
     else:
         utils.log("TIG < 1 hour away, enabling burn")
         self.burn.execute()
Esempio n. 44
0
 def execute(self):
     '''
     Executes the program
     :returns: None
     '''
     super().execute()
     # if TIG < 2 mins away, abort burn
     if utils.seconds_to_time(self.burn.time_until_ignition)["minutes"] < 2:
         self.computer.remove_burn()
         self.computer.poodoo_abort(226)
         return
     # if time to ignition if further than a hour away, display time to ignition
     if utils.seconds_to_time(self.burn.time_until_ignition)["hours"] > 0:
         utils.log("TIG > 1 hour away")
         self.computer.execute_verb(verb="16", noun="33")
         self.computer.main_loop_table.append(self._ten_minute_monitor)
     else:
         utils.log("TIG < 1 hour away, enabling burn")
         self.burn.execute()
Esempio n. 45
0
 def request_data(self,
                  requesting_object,
                  display_location,
                  is_proceed_available=False):
     """ Requests data entry from the user.
     :param requesting_object: the object requesting the data
     :param display_location: the register that entered data will be displayed in
     :param is_proceed_available: True if the user can key in PROCEED instead of data
     :return: None
     """
     # if is_proceed_available is set True, don't blank display as it should be showing data to proceed with
     if not is_proceed_available:
         self.blank_register(display_location)
     utils.log("{}, method {}() requesting data".format(
         requesting_object.__self__, requesting_object.__name__))
     self.verb_noun_flash_on()
     self.computer.keyboard_state[
         "object_requesting_data"] = requesting_object
     self.computer.keyboard_state["is_expecting_data"] = True
     self.computer.keyboard_state[
         "display_location_to_load"] = display_location
Esempio n. 46
0
 def handle_data_register_load():
 
     """ Handles data register loading
     :return: None
     """
     if keypress.isdigit() == False:
         utils.log("Expecting a digit for data load, got {}".format(keypress), log_level="ERROR")
         return
     display_register = state["display_location_to_load"]
     if state["register_index"] == 0:
         if keypress == "+":
             dsky.set_register("+", display_register)
         elif keypress == "-":
             dsky.set_register("-", display_register)
         else:
             dsky.set_register("b", display_register)
         state["register_index"] += 1
     if 1 <= state["register_index"] <= 5:
         dsky.set_register(keypress, display_register, digit=state["register_index"])
         if state["register_index"] >= 5:
             state["register_index"] = 0
         else:
             state["register_index"] += 1
     state["input_data_buffer"] += keypress
Esempio n. 47
0
    def execute(self):

        """ Executes the verb.
        :return: None
        """

        if Verb.computer.keyboard_state["backgrounded_update"]:
            utils.log("Terminating backgrounded update")
            Verb.computer.keyboard_state["backgrounded_update"].terminate()
            Verb.computer.dsky.stop_annunciator_blink("key_rel")
        if Verb.computer.running_program:
            utils.log("Terminating active program {}".format(Verb.computer.running_program.number))
            Verb.computer.running_program.terminate()
        else:
            utils.log("V34 called, but nothing to terminate!")
Esempio n. 48
0
 def _enable_directional_autopilot(self):
     
     telemachus.set_mechjeb_smartass("node")
     utils.log("Directional autopilot enabled", log_level="INFO")
     return True
Esempio n. 49
0
def calc_burn_duration(initial_mass, thrust, specific_impulse, delta_v):
    '''
    Calculates the duration of a burn in seconds.
    :param initial_mass: initial mass of spacecraft
    :type initial_mass: float
    :param thrust: total thrust of the spacecraft
    :type thrust: float
    :param specific_impulse: Isp
    :type specific_impulse: int or float
    :param delta_v: delta_v for burn
    :type delta_v: float
    :returns: float time of burn in seconds
    '''
    exhaust_velocity = specific_impulse * 9.81
    burn_duration = (initial_mass * exhaust_velocity / thrust) * (1 - math.exp(-delta_v / exhaust_velocity))
    utils.log(log_level="info")
    utils.log("-" * 40, log_level="info")
    utils.log("Burn duration calculations:", log_level="info")
    utils.log("Initial mass: {} tonnes".format(initial_mass), log_level="info")
    utils.log("Thrust: {} kN".format(thrust), log_level="info")
    utils.log("Specific Impulse: {} seconds".format(specific_impulse), log_level="info")
    utils.log("Exhaust Velocity: {:.2f} kg/s".format(exhaust_velocity), log_level="info")
    utils.log("Burn Duration: {:.1f} seconds".format(burn_duration), log_level="info")
    utils.log("-" * 40, log_level="info")
    return burn_duration
Esempio n. 50
0
 def calculate_other_parameters(self):
     utils.log("Initial velocity at start of transfer: {:.2f} m/s".format(self.calculate_velocity_initial()))
     utils.log("Velocity on transfer orbit at initial orbit: {:.2f} m/s".format(self.calculate_velocity_initial_on_transfer_orbit()))
     utils.log("Velocity on transfer orbit at final orbit: {:.2f} m/s".format(self.calculate_velocity_final_on_transfer_orbit()))
     utils.log("Initial velocity change (delta-v): {:.2f} m/s".format(self.calculate_initial_delta_v()))
     utils.log("Final velocity change (delta-v): {:.2f} m/s".format(self.calculate_final_delta_v()))
     utils.log("Total chance in velocity (delta-v): {:.2f} m/s".format(self.calculate_total_delta_v()))
     utils.log()
Esempio n. 51
0
    def set_register(self, value, register, digit=None):
        '''
        Displays some data on a register.
        :param value: the value to display
        :type value: str
        :param register: the register to display it on
        :type register: str
        :param digit: if set, indicates that just one digit is to be set
        :type digit: str
        :returns: False if value checks fail, True if display set sucessfully
        '''

        # some sanity checks. If checks fail, return False
        # if digit is set, only should be one digit supplied
        if digit:
            if len(value) != 1:
                utils.log("You are trying to display a single digit, but got {} digits instead!".format(len(value)))
                return False
        # if register is a control register, should have either 1 or 2 values to display
        else:
            if register in ["verb", "noun", "program"]:
                if not 1 <= len(value) <= 2:
                    utils.log("You are trying to display a value in the {} register, expecting 1 or 2 digits, " \
                              "got {}".format(register, len(value)))
                    return False
            else:
                # otherwise, check for value being length 1 to 6
                if not 1 <= len(value) <= 6:
                    # set_trace()
                    utils.log("Must have between 1 and 6 values to display in data register, got {}".format(len(value)))
                    return False
                # also check that the first digit is either a "+", "-" or "b" (for blank)
                if value[0] not in ["+", "-", "b"]:
                    utils.log("First digit to display should be either +, -, or b, got {}".format(value[0]))
                    return False
        
        # setting control register
        if register in ["verb", "noun", "program"]:
            this_register = self.get_register(register)  # get the register we want to change
            if digit is not None:
                this_register[digit].display(value)
            else:
                for index in range(len(value)):
                    this_register[str(index + 1)].display(value[index])
            return True

        # setting data register
        else:
            display_map = {
                0: "sign",
                1: "1",
                2: "2",
                3: "3",
                4: "4",
                5: "5",
                }
            # data register 1
            if register == "data_1":
                this_register = self.registers["data"]["1"]  # get the register we want to change
                if digit:
                    this_register[str(digit)].display(value)
                else:
                    for index in range(len(value)):
                        digit_to_set = display_map[index]
                        value_to_set = value[index]
                        this_register[digit_to_set].display(value_to_set)
                        
            elif register == "data_2":
                this_register = self.registers["data"]["2"]  # get the register we want to change
                if digit:
                    this_register[str(digit)].display(value)
                else:
                    for index in range(len(value)):
                        digit_to_set = display_map[index]
                        value_to_set = value[index]
                        this_register[digit_to_set].display(value_to_set)
    
            elif register == "data_3":
                this_register = self.registers["data"]["3"]  # get the register we want to change
                if digit:
                    this_register[str(digit)].display(value)
                else:
                    for index in range(len(value)):
                        digit_to_set = display_map[index]
                        value_to_set = value[index]
                        this_register[digit_to_set].display(value_to_set)