diff --git a/auto_scheduler/pass_predictor.py b/auto_scheduler/pass_predictor.py index fa39d83..d7ca7b3 100644 --- a/auto_scheduler/pass_predictor.py +++ b/auto_scheduler/pass_predictor.py @@ -1,4 +1,7 @@ -from datetime import timedelta +import ephem +import math + +from datetime import datetime, timedelta def overlap(satpass, scheduledpasses, wait_time_seconds): @@ -32,3 +35,88 @@ def overlap(satpass, scheduledpasses, wait_time_seconds): break return overlap + + +def find_passes(satellite, + observer, + tmin, + tmax, + minimum_altitude, + min_pass_duration): + passes = [] + + # Set start time + observer.date = ephem.date(tmin) + + # Load TLE + try: + sat_ephem = ephem.readtle(str(satellite.tle0), str(satellite.tle1), str(satellite.tle2)) + except (ValueError, AttributeError): + return [] + + # Loop over passes + keep_digging = True + while keep_digging: + sat_ephem.compute(observer) + try: + tr, azr, tt, altt, ts, azs = observer.next_pass(sat_ephem) + except ValueError: + break # there will be sats in our list that fall below horizon, skip + except TypeError: + break # if there happens to be a non-EarthSatellite object in the list + except Exception: + break + + if tr is None: + break + + # using the angles module convert the sexagesimal degree into + # something more easily read by a human + try: + elevation = format(math.degrees(altt), '.0f') + azimuth_r = format(math.degrees(azr), '.0f') + azimuth_s = format(math.degrees(azs), '.0f') + except TypeError: + break + + pass_duration = ts.datetime() - tr.datetime() + + # show only if >= configured horizon and till tmax, + # and not directly overhead (tr < ts see issue 199) + + if tr < ephem.date(tmax): + if (float(elevation) >= minimum_altitude and tr < ts and + pass_duration > timedelta(minutes=min_pass_duration)): + valid = True + + # invalidate passes that start too soon + if tr < ephem.Date(datetime.now() + timedelta(minutes=5)): + valid = False + + # get pass information + satpass = { + 'mytime': str(observer.date), + 'name': str(satellite.name), + 'id': str(satellite.id), + 'tle1': str(satellite.tle1), + 'tle2': str(satellite.tle2), + 'tr': tr.datetime(), # Rise time + 'azr': azimuth_r, # Rise Azimuth + 'tt': tt.datetime(), # Max altitude time + 'altt': elevation, # Max altitude + 'ts': ts.datetime(), # Set time + 'azs': azimuth_s, # Set azimuth + 'valid': valid, + 'uuid': satellite.transmitter, + 'success_rate': satellite.success_rate, + 'good_count': satellite.good_count, + 'data_count': satellite.data_count, + 'mode': satellite.mode, + 'scheduled': False + } + passes.append(satpass) + observer.date = ephem.Date(ts).datetime() + timedelta(minutes=1) + else: + keep_digging = False + + return passes diff --git a/schedule_single_station.py b/schedule_single_station.py index 199ec21..6ef6f08 100755 --- a/schedule_single_station.py +++ b/schedule_single_station.py @@ -12,13 +12,13 @@ from utils import get_active_transmitter_info, \ get_transmitter_stats, \ get_groundstation_info, \ get_scheduled_passes_from_network, \ - find_passes, \ schedule_observation, \ read_priorities_transmitters, \ get_satellite_info, \ update_needed, \ get_priority_passes from auto_scheduler import twolineelement, satellite +from auto_scheduler.pass_predictor import find_passes from auto_scheduler.schedulers import ordered_scheduler, \ report_efficiency import settings @@ -274,7 +274,16 @@ def main(): satellites.append(satellite(tle, uuid, success_rate, good_count, data_count, mode)) # Find passes - passes = find_passes(satellites, observer, tmin, tmax, min_culmination, min_pass_duration) + passes = [] + logging.info('Finding all passes for %s satellites:' % len(satellites)) + # Loop over satellites + for satellite in tqdm(satellites): + passes.extend(find_passes(satellite, + observer, + tmin, + tmax, + min_culmination, + min_pass_duration)) priorities, favorite_transmitters = read_priorities_transmitters(priority_filename) diff --git a/utils.py b/utils.py index c494df3..3a28762 100644 --- a/utils.py +++ b/utils.py @@ -1,11 +1,8 @@ import requests import logging -import math -from datetime import datetime, timedelta -import ephem +from datetime import datetime import lxml import settings -from tqdm import tqdm import os import sys @@ -140,88 +137,6 @@ def get_scheduled_passes_from_network(ground_station, tmin, tmax): return scheduledpasses -def find_passes(satellites, observer, tmin, tmax, minimum_altitude, min_pass_duration): - # Loop over satellites - passes = [] - logging.info('Finding all passes for %s satellites:' % len(satellites)) - for satellite in tqdm(satellites): - # Set start time - observer.date = ephem.date(tmin) - - # Load TLE - try: - sat_ephem = ephem.readtle(str(satellite.tle0), str(satellite.tle1), str(satellite.tle2)) - except (ValueError, AttributeError): - continue - - # Loop over passes - keep_digging = True - while keep_digging: - sat_ephem.compute(observer) - try: - tr, azr, tt, altt, ts, azs = observer.next_pass(sat_ephem) - except ValueError: - break # there will be sats in our list that fall below horizon, skip - except TypeError: - break # if there happens to be a non-EarthSatellite object in the list - except Exception: - break - - if tr is None: - break - - # using the angles module convert the sexagesimal degree into - # something more easily read by a human - try: - elevation = format(math.degrees(altt), '.0f') - azimuth_r = format(math.degrees(azr), '.0f') - azimuth_s = format(math.degrees(azs), '.0f') - except TypeError: - break - - pass_duration = ts.datetime() - tr.datetime() - - # show only if >= configured horizon and till tmax, - # and not directly overhead (tr < ts see issue 199) - - if tr < ephem.date(tmax): - if (float(elevation) >= minimum_altitude and tr < ts and - pass_duration > timedelta(minutes=min_pass_duration)): - valid = True - - # invalidate passes that start too soon - if tr < ephem.Date(datetime.now() + timedelta(minutes=5)): - valid = False - - # get pass information - satpass = { - 'mytime': str(observer.date), - 'name': str(satellite.name), - 'id': str(satellite.id), - 'tle1': str(satellite.tle1), - 'tle2': str(satellite.tle2), - 'tr': tr.datetime(), # Rise time - 'azr': azimuth_r, # Rise Azimuth - 'tt': tt.datetime(), # Max altitude time - 'altt': elevation, # Max altitude - 'ts': ts.datetime(), # Set time - 'azs': azimuth_s, # Set azimuth - 'valid': valid, - 'uuid': satellite.transmitter, - 'success_rate': satellite.success_rate, - 'good_count': satellite.good_count, - 'data_count': satellite.data_count, - 'mode': satellite.mode, - 'scheduled': False - } - passes.append(satpass) - observer.date = ephem.Date(ts).datetime() + timedelta(minutes=1) - else: - keep_digging = False - - return passes - - def get_priority_passes(passes, priorities, favorite_transmitters, only_priority, min_priority): priority = [] normal = []