From 60828ba200c0d35d3e1eae261eaee7f6af49e776 Mon Sep 17 00:00:00 2001 From: Christian Wygoda Date: Thu, 30 Jan 2025 09:32:05 +0100 Subject: [PATCH] fix: footprint was calculated on wrong side of orbit --- tle_sat/satellite.py | 8 ++++---- tle_sat/satellite_test.py | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/tle_sat/satellite.py b/tle_sat/satellite.py index 3711fbd..954acb9 100644 --- a/tle_sat/satellite.py +++ b/tle_sat/satellite.py @@ -165,22 +165,22 @@ def footprint( try: fr = self.los( t, - -view_angles.across - 0.5 * fov.x, + view_angles.across + 0.5 * fov.x, view_angles.along + 0.5 * fov.y, ) fl = self.los( t, - -view_angles.across + 0.5 * fov.x, + view_angles.across - 0.5 * fov.x, view_angles.along + 0.5 * fov.y, ) rl = self.los( t, - -view_angles.across + 0.5 * fov.x, + view_angles.across - 0.5 * fov.x, view_angles.along - 0.5 * fov.y, ) rr = self.los( t, - -view_angles.across - 0.5 * fov.x, + view_angles.across + 0.5 * fov.x, view_angles.along - 0.5 * fov.y, ) except OverflowError as exc: diff --git a/tle_sat/satellite_test.py b/tle_sat/satellite_test.py index 867c4fe..3026181 100644 --- a/tle_sat/satellite_test.py +++ b/tle_sat/satellite_test.py @@ -134,6 +134,40 @@ def test_footprint(polar_tle, t, v, f, expectation): assert all(not is_ccw(interior) for interior in e.interiors) +@mark.parametrize( + "target,t,footprint", + ( + ( + Point(13, 53, 0), + datetime(2024, 4, 19, 21, 39, 59, tzinfo=timezone.utc), + Polygon( + ( + (13.20496447259038, 52.87415752284107), + (12.758567800131482, 52.90986652401911), + (12.799711072078717, 53.12031287404936), + (13.249444062185855, 53.090245713914435), + (13.20496447259038, 52.87415752284107), + ) + ), + ), + ), +) +def test_pass_footprint(polar_tle, target: Point, t: datetime, footprint: Polygon): + sat = Satellite(polar_tle) + + passes = sat.passes( + TimeOfInterest(t - timedelta(minutes=15), t + timedelta(minutes=15)), target + ) + assert len(passes) == 1 + p = passes[0] + + actual_footprint = sat.footprint(t=p.t, view_angles=p.view_angles) + + assert _precision(footprint, 8).equals(_precision(actual_footprint, 8)) + assert actual_footprint.contains(target) + assert _precision(footprint.centroid, 2).equals(_precision(target, 2)) + + @mark.parametrize( "t,target,passes", (