Exemple #1
0
    def execute(self):

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

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

        # test if KSP is connected
        try:
            get_telemetry("universalTime")
        except KSPNotConnected:
            self.terminate()
            return

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

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

        # --> compute initial state vector
        # gc.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
        gc.execute_verb(verb="16", noun="62")
def delta_v(departure_altitude, destination_altitude, departure_body="Kerbin"):
    """
    Given a circular orbit at altitude departure_altitude and a target orbit at altitude
    destination_altitude, return the delta-V budget of the two burns required for a Hohmann
    transfer.

    departure_altitude and destination_altitude are in meters above the surface.
    returns a float of the burn delta-v required, positive means prograde, negative means retrograde

    :param departure_body:
    :param departure_altitude: departure orbit altitude
    :param destination_altitude: destination orbit altitude
    """

    departure_planet_radius = get_telemetry("body_radius", body_number=TELEMACHUS_BODY_IDS[departure_body])
    r1 = departure_altitude + departure_planet_radius
    r2 = destination_altitude + departure_planet_radius
    mu = float(get_telemetry("body_gravParameter", body_number=TELEMACHUS_BODY_IDS[departure_body]))
    sqrt_r1 = math.sqrt(r1)
    sqrt_r2 = math.sqrt(r2)
    sqrt_2_sum = math.sqrt(2 / (r1 + r2))
    sqrt_mu = math.sqrt(mu)
    delta_v_1 = sqrt_mu / sqrt_r1 * (sqrt_r2 * sqrt_2_sum - 1)
    delta_v_2 = sqrt_mu / sqrt_r2 * (1 - sqrt_r1 * sqrt_2_sum)
    return delta_v_1, delta_v_2
Exemple #3
0
    def _check_target(self):

        """Checks if a target exists, it not, returns the default target, else returns the selected target number
        Returns: octal target code
        :rtype: str

        """

        if get_telemetry("target_name") == u"No Target Selected.":
            utils.log("No target selected in KSP, defaulting to Mun", log_level="WARNING")
            return "Mun"
        else:
            return get_telemetry("target_name")
Exemple #4
0
    def _begin_burn(self):

        self.initial_speed = get_telemetry("orbitalVelocity")

        # start thrusting
        telemachus.set_throttle(100)
        gc.main_loop_table.append(self._thrust_monitor)
Exemple #5
0
    def check_paused_state(self):

        """ Checks the paused state of KSP, and illuminates STBY annunciator and logs state as necessary.
        :return: None
        """

        if self.is_ksp_connected:
            paused_state = get_telemetry("paused")
            # if the paused state hasn't changed, skip any annunciator changes
            if paused_state != self.ksp_paused_state:
                if paused_state == 0:
                    self.dsky.annunciators["stby"].off()
                    utils.log("KSP unpaused, all systems go", log_level="INFO")
                elif paused_state == 1:
                    self.dsky.annunciators["stby"].on()
                    utils.log("KSP paused", log_level="INFO")
                elif paused_state == 2:
                    self.dsky.annunciators["stby"].on()
                    utils.log("No power to Telemachus antenna", log_level="WARNING")
                elif paused_state == 3:
                    self.dsky.annunciators["stby"].on()
                    utils.log("Telemachus antenna off", log_level="WARNING")
                elif paused_state == 4:
                    self.dsky.annunciators["stby"].on()
                    utils.log("No Telemachus antenna found", log_level="WARNING")
                self.ksp_paused_state = paused_state
Exemple #6
0
    def calculate_time_to_ignition(self):

        """ Calculates the time to ignition in seconds
        :return: time to ignition in seconds
        :rtype : float
        """

        current_time = get_telemetry("missionTime")
        return self.time_of_ignition - current_time
Exemple #7
0
    def execute(self):

        """ Entry point for the program
        :return: None
        """

        super(Program15, self).execute()
        self.departure_body = get_telemetry("body")
        self.orbiting_body = get_telemetry("body")

        if not self._check_orbital_parameters():
            return
        self.target_name = self._check_target()
        gc.noun_data["30"] = config.OCTAL_BODY_IDS[self.target_name]

        gc.execute_verb(verb="01", noun="30")
        gc.dsky.request_data(requesting_object=self._accept_target_input, display_location=dsky.registers[1],
                             is_proceed_available=True)
Exemple #8
0
    def _check_orbital_parameters(self):

        """ Checks to see if current orbital parameters are within an acceptable range to plot maneuver
        :return: Bool
        """

        # check if orbit is circular
        if get_telemetry("eccentricity") > 0.001:
            gc.poodoo_abort(224)
            return False

        # check if orbit is excessively inclined
        target_inclination = float(get_telemetry("target_inclination"))
        vessel_inclination = get_telemetry("inclination")
        if (vessel_inclination > (target_inclination - 0.5)) and (vessel_inclination > (target_inclination + 0.5)):
            gc.poodoo_abort(225)
            return False
        else:
            return True
Exemple #9
0
 def recalculate_phase_angles(self):
 
     """ This function is to be placed in the GC main loop to recalculate maneuver parameters.
     :return: nothing
     """
 
     # update current phase angle
     telemachus_body_id = config.TELEMACHUS_BODY_IDS[config.OCTAL_BODY_NAMES[self.target_name]]
     current_phase_angle = get_telemetry("body_phaseAngle",
                                         body_number=telemachus_body_id)
 
     # recalculate phase angle difference
     phase_angle_difference = current_phase_angle - self.phase_angle_required
     if phase_angle_difference < 0:
         phase_angle_difference = 180 + abs(phase_angle_difference)
     self.delta_time_to_burn = phase_angle_difference / ((360 / self.orbital_period) - (360 /
                                                                                 self.departure_body_orbital_period))
     delta_time = utils.seconds_to_time(self.delta_time_to_burn)
     velocity_at_cutoff = get_telemetry("orbitalVelocity") + self.delta_v_first_burn
Exemple #10
0
    def terminate(self):

        """ Terminates the burn, disabling autopilot if running
        :return: None
        """
        self._disable_directional_autopilot()

        # if the throttle is open, close it
        if telemachus.get_telemetry("throttle") > 0:
            telemachus.cut_throttle()

        gc.remove_burn(self)
Exemple #11
0
 def _calculate_accumulated_delta_v(self):
     current_speed = get_telemetry("orbitalVelocity")
     return current_speed - self.initial_speed
Exemple #12
0
 def _calculate_velocity_at_cutoff(self):
     return get_telemetry("orbitalVelocity") + self.delta_v_required
Exemple #13
0
    def calculate_maneuver(self):

        """ Calculates the maneuver parameters and creates a Burn object
        :return: Nothing
        """

        # load target
        telemachus_target_id = config.TELEMACHUS_BODY_IDS[self.target_name]
        target_apoapsis = float(get_telemetry("body_ApA", body_number=telemachus_target_id))

        # set destination altitude
        self.destination_altitude = target_apoapsis + 500000
        # if target == "Mun":
        #     self.destination_altitude = 12750000

        # obtain parameters to calculate burn
        self.departure_altitude = get_telemetry("altitude")
        self.orbital_period = get_telemetry("period")
        self.departure_body_orbital_period = get_telemetry("body_period", body_number=config.TELEMACHUS_BODY_IDS[
            "Kerbin"])
        self.grav_param = get_telemetry("body_gravParameter", body_number=config.TELEMACHUS_BODY_IDS[
            self.orbiting_body])
        current_phase_angle = get_telemetry("body_phaseAngle", body_number=telemachus_target_id)

        # calculate the first and second burn Δv parameters
        self.delta_v_first_burn, gc.moi_burn_delta_v = hohmann_transfer.delta_v(self.departure_altitude,
                                                                                self.destination_altitude)
        print(gc.moi_burn_delta_v)

        # calculate the time to complete the Hohmann transfer
        self.time_to_transfer = hohmann_transfer.time_to_transfer(self.departure_altitude, self.destination_altitude,
                                                                  self.grav_param)

        # calculate the correct phase angle for the start of the burn
        # note that the burn impulse is calculated as a instantaneous burn, to be correct the burn should be halfway
        # complete at this calculated time

        self.phase_angle_required = hohmann_transfer.phase_angle(self.departure_altitude, self.destination_altitude,
                                                                 self.grav_param)

        # calculate the current difference in phase angle required and current phase angle
        self.phase_angle_difference = current_phase_angle - self.phase_angle_required
        # if self.phase_angle_difference < 0:
        #     self.phase_angle_difference = 180 + abs(self.phase_angle_difference)

        # calculate time of ignition (TIG)
        self.delta_time_to_burn = self.phase_angle_difference / ((360 / self.orbital_period) -
                                                                 (360 / self.departure_body_orbital_period))

        # if the time of ignition is less than 120 seconds in the future, schedule the burn for next orbit
        if self.delta_time_to_burn <= 120:
            utils.log("Time of ignition less that 2 minutes in the future, starting burn during next orbit")
            self.delta_time_to_burn += get_telemetry("period")

        # convert the raw value in seconds to HMS
        delta_time = utils.seconds_to_time(self.delta_time_to_burn)

        # log the maneuver calculations
        utils.log("P15 calculations:")
        utils.log("Phase angle required: {}, Δv for burn: {} m/s, time to transfer: {}".format(
            round(self.phase_angle_required, 2),
            int(self.delta_v_first_burn),
            utils.seconds_to_time(self.time_to_transfer)))
        utils.log("Current Phase Angle: {}, difference: {}".format(
            current_phase_angle,
            self.phase_angle_difference))
        utils.log("Time to burn: {} hours, {} minutes, {} seconds".format(
            int(delta_time["hours"]),
            int(delta_time["minutes"]),
            delta_time["seconds"]))

        # calculate the Δt from now of TIG for both burns
        self.time_of_ignition_first_burn = get_telemetry("missionTime") + self.delta_time_to_burn

        # create a Burn object for the outbound burn
        self.first_burn = Burn(delta_v=self.delta_v_first_burn,
                               direction="prograde",
                               time_of_ignition=self.time_of_ignition_first_burn,
                               calling_program=self)


        # load the Burn object into computer
        gc.add_burn_to_queue(self.first_burn, execute=False)

        # display burn parameters and go to poo
        gc.execute_verb(verb="06", noun="95")
        gc.go_to_poo()