update airborne_position(), allow swapping the odd and even messages

This commit is contained in:
Junzi Sun 2019-09-10 14:47:15 +02:00
parent 0eb333ba8c
commit 695fc34988
2 changed files with 37 additions and 21 deletions

View File

@ -24,6 +24,7 @@
from __future__ import absolute_import, print_function, division from __future__ import absolute_import, print_function, division
from pyModeS.decoder import common from pyModeS.decoder import common
def airborne_position(msg0, msg1, t0, t1): def airborne_position(msg0, msg1, t0, t1):
"""Decode airborn position from a pair of even and odd position message """Decode airborn position from a pair of even and odd position message
@ -40,6 +41,16 @@ def airborne_position(msg0, msg1, t0, t1):
mb0 = common.hex2bin(msg0)[32:] mb0 = common.hex2bin(msg0)[32:]
mb1 = common.hex2bin(msg1)[32:] mb1 = common.hex2bin(msg1)[32:]
oe0 = int(mb0[21])
oe1 = int(mb1[21])
if oe0 == 0 and oe1 == 1:
pass
elif oe0 == 1 and oe1 == 0:
mb0, mb1 = mb1, mb0
t0, t1 = t1, t0
else:
raise RuntimeError("Both even and odd CPR frames are required.")
# 131072 is 2^17, since CPR lat and lon are 17 bits each. # 131072 is 2^17, since CPR lat and lon are 17 bits each.
cprlat_even = common.bin2int(mb0[22:39]) / 131072.0 cprlat_even = common.bin2int(mb0[22:39]) / 131072.0
cprlon_even = common.bin2int(mb0[39:56]) / 131072.0 cprlon_even = common.bin2int(mb0[39:56]) / 131072.0
@ -66,7 +77,7 @@ def airborne_position(msg0, msg1, t0, t1):
return None return None
# compute ni, longitude index m, and longitude # compute ni, longitude index m, and longitude
if (t0 > t1): if t0 > t1:
lat = lat_even lat = lat_even
nl = common.cprNL(lat) nl = common.cprNL(lat)
ni = max(common.cprNL(lat) - 0, 1) ni = max(common.cprNL(lat) - 0, 1)
@ -100,7 +111,6 @@ def airborne_position_with_ref(msg, lat_ref, lon_ref):
(float, float): (latitude, longitude) of the aircraft (float, float): (latitude, longitude) of the aircraft
""" """
mb = common.hex2bin(msg)[32:] mb = common.hex2bin(msg)[32:]
cprlat = common.bin2int(mb[22:39]) / 131072.0 cprlat = common.bin2int(mb[22:39]) / 131072.0
@ -109,8 +119,9 @@ def airborne_position_with_ref(msg, lat_ref, lon_ref):
i = int(mb[21]) i = int(mb[21])
d_lat = 360.0 / 59 if i else 360.0 / 60 d_lat = 360.0 / 59 if i else 360.0 / 60
j = common.floor(lat_ref / d_lat) \ j = common.floor(lat_ref / d_lat) + common.floor(
+ common.floor(0.5 + ((lat_ref % d_lat) / d_lat) - cprlat) 0.5 + ((lat_ref % d_lat) / d_lat) - cprlat
)
lat = d_lat * (j + cprlat) lat = d_lat * (j + cprlat)
@ -121,8 +132,9 @@ def airborne_position_with_ref(msg, lat_ref, lon_ref):
else: else:
d_lon = 360.0 d_lon = 360.0
m = common.floor(lon_ref / d_lon) \ m = common.floor(lon_ref / d_lon) + common.floor(
+ common.floor(0.5 + ((lon_ref % d_lon) / d_lon) - cprlon) 0.5 + ((lon_ref % d_lon) / d_lon) - cprlon
)
lon = d_lon * (m + cprlon) lon = d_lon * (m + cprlon)

View File

@ -25,6 +25,16 @@ def test_adsb_position():
assert pos == (49.81755, 6.08442) assert pos == (49.81755, 6.08442)
def test_adsb_position_swap_odd_even():
pos = adsb.position(
"8D40058B58C904A87F402D3B8C59",
"8D40058B58C901375147EFD09357",
1446332405,
1446332400,
)
assert pos == (49.81755, 6.08442)
def test_adsb_position_with_ref(): def test_adsb_position_with_ref():
pos = adsb.position_with_ref("8D40058B58C901375147EFD09357", 49.0, 6.0) pos = adsb.position_with_ref("8D40058B58C901375147EFD09357", 49.0, 6.0)
assert pos == (49.82410, 6.06785) assert pos == (49.82410, 6.06785)
@ -33,20 +43,14 @@ def test_adsb_position_with_ref():
def test_adsb_airborne_position_with_ref(): def test_adsb_airborne_position_with_ref():
pos = adsb.airborne_position_with_ref( pos = adsb.airborne_position_with_ref("8D40058B58C901375147EFD09357", 49.0, 6.0)
"8D40058B58C901375147EFD09357", 49.0, 6.0
)
assert pos == (49.82410, 6.06785) assert pos == (49.82410, 6.06785)
pos = adsb.airborne_position_with_ref( pos = adsb.airborne_position_with_ref("8D40058B58C904A87F402D3B8C59", 49.0, 6.0)
"8D40058B58C904A87F402D3B8C59", 49.0, 6.0
)
assert pos == (49.81755, 6.08442) assert pos == (49.81755, 6.08442)
def test_adsb_surface_position_with_ref(): def test_adsb_surface_position_with_ref():
pos = adsb.surface_position_with_ref( pos = adsb.surface_position_with_ref("8FC8200A3AB8F5F893096B000000", -43.5, 172.5)
"8FC8200A3AB8F5F893096B000000", -43.5, 172.5
)
assert pos == (-43.48564, 172.53942) assert pos == (-43.48564, 172.53942)