Exemplo n.º 1
0
def rise_set_yydoy(df_tle: pd.DataFrame, yydoy: str, dir_tle: str, logger: logging.Logger) -> pd.DataFrame:
    """
    rise_set_yydoy calculates the rise/set times for GNSS PRNs
    """
    cFuncName = colored(os.path.basename(__file__), 'yellow') + ' - ' + colored(sys._getframe().f_code.co_name, 'green')

    # get the datetime that corresponds to yydoy
    date_yydoy = datetime.strptime(yydoy, '%y%j')
    logger.info('{func:s}: calculating rise / set times for {date:s} ({yy:s}/{doy:s})'.format(date=colored(date_yydoy.strftime('%d-%m-%Y'), 'green'), yy=yydoy[:2], doy=yydoy[2:], func=cFuncName))

    # load a time scale and set RMA as Topo
    # loader = sf.Loader(dir_tle, expire=True)  # loads the needed data files into the tle dir
    ts = sf.load.timescale()
    RMA = sf.Topos('50.8438 N', '4.3928 E')
    logger.info('{func:s}: Earth station RMA = {topo!s}'.format(topo=colored(RMA, 'green'), func=cFuncName))

    t0 = ts.utc(int(date_yydoy.strftime('%Y')), int(date_yydoy.strftime('%m')), int(date_yydoy.strftime('%d')))
    date_tomorrow = date_yydoy + timedelta(days=1)
    t1 = ts.utc(int(date_tomorrow.strftime('%Y')), int(date_tomorrow.strftime('%m')), int(date_tomorrow.strftime('%d')))

    # go over the PRN / NORADs that have TLE corresponding to the requested date
    for row, prn in enumerate(df_tle['PRN']):
        logger.info('{func:s}:   for NORAD {norad:s} ({prn:s})'.format(norad=colored(df_tle['NORAD'][row], 'green'), prn=colored(prn, 'green'), func=cFuncName))
        # create a EarthSatellites from the TLE lines for this PRN
        gnss_sv = EarthSatellite(df_tle['TLE1'][row], df_tle['TLE2'][row])
        logger.info('{func:s}:       created earth satellites {sat!s}'.format(sat=colored(gnss_sv, 'green'), func=cFuncName))

        t, events = gnss_sv.find_events(RMA, t0, t1, altitude_degrees=5.0)

        for ti, event in zip(t, events):
            name = ('rise above 5d', 'culminate', 'set below 5d')[event]
            logger.info('{func:s}:         {jpl!s} -- {name!s}'.format(jpl=ti.utc_jpl(), name=name, func=cFuncName))
Exemplo n.º 2
0
class SatTracker:
    """Satellite tracker for observer."""
    def __init__(self, lat, lon, norad_id=None, horizon=10.0):
        self.eph = skyfield_load("de421.bsp")
        self.timescale = skyfield_load.timescale()
        self.horizon = horizon
        tle = get_tle(norad_id)
        self.observer = Topos(latitude_degrees=lat, longitude_degrees=lon)
        self.satellite = EarthSatellite(tle[1], tle[2], tle[0], self.timescale)

    def next_passes(self, days=7, visible_only=False):
        passes = []
        now = self.timescale.now()

        t0, t1 = now, self.timescale.utc(now.utc_datetime() +
                                         timedelta(days=days))

        # Find satellite events for observer
        times, events = self.satellite.find_events(
            self.observer, t0, t1, altitude_degrees=self.horizon)

        # Each pass is composed by 3 events (rise, culmination, set)
        # Start arrays on next first pass
        offset = len(events) % 3
        times = times[offset:]
        events = events[offset:]

        # Loop for each pass (3 events)
        for pass_times, pass_events in zip(chunked(times, 3),
                                           chunked(events, 3)):
            full_pass = self.serialize_pass(pass_times, pass_events)
            full_pass["visible"] = any(event["visible"]
                                       for event in full_pass.values())
            passes.append(full_pass)

        # Filter visible ones
        if visible_only:
            passes = [p for p in passes if p["visible"]]

        return passes

    def serialize_pass(self, pass_times, pass_events):
        full_pass = {}
        observer_barycenter = self.eph["earth"] + self.observer

        for time, event_type in zip(pass_times, pass_events):
            geometric_sat = (self.satellite - self.observer).at(time)
            geometric_sun = (self.eph["sun"] - observer_barycenter).at(time)

            sat_alt, sat_az, sat_d = geometric_sat.altaz()
            sun_alt, sun_az, sun_d = geometric_sun.altaz()

            is_sunlit = geometric_sat.is_sunlit(self.eph)
            event = ('rise', 'culmination', 'set')[event_type]

            full_pass[event] = {
                "alt": f"{sat_alt.degrees:.2f}",
                "az": f"{sat_az.degrees:.2f}",
                "az_octant": az_to_octant(sat_az.degrees),
                "utc_datetime": str(time.utc_datetime()),
                "utc_timestamp": int(time.utc_datetime().timestamp()),
                "is_sunlit": bool(is_sunlit),
                "visible": -18 <= int(sun_alt.degrees) <= -6
                and bool(is_sunlit)
            }

        return full_pass
Exemplo n.º 3
0
from skyfield.api import EarthSatellite, Topos, load
import math
import numpy

ts = load.timescale(builtin=True)

satname = "USA 224"
line1 = "1 37348U 11002A   20053.50800700  .00010600  00000-0  95354-4 0    09"
line2 = "2 37348  97.9000 166.7120 0540467 271.5258 235.8003 14.76330431    04"
satellite = EarthSatellite(line1, line2, satname, ts)

st = ts.utc(2020, 4, 22, 0, 0, 0)
et = ts.utc(2020, 4, 24, 0, 0, 0)

#visibility intervals
target = Topos('35.234722 N', '53.920833 E')
t, events = satellite.find_events(target, st, et, altitude_degrees=0.0)
print("Target visibility intervals")
for ti, event in zip(t, events):
    name = ('rise', 'culminate', 'set')[event]
    print(ti.utc_jpl(), name)

#downlink intervals
gs = Topos('64.977488 N', '147.510697 W')
t, events = satellite.find_events(gs, st, et, altitude_degrees=5.0)
print("Ground station passes")
for ti, event in zip(t, events):
    name = ('rise', 'culminate', 'set')[event]
    print(ti.utc_jpl(), name)
Exemplo n.º 4
0
def tle_rise_set_times(prn: int, df_tle: pd.DataFrame, marker: sf.Topos, t0: sf.Time, t1: sf.Time, elev_min: int, obs_int: float, logger: logging.Logger) -> Tuple[list, list, list, list]:
    """
    tle_rise_set_info calculates for a PRN based on TLEs the rise and set times and theoreticlal number of observations.
    """
    cFuncName = colored(os.path.basename(__file__), 'yellow') + ' - ' + colored(sys._getframe().f_code.co_name, 'green')

    # create the to be returned lists
    dt_tle_rise = []
    dt_tle_set = []
    dt_tle_cul = []
    tle_arc_count = []

    # check with the TLEs what the theoretical rise / set times should be
    try:
        row = df_tle.index[df_tle['PRN'] == prn].tolist()[0]

        logger.info('{func:s}:    for NORAD {norad:s} ({prn:s})'.format(norad=colored(df_tle['NORAD'][row], 'green'), prn=colored(prn, 'green'), func=cFuncName))

        # create a EarthSatellites from the TLE lines for this PRN
        gnss_sv = EarthSatellite(df_tle['TLE1'][row], df_tle['TLE2'][row])
        logger.info('{func:s}:       created earth satellite {sat!s}'.format(sat=colored(gnss_sv, 'green'), func=cFuncName))

        # find rise:set/cul times
        t, events = gnss_sv.find_events(marker, t0, t1, altitude_degrees=elev_min)

        # create a list for setting for each rise-culminate-set sequence the datetime values
        tle_events = [t0.utc_datetime(), np.NaN, t1.utc_datetime()]
        event_latest = -1

        # event: 0=RISE, 1=Culminate, 2=SET
        for i, (ti, event) in enumerate(zip(t, events)):
            tle_events[event] = ti.utc_datetime()
            event_latest = event

            if event == 2:  # PRN below cutoff
                dt_tle_rise.append(tle_events[0].time().replace(microsecond=0))
                dt_tle_set.append(tle_events[2].time().replace(microsecond=0))
                if isinstance(tle_events[1], float):
                    dt_tle_cul.append(np.NaN)
                else:
                    dt_tle_cul.append(tle_events[1].time().replace(microsecond=0))

                tle_events = [t0.utc_datetime(), np.NaN, t1.utc_datetime()]

        # add the final events detected
        if event_latest != 2:
            dt_tle_rise.append(tle_events[0].time().replace(microsecond=0))
            dt_tle_set.append(tle_events[2].time().replace(microsecond=0))
            if isinstance(tle_events[1], float):
                dt_tle_cul.append(np.NaN)
            else:
                dt_tle_cul.append(tle_events[1].time().replace(microsecond=0))

        # check whether a set time is "00:00:00" and change to "23:59:59"
        midnight = time(hour=0, minute=0, second=0, microsecond=0)
        for i, tle_set in enumerate(dt_tle_set):
            if tle_set == midnight:
                dt_tle_set[i] = time(hour=23, minute=59, second=59, microsecond=0)

        for tle_rise, tle_set in zip(dt_tle_rise, dt_tle_set):
            print('type tle_rise {!s}'.format(type(tle_rise)))
            rise_sec = int(timedelta(hours=tle_rise.hour, minutes=tle_rise.minute, seconds=tle_rise.second).total_seconds())
            set_sec = int(timedelta(hours=tle_set.hour, minutes=tle_set.minute, seconds=tle_set.second).total_seconds())
            tle_arc_count.append((set_sec - rise_sec) / obs_int)

        # inform the user
        logger.info('{func:s}:       TLE based times for {prn:s}'.format(prn=colored(prn, 'green'), func=cFuncName))
        for i, (stdt, culdt, enddt) in enumerate(zip(dt_tle_rise, dt_tle_cul, dt_tle_set)):
            if isinstance(culdt, float):
                str_culdt = 'N/A'
            else:
                str_culdt = culdt.strftime('%H:%M:%S')
            logger.info('{func:s}:          arc[{nr:d}]: {stdt:s} -> {culdt:s} -> {enddt:s}'.format(nr=i, stdt=colored(stdt.strftime('%H:%M:%S'), 'yellow'), culdt=colored(str_culdt, 'yellow'), enddt=colored(enddt.strftime('%H:%M:%S'), 'yellow'), func=cFuncName))

    except IndexError:
        logger.info('{func:s}: No NARAD TLE file present for {prn:s}'.format(prn=colored(prn, 'red'), func=cFuncName))

    return dt_tle_rise, dt_tle_set, dt_tle_cul, tle_arc_count
Exemplo n.º 5
0
from spacetrack import SpaceTrackClient
from skyfield.api import EarthSatellite, Topos, load
from .stconfig.auth import USR, PASS


if __name__ == "__main__":
    st = SpaceTrackClient(USR, PASS)
    tlelines = [st.tle_latest(norad_cat_id=45438)[0]["TLE_LINE1"], st.tle_latest(norad_cat_id=45438)[0]["TLE_LINE2"]]


    bcn = Topos(41.414850, 2.165036)
    ts = load.timescale()
    t0 = ts.utc(2020,12,23)
    t1 = ts.utc(2020,12,30)
    satellite = EarthSatellite(*tlelines, "STARKLINK-61", ts)
    t, events = satellite.find_events(bcn, t0, t1, altitude_degrees=30.0)

    for ti, event in zip(t, events):
        name = ('aos @ 30°', 'culminate', 'los @ < 30°')[event]
        if (ti.utc.hour >18 ):#and (event == 0):
            print(ti.utc_strftime('%Y %b %d %H:%M:%S'), name)
            difference = satellite - bcn
            topocentric = difference.at(ti)
            alt, az, distance = topocentric.altaz()
            print(" ",alt)
            print(" ",az)
            print(" ",int(distance.km), 'km')

Exemplo n.º 6
0
def get_all_passes(tle: [str],
                   lat_deg: float,
                   long_deg: float,
                   start_datetime_utc: datetime,
                   end_datetime_utc: datetime,
                   approved_passes: [OrbitalPass] = None,
                   elev_m: float = 0.0,
                   horizon_deg: float = 0.0,
                   min_duration_s: int = 0) -> [OrbitalPass]:
    """
    Get a list of all passes for a satellite and location for a time span.

    Wrapper for Skyfield TLE ground station pass functions that produces an
    OrbitalPass object list of possible passes.

    Parameters
    ----------
    tle : [str]
        Can be [tle_line1, tle_line2] or [tle_header, tle_line1, tle_line2]
    lat_deg : float
        latitude of ground station in degrees
    long_deg : float
        longitude of ground station in degrees
    start_datetime_utc : datetime
        The start datetime wanted.
    end_datetime_utc : datetime
        The end datetime wanted.
    approved_passes : [OrbitalPass]
        A list of OrbitalPass objects for existing approved passes.
    elev_m : float
        elevation of ground station in meters
    horizon_deg : float
        Minimum horizon degrees
    min_duration_s : int
        Minimum duration wanted

    Raises
    ------
    ValueError
        If the tle list is incorrect.

    Returns
    -------
    [OrbitalPass]
        A list of OrbitalPass.
    """

    pass_list = []

    load = Loader('/tmp', verbose=False)
    ts = load.timescale()
    t0 = ts.utc(start_datetime_utc.replace(tzinfo=timezone.utc))
    t1 = ts.utc(end_datetime_utc.replace(tzinfo=timezone.utc))

    # make topocentric object
    loc = Topos(lat_deg, long_deg, elev_m)
    loc = Topos(latitude_degrees=lat_deg,
                longitude_degrees=long_deg,
                elevation_m=elev_m)

    # make satellite object from TLE
    if len(tle) == 2:
        satellite = EarthSatellite(tle[0], tle[1], "", ts)
    elif len(tle) == 3:
        satellite = EarthSatellite(tle[1], tle[2], tle[0], ts)
    else:
        raise ValueError("Invalid tle string list\n")

    # find all events
    t, events = satellite.find_events(loc, t0, t1, horizon_deg)

    # make a list of datetimes for passes
    for x in range(0, len(events)-3, 3):
        aos_utc = t[x].utc_datetime()
        los_utc = t[x+2].utc_datetime()
        duration_s = (los_utc - aos_utc).total_seconds()

        if duration_s > min_duration_s:

            new_pass = OrbitalPass(gs_latitude_deg=lat_deg,
                                   gs_longitude_deg=long_deg,
                                   aos_utc=aos_utc.replace(tzinfo=None),
                                   los_utc=los_utc.replace(tzinfo=None),
                                   gs_elevation_m=elev_m,
                                   horizon_deg=horizon_deg)

            if not pass_overlap(new_pass, approved_passes):
                pass_list.append(new_pass)  # add pass to list
    return pass_list
class Satellite:
    def __init__(self, tle_1, tle_2, gs_lat, gs_long, target_lat, target_long,
                 T0, duration):
        self.current_mode = "data_downlink"
        self.possible_modes = [
            "sun_point", "imaging", "data_downlink", "wheel_desaturate"
        ]
        self.telemetry = {
            "batt": {
                "percent": 80,
                "temp": 25
            },
            "panels": {
                "illuminated": True
            },
            "comms": {
                "pwr": False,
                "temp": 25
            },
            "obc": {
                "disk": 0,
                "temp": 25
            },
            "adcs": {
                "mode": None,
                "temp": 25,
                "whl_rpm": [0, 0, 0],
                "mag_pwr": [False, False, False]
            },
            "cam": {
                "pwr": False,
                "temp": 25
            }
        }
        self.collected_data = 0
        self.start_time = datetime(T0[0], T0[1], T0[2], tzinfo=timezone.utc)
        self.end_time = self.start_time + timedelta(hours=duration)
        self.duration = duration

        self.ts = load.timescale()
        self.groundstation = Topos(gs_lat, gs_long)
        self.target = Topos(target_lat, target_long)
        self.satellite = EarthSatellite(tle_1, tle_2)
        self.ephemeris = load('de421.bsp')

        # Calculate groundstation passes in the time window
        gs_min_alt_degrees = 5.0
        gs_t, gs_events = self.satellite.find_events(
            self.groundstation,
            self.ts.utc(self.start_time),
            self.ts.utc(self.end_time),
            altitude_degrees=gs_min_alt_degrees)
        if len(gs_events) == 0:
            raise (ValueError(
                "No ground station passes in the given time window."))

        gs_sunlit = self._satellite_sunlit(times=gs_t)
        # print("\nExpected Ground Station Passses\n##############")
        aos = []
        los = []
        for ti, event, is_sunlit in zip(gs_t, gs_events, gs_sunlit):
            name = (f'rise above {gs_min_alt_degrees}°', 'culminate',
                    f'set below {gs_min_alt_degrees}°')[event]
            # print(ti.utc_datetime().strftime("%Y-%m-%dT%H:%M:%SZ"),
            #       name, "Satellite Illuminated:", is_sunlit)
            if event == 0:
                aos.append(ti)
            elif event == 2:
                los.append(ti)

        self.gs_passes = []
        for aos_t in aos:
            for los_t in los:
                if los_t.utc_datetime() > aos_t.utc_datetime():
                    self.gs_passes.append([aos_t, los_t])
                    break

        # Calculate target passes in the time window
        target_min_alt_degrees = 5.0
        target_t, target_events = self.satellite.find_events(
            self.target,
            self.ts.utc(self.start_time),
            self.ts.utc(self.end_time),
            altitude_degrees=target_min_alt_degrees)
        if len(target_events) == 0:
            raise (ValueError("No target passes in the given time window."))

        # print("\nExpected Target Passses\n##############")
        target_aos = []
        target_los = []
        for ti, event in zip(target_t, target_events):
            name = (f'rise above {target_min_alt_degrees}°', 'culminate',
                    f'set below {target_min_alt_degrees}°')[event]

            # print(ti.utc_datetime().strftime("%Y-%m-%dT%H:%M:%SZ"),
            #       name, "Target Illuminated:", self._location_sunlit(ti, self.target))
            if event == 0:
                target_aos.append(ti)
            elif event == 2:
                target_los.append(ti)

        self.target_passes = []
        for aos_t in target_aos:
            for los_t in target_los:
                if los_t.utc_datetime() > aos_t.utc_datetime():
                    self.target_passes.append([aos_t, los_t])
                    break

    def execute_mission_plan(self, mission_plan):
        tlm_plottable = {
            "batt": {
                "percent": [],
                "temp": []
            },
            "panels": {
                "illuminated": []
            },
            "comms": {
                "pwr": [],
                "temp": []
            },
            "obc": {
                "disk": [],
                "temp": []
            },
            "adcs": {
                "mode": [],
                "temp": [],
                "whl_rpm": [],
                "mag_pwr": []
            },
            "cam": {
                "pwr": [],
                "temp": []
            }
        }
        print("Executing mission plan.")
        time.sleep(1)

        # Construct iterator
        step_minutes = np.arange(0, self.duration * 60, 1.0)
        times = []
        for idx, step in enumerate(step_minutes):
            times.append(self.start_time + timedelta(minutes=step))

        # Calculate sunlit times
        sunlit = self._satellite_sunlit(times=self.ts.utc(times))

        # Begin simulation
        for idx, current_time in enumerate(times):
            print(current_time.strftime("%Y-%m-%dT%H:%M:%SZ"))
            for entry in mission_plan:
                if current_time == entry[0]:
                    self._mode_change(new_mode=entry[1],
                                      current_time=current_time)

            self._update_tlm(sunlit=sunlit[idx])
            self._check_pass_validity(current_time=current_time)
            errors = self._check_telemetry()
            for subsystem in self.telemetry:
                for item in self.telemetry[subsystem]:
                    tlm_plottable[subsystem][item].append(
                        self.telemetry[subsystem][item])
            if errors != []:
                raise (MissionFailure(errors))
            time.sleep(0.005)

        if self.collected_data >= REQUIRED_DATA:
            # from matplotlib import pyplot as plt
            # plt.title('Temperatures')
            # plt.plot(times, tlm_plottable["batt"]["temp"], label="batt")
            # plt.plot(times, tlm_plottable["comms"]["temp"], label="comms")
            # plt.plot(times, tlm_plottable["obc"]["temp"], label="obs")
            # plt.plot(times, tlm_plottable["adcs"]["temp"], label="adcs")
            # plt.plot(times, tlm_plottable["cam"]["temp"], label="cam")
            # plt.title('Wheel Speeds')
            # plt.plot(times, tlm_plottable["adcs"]["whl_rpm"])
            # plt.title('Percentages')
            # plt.plot(times, tlm_plottable["batt"]["percent"], label="batt %")
            # plt.plot(times, tlm_plottable["obc"]["disk"], label="obc disk")
            # plt.legend()
            # plt.show()

            return True
        else:
            raise (
                MissionFailure("Data was not obtained within the time limit."))

    def _update_tlm(self, sunlit):
        # Updates all the tlm based on current mode
        self.telemetry["panels"]["illuminated"] = sunlit

        # sun_point
        if self.current_mode == "sun_point":

            # batt
            if sunlit:
                if self.telemetry["batt"]["percent"] < 100:
                    if (100 - self.telemetry["batt"]["percent"]) < 0.6:
                        self.telemetry["batt"]["percent"] = 100
                    else:
                        self.telemetry["batt"]["percent"] += 0.6
                self._change_all_temps(step=0.1, upper=30)
            else:
                self._change_all_temps(step=-0.1)

            # comms
            self.telemetry["comms"]["pwr"] = False
            if self.telemetry["comms"]["temp"] > 25:
                self.telemetry["comms"]["temp"] += -0.2

            # cam
            self.telemetry["cam"]["pwr"] = False
            if self.telemetry["cam"]["temp"] > 25:
                self.telemetry["cam"]["temp"] += -0.2

            # adcs
            self.telemetry["adcs"]["mode"] = "track_sun"
            self.telemetry["adcs"]["mag_pwr"] = [False, False, False]
            self._change_wheel_speeds(step=10)
            self.telemetry["batt"]["percent"] += -.1

            # none for obc
        elif self.current_mode == "imaging":
            # batt
            if sunlit:
                self._change_all_temps(step=0.2)
            else:
                self._change_all_temps(step=-0.1)

            # comms
            self.telemetry["comms"]["pwr"] = False
            if self.telemetry["comms"]["temp"] > 25:
                self.telemetry["comms"]["temp"] += -0.2

            # cam
            self.telemetry["cam"]["pwr"] = True
            self.telemetry["batt"]["percent"] += -8
            self.telemetry["cam"]["temp"] += 5
            self.telemetry["batt"]["temp"] += 1

            # adcs
            self.telemetry["adcs"]["mode"] = "target_track"
            self.telemetry["adcs"]["mag_pwr"] = [False, False, False]
            self._change_wheel_speeds(step=50)
            self.telemetry["batt"]["percent"] += -.1

            # obc
            self.telemetry["obc"]["disk"] += 10

        elif self.current_mode == "data_downlink":
            # batt
            if sunlit:
                self._change_all_temps(step=0.2)
            else:
                self._change_all_temps(step=-0.1)

            # comms
            self.telemetry["comms"]["pwr"] = True
            self.telemetry["batt"]["percent"] += -10
            self.telemetry["comms"]["temp"] += 7
            self.telemetry["batt"]["temp"] += 1

            # cam
            self.telemetry["cam"]["pwr"] = False
            if self.telemetry["cam"]["temp"] > 25:
                self.telemetry["cam"]["temp"] += -0.2

            # adcs
            self.telemetry["adcs"]["mode"] = "target_track"
            self.telemetry["adcs"]["mag_pwr"] = [False, False, False]
            self._change_wheel_speeds(step=50)
            self.telemetry["batt"]["percent"] += -.1

            # obc and data collection
            if self.telemetry["obc"]["disk"] <= 20:
                self.collected_data += self.telemetry["obc"][
                    "disk"] / 100 * OBC_DISK_SIZE
                self.telemetry["obc"]["disk"] = 0
            else:
                self.telemetry["obc"]["disk"] += -20
                self.collected_data += 20 / 100 * OBC_DISK_SIZE

        elif self.current_mode == "wheel_desaturate":
            # batt
            if sunlit:
                self._change_all_temps(step=0.2)
            else:
                self._change_all_temps(step=-0.1)

            # comms
            self.telemetry["comms"]["pwr"] = False

            # cam
            self.telemetry["cam"]["pwr"] = False

            # adcs
            self.telemetry["adcs"]["mode"] = "desaturate"
            self.telemetry["adcs"]["mag_pwr"] = [True, True, True]
            self._change_wheel_speeds(step=-100)
            self.telemetry["batt"]["percent"] += -.2

            # none for obc

        print(self.telemetry)
        print(f"Collected Data: {self.collected_data} bytes")

    def _mode_change(self, new_mode, current_time):
        if self.current_mode == new_mode:
            raise (ValueError(f"Already in '{new_mode}'"))
        elif new_mode not in self.possible_modes:
            raise (ValueError(f"Mode must be one of: {self.possible_modes}"))

        print(f"Changing mode to: {new_mode}")
        self.current_mode = new_mode

    def _check_pass_validity(self, current_time):
        valid_pass = False
        if self.current_mode == "imaging":
            for target_pass in self.target_passes:
                if target_pass[0].utc_datetime(
                ) < current_time and target_pass[1].utc_datetime(
                ) > current_time:
                    valid_pass = True
            if not valid_pass:
                raise (
                    MissionFailure("ERROR: Target not in view. Cannot image."))
            if not self._location_sunlit(time=self.ts.utc(current_time),
                                         location=self.target):
                raise (MissionFailure(
                    "ERROR: Target location is not sunlit. Cannot image."))

        elif self.current_mode == "data_downlink":
            for gs_pass in self.gs_passes:
                if gs_pass[0].utc_datetime(
                ) < current_time and gs_pass[1].utc_datetime() > current_time:
                    valid_pass = True
            if not valid_pass:
                raise (MissionFailure(
                    "ERROR: Ground station not in view. Cannot downlink data.")
                       )

    def _satellite_sunlit(self, times):
        # Calculate eclipse times for passes
        Re = 6378.137
        earth = self.ephemeris['earth']
        sun = self.ephemeris['sun']
        sat = earth + self.satellite
        sunpos, earthpos, satpos = [
            thing.at(times).position.km for thing in (sun, earth, sat)
        ]
        sunearth, sunsat = earthpos - sunpos, satpos - sunpos
        sunearthnorm, sunsatnorm = [
            vec / np.sqrt((vec**2).sum(axis=0)) for vec in (sunearth, sunsat)
        ]
        angle = np.arccos((sunearthnorm * sunsatnorm).sum(axis=0))
        sunearthdistance = np.sqrt((sunearth**2).sum(axis=0))
        sunsatdistance = np.sqrt((sunsat**2).sum(axis=0))
        limbangle = np.arctan2(Re, sunearthdistance)
        sunlit = []
        for idx, value in enumerate(angle):
            sunlit.append(((angle[idx] > limbangle[idx])
                           or (sunsatdistance[idx] < sunearthdistance[idx])))
        return sunlit

    def _location_sunlit(self, time, location):
        """
        Returns a function that tells you if the sun is shining at a given
        time in a given location.
        """
        func = almanac.sunrise_sunset(self.ephemeris, self.target)
        return func(time)

    def _change_all_temps(self, step, upper=None, lower=None):
        for subsystem in self.telemetry:
            for field in self.telemetry[subsystem]:
                if field == "temp":
                    if upper:
                        if self.telemetry[subsystem][field] < upper:
                            self.telemetry[subsystem][field] += step
                    elif lower:
                        if self.telemetry[subsystem][field] > lower:
                            self.telemetry[subsystem][field] += step
                    else:
                        self.telemetry[subsystem][field] += step

    def _change_wheel_speeds(self, step):
        x = randint(1, 100)
        y = randint(1, 100)
        z = randint(1, 100)
        total = x + y + z
        x = x / total * step
        y = y / total * step
        z = z / total * step
        if step < 0:
            if self.telemetry["adcs"]["whl_rpm"][0] <= abs(x):
                self.telemetry["adcs"]["whl_rpm"][0] = 0
                x = 0
            if self.telemetry["adcs"]["whl_rpm"][1] <= abs(y):
                self.telemetry["adcs"]["whl_rpm"][1] = 0
                y = 0
            if self.telemetry["adcs"]["whl_rpm"][2] <= abs(z):
                self.telemetry["adcs"]["whl_rpm"][2] = 0
                z = 0

        self.telemetry["adcs"]["whl_rpm"] = [
            self.telemetry["adcs"]["whl_rpm"][0] + x,
            self.telemetry["adcs"]["whl_rpm"][1] + y,
            self.telemetry["adcs"]["whl_rpm"][2] + z
        ]

    def _check_telemetry(self):
        errors = []
        for subsystem in self.telemetry:
            for field in self.telemetry[subsystem]:
                if field == "temp":
                    if self.telemetry[subsystem][field] < TEMP_LOWER:
                        errors.append(
                            f"ERROR: {subsystem} is no longer operational due to low temp."
                        )
                    elif self.telemetry[subsystem][field] > TEMP_UPPER:
                        errors.append(
                            f"ERROR: {subsystem} fried due to high temp.")

        for idx, axis in enumerate(self.telemetry['adcs']['whl_rpm']):
            if abs(axis) > ADCS_WHEEL_RPM:
                errors.append(
                    f"ERROR: adcs wheel {idx} has exceeded max wheel speed.")

        if self.telemetry["obc"]["disk"] > OBC_DISK:
            errors.append("ERROR: Disk is full. Data partition is corrupted.")

        if self.telemetry["batt"]["percent"] < BATT_PERCENT:
            errors.append("ERROR: Battery level critical. Entering Safe Mode.")

        return errors
Exemplo n.º 8
0
def get_next_satellite_pass_for_latlon(
    latitude: float,
    longitude: float,
    requested_date: datetime.datetime,
    tle_satellite_name: str,
    elevation: float = 0.0,
    number_of_results: int = 1,
    visible_passes_only: bool = False,
    altitude_degrees: float = 10.0,
    units: str = "metric",
):
    """
    Determine the next pass of the ISS for a given set
    of coordinates for a certain date

    Parameters
    ==========
    latitude : 'float'
        Latitude value
    longitude : 'float'
        Longitude value
    requested_date: class 'datetime'
        Start-datestamp for the given calculation
    tle_satellite_name: 'str'
        Name of the satellite whose pass we want to
        calculate (see http://www.celestrak.com/NORAD/elements/amateur.txt)
    elevation : 'float'
        Elevation in meters above sea levels
        Default is 0 (sea level)
    number_of_results: int
        default: 1, supports up to 5 max results
    visible_passes_only: bool
        If True, then show only visible passes to the user
    altitude_degrees: float
        default: 10.0 degrees
    units: str
        units of measure, either metric or imperial

    Returns
    =======
    success: bool
        False in case an error has occurred

    """

    assert 1 <= number_of_results <= 5
    assert units in ["metric", "imperial"]

    satellite_response_data = {}

    rise_time = (
        rise_azimuth
    ) = maximum_time = maximum_altitude = set_time = set_azimuth = None

    # Try to get the satellite information from the dictionary
    # Return error settings if not found
    success, tle_satellite, tle_data_line1, tle_data_line2 = get_tle_data(
        satellite_id=tle_satellite_name)
    if success:
        ts = api.load.timescale()
        eph = api.load("de421.bsp")

        satellite = EarthSatellite(tle_data_line1, tle_data_line2,
                                   tle_satellite, ts)

        pos = api.Topos(
            latitude_degrees=latitude,
            longitude_degrees=longitude,
            elevation_m=elevation,
        )

        today = requested_date
        tomorrow = requested_date + datetime.timedelta(days=10)

        #
        # t = ts.utc(
        #    year=today.year,
        #    month=today.month,
        #    day=today.day,
        #    hour=today.hour,
        #    minute=today.minute,
        #    second=today.second,
        # )
        # days = t - satellite.epoch
        # logger.info(msg="{:.3f} days away from epoch".format(days))

        t0 = ts.utc(today.year, today.month, today.day, today.hour,
                    today.minute, today.second)
        t1 = ts.utc(
            tomorrow.year,
            tomorrow.month,
            tomorrow.day,
            tomorrow.hour,
            tomorrow.minute,
            tomorrow.second,
        )

        t, events = satellite.find_events(pos,
                                          t0,
                                          t1,
                                          altitude_degrees=altitude_degrees)

        events_dictionary = {}

        found_rise = False
        for ti, event in zip(t, events):
            #            name = ("rise above 10°", "culminate", "set below 10°")[event]
            #            print(ti.utc_strftime("%Y %b %d %H:%M:%S"), name)

            # create a datetime object out of the skyfield date/time-stamp
            # we don't really need the microsecond information but keeping this data
            # should make our dictionary key unique :-)
            timestamp = datetime.datetime(
                year=ti.utc.year,
                month=ti.utc.month,
                day=ti.utc.day,
                hour=ti.utc.hour,
                minute=ti.utc.minute,
                second=floor(ti.utc.second),
                microsecond=floor(1000000 *
                                  (ti.utc.second - floor(ti.utc.second))),
            )
            is_sunlit = satellite.at(ti).is_sunlit(eph)
            difference = satellite - pos
            topocentric = difference.at(ti)
            alt, az, distance = topocentric.altaz()
            above_horizon = True if alt.degrees > 0 else False

            # (re)calculate km distance in miles if the user has requested imperial units
            _div = 1.0
            if units == "imperial":
                _div = 1.609  # change km to miles

            # 'event' values: '0' = rise above, '1' = culminate, '2' = set below
            # at the point in time for which the user has requested the data
            # there might happen a flyby (meaning that we receive a '1'/'2'
            # even as first event). We are going to skip those until we receive
            # the first '0' event
            if event == 0 or found_rise:
                events_dictionary[timestamp] = {
                    "event": event,
                    "above_horizon": above_horizon,
                    "altitude": ceil(altitude_degrees),
                    "azimuth": ceil(az.degrees),
                    "distance": floor(distance.km /
                                      _div),  # Change km to miles if necessary
                    "is_sunlit": is_sunlit,
                }
                found_rise = True

        # We now have a dictionary that is a) in the correct order and b) starts with a '0' event
        # Try to process the data and build the dictionary that will contain
        # the blended data

        is_visible = False
        rise_date = culmination_date = set_date = datetime.datetime.min
        alt = az = dst = 0.0

        count = 0

        for event_datetime in events_dictionary:
            event_item = events_dictionary[event_datetime]
            event = event_item["event"]
            above_horizon = event_item["above_horizon"]
            altitude = event_item["altitude"]
            azimuth = event_item["azimuth"]
            distance = event_item["distance"]
            is_sunlit = event_item["is_sunlit"]

            if event == 0:  # rise
                rise_date = event_datetime
                if is_sunlit:
                    is_visible = True
            elif event == 1:  # culmination
                culmination_date = event_datetime
                alt = altitude
                az = azimuth
                dst = distance
                if is_sunlit:
                    is_visible = True
            elif event == 2:  # set
                set_date = event_datetime
                if is_sunlit:
                    is_visible = True
                # we should now have all of the required data for creating
                # a full entry. Now check if we need to add it
                if is_visible or not visible_passes_only:
                    satellite_response_data[rise_date] = {
                        "culmination_date": culmination_date,
                        "set_date": set_date,
                        "altitude": alt,
                        "azimuth": az,
                        "distance": dst,
                        "is_visible": is_visible,
                    }
                    # Increase entry counter and end for loop
                    # if we have enough results
                    count = count + 1
                    if count >= number_of_results:
                        break
                # Otherwise, we are going to reset our work variables for
                # the next loop that we are going to enter
                is_visible = False
                rise_date = culmination_date = set_date = datetime.datetime.min
                alt = az = dst = 0.0
    return success, satellite_response_data
Exemplo n.º 9
0
geocentric = satellite.at(t)
print(geocentric.position.km)

# 星下点
subpoint = geocentric.subpoint()
print('Latitude:', subpoint.latitude)
print('Longitude:', subpoint.longitude)
print('Elevation (m):', int(subpoint.elevation.m))

# 卫星的高度超过地平线以上指定的度数
# 纬度:北纬为正数,南纬为负数。北纬(N)南纬(S)
# 经度:东经为正数,西经为负数。东经(E)西经(W)
bluffton = Topos('34.23053 N', '108.93425 E')
t1 = ts.utc(2014, 1, 23)
t2 = ts.utc(2014, 1, 24)
t, events = satellite.find_events(bluffton, t1, t2, altitude_degrees=30.0)
for ti, event in zip(t, events):
    name = ('rise above 30°', 'culminate', 'set below 30°')[event]
    print(ti.utc_strftime('%Y %b %d %H:%M:%S'), name)

# 卫星相对于观察者位置
t = ts.utc(2014, 1, 21, 22, 23, 4)
difference = satellite - bluffton
topocentric = difference.at(t)
alt, az, distance = topocentric.altaz()
if alt.degrees > 0:
    print('The ISS is above the horizon')

print(alt)
print(az)
print(int(distance.km), 'km')
Exemplo n.º 10
0
def calculatePasses(params):
    try:
        ephem = load(params[13])
        sun = ephem['sun']
        earth = ephem['earth']
        CityElevation = int(params[15])
        Location = Topos(params[12].split(',')[0],
                         params[12].split(',')[1],
                         elevation_m=CityElevation)

        tle0 = params[0]
        tle1 = params[1]
        tle2 = params[2]
        NORADID = params[3]
        tleEpoch = params[4]
        City = params[5]
        YearFrom = params[6]
        MonthFrom = params[7]
        DayFrom = params[8]
        YearTo = params[9]
        MonthTo = params[10]
        DayTo = params[11]
        stdmag = params[14]
        ts = load.timescale()
        E_TLEEEPOCH = tleEpoch
        E_SATID = NORADID
        E_CITY = City
        E_UTCCALCDATE = ts.now()
        E_TLEEEPOCH = tleEpoch
        satellite = EarthSatellite(tle1, tle2, tle0, ts)
        difference = satellite - Location
        EarthLoc = (earth + Location)
        SunEarth = (sun - earth)
        obj = []
        t0 = ts.utc(YearFrom, MonthFrom, DayFrom)
        t1 = ts.utc(YearTo, MonthTo, DayTo)

        lastevent = -1
        times, events = satellite.find_events(Location,
                                              t0,
                                              t1,
                                              altitude_degrees=0)

        if len(events) == 0:
            return obj

        if events[len(events) - 1] != 2:
            t1 = ts.utc(YearTo, MonthTo, DayTo, 0, 40, 0)
            times, events = satellite.find_events(Location,
                                                  t0,
                                                  t1,
                                                  altitude_degrees=0)

        for ti, event in zip(times, events):
            if lastevent == -1 and event > 0:
                continue
            else:
                lastevent = event
            if event == 0:
                E_UTC0R = None
                E_UTC0S = None
                E_UTC15R = None
                E_UTC15S = None
                E_UTC30R = None
                E_UTC30S = None
                E_UTCMAX = None
                E_MAXELEV = None
                E_SUNELEVAT0R = None
                E_SUNELEVAT0S = None
                E_SUNELEVAT15R = None
                E_SUNELEVAT15S = None
                E_SUNELEVAT30R = None
                E_SUNELEVAT30S = None
                E_SUNELEVATMAX = None
                E_ISSUNLIT0R = None
                E_ISSUNLIT0S = None
                E_ISSUNLIT15R = None
                E_ISSUNLIT15S = None
                E_ISSUNLIT30R = None
                E_ISSUNLIT30S = None
                E_ISSUNLITMAX = None
                E_UTCSHADOW = None
                E_ELEVATSHADOW = None
                E_MAG0R = None
                E_MAG0S = None
                E_MAG15R = None
                E_MAG15S = None
                E_MAG30R = None
                E_MAG30S = None
                E_MAGMAX = None
                E_MAGPRESHADOW = None
                E_AZ0R = None
                E_AZ15R = None
                E_AZ30R = None
                E_AZMAX = None
                E_AZ30S = None
                E_AZ15S = None
                E_AZ0S = None

                E_UTC0R = ti
                topocentric = difference.at(E_UTC0R)
                alt, az, distance = topocentric.altaz()
                E_AZ0R = az.degrees
                E_ISSUNLIT0R = satellite.at(E_UTC0R).is_sunlit(ephem)
                EarthLocSun = EarthLoc.at(E_UTC0R).observe(sun)
                altSun, azSun, distanceSun = EarthLocSun.apparent().altaz()
                E_SUNELEVAT0R = altSun.degrees
                if E_ISSUNLIT0R:
                    E_MAG0R = calculateMag(E_UTC0R, difference, SunEarth,
                                           EarthLocSun, stdmag)
            if event == 1:
                E_UTCMAX = ti
                topocentric = difference.at(E_UTCMAX)
                alt, az, distance = topocentric.altaz()
                E_MAXELEV = alt.degrees
                E_AZMAX = az.degrees
                E_ISSUNLITMAX = satellite.at(E_UTCMAX).is_sunlit(ephem)
                EarthLocSun = EarthLoc.at(E_UTCMAX).observe(sun)
                altSun, azSun, distanceSun = EarthLocSun.apparent().altaz()
                E_SUNELEVATMAX = altSun.degrees
                if E_ISSUNLITMAX:
                    E_MAGMAX = calculateMag(E_UTCMAX, difference, SunEarth,
                                            EarthLocSun, stdmag)
            if event == 2:
                E_UTC0S = ti
                topocentric = difference.at(E_UTC0S)
                alt, az, distance = topocentric.altaz()
                E_AZ0S = az.degrees
                E_ISSUNLIT0S = satellite.at(E_UTC0S).is_sunlit(ephem)
                EarthLocSun = EarthLoc.at(E_UTC0S).observe(sun)
                altSun, azSun, distanceSun = EarthLocSun.apparent().altaz()
                E_SUNELEVAT0S = altSun.degrees
                if E_ISSUNLIT0S:
                    E_MAG0S = calculateMag(E_UTC0S, difference, SunEarth,
                                           EarthLocSun, stdmag)
                if E_MAXELEV > 15:
                    times15, events15 = satellite.find_events(
                        Location, E_UTC0R, E_UTC0S, altitude_degrees=15)
                    for ti15, event15 in zip(times15, events15):
                        if event15 == 0:
                            E_UTC15R = ti15
                            topocentric = difference.at(E_UTC15R)
                            alt, az, distance = topocentric.altaz()
                            E_AZ15R = az.degrees
                            E_ISSUNLIT15R = satellite.at(E_UTC15R).is_sunlit(
                                ephem)
                            EarthLocSun = EarthLoc.at(E_UTC15R).observe(sun)
                            altSun, azSun, distanceSun = EarthLocSun.apparent(
                            ).altaz()
                            E_SUNELEVAT15R = altSun.degrees
                            if E_ISSUNLIT15R:
                                E_MAG15R = calculateMag(
                                    E_UTC15R, difference, SunEarth,
                                    EarthLocSun, stdmag)
                        if event15 == 2:
                            E_UTC15S = ti15
                            topocentric = difference.at(E_UTC15S)
                            alt, az, distance = topocentric.altaz()
                            E_AZ15S = az.degrees
                            E_ISSUNLIT15S = satellite.at(E_UTC15S).is_sunlit(
                                ephem)
                            EarthLocSun = EarthLoc.at(E_UTC15S).observe(sun)
                            altSun, azSun, distanceSun = EarthLocSun.apparent(
                            ).altaz()
                            E_SUNELEVAT15S = altSun.degrees
                            if E_ISSUNLIT15S:
                                E_MAG15S = calculateMag(
                                    E_UTC15S, difference, SunEarth,
                                    EarthLocSun, stdmag)
                if E_MAXELEV > 30:
                    times30, events30 = satellite.find_events(
                        Location, E_UTC15R, E_UTC15S, altitude_degrees=30)
                    for ti30, event30 in zip(times30, events30):
                        if event30 == 0:
                            E_UTC30R = ti30
                            topocentric = difference.at(E_UTC30R)
                            alt, az, distance = topocentric.altaz()
                            E_AZ30R = az.degrees
                            E_ISSUNLIT30R = satellite.at(E_UTC30R).is_sunlit(
                                ephem)
                            EarthLocSun = EarthLoc.at(E_UTC30R).observe(sun)
                            altSun, azSun, distanceSun = EarthLocSun.apparent(
                            ).altaz()
                            E_SUNELEVAT30R = altSun.degrees
                            if E_ISSUNLIT30R:
                                E_MAG30R = calculateMag(
                                    E_UTC30R, difference, SunEarth,
                                    EarthLocSun, stdmag)
                        if event30 == 2:
                            E_UTC30S = ti30
                            topocentric = difference.at(E_UTC30S)
                            alt, az, distance = topocentric.altaz()
                            E_AZ30S = az.degrees
                            E_ISSUNLIT30S = satellite.at(E_UTC30S).is_sunlit(
                                ephem)
                            EarthLocSun = EarthLoc.at(E_UTC30S).observe(sun)
                            altSun, azSun, distanceSun = EarthLocSun.apparent(
                            ).altaz()
                            E_SUNELEVAT30S = altSun.degrees
                            if E_ISSUNLIT30S:
                                E_MAG30S = calculateMag(
                                    E_UTC30S, difference, SunEarth,
                                    EarthLocSun, stdmag)

                SHADOWDIRECTION = 0
                if (E_ISSUNLIT0R and (not E_ISSUNLITMAX or not E_ISSUNLIT0S)):
                    SHADOWDIRECTION = 1

                if (not E_ISSUNLIT0R and (E_ISSUNLITMAX or E_ISSUNLIT0S)):
                    SHADOWDIRECTION = -1

                if SHADOWDIRECTION != 0:
                    SatRiseTime = datetime.datetime.strptime(
                        E_UTC0R.utc_iso(' '), '%Y-%m-%d %H:%M:%SZ')
                    SatSetTime = datetime.datetime.strptime(
                        E_UTC0S.utc_iso(' '), '%Y-%m-%d %H:%M:%SZ')
                    SatTimeDiff = (SatSetTime - SatRiseTime).total_seconds()
                    TimeIncrease = 1

                    if SHADOWDIRECTION > 0:
                        MinLitTime = SatRiseTime
                        MaxLitTime = SatSetTime
                        TTC1 = SatRiseTime
                    if SHADOWDIRECTION < 0:
                        MinLitTime = SatRiseTime
                        MaxLitTime = SatSetTime
                        TTC1 = SatSetTime

                    while TimeIncrease > 0:
                        TimeIncrease = math.ceil(SatTimeDiff / 2)
                        TTC1 = TTC1 + datetime.timedelta(
                            seconds=SHADOWDIRECTION * TimeIncrease)
                        TTC2 = TTC1 + datetime.timedelta(
                            seconds=SHADOWDIRECTION)
                        tsunlit1 = ts.utc(TTC1.year, TTC1.month, TTC1.day,
                                          TTC1.hour, TTC1.minute, TTC1.second)
                        tsunlit2 = ts.utc(TTC2.year, TTC2.month, TTC2.day,
                                          TTC2.hour, TTC2.minute, TTC2.second)
                        ShadowSunLit1 = satellite.at(tsunlit1).is_sunlit(ephem)
                        ShadowSunLit2 = satellite.at(tsunlit2).is_sunlit(ephem)
                        if ShadowSunLit1 != ShadowSunLit2:
                            TimeIncrease = -1
                        else:
                            if ShadowSunLit1 and SHADOWDIRECTION > 0:
                                MinLitTime = TTC1

                            elif not ShadowSunLit1 and SHADOWDIRECTION > 0:
                                MaxLitTime = TTC1
                                SHADOWDIRECTION = -1

                            elif ShadowSunLit1 and SHADOWDIRECTION < 0:
                                MinLitTime = TTC1
                                SHADOWDIRECTION = 1

                            elif not ShadowSunLit1 and SHADOWDIRECTION < 0:
                                MinLitTime = TTC1

                            SatTimeDiff = (MaxLitTime -
                                           MinLitTime).total_seconds()
                            if SatTimeDiff <= 1:
                                TimeIncrease = -1

                    topocentric = difference.at(tsunlit1)
                    alt, az, distance = topocentric.altaz()
                    E_ELEVATSHADOW = alt.degrees
                    E_UTCSHADOW = tsunlit1
                    E_MAGPRESHADOW = calculateMag(E_UTCSHADOW, difference,
                                                  SunEarth, EarthLocSun,
                                                  stdmag)

                obj.append(
                    fillValues(P_SATID=E_SATID,
                               P_CITY=E_CITY,
                               P_UTCCALCDATE=E_UTCCALCDATE,
                               P_TLEEEPOCH=E_TLEEEPOCH,
                               P_UTC0R=E_UTC0R,
                               P_UTC0S=E_UTC0S,
                               P_UTC15R=E_UTC15R,
                               P_UTC15S=E_UTC15S,
                               P_UTC30R=E_UTC30R,
                               P_UTC30S=E_UTC30S,
                               P_UTCMAX=E_UTCMAX,
                               P_MAXELEV=E_MAXELEV,
                               P_SUNELEVAT0R=E_SUNELEVAT0R,
                               P_SUNELEVAT0S=E_SUNELEVAT0S,
                               P_SUNELEVAT15R=E_SUNELEVAT15R,
                               P_SUNELEVAT15S=E_SUNELEVAT15S,
                               P_SUNELEVAT30R=E_SUNELEVAT30R,
                               P_SUNELEVAT30S=E_SUNELEVAT30S,
                               P_SUNELEVATMAX=E_SUNELEVATMAX,
                               P_ISSUNLIT0R=E_ISSUNLIT0R,
                               P_ISSUNLIT0S=E_ISSUNLIT0S,
                               P_ISSUNLIT15R=E_ISSUNLIT15R,
                               P_ISSUNLIT15S=E_ISSUNLIT15S,
                               P_ISSUNLIT30R=E_ISSUNLIT30R,
                               P_ISSUNLIT30S=E_ISSUNLIT30S,
                               P_ISSUNLITMAX=E_ISSUNLITMAX,
                               P_UTCSHADOW=E_UTCSHADOW,
                               P_ELEVATSHADOW=E_ELEVATSHADOW,
                               P_MAG0R=E_MAG0R,
                               P_MAG0S=E_MAG0S,
                               P_MAG15R=E_MAG15R,
                               P_MAG15S=E_MAG15S,
                               P_MAG30R=E_MAG30R,
                               P_MAG30S=E_MAG30S,
                               P_MAGMAX=E_MAGMAX,
                               P_MAGPRESHADOW=E_MAGPRESHADOW,
                               P_AZ0R=E_AZ0R,
                               P_AZ15R=E_AZ15R,
                               P_AZ30R=E_AZ30R,
                               P_AZMAX=E_AZMAX,
                               P_AZ30S=E_AZ30S,
                               P_AZ15S=E_AZ15S,
                               P_AZ0S=E_AZ0S))
        return obj
    except Exception as e:
        if hasattr(e, 'message'):
            return "Error {0} processing values: {1}".format(
                e.message, ",".join(str(x) for x in params))
        else:
            return "Error {0} processing values: {1}".format(
                str(e), ",".join(str(x) for x in params))
Exemplo n.º 11
0
class Orbit:
    def __init__(self):
        self.tle = None
        self.id = None
        self.line1 = None
        self.line2 = None
        self.url = None
        self.satellites = None
        self.observer = None
        self.ts = load.timescale()
        self.alt = None
        self.az = None
        self.distance = None

    def __str__(self):
        temp = "TLE\n"
        temp += 69 * "-"
        temp += self.id
        temp += self.line1
        temp += self.line2
        return temp

    def loadTLE(self, tle):
        '''

        :param tle:
        :return:
        '''
        self.tle = tle
        self.id = self.tle[0]
        self.line1 = self.tle[1]
        self.line2 = self.tle[2]
        return self.id, self.line1, self.line2

    def loadSatellites(self):
        '''

        :return:
        '''
        self.satellites = load.tle_file(self.url)
        return

    def loadSatfromTLE(self, tle):
        '''

        :param tle:
        TLE EXAMPLE
        tle = """
        GOCE
        1 34602U 09013A   13314.96046236  .14220718  20669-5  50412-4 0   930
        2 34602 096.5717 344.5256 0009826 296.2811 064.0942 16.58673376272979
        """

        :return:
        '''

        lines = tle.strip().splitlines()
        self.satellites = EarthSatellite(lines[1], lines[2], lines[0])
        return

    def loadObserver(self, lat, long):
        '''

        :param lat:
        :param long:
        :return:
        '''
        self.observer = wgs84.latlon(lat, long)
        return

    def setURL(self, url):
        '''

        :param url:
        :return:
        '''
        self.url = url
        return

    def currentTime(self):
        '''

        :return:
        '''
        return self.ts.now()

    def showSatellite(self):
        '''

        :return:
        '''
        print(self.satellite)
        return

    def setTime(self, year, month, day):
        '''

        :param year:
        :param month:
        :param day:
        :return:
        '''
        t = self.ts.utc(year, month, day)
        return t

    def findRiseSets(self, timedate_init, timedate_final, altitude_degrees):
        '''

        :param timedate_init:
        :param timedate_final:
        :param altitude_degrees:
        :return:
        '''
        t0 = self.setTime(timedate_init)
        t1 = self.setTime(timedate_final)
        t, events = self.satellites.find_events(self.observer, t0, t1,
                                                altitude_degrees)
        for ti, event in zip(t, events):
            name = ('rise above' + str(altitude_degrees), 'culminate',
                    'set below' + str(altitude_degrees))[event]
            print(ti.utc_strftime('%Y %b %d %H:%M:%S'), name)
        return

    def checkSatEpoch(self):
        '''

        :return:
        '''
        self.epoch = self.satellites.epoch.utc_jpl()
        print(self.epoch)
        return

    def checkSatellitePosition(self):
        '''

        :return:
        '''
        return self.satellites.at(self.currentTime())

    def getSatfromYours(self):
        '''

        :return:
        '''
        return print(self.satellites - self.observer)

    def getObservation(self):
        '''

        :return:
        '''
        self.alt, self.az, self.distance = self.getSatfromYours()

        if self.alt.degrees > 0:
            print(str(self.satellites.name) + " is above the horizon")

        print(self.alt)
        print(self.az)
        print(self.int(self.distance.km), 'km')
        return