diff --git a/src/pyModeS/decoder/bds/bds05.py b/src/pyModeS/decoder/bds/bds05.py index 0dc8b8b..08e07c0 100644 --- a/src/pyModeS/decoder/bds/bds05.py +++ b/src/pyModeS/decoder/bds/bds05.py @@ -110,9 +110,8 @@ def airborne_position_with_ref( i = int(mb[21]) d_lat = 360 / 59 if i else 360 / 60 - j = common.floor(lat_ref / d_lat) + common.floor( - 0.5 + ((lat_ref % d_lat) / d_lat) - cprlat - ) + # From 1090 MOPS, Vol.1 DO-260C, A.1.7.5 + j = common.floor(0.5 + lat_ref / d_lat - cprlat) lat = d_lat * (j + cprlat) @@ -123,9 +122,7 @@ def airborne_position_with_ref( else: d_lon = 360 - m = common.floor(lon_ref / d_lon) + common.floor( - 0.5 + ((lon_ref % d_lon) / d_lon) - cprlon - ) + m = common.floor(0.5 + lon_ref / d_lon - cprlon) lon = d_lon * (m + cprlon) diff --git a/src/pyModeS/decoder/bds/bds06.py b/src/pyModeS/decoder/bds/bds06.py index 14b2a2f..d108033 100644 --- a/src/pyModeS/decoder/bds/bds06.py +++ b/src/pyModeS/decoder/bds/bds06.py @@ -119,9 +119,8 @@ def surface_position_with_ref( i = int(mb[21]) d_lat = 90 / 59 if i else 90 / 60 - j = common.floor(lat_ref / d_lat) + common.floor( - 0.5 + ((lat_ref % d_lat) / d_lat) - cprlat - ) + # From 1090 MOPS, Vol.1 DO-260C, A.1.7.6 + j = common.floor(0.5 + lat_ref / d_lat - cprlat) lat = d_lat * (j + cprlat) @@ -132,9 +131,7 @@ def surface_position_with_ref( else: d_lon = 90 - m = common.floor(lon_ref / d_lon) + common.floor( - 0.5 + ((lon_ref % d_lon) / d_lon) - cprlon - ) + m = common.floor(0.5 + lon_ref / d_lon - cprlon) lon = d_lon * (m + cprlon) diff --git a/tests/test_adsb.py b/tests/test_adsb.py index 9c7f5d4..ac57bca 100644 --- a/tests/test_adsb.py +++ b/tests/test_adsb.py @@ -54,6 +54,15 @@ def test_adsb_airborne_position_with_ref(): assert pos == (approx(49.81755, 0.001), approx(6.08442, 0.001)) +def test_adsb_airborne_position_with_ref_numerical_challenge(): + lat_ref = 30.508474576271183 # Close to (360.0/59.0)*5 + lon_ref = 7.2*5.0+3e-15 + pos = adsb.airborne_position_with_ref( + "8D06A15358BF17FF7D4A84B47B95", lat_ref, lon_ref + ) + assert pos == (approx(30.50540, 0.001), approx(33.44787, 0.001)) + + def test_adsb_surface_position_with_ref(): pos = adsb.surface_position_with_ref( "8FC8200A3AB8F5F893096B000000", -43.5, 172.5