update position decoding, handle surface position messages, error fix in vertical rate calculation.
This commit is contained in:
parent
556e499064
commit
2fccacd724
@ -60,7 +60,7 @@ Core functions for ADS-B decoding:
|
||||
|
||||
pms.adsb.icao(msg)
|
||||
pms.adsb.callsign(msg)
|
||||
pms.adsb.position(msg_odd, msg_even, t_odd, t_even)
|
||||
pms.adsb.position(msg_even, msg_odd, t_even, t_odd)
|
||||
pms.adsb.altitude(msg)
|
||||
pms.adsb.velocity(msg)
|
||||
pms.adsb.speed_heading(msg)
|
||||
|
@ -222,11 +222,99 @@ def airborne_position(msg0, msg1, t0, t1):
|
||||
return round(lat, 5), round(lon, 5)
|
||||
|
||||
|
||||
def position_with_ref(msg, lat_ref, lon_ref):
|
||||
if 5 <= typecode(msg) <= 8:
|
||||
return airborne_position_with_ref(msg, lat_ref, lon_ref)
|
||||
|
||||
elif 9 <= typecode(msg) <= 18:
|
||||
return surface_position_with_ref(msg, lat_ref, lon_ref)
|
||||
|
||||
else:
|
||||
raise RuntimeError("incorrect or inconsistant message types")
|
||||
|
||||
|
||||
def airborne_position_with_ref(msg, lat_ref, lon_ref):
|
||||
"""Decode airborn position with one message,
|
||||
knowing previous reference location
|
||||
Args:
|
||||
msg (string): even message (28 bytes hexadecimal string)
|
||||
lat_ref: previous known latitude
|
||||
lon_ref: previous known longitude
|
||||
Returns:
|
||||
(float, float): (latitude, longitude) of the aircraft
|
||||
"""
|
||||
|
||||
i = oe_flag(msg)
|
||||
d_lat = 360.0/59 if i else 360.0/60
|
||||
|
||||
msgbin = util.hex2bin(msg)
|
||||
cprlat = util.bin2int(msgbin[54:71]) / 131072.0
|
||||
cprlon = util.bin2int(msgbin[71:88]) / 131072.0
|
||||
|
||||
j = util.floor(lat_ref / d_lat) \
|
||||
+ util.floor(0.5 + ((lat_ref % d_lat) / d_lat) - cprlat)
|
||||
|
||||
lat = d_lat * (j + cprlat)
|
||||
|
||||
ni = _cprNL(lat) - i
|
||||
|
||||
if ni > 0:
|
||||
d_lon = 360.0 / ni
|
||||
else:
|
||||
d_lon = 360.0
|
||||
|
||||
m = util.floor(lon_ref / d_lon) \
|
||||
+ util.floor(0.5 + ((lon_ref % d_lon) / d_lon) - cprlon)
|
||||
|
||||
lon = d_lon * (m + cprlon)
|
||||
|
||||
return round(lat, 5), round(lon, 5)
|
||||
|
||||
|
||||
def surface_position(msg0, msg1, t0, t1):
|
||||
# TODO: implement surface positon decoding
|
||||
# TODO: implement surface positon
|
||||
raise RuntimeError('suface position decoding to be implemented soon...')
|
||||
|
||||
|
||||
def surface_position_with_ref(msg, lat_ref, lon_ref):
|
||||
"""Decode surface position with one message,
|
||||
knowing reference nearby location, such as previously calculated location,
|
||||
ground station, or airport location, etc.
|
||||
Args:
|
||||
msg (string): even message (28 bytes hexadecimal string)
|
||||
lat_ref: previous known latitude
|
||||
lon_ref: previous known longitude
|
||||
Returns:
|
||||
(float, float): (latitude, longitude) of the aircraft
|
||||
"""
|
||||
|
||||
i = oe_flag(msg)
|
||||
d_lat = 90.0/59 if i else 90.0/60
|
||||
|
||||
msgbin = util.hex2bin(msg)
|
||||
cprlat = util.bin2int(msgbin[54:71]) / 131072.0
|
||||
cprlon = util.bin2int(msgbin[71:88]) / 131072.0
|
||||
|
||||
j = util.floor(lat_ref / d_lat) \
|
||||
+ util.floor(0.5 + ((lat_ref % d_lat) / d_lat) - cprlat)
|
||||
|
||||
lat = d_lat * (j + cprlat)
|
||||
|
||||
ni = _cprNL(lat) - i
|
||||
|
||||
if ni > 0:
|
||||
d_lon = 360.0 / ni
|
||||
else:
|
||||
d_lon = 360.0
|
||||
|
||||
m = util.floor(lon_ref / d_lon) \
|
||||
+ util.floor(0.5 + ((lon_ref % d_lon) / d_lon) - cprlon)
|
||||
|
||||
lon = d_lon * (m + cprlon)
|
||||
|
||||
return round(lat, 5), round(lon, 5)
|
||||
|
||||
|
||||
def _cprNL(lat):
|
||||
if lat == 0:
|
||||
return 59
|
||||
@ -356,8 +444,8 @@ def velocity(msg):
|
||||
tag = 'AS'
|
||||
|
||||
vr_sign = util.bin2int(msgbin[68])
|
||||
vr = util.bin2int(msgbin[68:77]) # vertical rate
|
||||
rocd = -1*vr if vr_sign else vr # rate of climb/descend
|
||||
vr = util.bin2int(msgbin[69:78]) # vertical rate
|
||||
rocd = -1*vr if vr_sign else vr # rate of climb/descend
|
||||
|
||||
return int(spd), round(hdg, 1), int(rocd), tag
|
||||
|
||||
|
35
tests/run.py
35
tests/run.py
@ -39,13 +39,28 @@ def test_adsb_callsign():
|
||||
assert adsb.callsign("8D406B902015A678D4D220AA4BDA") == "EZY85MH_"
|
||||
|
||||
|
||||
def test_adsb_position():
|
||||
pos = adsb.position("8D40058B58C901375147EFD09357",
|
||||
"8D40058B58C904A87F402D3B8C59",
|
||||
1446332400, 1446332405)
|
||||
def test_adsb_airborne_position():
|
||||
pos = adsb.airborne_position("8D40058B58C901375147EFD09357",
|
||||
"8D40058B58C904A87F402D3B8C59",
|
||||
1446332400, 1446332405)
|
||||
assert pos == (49.81755, 6.08442)
|
||||
|
||||
|
||||
def test_adsb_airborne_position_with_ref():
|
||||
pos = adsb.airborne_position_with_ref("8D40058B58C901375147EFD09357",
|
||||
49.0, 6.0)
|
||||
assert pos == (49.82410, 6.06785)
|
||||
pos = adsb.airborne_position_with_ref("8D40058B58C904A87F402D3B8C59",
|
||||
49.0, 6.0)
|
||||
assert pos == (49.81755, 6.08442)
|
||||
|
||||
|
||||
def test_adsb_surface_position_with_ref():
|
||||
pos = adsb.surface_position_with_ref("8FC8200A3AB8F5F893096B22B4A8",
|
||||
-43.5, 172.5)
|
||||
assert pos == (-43.48564, 175.87195)
|
||||
|
||||
|
||||
def test_adsb_alt():
|
||||
assert adsb.altitude("8D40058B58C901375147EFD09357") == 39000
|
||||
|
||||
@ -53,8 +68,8 @@ def test_adsb_alt():
|
||||
def test_adsb_velocity():
|
||||
vgs = adsb.velocity("8D485020994409940838175B284F")
|
||||
vas = adsb.velocity("8DA05F219B06B6AF189400CBC33F")
|
||||
assert vgs == (159, 182.9, -263, 'GS')
|
||||
assert vas == (376, 244.0, -274, 'AS')
|
||||
assert vgs == (159, 182.9, -14, 'GS')
|
||||
assert vas == (376, 244.0, -37, 'AS')
|
||||
|
||||
|
||||
def test_nic():
|
||||
@ -183,5 +198,9 @@ def ehs_decode_all(n=None):
|
||||
print ts, m, icao, vBDS
|
||||
|
||||
if __name__ == '__main__':
|
||||
adsb_decode_all(100)
|
||||
ehs_decode_all(100)
|
||||
# adsb_decode_all(100)
|
||||
# ehs_decode_all(100)
|
||||
|
||||
|
||||
adsb.airborne_position_with_ref("8D40058B58C901375147EFD09357",
|
||||
49.0, 6.0)
|
Loading…
Reference in New Issue
Block a user