From d84c0c3204c0628f4a5bd8bb16bf6178356f288c Mon Sep 17 00:00:00 2001 From: Nick Foster Date: Tue, 18 Jun 2013 17:47:13 -0700 Subject: [PATCH] Parser works for the print case. Not quite sure this is the best way to do it, but it's better. --- apps/modes_rx | 5 ++- python/__init__.py | 22 +++++------ python/msprint.py | 91 +++++++++++++++++++++++----------------------- python/parse.py | 30 +++++++-------- 4 files changed, 76 insertions(+), 72 deletions(-) diff --git a/apps/modes_rx b/apps/modes_rx index 656758c..ee2355a 100755 --- a/apps/modes_rx +++ b/apps/modes_rx @@ -78,6 +78,9 @@ def main(): if options.location is not None: my_position = [float(n) for n in options.location.split(",")] + #CPR decoder obj to handle getting position from BDS0,5 and BDS0,6 pkts + cpr_dec = air_modes.cpr.cpr_decoder(my_position) + if options.kml is not None: dbname = 'adsb.db' lock = threading.Lock() @@ -87,7 +90,7 @@ def main(): if options.no_print is not True: #relay.subscribe("dl_data", air_modes.output_print(my_position).output) - printer = air_modes.output_print(my_position, publisher) + printer = air_modes.output_print(cpr_dec, publisher) if options.multiplayer is not None: [fghost, fgport] = options.multiplayer.split(':') diff --git a/python/__init__.py b/python/__init__.py index c42c61d..28560f2 100644 --- a/python/__init__.py +++ b/python/__init__.py @@ -55,22 +55,22 @@ from rx_path import rx_path from zmq_socket import zmq_pubsub_iface from parse import * from msprint import output_print -from sql import output_sql -from sbs1 import output_sbs1 -from kml import output_kml -from raw_server import raw_server +#from sql import output_sql +#from sbs1 import output_sbs1 +#from kml import output_kml +#from raw_server import raw_server from radio import modes_radio from exceptions import * -from az_map import * +#from az_map import * from types import * from altitude import * #this is try/excepted in case the user doesn't have numpy installed -try: - from flightgear import output_flightgear - from Quaternion import * -except ImportError: - print "gr-air-modes warning: numpy+scipy not installed, FlightGear interface not supported" - pass +#try: +# from flightgear import output_flightgear +# from Quaternion import * +#except ImportError: +# print "gr-air-modes warning: numpy+scipy not installed, FlightGear interface not supported" +# pass # ---------------------------------------------------------------- # Tail of workaround diff --git a/python/msprint.py b/python/msprint.py index 9d5b9b8..5a4914f 100644 --- a/python/msprint.py +++ b/python/msprint.py @@ -28,8 +28,8 @@ import math #TODO get rid of class and convert to functions #no need for class here class output_print: - def __init__(self, mypos, publisher): - #self._cpr = air_modes.cpr_decoder(mypos) + def __init__(self, cpr, publisher): + self._cpr = cpr #sub to every function that starts with "print" self._fns = [int(l[6:]) for l in dir(self) if l.startswith("handle")] for i in self._fns: @@ -119,55 +119,56 @@ class output_print: print retstr #the only one which requires state - def handle17(self, data): - return - icao24 = data["aa"] - bdsreg = data["me"].get_type() + def handle17(self, msg): + icao24 = msg.data["aa"] + bdsreg = msg.data["me"].get_type() - retstr = None + retstr = output_print.prefix(msg) + try: + if bdsreg == 0x08: + (ident, typestring) = air_modes.parseBDS08(msg.data) + retstr += "Type 17 BDS0,8 (ident) from %x type %s ident %s" % (icao24, typestring, ident) - if bdsreg == 0x08: - (msg, typestring) = self.parseBDS08(data) - retstr = "Type 17 BDS0,8 (ident) from %x type %s ident %s" % (icao24, typestring, msg) + elif bdsreg == 0x06: + [ground_track, decoded_lat, decoded_lon, rnge, bearing] = air_modes.parseBDS06(msg.data, self._cpr) + retstr += "Type 17 BDS0,6 (surface report) from %x at (%.6f, %.6f) ground track %i" % (icao24, decoded_lat, decoded_lon, ground_track) + if rnge is not None and bearing is not None: + retstr += " (%.2f @ %.0f)" % (rnge, bearing) - elif bdsreg == 0x06: - [ground_track, decoded_lat, decoded_lon, rnge, bearing] = self.parseBDS06(data) - retstr = "Type 17 BDS0,6 (surface report) from %x at (%.6f, %.6f) ground track %i" % (icao24, decoded_lat, decoded_lon, ground_track) - if rnge is not None and bearing is not None: - retstr += " (%.2f @ %.0f)" % (rnge, bearing) + elif bdsreg == 0x05: + [altitude, decoded_lat, decoded_lon, rnge, bearing] = air_modes.parseBDS05(msg.data, self._cpr) + retstr += "Type 17 BDS0,5 (position report) from %x at (%.6f, %.6f)" % (icao24, decoded_lat, decoded_lon) + if rnge is not None and bearing is not None: + retstr += " (" + "%.2f" % rnge + " @ " + "%.0f" % bearing + ")" + retstr += " at " + str(altitude) + "ft" - elif bdsreg == 0x05: - [altitude, decoded_lat, decoded_lon, rnge, bearing] = self.parseBDS05(data) - retstr = "Type 17 BDS0,5 (position report) from %x at (%.6f, %.6f)" % (icao24, decoded_lat, decoded_lon) - if rnge is not None and bearing is not None: - retstr += " (" + "%.2f" % rnge + " @ " + "%.0f" % bearing + ")" - retstr += " at " + str(altitude) + "ft" + elif bdsreg == 0x09: + subtype = msg.data["bds09"].get_type() + if subtype == 0: + [velocity, heading, vert_spd, turnrate] = air_modes.parseBDS09_0(msg.data) + retstr += "Type 17 BDS0,9-%i (track report) from %x with velocity %.0fkt heading %.0f VS %.0f turn rate %.0f" \ + % (subtype, icao24, velocity, heading, vert_spd, turnrate) + elif subtype == 1: + [velocity, heading, vert_spd] = air_modes.parseBDS09_1(msg.data) + retstr += "Type 17 BDS0,9-%i (track report) from %x with velocity %.0fkt heading %.0f VS %.0f" % (subtype, icao24, velocity, heading, vert_spd) + elif subtype == 3: + [mag_hdg, vel_src, vel, vert_spd, geo_diff] = air_modes.parseBDS09_3(msg.data) + retstr += "Type 17 BDS0,9-%i (air course report) from %x with %s %.0fkt magnetic heading %.0f VS %.0f geo. diff. from baro. alt. %.0fft" \ + % (subtype, icao24, vel_src, vel, mag_hdg, vert_spd, geo_diff) + + else: + retstr += "Type 17 BDS0,9-%i from %x not implemented" % (subtype, icao24) - elif bdsreg == 0x09: - subtype = data["bds09"].get_type() - if subtype == 0: - [velocity, heading, vert_spd, turnrate] = self.parseBDS09_0(data) - retstr = "Type 17 BDS0,9-%i (track report) from %x with velocity %.0fkt heading %.0f VS %.0f turn rate %.0f" \ - % (subtype, icao24, velocity, heading, vert_spd, turnrate) - elif subtype == 1: - [velocity, heading, vert_spd] = self.parseBDS09_1(data) - retstr = "Type 17 BDS0,9-%i (track report) from %x with velocity %.0fkt heading %.0f VS %.0f" % (subtype, icao24, velocity, heading, vert_spd) - elif subtype == 3: - [mag_hdg, vel_src, vel, vert_spd, geo_diff] = self.parseBDS09_3(data) - retstr = "Type 17 BDS0,9-%i (air course report) from %x with %s %.0fkt magnetic heading %.0f VS %.0f geo. diff. from baro. alt. %.0fft" \ - % (subtype, icao24, vel_src, vel, mag_hdg, vert_spd, geo_diff) - - else: - retstr = "Type 17 BDS0,9-%i from %x not implemented" % (subtype, icao24) + elif bdsreg == 0x62: + emerg_str = air_modes.parseBDS62(data) + retstr += "Type 17 BDS6,2 (emergency) from %x type %s" % (icao24, emerg_str) + + else: + retstr += "Type 17 with FTC=%i from %x not implemented" % (msg.data["ftc"], icao24) + except ADSBError: + return - elif bdsreg == 0x62: - emerg_str = self.parseBDS62(data) - retstr = "Type 17 BDS6,2 (emergency) from %x type %s" % (icao24, emerg_str) - - else: - retstr = "Type 17 with FTC=%i from %x not implemented" % (data["ftc"], icao24) - - return retstr + print retstr def printTCAS(self, msg): return diff --git a/python/parse.py b/python/parse.py index af4fefd..15cf210 100644 --- a/python/parse.py +++ b/python/parse.py @@ -255,7 +255,7 @@ def decode_id(id): return (a * 1000) + (b * 100) + (c * 10) + d #decode ident squawks -def charmap(self, d): +def charmap(d): if d > 0 and d < 27: retval = chr(ord("A")+d-1) elif d == 32: @@ -267,7 +267,7 @@ def charmap(self, d): return retval -def parseBDS08(self, data): +def parseBDS08(data): categories = [["NO INFO", "RESERVED", "RESERVED", "RESERVED", "RESERVED", "RESERVED", "RESERVED", "RESERVED"],\ ["NO INFO", "SURFACE EMERGENCY VEHICLE", "SURFACE SERVICE VEHICLE", "FIXED OBSTRUCTION", "CLUSTER OBSTRUCTION", "LINE OBSTRUCTION", "RESERVED"],\ ["NO INFO", "GLIDER", "BALLOON/BLIMP", "PARACHUTE", "ULTRALIGHT", "RESERVED", "UAV", "SPACECRAFT"],\ @@ -281,18 +281,18 @@ def parseBDS08(self, data): return (msg, catstring) #NOTE: this is stateful -- requires CPR decoder -def parseBDS05(self, data, cpr): +def parseBDS05(data, cprdec): altitude = decode_alt(data["alt"], False) - [decoded_lat, decoded_lon, rnge, bearing] = cpr.decode(data["aa"], data["lat"], data["lon"], data["cpr"], 0) + [decoded_lat, decoded_lon, rnge, bearing] = cprdec.decode(data["aa"], data["lat"], data["lon"], data["cpr"], 0) return [altitude, decoded_lat, decoded_lon, rnge, bearing] #NOTE: this is stateful -- requires CPR decoder -def parseBDS06(self, data, cpr): +def parseBDS06(data, cprdec): ground_track = data["gtk"] * 360. / 128 - [decoded_lat, decoded_lon, rnge, bearing] = cpr.decode(data["aa"], data["lat"], data["lon"], data["cpr"], 1) + [decoded_lat, decoded_lon, rnge, bearing] = cprdec.decode(data["aa"], data["lat"], data["lon"], data["cpr"], 1) return [ground_track, decoded_lat, decoded_lon, rnge, bearing] -def parseBDS09_0(self, data): +def parseBDS09_0(data): #0: ["sub", "dew", "vew", "dns", "vns", "str", "tr", "svr", "vr"], vert_spd = data["vr"] * 32 ud = bool(data["dvr"]) @@ -318,7 +318,7 @@ def parseBDS09_0(self, data): return [velocity, heading, vert_spd, turn_rate] -def parseBDS09_1(self, data): +def parseBDS09_1(data): #1: ["sub", "icf", "ifr", "nuc", "dew", "vew", "dns", "vns", "vrsrc", "dvr", "vr", "dhd", "hd"], alt_geo_diff = data["hd"] * 25 above_below = bool(data["dhd"]) @@ -353,7 +353,7 @@ def parseBDS09_1(self, data): return [velocity, heading, vert_spd] -def parseBDS09_3(self, data): +def parseBDS09_3(data): #3: {"sub", "icf", "ifr", "nuc", "mhs", "hdg", "ast", "spd", "vrsrc", # "dvr", "vr", "dhd", "hd"} mag_hdg = data["mhs"] * 360. / 1024 @@ -368,18 +368,18 @@ def parseBDS09_3(self, data): return [mag_hdg, vel_src, vel, vert_spd, geo_diff] -def parseBDS62(self, data): +def parseBDS62(data): eps_strings = ["NO EMERGENCY", "GENERAL EMERGENCY", "LIFEGUARD/MEDICAL", "FUEL EMERGENCY", "NO COMMUNICATIONS", "UNLAWFUL INTERFERENCE", "RESERVED", "RESERVED"] return eps_strings[data["eps"]] -def parseMB_id(self, data): #bds1 == 2, bds2 == 0 +def parseMB_id(data): #bds1 == 2, bds2 == 0 msg = "" for i in range(0, 8): msg += self.charmap( data["ais"] >> (42-6*i) & 0x3F) return (msg) -def parseMB_TCAS_resolutions(self, data): +def parseMB_TCAS_resolutions(data): #these are LSB because the ICAO are asshats ara_bits = {41: "CLIMB", 42: "DON'T DESCEND", 43: "DON'T DESCEND >500FPM", 44: "DON'T DESCEND >1000FPM", 45: "DON'T DESCEND >2000FPM", 46: "DESCEND", 47: "DON'T CLIMB", 48: "DON'T CLIMB >500FPM", @@ -403,18 +403,18 @@ def parseMB_TCAS_resolutions(self, data): #mte is 1 if multiple threats indicated #tti is threat type: 1 if ID, 2 if range/brg/alt #tida is threat altitude in Mode C format -def parseMB_TCAS_threatid(self, data): #bds1==3, bds2==0, TTI==1 +def parseMB_TCAS_threatid(data): #bds1==3, bds2==0, TTI==1 #3: {"bds1": (33,4), "bds2": (37,4), "ara": (41,14), "rac": (55,4), "rat": (59,1), # "mte": (60,1), "tti": (61,2), "tida": (63,13), "tidr": (76,7), "tidb": (83,6)} (resolutions, complements) = self.parseMB_TCAS_resolutions(data) return (resolutions, complements, data["rat"], data["mte"], data["tid"]) -def parseMB_TCAS_threatloc(self, data): #bds1==3, bds2==0, TTI==2 +def parseMB_TCAS_threatloc(data): #bds1==3, bds2==0, TTI==2 (resolutions, complements) = self.parseMB_TCAS_resolutions(data) threat_alt = decode_alt(data["tida"], True) return (resolutions, complements, data["rat"], data["mte"], threat_alt, data["tidr"], data["tidb"]) #type 16 Coordination Reply Message -def parse_TCAS_CRM(self, data): +def parse_TCAS_CRM(data): (resolutions, complements) = self.parseMB_TCAS_resolutions(data) return (resolutions, complements, data["rat"], data["mte"])