Exemplo n.º 1
0
    def test_from_tle_returns_same_initial_conditions_on_epoch(self):
        start = datetime(2017, 3, 6, 7, 51)
        db = MemoryTLESource()
        db.add_tle(self.SATE_ID, self.LINES, start)

        keplerian_predictor = KeplerianPredictor.from_tle(self.SATE_ID, db, start)
        tle_predictor = TLEPredictor(self.SATE_ID, db)

        epoch = keplerian_predictor._epoch

        pos_keplerian = keplerian_predictor.get_position(epoch)
        pos_tle = tle_predictor.get_position(epoch)

        assert_allclose(pos_keplerian.position_ecef, pos_tle.position_ecef, rtol=1e-11)
        assert_allclose(pos_keplerian.velocity_ecef, pos_tle.velocity_ecef, rtol=1e-13)
Exemplo n.º 2
0
class AccuratePredictorTests(TestCase):
    def setUp(self):
        # Source
        self.db = MemoryTLESource()
        self.start = datetime(2017, 3, 6, 7, 51)
        self.db.add_tle(SATE_ID, LINES, self.start)
        # Predictor
        self.predictor = HighAccuracyTLEPredictor(SATE_ID, self.db)
        self.old_predictor = TLEPredictor(SATE_ID, self.db)
        self.end = self.start + timedelta(days=5)

    def all_passes_old_predictor(self, location, start, end):
        while True:
            try:
                pass_ = self.old_predictor.get_next_pass(location,
                                                         when_utc=start,
                                                         limit_date=end)
                start = pass_.los
                yield pass_
            except Exception:
                break

    def assertEqualOrGreaterPassesAmount(self, location):
        """Compare propagators and check no passes lost and no performance degradation"""
        t0 = time.time()
        old_passes = list(
            self.all_passes_old_predictor(location, self.start, self.end))
        t1 = time.time()
        predicted_passes = list(
            self.predictor.passes_over(location, self.start, self.end))
        t2 = time.time()
        self.assertGreaterEqual(len(predicted_passes), len(old_passes),
                                'We are loosing passes')
        self.assertLessEqual(t2 - t1, t1 - t0, 'Performance is degraded')

    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 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_have_elevation_positive_and_visible_on_date(
            self):
        end = self.start + timedelta(days=60)
        for pass_ in self.predictor.passes_over(svalbard, self.start, end):
            self.assertGreater(pass_.max_elevation_deg, 0)
            position = self.old_predictor.get_position(
                pass_.max_elevation_date)
            svalbard.is_visible(position)
            self.assertGreaterEqual(pass_.off_nadir_deg, -90)
            self.assertLessEqual(pass_.off_nadir_deg, 90)

    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)

    @given(start=datetimes(
        min_value=datetime(2017, 1, 1),
        max_value=datetime(2020, 12, 31),
    ),
           location=tuples(floats(min_value=-90, max_value=90),
                           floats(min_value=0, max_value=180),
                           floats(min_value=-200, max_value=9000)))
    @settings(max_examples=10000, deadline=None)
    @example(start=datetime(2017, 1, 26, 11, 51, 51),
             location=(-37.69358328273305, 153.96875, 0.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)

    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)

    def test_predicted_passes_whit_aos(self):
        end = self.start + timedelta(days=60)
        for pass_ in self.predictor.passes_over(svalbard,
                                                self.start,
                                                end,
                                                aos_at_dg=5):
            self.assertGreater(pass_.max_elevation_deg, 5)
            position = self.old_predictor.get_position(pass_.aos)
            _, elev = svalbard.get_azimuth_elev_deg(position)
            self.assertAlmostEqual(elev, 5, delta=0.1)
Exemplo n.º 3
0
class LocationTestCase(unittest.TestCase):
    def setUp(self):
        # Source
        self.db = MemoryTLESource()
        self.db.add_tle(SATE_ID, BUGSAT1_TLE_LINES, datetime.datetime.now())
        # Predictor
        self.predictor = TLEPredictor(SATE_ID, self.db)
        date = datetime.datetime.strptime("2014-10-22 20:18:11.921921",
                                          '%Y-%m-%d %H:%M:%S.%f')
        self.next_pass = self.predictor.get_next_pass(ARG, when_utc=date)

    def test_compare_eq(self):
        l1 = Location(latitude_deg=1,
                      longitude_deg=2,
                      elevation_m=3,
                      name="location1")
        l2 = Location(latitude_deg=1,
                      longitude_deg=2,
                      elevation_m=3,
                      name="location1")

        self.assertEqual(l1, l2)
        self.assertEqual(l2, l1)

    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)

    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)

    def test_get_azimuth_elev(self):
        date = datetime.datetime.strptime("2014-10-21 22:47:29.147740",
                                          '%Y-%m-%d %H:%M:%S.%f')
        azimuth, elevation = ARG.get_azimuth_elev(
            self.predictor.get_position(date))

        self.assertAlmostEqual(degrees(azimuth), 249.7, delta=0.1)
        self.assertAlmostEqual(degrees(elevation), -52.1, delta=0.1)

    def test_get_azimuth_elev_deg(self):
        date = datetime.datetime.strptime("2014-10-21 22:47:29.147740",
                                          '%Y-%m-%d %H:%M:%S.%f')
        azimuth, elevation = ARG.get_azimuth_elev_deg(
            self.predictor.get_position(date))

        self.assertAlmostEqual(azimuth, 249.7, delta=0.1)
        self.assertAlmostEqual(elevation, -52.1, delta=0.1)

    def test_is_visible(self):
        position = self.predictor.get_position(self.next_pass.aos)
        self.assertTrue(ARG.is_visible(position))

    def test_no_visible(self):
        position = self.predictor.get_position(self.next_pass.los +
                                               datetime.timedelta(minutes=10))
        self.assertFalse(ARG.is_visible(position))

    def test_is_visible_with_deg(self):
        position = self.predictor.get_position(self.next_pass.aos +
                                               datetime.timedelta(minutes=4))
        # 21 deg
        self.assertTrue(ARG.is_visible(position, elevation=4))

    def test_no_visible_with_deg(self):
        position = self.predictor.get_position(self.next_pass.aos +
                                               datetime.timedelta(minutes=4))
        # 21 deg
        self.assertFalse(ARG.is_visible(position, elevation=30))

    def test_doppler_factor(self):
        date = datetime.datetime.strptime("2014-10-21 23:06:11.132438",
                                          '%Y-%m-%d %H:%M:%S.%f')
        position = self.predictor.get_position(date)
        doppler_factor = ARG.doppler_factor(position)

        self.assertAlmostEqual((2 - doppler_factor) * 437.445e6,
                               437.445632e6,
                               delta=100)
class AccuratePredictorTests(TestCase):
    def setUp(self):
        # Source
        self.db = MemoryTLESource()
        self.start = dt.datetime(2017, 3, 6, 7, 51)
        self.db.add_tle(SATE_ID, LINES, self.start)
        # Predictor
        self.predictor = TLEPredictor(SATE_ID, self.db)
        self.end = self.start + dt.timedelta(days=5)

    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 + dt.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)

    def test_predicted_passes_have_elevation_positive_and_visible_on_date(
            self):
        end = self.start + dt.timedelta(days=60)
        for pass_ in self.predictor.passes_over(ARG, self.start, end):
            self.assertGreater(pass_.max_elevation_deg, 0)
            position = self.predictor.get_position(pass_.max_elevation_date)
            ARG.is_visible(position)
            self.assertGreaterEqual(pass_.off_nadir_deg, -90)
            self.assertLessEqual(pass_.off_nadir_deg, 90)

    def test_predicted_passes_off_nadir_angle_works(self):
        start = dt.datetime(2017, 3, 6, 13, 30)
        end = start + dt.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)

    @given(start=datetimes(
        min_value=dt.datetime(2017, 1, 1),
        max_value=dt.datetime(2020, 12, 31),
    ),
           location=tuples(floats(min_value=-90, max_value=90),
                           floats(min_value=0, max_value=180),
                           floats(min_value=-200, max_value=9000)))
    @settings(max_examples=10000, deadline=None)
    @example(start=dt.datetime(2017, 1, 26, 11, 51, 51),
             location=(-37.69358328273305, 153.96875, 0.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)

    def test_aos_deg_can_be_used_in_get_next_pass(self):
        start = dt.datetime(2017, 3, 6, 13, 30)
        end = start + dt.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=dt.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.predictor.get_position(pass_with_aos.aos)
        _, elev = location.get_azimuth_elev_deg(position)

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

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

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

    def test_predicted_passes_whit_aos(self):
        end = self.start + dt.timedelta(days=60)
        for pass_ in self.predictor.passes_over(ARG,
                                                self.start,
                                                end,
                                                aos_at_dg=5):
            self.assertGreater(pass_.max_elevation_deg, 5)
            position = self.predictor.get_position(pass_.aos)
            _, elev = ARG.get_azimuth_elev_deg(position)
            self.assertAlmostEqual(elev, 5, delta=0.1)
Exemplo n.º 5
0
import pandas as pd

from orbit_predictor.sources import EtcTLESource
from orbit_predictor.predictors import TLEPredictor

source = EtcTLESource(filename=r'e:/resource.txt')
#source = EtcTLESource(filename=r'd:/visual.txt')
predictor = TLEPredictor("WORLDVIEW-2 (WV-2)      ", source)
#predictor = TLEPredictor('ATLAS CENTAUR 2         ', source)

dates = pd.date_range(start="2018-04-01 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)

latlon.plot()

plt.figure(figsize=(15, 25))
ax = plt.axes(projection=ccrs.PlateCarree())
ax.stock_img()

plt.plot(
    latlon["lon"],
    latlon["lat"],
    'red',
    transform=ccrs.Geodetic(),
    linestyle=":",
)