bds09
This commit is contained in:
parent
b503beb3fd
commit
6144b88188
@ -46,7 +46,7 @@ from .bds.bds06 import (
|
|||||||
surface_velocity,
|
surface_velocity,
|
||||||
)
|
)
|
||||||
from .bds.bds08 import category, callsign
|
from .bds.bds08 import category, callsign
|
||||||
from pyModeS.decoder.bds.bds09 import airborne_velocity, altitude_diff
|
from .bds.bds09 import airborne_velocity, altitude_diff
|
||||||
|
|
||||||
def icao(bytes msg):
|
def icao(bytes msg):
|
||||||
return c_icao(msg)
|
return c_icao(msg)
|
||||||
|
122
pyModeS/c_decoder/bds/bds09.pyx
Normal file
122
pyModeS/c_decoder/bds/bds09.pyx
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
# cython: language_level=3
|
||||||
|
|
||||||
|
cimport cython
|
||||||
|
|
||||||
|
from ..common cimport char_to_int, typecode, hex2bin, bin2int
|
||||||
|
from libc.math cimport atan2, sqrt, pi, NAN as nan
|
||||||
|
|
||||||
|
def airborne_velocity(bytes msg, bint rtn_sources=False):
|
||||||
|
"""Calculate the speed, track (or heading), and vertical rate
|
||||||
|
|
||||||
|
Args:
|
||||||
|
msg (string): 28 bytes hexadecimal message string
|
||||||
|
rtn_source (boolean): If the function will return
|
||||||
|
the sources for direction of travel and vertical
|
||||||
|
rate. This will change the return value from a four
|
||||||
|
element array to a six element array.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
(int, float, int, string, string, string): speed (kt),
|
||||||
|
ground track or heading (degree),
|
||||||
|
rate of climb/descent (ft/min), speed type
|
||||||
|
('GS' for ground speed, 'AS' for airspeed),
|
||||||
|
direction source ('true_north' for ground track / true north
|
||||||
|
as refrence, 'mag_north' for magnetic north as reference),
|
||||||
|
rate of climb/descent source ('Baro' for barometer, 'GNSS'
|
||||||
|
for GNSS constellation).
|
||||||
|
"""
|
||||||
|
|
||||||
|
if typecode(msg) != 19:
|
||||||
|
raise RuntimeError("%s: Not a airborne velocity message, expecting TC=19" % msg)
|
||||||
|
|
||||||
|
cdef bytearray mb = hex2bin(msg)[32:]
|
||||||
|
|
||||||
|
cdef int subtype = bin2int(mb[5:8])
|
||||||
|
|
||||||
|
if bin2int(mb[14:24]) == 0 or bin2int(mb[25:35]) == 0:
|
||||||
|
return None
|
||||||
|
|
||||||
|
cdef int v_ew_sign, v_ew, v_ns_sign, v_ns
|
||||||
|
cdef double spd, trk, trk_or_hdg, hdg
|
||||||
|
|
||||||
|
if subtype in (1, 2):
|
||||||
|
v_ew_sign = -1 if mb[13] == 49 else 1 # "1"
|
||||||
|
v_ew = bin2int(mb[14:24]) - 1 # east-west velocity
|
||||||
|
if subtype == 2: # Supersonic
|
||||||
|
v_ew *= 4
|
||||||
|
|
||||||
|
v_ns_sign = -1 if mb[24] == 49 else 1 # "1"
|
||||||
|
v_ns = bin2int(mb[25:35]) - 1 # north-south velocity
|
||||||
|
if subtype == 2: # Supersonic
|
||||||
|
v_ns *= 4
|
||||||
|
|
||||||
|
v_we = v_ew_sign * v_ew
|
||||||
|
v_sn = v_ns_sign * v_ns
|
||||||
|
|
||||||
|
spd = sqrt(v_sn * v_sn + v_we * v_we) # unit in kts
|
||||||
|
# spd = int(spd)
|
||||||
|
|
||||||
|
trk = atan2(v_we, v_sn)
|
||||||
|
# trk = math.degrees(trk) # convert to degrees
|
||||||
|
trk = trk * 180 / pi
|
||||||
|
trk = trk if trk >= 0 else trk + 360 # no negative val
|
||||||
|
|
||||||
|
tag = "GS"
|
||||||
|
trk_or_hdg = round(trk, 2)
|
||||||
|
dir_type = "true_north"
|
||||||
|
|
||||||
|
else:
|
||||||
|
if mb[13] == 48: # "0"
|
||||||
|
hdg = nan
|
||||||
|
else:
|
||||||
|
hdg = bin2int(mb[14:24]) / 1024.0 * 360.0
|
||||||
|
hdg = round(hdg, 2)
|
||||||
|
|
||||||
|
trk_or_hdg = hdg
|
||||||
|
|
||||||
|
spd = bin2int(mb[25:35])
|
||||||
|
spd = nan if spd == 0 else spd - 1
|
||||||
|
if subtype == 4: # Supersonic
|
||||||
|
spd *= 4
|
||||||
|
|
||||||
|
if mb[24] == 48: # "0"
|
||||||
|
tag = "IAS"
|
||||||
|
else:
|
||||||
|
tag = "TAS"
|
||||||
|
|
||||||
|
dir_type = "mag_north"
|
||||||
|
|
||||||
|
vr_source = "GNSS" if mb[35] == 48 else "Baro" # "0"
|
||||||
|
vr_sign = -1 if mb[36] == 49 else 1 # "1"
|
||||||
|
vr = bin2int(mb[37:46])
|
||||||
|
rocd = None if vr == 0 else int(vr_sign * (vr - 1) * 64)
|
||||||
|
|
||||||
|
if rtn_sources:
|
||||||
|
return int(spd), trk_or_hdg, rocd, tag, dir_type, vr_source
|
||||||
|
else:
|
||||||
|
return int(spd), trk_or_hdg, rocd, tag
|
||||||
|
|
||||||
|
|
||||||
|
def altitude_diff(bytes msg):
|
||||||
|
"""Decode the differece between GNSS and barometric altitude
|
||||||
|
|
||||||
|
Args:
|
||||||
|
msg (string): 28 bytes hexadecimal message string, TC=19
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
int: Altitude difference in ft. Negative value indicates GNSS altitude
|
||||||
|
below barometric altitude.
|
||||||
|
"""
|
||||||
|
cdef int tc = typecode(msg)
|
||||||
|
|
||||||
|
if tc != 19:
|
||||||
|
raise RuntimeError("%s: Not a airborne velocity message, expecting TC=19" % msg)
|
||||||
|
|
||||||
|
cdef bytearray msgbin = hex2bin(msg)
|
||||||
|
cdef int sign = -1 if char_to_int(msgbin[80]) else 1
|
||||||
|
cdef int value = bin2int(msgbin[81:88])
|
||||||
|
|
||||||
|
if value == 0 or value == 127:
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
return sign * (value - 1) * 25 # in ft.
|
1
setup.py
1
setup.py
@ -25,6 +25,7 @@ extensions = [
|
|||||||
Extension("pyModeS.c_decoder.bds.bds05", ["pyModeS/c_decoder/bds/bds05.pyx"]),
|
Extension("pyModeS.c_decoder.bds.bds05", ["pyModeS/c_decoder/bds/bds05.pyx"]),
|
||||||
Extension("pyModeS.c_decoder.bds.bds06", ["pyModeS/c_decoder/bds/bds06.pyx"]),
|
Extension("pyModeS.c_decoder.bds.bds06", ["pyModeS/c_decoder/bds/bds06.pyx"]),
|
||||||
Extension("pyModeS.c_decoder.bds.bds08", ["pyModeS/c_decoder/bds/bds08.pyx"]),
|
Extension("pyModeS.c_decoder.bds.bds08", ["pyModeS/c_decoder/bds/bds08.pyx"]),
|
||||||
|
Extension("pyModeS.c_decoder.bds.bds09", ["pyModeS/c_decoder/bds/bds09.pyx"]),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user