コード例 #1
0
 def setUp(self):
     # Source
     self.db = MemoryTLESource()
     self.db.add_tle(BUGSAT_SATE_ID, BUGSAT1_TLE_LINES,
                     dt.datetime.utcnow())
     # Predictor
     self.predictor = TLEPredictor(BUGSAT_SATE_ID, self.db)
コード例 #2
0
class AccuratePredictorCalculationErrorTests(TestCase):
    """Check that we can learn from calculation errors and provide patches for corner cases"""
    def setUp(self):
        # Source
        self.db = MemoryTLESource()
        self.db.add_tle(BUGSAT_SATE_ID, BUGSAT1_TLE_LINES,
                        dt.datetime.utcnow())
        # Predictor
        self.predictor = TLEPredictor(BUGSAT_SATE_ID, self.db)
        self.is_ascending_mock = self._patch(
            'orbit_predictor.predictors.base.LocationPredictor._is_ascending')
        self.start = dt.datetime(2017, 3, 6, 7, 51)
        logassert.setup(self, 'orbit_predictor.predictors.pass_iterators')

    def _patch(self, *args, **kwargs):
        patcher = mock.patch(*args, **kwargs)
        self.addCleanup(patcher.stop)
        return patcher.start()

    def test_ascending_failure(self):
        self.is_ascending_mock.return_value = False
        with self.assertRaises(PropagationError):
            self.predictor.get_next_pass(
                ARG, self.start, location_predictor_class=LocationPredictor)

        self.assertLoggedError(str(ARG), str(self.start), *BUGSAT1_TLE_LINES)

    def test_descending_failure(self):
        self.is_ascending_mock.return_value = True
        with self.assertRaises(PropagationError):
            self.predictor.get_next_pass(
                ARG, self.start, location_predictor_class=LocationPredictor)

        self.assertLoggedError(str(ARG), str(self.start), *BUGSAT1_TLE_LINES)
コード例 #3
0
 def setUp(self):
     tle_lines = (
         "1 42760U 17034C   19070.46618549  .00000282  00000-0  30543-4 0  9995",
         "2 42760  43.0166  56.1509 0009676 356.3576 146.0151 15.09909885 95848",
     )
     self.db = MemoryTLESource()
     self.db.add_tle("42760U", tle_lines, dt.datetime.now())
     self.predictor = TLEPredictor("42760U", self.db)
コード例 #4
0
 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)
コード例 #5
0
 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(tortu1, when_utc=date)
コード例 #6
0
class SkippedPassesRegressionTests(TestCase):
    """Check that we do not skip passes"""

    # See https://github.com/satellogic/orbit-predictor/issues/99

    def setUp(self):
        self.db = MemoryTLESource()
        self.db.add_tle(TRICKY_SAT_ID, TRICKY_SAT_TLE_LINES, dt.datetime.now())
        self.predictor = TLEPredictor(TRICKY_SAT_ID, self.db)

    @pytest.mark.xfail(reason="Legacy LocationPredictor skips some passes")
    def test_pass_is_not_skipped_old(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=LocationPredictor,
            ))

        assert predicted_passes

    @pytest.mark.skipif(sys.version_info < (3, 5),
                        reason="Not installing SciPy in Python 3.4")
    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
コード例 #7
0
 def setUp(self):
     # Source
     self.db = MemoryTLESource()
     self.db.add_tle(BUGSAT_SATE_ID, BUGSAT1_TLE_LINES,
                     dt.datetime.utcnow())
     # Predictor
     self.predictor = TLEPredictor(BUGSAT_SATE_ID, self.db)
     self.is_ascending_mock = self._patch(
         'orbit_predictor.predictors.base.LocationPredictor._is_ascending')
     self.start = dt.datetime(2017, 3, 6, 7, 51)
     logassert.setup(self, 'orbit_predictor.predictors.pass_iterators')
コード例 #8
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)
コード例 #9
0
    def from_tle(cls, sate_id, source, date=None):
        """Returns approximate keplerian elements from TLE.

        The conversion between mean elements in the TEME reference
        frame to osculating elements in any standard reference frame
        is not well defined in literature (see Vallado 3rd edition, pp 236 to 240)

        """
        # Get latest TLE, or the one corresponding to a specified date
        if date is None:
            date = datetime.datetime.utcnow()

        tle = source.get_tle(sate_id, date)

        # Retrieve TLE epoch and corresponding position
        epoch = twoline2rv(tle.lines[0], tle.lines[1], wgs84).epoch
        pos = TLEPredictor(sate_id, source).get_position(epoch)

        # Convert position from ECEF to ECI
        gmst = gstime_from_datetime(epoch)
        position_eci = coordinate_systems.ecef_to_eci(pos.position_ecef, gmst)
        velocity_eci = coordinate_systems.ecef_to_eci(pos.velocity_ecef, gmst)

        # Convert position to Keplerian osculating elements
        p, ecc, inc, raan, argp, ta = rv2coe(wgs84.mu, np.array(position_eci),
                                             np.array(velocity_eci))
        sma = p / (1 - ecc**2)

        return cls(sma, ecc, degrees(inc), degrees(raan), degrees(argp),
                   degrees(ta), epoch)
コード例 #10
0
ファイル: sources.py プロジェクト: satellogic/orbit-predictor
def get_predictor_from_tle_lines(tle_lines):
    db = MemoryTLESource()
    sgp4_sat = Satrec.twoline2rv(tle_lines[0], tle_lines[1])
    db.add_tle(
        sgp4_sat.satnum,
        tuple(tle_lines),
        datetime_from_jday(sgp4_sat.jdsatepoch, sgp4_sat.jdsatepochF),
    )
    predictor = TLEPredictor(sgp4_sat.satnum, db)
    return predictor
コード例 #11
0
class AccurateVsGpredictTests(TestCase):
    def setUp(self):
        # Source
        self.db = MemoryTLESource()
        self.db.add_tle(BUGSAT_SATE_ID, BUGSAT1_TLE_LINES,
                        dt.datetime.utcnow())
        # Predictor
        self.predictor = TLEPredictor(BUGSAT_SATE_ID, self.db)

    def test_get_next_pass_with_stk_data(self):
        STK_DATA = """
        ------------------------------------------------------------------------------------------------
         AOS                      TCA                      LOS                      Duration      Max El
        ------------------------------------------------------------------------------------------------
         2014/10/23 01:27:33.224  2014/10/23 01:32:41.074  2014/10/23 01:37:47.944  00:10:14.720   12.76
         2014/10/23 03:01:37.007  2014/10/23 03:07:48.890  2014/10/23 03:14:01.451  00:12:24.000   39.32
         2014/10/23 14:49:34.783  2014/10/23 14:55:44.394  2014/10/23 15:01:51.154  00:12:16.000   41.75
         2014/10/23 16:25:54.939  2014/10/23 16:30:50.152  2014/10/23 16:35:44.984  00:09:50.000   11.45
         2014/10/24 01:35:47.889  2014/10/24 01:41:13.181  2014/10/24 01:46:37.548  00:10:50.000   16.07
         2014/10/24 03:10:23.486  2014/10/24 03:16:27.230  2014/10/24 03:22:31.865  00:12:08.000   30.62
         2014/10/24 14:58:07.378  2014/10/24 15:04:21.721  2014/10/24 15:10:33.546  00:12:26.000   54.83
         2014/10/24 16:34:48.635  2014/10/24 16:39:20.960  2014/10/24 16:43:53.204  00:09:04.000    8.78
         2014/10/25 01:44:05.771  2014/10/25 01:49:45.487  2014/10/25 01:55:24.414  00:11:18.000   20.07
         2014/10/25 03:19:12.611  2014/10/25 03:25:05.674  2014/10/25 03:30:59.815  00:11:47.000   24.09"""  # NOQA

        for line in STK_DATA.splitlines()[4:]:
            line_parts = line.split()
            aos = dt.datetime.strptime(" ".join(line_parts[:2]),
                                       '%Y/%m/%d %H:%M:%S.%f')
            max_elevation_date = dt.datetime.strptime(
                " ".join(line_parts[2:4]), '%Y/%m/%d %H:%M:%S.%f')
            los = dt.datetime.strptime(" ".join(line_parts[4:6]),
                                       '%Y/%m/%d %H:%M:%S.%f')
            duration = dt.datetime.strptime(line_parts[6], '%H:%M:%S.%f')
            duration_s = dt.timedelta(minutes=duration.minute,
                                      seconds=duration.second).total_seconds()
            max_elev_deg = float(line_parts[7])

            try:
                date = pass_.los  # NOQA
            except UnboundLocalError:
                date = dt.datetime.strptime("2014-10-22 20:18:11.921921",
                                            '%Y-%m-%d %H:%M:%S.%f')

            pass_ = self.predictor.get_next_pass(ARG, date)
            self.assertAlmostEqual(pass_.aos, aos, delta=ONE_SECOND)
            self.assertAlmostEqual(pass_.los, los, delta=ONE_SECOND)
            self.assertAlmostEqual(pass_.max_elevation_date,
                                   max_elevation_date,
                                   delta=ONE_SECOND)
            self.assertAlmostEqual(pass_.duration_s, duration_s, delta=2 * 1)
            self.assertAlmostEqual(pass_.max_elevation_deg,
                                   max_elev_deg,
                                   delta=0.05)
コード例 #12
0
    def from_tle(cls, sate_id, source, date=None):
        """Returns approximate keplerian elements from TLE.

        The conversion between mean elements in the TEME reference
        frame to osculating elements in any standard reference frame
        is not well defined in literature (see Vallado 3rd edition, pp 236 to 240)

        """
        # Get latest TLE, or the one corresponding to a specified date
        if date is None:
            date = dt.datetime.utcnow()

        # Retrieve TLE position at given date as starting point
        pos = TLEPredictor(sate_id, source).get_position(date)

        return cls(*pos.osculating_elements, epoch=date)
コード例 #13
0
class LOSComputationRegressionTests(TestCase):
    """Check that the LOS is computed correctly"""

    # See https://github.com/satellogic/orbit-predictor/issues/104

    def setUp(self):
        tle_lines = (
            "1 42760U 17034C   19070.46618549  .00000282  00000-0  30543-4 0  9995",
            "2 42760  43.0166  56.1509 0009676 356.3576 146.0151 15.09909885 95848",
        )
        self.db = MemoryTLESource()
        self.db.add_tle("42760U", tle_lines, dt.datetime.now())
        self.predictor = TLEPredictor("42760U", self.db)

    @pytest.mark.skipif(sys.version_info < (3, 5),
                        reason="Not installing SciPy in Python 3.4")
    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
コード例 #14
0
    def get_predictor(self, sate_id, precise=False):
        """Return a Predictor instance using the current storage."""
        if precise:
            return HighAccuracyTLEPredictor(sate_id, self)

        return TLEPredictor(sate_id, self)
コード例 #15
0
 def setUpClass(cls):
     # Source
     cls.db = MemoryTLESource()
     cls.db.add_tle(SATE_ID, BUGSAT1_TLE_LINES, datetime.datetime.now())
     # Predictor
     cls.predictor = TLEPredictor(SATE_ID, cls.db)
コード例 #16
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)
コード例 #17
0
ファイル: sources.py プロジェクト: rak183/orbit-predictor
def get_predictor_from_tle_lines(tle_lines):
    db = MemoryTLESource()
    sgp4_sat = twoline2rv(tle_lines[0], tle_lines[1], wgs84)
    db.add_tle(sgp4_sat.satnum, tuple(tle_lines), sgp4_sat.epoch)
    predictor = TLEPredictor(sgp4_sat.satnum, db)
    return predictor
コード例 #18
0
 def setUp(self):
     self.db = MemoryTLESource()
     self.db.add_tle(TRICKY_SAT_ID, TRICKY_SAT_TLE_LINES, dt.datetime.now())
     self.predictor = TLEPredictor(TRICKY_SAT_ID, self.db)
コード例 #19
0
ファイル: sources.py プロジェクト: rak183/orbit-predictor
 def get_predictor(self, sate_id):
     """Return a Predictor instance using the current storage."""
     return TLEPredictor(sate_id, self)
コード例 #20
0
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)
コード例 #21
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)
コード例 #22
0
ファイル: lat_lon.py プロジェクト: prasunkgupta/TrackSat
import matplotlib.pyplot as plt

import cartopy.crs as ccrs

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"],