From 4dab9464d37b1952544aae3f4fdcf99d065f485e 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 | 16 +++++++------- tle_sat/satellite_test.py | 46 ++++++++++++++++++++++++++++++++++----- 2 files changed, 48 insertions(+), 14 deletions(-) diff --git a/tle_sat/satellite.py b/tle_sat/satellite.py index 3711fbd..e7d8438 100644 --- a/tle_sat/satellite.py +++ b/tle_sat/satellite.py @@ -163,24 +163,24 @@ def footprint( self, t: datetime | Time, view_angles: ViewAngles, fov=FieldOfView(2.0, 2.0) ) -> Polygon: try: - fr = self.los( + 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, ) - fl = self.los( + 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, ) - rl = self.los( + 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, ) - rr = self.los( + 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, ) except OverflowError as exc: diff --git a/tle_sat/satellite_test.py b/tle_sat/satellite_test.py index 867c4fe..d9bd4a4 100644 --- a/tle_sat/satellite_test.py +++ b/tle_sat/satellite_test.py @@ -105,11 +105,11 @@ def test_view_angles(polar_tle, t, o, v): nullcontext( Polygon( ( - (127.7379246591503, 76.95181009374622), - (129.391022866435, 77.1132119968597), - (128.95920974658245, 77.3478604621005), - (127.26201922293443, 77.19358515346873), - (127.7379246591503, 76.95181009374622), + (175.60359680143947, 76.98714113663245), + (177.22394652541345, 76.81734966236745), + (177.71903131823174, 77.05665979118999), + (176.05545933500957, 77.21951692944646), + (175.60359680143947, 76.98714113663245), ) ) ), @@ -130,10 +130,44 @@ def test_footprint(polar_tle, t, v, f, expectation): assert _precision(e, 8).equals(_precision(footprint, 8)) if isinstance(e, Polygon): - assert is_ccw(e.exterior) + assert is_ccw(footprint.exterior) 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", (