Exemple #1
0
    def test_aos_deg_can_be_used_in_get_next_pass(self):
        start = datetime(2017, 3, 6, 13, 30)
        end = start + timedelta(hours=1)
        location = Location('bad-case-1', 11.937501570612568,
                            -55.35189435098657, 1780.674044538666)
        complete_pass = self.predictor.get_next_pass(location,
                                                     when_utc=start,
                                                     limit_date=end)

        pass_with_aos = self.predictor.get_next_pass(location,
                                                     when_utc=start,
                                                     limit_date=end,
                                                     aos_at_dg=5)

        self.assertGreater(pass_with_aos.aos, complete_pass.aos)
        self.assertLess(pass_with_aos.aos, complete_pass.max_elevation_date)
        self.assertAlmostEqual(pass_with_aos.max_elevation_date,
                               complete_pass.max_elevation_date,
                               delta=timedelta(seconds=1))

        self.assertGreater(pass_with_aos.los, complete_pass.max_elevation_date)
        self.assertLess(pass_with_aos.los, complete_pass.los)

        position = self.old_predictor.get_position(pass_with_aos.aos)
        _, elev = location.get_azimuth_elev_deg(position)

        self.assertAlmostEqual(elev, 5, delta=0.1)

        position = self.old_predictor.get_position(pass_with_aos.los)
        _, elev = location.get_azimuth_elev_deg(position)

        self.assertAlmostEqual(elev, 5, delta=0.1)
Exemple #2
0
 def test_sun_elevation_on_earth_works(self):
     # https://github.com/satellogic/orbit-predictor/issues/52
     l1 = Location(latitude_deg=1,
                   longitude_deg=2,
                   elevation_m=3,
                   name="location1")
     l1.sun_elevation_on_earth()
Exemple #3
0
    def test_compare_no_eq(self):
        l1 = Location(latitude_deg=1,
                      longitude_deg=2,
                      elevation_m=3,
                      name="location_other")
        l2 = Location(latitude_deg=1,
                      longitude_deg=2,
                      elevation_m=3,
                      name="location1")

        self.assertNotEqual(l1, l2)
        self.assertNotEqual(l2, l1)
Exemple #4
0
 def test_accurate_predictor_find_more_or_equal_passes_amount(self):
     self.assertEqualOrGreaterPassesAmount(
         Location('bad-case-1', 11.937501570612568, -55.35189435098657,
                  1780.674044538666))
     self.assertEqualOrGreaterPassesAmount(tortu1)
     self.assertEqualOrGreaterPassesAmount(svalbard)
     self.assertEqualOrGreaterPassesAmount(
         Location('bad-case-2', -11.011509137116818, 123.29554733688798,
                  1451.5695915302097))
     self.assertEqualOrGreaterPassesAmount(
         Location('bad-case-3', 10.20803236163988, 138.01236517021056,
                  4967.661890730469))
     self.assertEqualOrGreaterPassesAmount(
         Location('less passes', -82.41515032683046, -33.712555446065664,
                  4417.427841452149))
 def __init__(self, args):
     self.slack_url = args.slackUrl
     self.location = Location("",
                              latitude_deg=args.locationLat,
                              longitude_deg=args.locationLng,
                              elevation_m=args.locationElevation)
     self.satellite_tle_url = f'https://celestrak.com/satcat/tle.php?CATNR={args.satellite}'
     self.notification = args.notificationMsg
    def test_compare_eq_subclass(self):

        class SubLocation(Location):
            pass

        l1 = Location(latitude_deg=1, longitude_deg=2, elevation_m=3, name="location1")
        l2 = SubLocation(latitude_deg=1, longitude_deg=2, elevation_m=3, name="location1")

        self.assertEqual(l1, l2)
        self.assertEqual(l2, l1)
Exemple #7
0
    def test_predicted_passes_off_nadir_angle_works(self):
        start = datetime(2017, 3, 6, 13, 30)
        end = start + timedelta(hours=1)
        location = Location('bad-case-1', 11.937501570612568,
                            -55.35189435098657, 1780.674044538666)

        pass_ = self.predictor.get_next_pass(location,
                                             when_utc=start,
                                             limit_date=end)
        self.assertGreaterEqual(0, pass_.off_nadir_deg)
Exemple #8
0
    def test_predicted_passes_are_equal_between_executions(self):
        location = Location('bad-case-1', 11.937501570612568,
                            -55.35189435098657, 1780.674044538666)
        first_set = list(
            self.predictor.passes_over(location, self.start, self.end))
        second_set = list(
            self.predictor.passes_over(location,
                                       self.start + timedelta(seconds=3),
                                       self.end))

        self.assertEqual(first_set, second_set)
    def test_predicted_passes_are_equal_between_executions(self):
        location = Location('bad-case-1', 11.937501570612568,
                            -55.35189435098657, 1780.674044538666)
        first_set = list(
            self.predictor.passes_over(location, self.start, self.end))
        second_set = list(
            self.predictor.passes_over(location,
                                       self.start + timedelta(seconds=3),
                                       self.end))

        # We use delta=ONE_SECOND because
        # that's the hardcoded value for the precision
        self.assertAlmostEqual(first_set[0].aos,
                               second_set[0].aos,
                               delta=ONE_SECOND)
        self.assertAlmostEqual(first_set[0].los,
                               second_set[0].los,
                               delta=ONE_SECOND)
Exemple #10
0
def get_passes(config: Configuration, from_: datetime.datetime, to: datetime.datetime):
    location = Location(*get_location(config))
    satellties = filter(lambda s: not s.get("disabled", False), config["satellites"])
    strategy_name: str = config.get("strategy", "max-elevation") # type: ignore

    orbit_db = OrbitDatabase(config["norad"])
    strategy = strategy_factory(strategy_name)
    
    init = []
    for sat in satellties:
        set_satellite_defaults(config, sat)
        aos_at = sat["aos_at"]
        max_elevation_greater_than = sat["max_elevation_greater_than"]
        predictor = orbit_db.get_predictor(sat["name"])
        passes = predictor.passes_over(location, from_, to, max_elevation_greater_than, aos_at_dg=aos_at)
        init += [(sat["name"], p) for p in passes]
    
    selected = strategy(init)
    return selected
    def test_pass_is_not_skipped_smart(self):
        loc = Location(
            name="loc",
            latitude_deg=-15.137152171507697,
            longitude_deg=-0.4276612055384211,
            elevation_m=1.665102900005877e-05,
        )

        PASS_DATE = dt.datetime(2020, 9, 25, 9, 2, 6)
        LIMIT_DATE = dt.datetime(2020, 9, 25, 10, 36, 0)

        predicted_passes = list(
            self.predictor.passes_over(
                loc,
                when_utc=PASS_DATE,
                limit_date=LIMIT_DATE,
                aos_at_dg=0,
                max_elevation_gt=0,
                location_predictor_class=SmartLocationPredictor,
            ))

        assert predicted_passes
Exemple #12
0
    def test_tca_is_correctly_computed(self):
        start = dt.datetime(2020, 5, 9)
        end = start + dt.timedelta(days=1)
        location = Location(name="loc", latitude_deg=11, longitude_deg=0, elevation_m=0)
        predictor = J2Predictor(
            sma=475 + 6371, ecc=1.65e-3, inc=53.0, argp=90, raan=0, ta=300, epoch=start,
        )
        expected_tca = dt.datetime(2020, 5, 9, 9, 19, 15)

        passes = list(
            predictor.passes_over(
                location,
                start,
                aos_at_dg=0,
                max_elevation_gt=0,
                limit_date=end,
                location_predictor_class=SmartLocationPredictor,
                tolerance_s=1e-3,
            )
        )

        self.assertAlmostEqual(passes[1].max_elevation_date, expected_tca, delta=ONE_SECOND)
    def test_los_is_correctly_computed(self):
        loc = Location(
            name='loc',
            latitude_deg=-34.61315,
            longitude_deg=-58.37723,
            elevation_m=30,
        )

        PASS_DATE = dt.datetime(2019, 1, 1, 0, 0)
        LIMIT_DATE = dt.datetime(2019, 1, 15, 0, 0)

        predicted_passes = list(
            self.predictor.passes_over(
                loc,
                when_utc=PASS_DATE,
                limit_date=LIMIT_DATE,
                aos_at_dg=0,
                max_elevation_gt=0,
                location_predictor_class=SmartLocationPredictor,
            ))

        assert predicted_passes
Exemple #14
0
    def __init__(self, lat, long, alt, sat_id, tle_file, refresh_period,
                 verbose):
        gr.sync_block.__init__(self, name="Doppler", in_sig=None, out_sig=None)

        # Init block variables
        self.lat = lat
        self.long = long
        self.alt = alt
        self.sat_id = sat_id
        self.tle_file = tle_file
        self.refresh_period = refresh_period

        gndlocation = Location("GND",
                               latitude_deg=float(self.lat),
                               longitude_deg=float(self.long),
                               elevation_m=float(self.alt))
        source = MultipleEtcTLESource(filename=tle_file)
        predictor = source.get_predictor(self.sat_id)

        self.thread = doppler_runner(self, predictor, gndlocation,
                                     refresh_period, verbose)
        self.thread.start()
        self.message_port_register_out(pmt.intern("dop_factor"))
        self.message_port_register_out(pmt.intern("state"))
Exemple #15
0
from orbit_predictor.locations import Location

BCN = Location(
    name="Barcelona",
    latitude_deg=41.384740,
    longitude_deg=2.177813,
    elevation_m=0,  # estimation
)
DOWNLINK_FREQS = {"NOAA 15": 137.62, "NOAA 18": 137.9125, "NOAA 19": 137.1}
NOAA_IDS = ["NOAA 15", "NOAA 18", "NOAA 19"]
MAX_ELEV_GT = 20  # min elevation for the sat flyby trigger recording
Exemple #16
0
 def test_pass_is_always_returned(self, start, location):
     location = Location('bad-case-1', *location)
     pass_ = self.predictor.get_next_pass(location, start)
     self.assertGreater(pass_.max_elevation_deg, 0)
Exemple #17
0
def loadConfig(file):
    global satellites, tle_update_interval, location, output_dir, rss_enabled, rss_port, rss_webserver, post_processing_hook_command, post_processing_hook_enabled, post_processing_hook_foreach, maximum_overlap
    # Open our file
    f = io.open(file, mode="r", encoding="utf-8")

    # Parse it
    config = yaml.load(f, Loader=yaml.FullLoader)

    # Software options
    tle_update_interval = int(config["config"]["tle_update_interval"])
    output_dir = str(config["config"]["output_dir"])
    maximum_overlap = int(config["config"]["max_overlap"])

    # RSS
    rss_enabled = bool(config["config"]["rss"]["enabled"])
    rss_webserver = bool(config["config"]["rss"]["webserver"])
    rss_port = int(config["config"]["rss"]["port"])

    # Post-Processing Hook
    post_processing_hook_command = str(
        config["config"]["post_processing_hook"]["command"])
    post_processing_hook_enabled = bool(
        config["config"]["post_processing_hook"]["enabled"])
    post_processing_hook_foreach = bool(
        config["config"]["post_processing_hook"]["run_foreach"])

    print("TLE Update interval : " + str(tle_update_interval) + " hour(s)")
    print('\n')

    # Ground station
    latitude = config["config"]["station"]["latitude"]
    longitude = config["config"]["station"]["longitude"]
    elevation = config["config"]["station"]["elevation"]
    print("Groud station :")
    print("    Latitude     : " + str(latitude))
    print("    Longitude    : " + str(longitude))
    print("    Elevation    : " + str(elevation))
    print('\n')
    location = Location("Station", latitude, longitude, elevation)

    # Load satellites
    for sat in config["satellites"]:
        name = sat["name"]
        norad = sat["norad"]
        priority = sat["priority"]
        min_elevation = sat["min_elevation"]
        frequency = sat["frequency"]
        downlink = sat["downlink"]
        delete_processed_files = sat["delete_processed_files"]
        print("Adding " + name + " :")
        print("     NORAD                   : " + str(norad))
        print("     Priority                : " + str(priority))
        print("     Minimum elevation       : " + str(min_elevation))
        print("     Frequency               : " + str(frequency))
        print("     Downlink type           : " + downlink)
        print("     Delete processed files  : " + str(delete_processed_files))
        satellite = Satellite(name, norad, priority, min_elevation, frequency,
                              downlink, delete_processed_files)
        satellites.append(satellite)

    print('\n')
Exemple #18
0
from orbit_predictor.sources import NoradTLESource

source = NoradTLESource.from_url(
    "http://www.celestrak.com/NORAD/elements/resource.txt")
predictor = source.get_predictor("NUSAT-3")
from orbit_predictor.locations import Location

FBR = Location("Observatori Fabra", 41.4184, 2.1239, 408)
predicted_pass = predictor.get_next_pass(FBR)
predicted_pass
predicted_pass.aos  # Acquisition Of Signal
predicted_pass.duration_s
predictor.get_position(predicted_pass.aos).position_llh

import matplotlib.pyplot as plt
plt.ion()

import cartopy.crs as ccrs

import pandas as pd
dates = pd.date_range(start="2017-12-11 00:00", periods=1000, freq="30S")
latlon = pd.DataFrame(index=dates, columns=["lat", "lon"])

for date in dates:
    lat, lon, _ = predictor.get_position(date).position_llh
    latlon.loc[date] = (lat, lon)

plt.figure(figsize=(15, 25))
ax = plt.axes(projection=ccrs.PlateCarree())
ax.stock_img()
Exemple #19
0
def _calculate_series(sat_id: str,
        aos: datetime.datetime, los: datetime.datetime,
        location: Optional[Location]=None,
        time_step: Optional[datetime.timedelta]=None) \
    -> Tuple[Sequence[datetime.datetime], Sequence[float], Sequence[float]]:
    '''
    Produce data for plot charts

    Parameters
    ==========
    sat_id: str
        Satellite ID (name compatible with Celestrak)
    aos: datetime.datetime
        AOS date
    los: datetime.datetime
        LOS date
    location: orbit_predictor.locations.Location, optional
        Location of the station. If not provided it will be read from config
    time_step: datetime.timedelta, optional
        Time quantization factor for generate samples. Determines interval
        between samples. Default one minute.
        Too small value causes more accurate shape of chart, but plotille draws
        then thicker lines.
        Too big value causes low accurate (or false) chart.
    
    Returns
    =======
    date_series: sequence of datetime.datetime
        Dates for which samples were designated. In UTC.
    azimuth_series: sequence of float
        Series of azimuths in degrees.
    elevation_series: sequence of float
        Series of elevation angles in degrees.
    '''
    tzutc = tz.tzutc()
    if aos.tzinfo != tzutc:
        aos = aos.replace(tzinfo=tzutc)
    if los.tzinfo != tzutc:
        los = los.replace(tzinfo=tzutc)

    if time_step is None:
        time_step = datetime.timedelta(minutes=1)
    if location is None:
        config = open_config()
        location = Location(*get_location(config))

    db = OrbitDatabase()
    predictor = db.get_predictor(sat_id)

    date_series: List[datetime.datetime] = []
    azimuth_series: List[float] = []
    elevation_series: List[float] = []

    for date in DateTimeRange(aos, los).range(time_step):
        position = predictor.get_position(date)
        az, el = location.get_azimuth_elev_deg(position)
        date_series.append(date) # type: ignore
        azimuth_series.append(az)
        elevation_series.append(el)

    return date_series, azimuth_series, elevation_series
Exemple #20
0
 def setUp(self):
     self.location = Location("A random location",
                              latitude_deg=0,
                              longitude_deg=0,
                              elevation_m=0)
Exemple #21
0
 def as_op_location(self):
     """
     Return an equivalent orbit predictor Location.
     """
     return Location('position', latitude_deg=self.latitude, longitude_deg=self.longitude,
                     elevation_m=self.altitude)
Exemple #22
0
#!/usr/bin/env python3
from glob import glob
import datetime
import numpy as np

import matplotlib.pyplot as plt

from orbit_predictor.sources import EtcTLESource
from orbit_predictor.locations import Location
from orbit_predictor.predictors import Position

BNL_LOC = Location("BNL",
                   latitude_deg=40.878180,
                   longitude_deg=-72.856640,
                   elevation_m=79)
now_time = datetime.datetime(2018, 4, 2, 17, 58, 46, 22518)

sources = EtcTLESource("gps/3le.txt")
sources2 = EtcTLESource("gps/gps-ops.txt")

for sate_id in sources.satellite_list():
    if "USA" in sate_id:
        predictor = sources.get_predictor(sate_id, True)
        print(sate_id, predictor.get_position(now_time).position_llh)

for sate_id in sources2.satellite_list():
    predictor = sources2.get_predictor(sate_id, True)
    print(sate_id, predictor.get_position(now_time).position_ecef)
Exemple #23
0
        except StopIteration:
            raise LookupError("Job not found in CronTab.")
    else:
        sat_name = pass_target
        if args.aos is not None:
            aos: datetime.datetime = args.aos
            aos = aos.replace(tzinfo=tz.tzutc())
        else:
            aos = datetime.datetime.utcnow()
            aos = aos.replace(tzinfo=tz.tzutc())

    aos = aos.astimezone(tz.tzutc())
    db = OrbitDatabase()
    config = open_config()
    from orbit_predictor.locations import Location
    location = Location(*get_location(config))
    satellite = get_satellite(config, sat_name)
    predictor = db.get_predictor(sat_name)
    pass_ = predictor.get_next_pass(location, aos, 0, 0)

    target_tz = tz.tzutc() if args.print_utc else tz.tzlocal()

    print("Satellite:", sat_name)
    print("AOS:", str(pass_.aos.astimezone(target_tz)))
    print("LOS:", str(pass_.los.astimezone(target_tz)))
    print("Duration:", str(datetime.timedelta(seconds=pass_.duration_s)))
    print("Max elevation:", "%.2f" % (pass_.max_elevation_deg, ), "deg",
          str(pass_.max_elevation_date.astimezone(target_tz)))
    print("Off nadir", "%.2f" % (pass_.off_nadir_deg, ), "deg")

    import az_elev_chart
Exemple #24
0
import datetime
import unittest

from datetimerange import DateTimeRange
from orbit_predictor.predictors import PredictedPass
from orbit_predictor.locations import Location

import selectstrategy

def get_pass(location, name, aos, los, max_elevation, when_max_elevation = 0.5):
    duration_s = (los - aos).total_seconds()
    max_elevation_date = aos + datetime.timedelta(seconds=duration_s * when_max_elevation)
    return PredictedPass(location, name, max_elevation, aos, los, duration_s, max_elevation_date=max_elevation_date)

location = Location("TEST_LOC", 50, 20, 100)
start = datetime.datetime(2020, 1, 1, 0, 0, 0)
moments = {}
for i in range(10):
    moments[i] = start + datetime.timedelta(minutes=i)

class TestSelectStrategy(unittest.TestCase):
    #    | 0    1    2    3    4    5    6    7    8    9
    # 90 | |--- A ---|
    # 80 |      |- B |
    # 70 |      |-*- C --|
    # 60 |                          |--- D ---|
    # 50 |                     |--- E *--|
    # 40 |                     |-*- F ---|
    # 30 |                                    |--G |-- H |
    def setUp(self):
        A = get_pass(location, "A", moments[0], moments[2], 90)