update pmstream, add nic/nac/sil.

This commit is contained in:
Junzi Sun 2018-06-23 00:20:38 +02:00
parent bbe6e50fb2
commit 0ef64be934
5 changed files with 98 additions and 80 deletions

View File

@ -452,6 +452,8 @@ def sil(msg, version):
elif tc == 31: elif tc == 31:
sil = common.bin2int(msg[82:84]) sil = common.bin2int(msg[82:84])
sil_sup = None
if version == 2: if version == 2:
if version == 29: if version == 29:
sil_sup = common.bin2int(msgbin[39]) sil_sup = common.bin2int(msgbin[39])

View File

View File

@ -14,8 +14,8 @@ from pyModeS.streamer.screen import Screen
LOCK = Lock() LOCK = Lock()
ADSB_MSG = [] ADSB_MSG = []
ADSB_TS = [] ADSB_TS = []
EHS_MSG = [] COMMB_MSG = []
EHS_TS = [] COMMB_TS = []
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument('--server', help='server address or IP', required=True) parser.add_argument('--server', help='server address or IP', required=True)
@ -58,11 +58,12 @@ class ModesClient(BaseClient):
LOCK.acquire() LOCK.acquire()
ADSB_MSG.extend(local_buffer_adsb_msg) ADSB_MSG.extend(local_buffer_adsb_msg)
ADSB_TS.extend(local_buffer_adsb_ts) ADSB_TS.extend(local_buffer_adsb_ts)
EHS_MSG.extend(local_buffer_ehs_msg) COMMB_MSG.extend(local_buffer_ehs_msg)
EHS_TS.extend(local_buffer_ehs_ts) COMMB_TS.extend(local_buffer_ehs_ts)
LOCK.release() LOCK.release()
# redirect all stdout to null, avoiding messing up with the screen
sys.stdout = open(os.devnull, 'w') sys.stdout = open(os.devnull, 'w')
client = ModesClient(host=SERVER, port=PORT) client = ModesClient(host=SERVER, port=PORT)
@ -79,11 +80,11 @@ try:
while True: while True:
if len(ADSB_MSG) > 200: if len(ADSB_MSG) > 200:
LOCK.acquire() LOCK.acquire()
stream.process_raw(ADSB_TS, ADSB_MSG, EHS_TS, EHS_MSG) stream.process_raw(ADSB_TS, ADSB_MSG, COMMB_TS, COMMB_MSG)
ADSB_MSG = [] ADSB_MSG = []
ADSB_TS = [] ADSB_TS = []
EHS_MSG = [] COMMB_MSG = []
EHS_TS = [] COMMB_TS = []
LOCK.release() LOCK.release()
acs = stream.get_aircraft() acs = stream.get_aircraft()

View File

@ -4,7 +4,24 @@ import numpy as np
import time import time
from threading import Thread from threading import Thread
COLUMNS = ['lat', 'lon', 'alt', 'gs', 'tas', 'ias', 'mach', 'roc', 'trk', 'hdg', 't'] COLUMNS = [
('lat', 10),
('lon', 10),
('alt', 7),
('gs', 5),
('tas', 5),
('ias', 5),
('mach', 7),
('roc', 7),
('trk', 10),
('hdg', 10),
('ver', 4),
('NIC', 5),
('NACv', 5),
('NACp', 5),
('SIL', 5),
('updated', 12),
]
class Screen(Thread): class Screen(Thread):
def __init__(self): def __init__(self):
@ -44,10 +61,10 @@ class Screen(Thread):
row = 1 row = 1
header = 'icao' header = ' icao'
for c in COLUMNS: for c, cw in COLUMNS:
c = 'updated' if c=='t' else c c = 'updated' if c=='t' else c
header += '%10s' % c header += (cw-len(c))*' ' + c
if len(header) > self.scr_w - 2: if len(header) > self.scr_w - 2:
header = header[:self.scr_w-3] + '>' header = header[:self.scr_w-3] + '>'
@ -74,19 +91,15 @@ class Screen(Thread):
line += icao line += icao
for c in COLUMNS: for c, cw in COLUMNS:
val = '' if ac[c] is None else ac[c]
if c == 't': val_str = str(val)
val = str(int(ac[c])) line += (cw-len(val_str))*' ' + val_str
line += '%12s' % val
else:
val = '' if ac[c] is None else ac[c]
line += '%10s' % val
if len(line) > self.scr_w - 2: if len(line) > self.scr_w - 2:
line = line[:self.scr_w-3] + '>' line = line[:self.scr_w-3] + '>'
if self.lock_icao == icao: if (icao is not None) and (self.lock_icao == icao):
self.screen.addstr(row, 1, line, curses.A_STANDOUT) self.screen.addstr(row, 1, line, curses.A_STANDOUT)
elif row == self.y: elif row == self.y:
self.screen.addstr(row, 1, line, curses.A_BOLD) self.screen.addstr(row, 1, line, curses.A_BOLD)

View File

@ -1,7 +1,7 @@
from __future__ import absolute_import, print_function, division from __future__ import absolute_import, print_function, division
import numpy as np import numpy as np
import time import time
from pyModeS.decoder import adsb, ehs import pyModeS as pms
class Stream(): class Stream():
def __init__(self, lat0, lon0): def __init__(self, lat0, lon0):
@ -18,8 +18,8 @@ class Stream():
self.cache_timeout = 60 # seconds self.cache_timeout = 60 # seconds
def process_raw(self, adsb_ts, adsb_msgs, ehs_ts, ehs_msgs, tnow=None): def process_raw(self, adsb_ts, adsb_msgs, commb_ts, commb_msgs, tnow=None):
"""process a chunk of adsb and ehs messages recieved in the same """process a chunk of adsb and commb messages recieved in the same
time period. time period.
""" """
if tnow is None: if tnow is None:
@ -31,11 +31,12 @@ class Stream():
# process adsb message # process adsb message
for t, msg in zip(adsb_ts, adsb_msgs): for t, msg in zip(adsb_ts, adsb_msgs):
icao = adsb.icao(msg) icao = pms.icao(msg)
tc = adsb.typecode(msg) tc = pms.adsb.typecode(msg)
if icao not in self.acs: if icao not in self.acs:
self.acs[icao] = { self.acs[icao] = {
'updated': None,
'lat': None, 'lat': None,
'lon': None, 'lon': None,
'alt': None, 'alt': None,
@ -46,20 +47,20 @@ class Stream():
'ias': None, 'ias': None,
'mach': None, 'mach': None,
'hdg': None, 'hdg': None,
'adsb_version' : None, 'ver' : None,
'nic_s' : None, 'NIC' : None,
'nic_a' : None, 'NACp' : None,
'nic_b' : None, 'NACv' : None,
'nic_c' : None 'SIL' : None
} }
self.acs[icao]['t'] = t self.acs[icao]['updated'] = int(t)
if 1 <= tc <= 4: if 1 <= tc <= 4:
self.acs[icao]['callsign'] = adsb.callsign(msg) self.acs[icao]['callsign'] = pms.adsb.callsign(msg)
if (5 <= tc <= 8) or (tc == 19): if (5 <= tc <= 8) or (tc == 19):
vdata = adsb.velocity(msg) vdata = pms.adsb.velocity(msg)
if vdata is None: if vdata is None:
continue continue
@ -75,7 +76,7 @@ class Stream():
self.acs[icao]['tv'] = t self.acs[icao]['tv'] = t
if (5 <= tc <= 18): if (5 <= tc <= 18):
oe = adsb.oe_flag(msg) oe = pms.adsb.oe_flag(msg)
self.acs[icao][oe] = msg self.acs[icao][oe] = msg
self.acs[icao]['t'+str(oe)] = t self.acs[icao]['t'+str(oe)] = t
@ -83,21 +84,21 @@ class Stream():
# use single message decoding # use single message decoding
rlat = self.acs[icao]['lat'] rlat = self.acs[icao]['lat']
rlon = self.acs[icao]['lon'] rlon = self.acs[icao]['lon']
latlon = adsb.position_with_ref(msg, rlat, rlon) latlon = pms.adsb.position_with_ref(msg, rlat, rlon)
elif ('t0' in self.acs[icao]) and ('t1' in self.acs[icao]) and \ elif ('t0' in self.acs[icao]) and ('t1' in self.acs[icao]) and \
(abs(self.acs[icao]['t0'] - self.acs[icao]['t1']) < 10): (abs(self.acs[icao]['t0'] - self.acs[icao]['t1']) < 10):
# use multi message decoding # use multi message decoding
try: # try:
latlon = adsb.position( latlon = pms.adsb.position(
self.acs[icao][0], self.acs[icao][0],
self.acs[icao][1], self.acs[icao][1],
self.acs[icao]['t0'], self.acs[icao]['t0'],
self.acs[icao]['t1'], self.acs[icao]['t1'],
self.lat0, self.lon0 self.lat0, self.lon0
) )
except: # except:
# mix of surface and airborne position message # # mix of surface and airborne position message
continue # continue
else: else:
latlon = None latlon = None
@ -105,70 +106,71 @@ class Stream():
self.acs[icao]['tpos'] = t self.acs[icao]['tpos'] = t
self.acs[icao]['lat'] = latlon[0] self.acs[icao]['lat'] = latlon[0]
self.acs[icao]['lon'] = latlon[1] self.acs[icao]['lon'] = latlon[1]
self.acs[icao]['alt'] = adsb.altitude(msg) self.acs[icao]['alt'] = pms.adsb.altitude(msg)
local_updated_acs_buffer.append(icao) local_updated_acs_buffer.append(icao)
# Uncertainty & accuracy # Uncertainty & accuracy
if (5 <= tc <= 8): if (5 <= tc <= 8):
if self.acs[icao]['adsb_version'] == 1: if self.acs[icao]['ver'] == 1:
if self.acs[icao]['nic_s'] != None: if self.acs[icao]['nic_s'] != None:
self.nic = adsb.nic_v1(msg, self.acs[icao]['nic_s']) self.acs[icao]['NIC'] = pms.adsb.nic_v1(msg, self.acs[icao]['nic_s'])
elif self.acs[icao]['adsb_version'] == 2: elif self.acs[icao]['ver'] == 2:
if self.acs[icao]['nic_a'] != None and self.acs[icao]['nic_b'] != None: if self.acs[icao]['nic_a'] != None and self.acs[icao]['nic_b'] != None:
self.nic = adsb.nic_v2(msg, self.nic_a, self.acs[icao]['nic_b'], self.acs[icao]['nic_c']) self.acs[icao]['NIC'] = pms.adsb.nic_v2(msg, self.acs[icao]['nic_a'], self.acs[icao]['nic_b'], self.acs[icao]['nic_c'])
if (9 <= tc <= 18): if (9 <= tc <= 18):
if self.acs[icao]['adsb_version'] == 1: if self.acs[icao]['ver'] == 1:
if self.acs[icao]['nic_s'] != None: if self.acs[icao]['nic_s'] != None:
self.nic = adsb.nic_v1(msg, self.acs[icao]['nic_s']) self.acs[icao]['NIC'] = pms.adsb.nic_v1(msg, self.acs[icao]['nic_s'])
elif self.acs[icao]['adsb_version'] == 2: elif self.acs[icao]['ver'] == 2:
self.acs[icao]['nic_b'] = adsb.nic_b(msg) self.acs[icao]['nic_b'] = pms.adsb.nic_b(msg)
if self.acs[icao]['nic_a'] != None and self.acs[icao]['nic_b'] != None: if self.acs[icao]['nic_a'] != None and self.acs[icao]['nic_b'] != None:
self.nic = adsb.nic_v2(msg, self.acs[icao]['nic_a'], self.nic_b, self.acs[icao]['nic_c']) self.acs[icao]['NIC'] = pms.adsb.nic_v2(msg, self.acs[icao]['nic_a'], self.acs[icao]['nic_b'], self.acs[icao]['nic_c'])
if tc == 19: if tc == 19:
self.acs[icao]['nac_v'] = adsb.nac_v(msg) if self.acs[icao]['ver'] in [1, 2]:
self.acs[icao]['NACv'] = pms.adsb.nac_v(msg)
if (20 <= tc <= 22): if (20 <= tc <= 22):
if self.acs[icao]['adsb_version'] == 1: if self.acs[icao]['ver'] == 1:
if self.acs[icao]['nic_s'] != None: if self.acs[icao]['nic_s'] != None:
self.nic = adsb.nic_v1(msg, self.acs[icao]['nic_s']) self.acs[icao]['NIC'] = pms.adsb.nic_v1(msg, self.acs[icao]['nic_s'])
elif self.acs[icao]['adsb_version'] == 2: elif self.acs[icao]['ver'] == 2:
if self.acs[icao]['nic_a'] != None and self.acs[icao]['nic_b'] != None: if self.acs[icao]['nic_a'] != None and self.acs[icao]['nic_b'] != None:
self.nic = adsb.nic_v2(msg, self.acs[icao]['nic_a'], self.acs[icao]['nic_b'], self.acs[icao]['nic_c']) self.acs[icao]['NIC'] = pms.adsb.nic_v2(msg, self.acs[icao]['nic_a'], self.acs[icao]['nic_b'], self.acs[icao]['nic_c'])
if tc == 29: if tc == 29:
if self.acs[icao]['adsb_version'] != None: if self.acs[icao]['ver'] != None:
self.acs[icao]['sil'] = adsb.sil(msg, self.acs[icao]['adsb_version']) self.acs[icao]['SIL'], self.acs[icao]['sil_s'] = pms.adsb.sil(msg, self.acs[icao]['ver'])
self.acs[icao]['nac_p'] = adsb.nac_p(msg) self.acs[icao]['NACp'] = pms.adsb.nac_p(msg)
if tc == 31: if tc == 31:
self.acs[icao]['adsb_version'] = adsb.version(msg) self.acs[icao]['ver'] = pms.adsb.version(msg)
self.acs[icao]['sil'] = adsb.version(msg) self.acs[icao]['SIL'] = pms.adsb.version(msg)
self.acs[icao]['nac_p'] = adsb.nac_p(msg) self.acs[icao]['NACp'] = pms.adsb.nac_p(msg)
if self.acs[icao]['adsb_version'] == 1: if self.acs[icao]['ver'] == 1:
self.acs[icao]['nic_s'] = adsb.nic_s(msg) self.acs[icao]['nic_s'] = pms.adsb.nic_s(msg)
elif self.acs[icao]['adsb_version'] == 2: elif self.acs[icao]['ver'] == 2:
self.acs[icao]['nic_a'], self.acs[icao]['nic_c'] = adsb.nic_a_c(msg) self.acs[icao]['nic_a'], self.acs[icao]['nic_c'] = pms.adsb.nic_a_c(msg)
# process ehs message # process commb message
for t, msg in zip(ehs_ts, ehs_msgs): for t, msg in zip(commb_ts, commb_msgs):
icao = ehs.icao(msg) icao = pms.icao(msg)
if icao not in self.acs: if icao not in self.acs:
continue continue
bds = ehs.BDS(msg) bds = pms.bds.infer(msg)
if bds == 'BDS50': if bds == 'BDS50':
tas = ehs.tas50(msg) tas = pms.commb.tas50(msg)
if tas: if tas:
self.acs[icao]['t50'] = t self.acs[icao]['t50'] = t
self.acs[icao]['tas'] = tas self.acs[icao]['tas'] = tas
elif bds == 'BDS60': elif bds == 'BDS60':
ias = ehs.ias60(msg) ias = pms.commb.ias60(msg)
hdg = ehs.hdg60(msg) hdg = pms.commb.hdg60(msg)
mach = ehs.mach60(msg) mach = pms.commb.mach60(msg)
if ias or hdg or mach: if ias or hdg or mach:
self.acs[icao]['t60'] = t self.acs[icao]['t60'] = t
@ -181,7 +183,7 @@ class Stream():
# clear up old data # clear up old data
for icao in list(self.acs.keys()): for icao in list(self.acs.keys()):
if self.t - self.acs[icao]['t'] > self.cache_timeout: if self.t - self.acs[icao]['updated'] > self.cache_timeout:
del self.acs[icao] del self.acs[icao]
continue continue