add surface velocity decoding from msg TC:5-8

This commit is contained in:
junzis 2017-03-07 13:41:07 +01:00
parent 2b3e2c62d0
commit 15f2833aee
3 changed files with 79 additions and 8 deletions

View File

@ -72,8 +72,12 @@ Core functions for ADS-B decoding:
pms.adsb.surface_position_with_ref(msg, lat_ref, lon_ref) pms.adsb.surface_position_with_ref(msg, lat_ref, lon_ref)
pms.adsb.altitude(msg) pms.adsb.altitude(msg)
pms.adsb.velocity(msg)
pms.adsb.speed_heading(msg) pms.adsb.velocity(msg) # handles both surface & airborne messages
pms.adsb.speed_heading(msg) # handles both surface & airborne messages
pms.adsb.surface_velocity(msg)
pms.adsb.airborne_velocity(msg)
**Hint: When you have a fix position of the aircraft, it is convenient to **Hint: When you have a fix position of the aircraft, it is convenient to
use `position_with_ref()` method to decode with only one position message use `position_with_ref()` method to decode with only one position message

View File

@ -534,6 +534,42 @@ def nic(msg):
def velocity(msg): def velocity(msg):
"""Calculate the speed, heading, and vertical rate """Calculate the speed, heading, and vertical rate
(handles both airborne or surface message)
Args:
msg (string): 28 bytes hexadecimal message string
Returns:
(int, float, int, string): speed (kt), heading (degree),
rate of climb/descend (ft/min), and speed type
('GS' for ground speed, 'AS' for airspeed)
"""
if 5 <= typecode(msg) <= 8:
return surface_velocity(msg)
elif typecode(msg) == 19:
return airborne_velocity(msg)
else:
raise RuntimeError("incorrect or inconsistant message types")
def speed_heading(msg):
"""Get speed and heading only from the velocity message
(handles both airborne or surface message)
Args:
msg (string): 28 bytes hexadecimal message string
Returns:
(int, float): speed (kt), heading (degree)
"""
spd, hdg, rocd, tag = velocity(msg)
return spd, hdg
def airborne_velocity(msg):
"""Calculate the speed, heading, and vertical rate
Args: Args:
msg (string): 28 bytes hexadecimal message string msg (string): 28 bytes hexadecimal message string
@ -582,14 +618,43 @@ def velocity(msg):
return int(spd), round(hdg, 1), int(rocd), tag return int(spd), round(hdg, 1), int(rocd), tag
def speed_heading(msg): def surface_velocity(msg):
"""Get speed and heading only from the velocity message """Decode surface velocity from from a surface position message
Args: Args:
msg (string): 28 bytes hexadecimal message string msg (string): 28 bytes hexadecimal message string
Returns: Returns:
(int, float): speed (kt), heading (degree) (int, float, int, string): speed (kt), heading (degree),
rate of climb/descend (ft/min), and speed type
('GS' for ground speed, 'AS' for airspeed)
""" """
spd, hdg, rocd, tag = velocity(msg)
return spd, hdg if typecode(msg) < 5 or typecode(msg) > 8:
raise RuntimeError("%s: Not a surface message" % msg)
msgbin = util.hex2bin(msg)
# heading
hdg_status = int(msgbin[44])
if hdg_status == 1:
hdg = util.bin2int(msgbin[45:52]) * 360.0 / 128.0
else:
hdg = None
# ground movment / speed
mov = util.bin2int(msgbin[37:44])
if mov == 0 or mov > 124:
spd = None
elif mov == 1:
spd = 0
elif mov == 124:
spd = 175
else:
movs = [2, 9, 13, 39, 94, 109, 124]
kts = [0.125, 1, 2, 15, 70, 100, 175]
i = next(m[0] for m in enumerate(movs) if m[1] > mov)
step = (kts[i] - kts[i-1]) * 1.0 / (movs[i]-movs[i-1])
spd = kts[i-1] + (mov-movs[i-1]) * step
return round(spd, 2), round(hdg, 1), 0, 'GS'

View File

@ -58,8 +58,10 @@ def test_adsb_alt():
def test_adsb_velocity(): def test_adsb_velocity():
vgs = adsb.velocity("8D485020994409940838175B284F") vgs = adsb.velocity("8D485020994409940838175B284F")
vas = adsb.velocity("8DA05F219B06B6AF189400CBC33F") vas = adsb.velocity("8DA05F219B06B6AF189400CBC33F")
vgs_surface = adsb.velocity("8FC8200A3AB8F5F893096B000000")
assert vgs == (159, 182.9, -832, 'GS') assert vgs == (159, 182.9, -832, 'GS')
assert vas == (376, 244.0, -2304, 'AS') assert vas == (376, 244.0, -2304, 'AS')
assert vgs_surface == (19.0, 42.2, 0 , 'GS')
def test_nic(): def test_nic():