Parser works for the print case. Not quite sure this is the best way to do it, but it's better.

This commit is contained in:
Nick Foster 2013-06-18 17:47:13 -07:00
parent a1e2297134
commit d84c0c3204
4 changed files with 76 additions and 72 deletions

View File

@ -78,6 +78,9 @@ def main():
if options.location is not None: if options.location is not None:
my_position = [float(n) for n in options.location.split(",")] 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: if options.kml is not None:
dbname = 'adsb.db' dbname = 'adsb.db'
lock = threading.Lock() lock = threading.Lock()
@ -87,7 +90,7 @@ def main():
if options.no_print is not True: if options.no_print is not True:
#relay.subscribe("dl_data", air_modes.output_print(my_position).output) #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: if options.multiplayer is not None:
[fghost, fgport] = options.multiplayer.split(':') [fghost, fgport] = options.multiplayer.split(':')

View File

@ -55,22 +55,22 @@ from rx_path import rx_path
from zmq_socket import zmq_pubsub_iface from zmq_socket import zmq_pubsub_iface
from parse import * from parse import *
from msprint import output_print from msprint import output_print
from sql import output_sql #from sql import output_sql
from sbs1 import output_sbs1 #from sbs1 import output_sbs1
from kml import output_kml #from kml import output_kml
from raw_server import raw_server #from raw_server import raw_server
from radio import modes_radio from radio import modes_radio
from exceptions import * from exceptions import *
from az_map import * #from az_map import *
from types import * from types import *
from altitude import * from altitude import *
#this is try/excepted in case the user doesn't have numpy installed #this is try/excepted in case the user doesn't have numpy installed
try: #try:
from flightgear import output_flightgear # from flightgear import output_flightgear
from Quaternion import * # from Quaternion import *
except ImportError: #except ImportError:
print "gr-air-modes warning: numpy+scipy not installed, FlightGear interface not supported" # print "gr-air-modes warning: numpy+scipy not installed, FlightGear interface not supported"
pass # pass
# ---------------------------------------------------------------- # ----------------------------------------------------------------
# Tail of workaround # Tail of workaround

View File

@ -28,8 +28,8 @@ import math
#TODO get rid of class and convert to functions #TODO get rid of class and convert to functions
#no need for class here #no need for class here
class output_print: class output_print:
def __init__(self, mypos, publisher): def __init__(self, cpr, publisher):
#self._cpr = air_modes.cpr_decoder(mypos) self._cpr = cpr
#sub to every function that starts with "print" #sub to every function that starts with "print"
self._fns = [int(l[6:]) for l in dir(self) if l.startswith("handle")] self._fns = [int(l[6:]) for l in dir(self) if l.startswith("handle")]
for i in self._fns: for i in self._fns:
@ -119,55 +119,56 @@ class output_print:
print retstr print retstr
#the only one which requires state #the only one which requires state
def handle17(self, data): def handle17(self, msg):
return icao24 = msg.data["aa"]
icao24 = data["aa"] bdsreg = msg.data["me"].get_type()
bdsreg = 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: elif bdsreg == 0x06:
(msg, typestring) = self.parseBDS08(data) [ground_track, decoded_lat, decoded_lon, rnge, bearing] = air_modes.parseBDS06(msg.data, self._cpr)
retstr = "Type 17 BDS0,8 (ident) from %x type %s ident %s" % (icao24, typestring, msg) 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: elif bdsreg == 0x05:
[ground_track, decoded_lat, decoded_lon, rnge, bearing] = self.parseBDS06(data) [altitude, decoded_lat, decoded_lon, rnge, bearing] = air_modes.parseBDS05(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) 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: if rnge is not None and bearing is not None:
retstr += " (%.2f @ %.0f)" % (rnge, bearing) retstr += " (" + "%.2f" % rnge + " @ " + "%.0f" % bearing + ")"
retstr += " at " + str(altitude) + "ft"
elif bdsreg == 0x05: elif bdsreg == 0x09:
[altitude, decoded_lat, decoded_lon, rnge, bearing] = self.parseBDS05(data) subtype = msg.data["bds09"].get_type()
retstr = "Type 17 BDS0,5 (position report) from %x at (%.6f, %.6f)" % (icao24, decoded_lat, decoded_lon) if subtype == 0:
if rnge is not None and bearing is not None: [velocity, heading, vert_spd, turnrate] = air_modes.parseBDS09_0(msg.data)
retstr += " (" + "%.2f" % rnge + " @ " + "%.0f" % bearing + ")" retstr += "Type 17 BDS0,9-%i (track report) from %x with velocity %.0fkt heading %.0f VS %.0f turn rate %.0f" \
retstr += " at " + str(altitude) + "ft" % (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: elif bdsreg == 0x62:
subtype = data["bds09"].get_type() emerg_str = air_modes.parseBDS62(data)
if subtype == 0: retstr += "Type 17 BDS6,2 (emergency) from %x type %s" % (icao24, emerg_str)
[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" \ else:
% (subtype, icao24, velocity, heading, vert_spd, turnrate) retstr += "Type 17 with FTC=%i from %x not implemented" % (msg.data["ftc"], icao24)
elif subtype == 1: except ADSBError:
[velocity, heading, vert_spd] = self.parseBDS09_1(data) return
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: print retstr
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
def printTCAS(self, msg): def printTCAS(self, msg):
return return

View File

@ -255,7 +255,7 @@ def decode_id(id):
return (a * 1000) + (b * 100) + (c * 10) + d return (a * 1000) + (b * 100) + (c * 10) + d
#decode ident squawks #decode ident squawks
def charmap(self, d): def charmap(d):
if d > 0 and d < 27: if d > 0 and d < 27:
retval = chr(ord("A")+d-1) retval = chr(ord("A")+d-1)
elif d == 32: elif d == 32:
@ -267,7 +267,7 @@ def charmap(self, d):
return retval return retval
def parseBDS08(self, data): def parseBDS08(data):
categories = [["NO INFO", "RESERVED", "RESERVED", "RESERVED", "RESERVED", "RESERVED", "RESERVED", "RESERVED"],\ 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", "SURFACE EMERGENCY VEHICLE", "SURFACE SERVICE VEHICLE", "FIXED OBSTRUCTION", "CLUSTER OBSTRUCTION", "LINE OBSTRUCTION", "RESERVED"],\
["NO INFO", "GLIDER", "BALLOON/BLIMP", "PARACHUTE", "ULTRALIGHT", "RESERVED", "UAV", "SPACECRAFT"],\ ["NO INFO", "GLIDER", "BALLOON/BLIMP", "PARACHUTE", "ULTRALIGHT", "RESERVED", "UAV", "SPACECRAFT"],\
@ -281,18 +281,18 @@ def parseBDS08(self, data):
return (msg, catstring) return (msg, catstring)
#NOTE: this is stateful -- requires CPR decoder #NOTE: this is stateful -- requires CPR decoder
def parseBDS05(self, data, cpr): def parseBDS05(data, cprdec):
altitude = decode_alt(data["alt"], False) 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] return [altitude, decoded_lat, decoded_lon, rnge, bearing]
#NOTE: this is stateful -- requires CPR decoder #NOTE: this is stateful -- requires CPR decoder
def parseBDS06(self, data, cpr): def parseBDS06(data, cprdec):
ground_track = data["gtk"] * 360. / 128 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] 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"], #0: ["sub", "dew", "vew", "dns", "vns", "str", "tr", "svr", "vr"],
vert_spd = data["vr"] * 32 vert_spd = data["vr"] * 32
ud = bool(data["dvr"]) ud = bool(data["dvr"])
@ -318,7 +318,7 @@ def parseBDS09_0(self, data):
return [velocity, heading, vert_spd, turn_rate] 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"], #1: ["sub", "icf", "ifr", "nuc", "dew", "vew", "dns", "vns", "vrsrc", "dvr", "vr", "dhd", "hd"],
alt_geo_diff = data["hd"] * 25 alt_geo_diff = data["hd"] * 25
above_below = bool(data["dhd"]) above_below = bool(data["dhd"])
@ -353,7 +353,7 @@ def parseBDS09_1(self, data):
return [velocity, heading, vert_spd] return [velocity, heading, vert_spd]
def parseBDS09_3(self, data): def parseBDS09_3(data):
#3: {"sub", "icf", "ifr", "nuc", "mhs", "hdg", "ast", "spd", "vrsrc", #3: {"sub", "icf", "ifr", "nuc", "mhs", "hdg", "ast", "spd", "vrsrc",
# "dvr", "vr", "dhd", "hd"} # "dvr", "vr", "dhd", "hd"}
mag_hdg = data["mhs"] * 360. / 1024 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] 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", eps_strings = ["NO EMERGENCY", "GENERAL EMERGENCY", "LIFEGUARD/MEDICAL", "FUEL EMERGENCY",
"NO COMMUNICATIONS", "UNLAWFUL INTERFERENCE", "RESERVED", "RESERVED"] "NO COMMUNICATIONS", "UNLAWFUL INTERFERENCE", "RESERVED", "RESERVED"]
return eps_strings[data["eps"]] return eps_strings[data["eps"]]
def parseMB_id(self, data): #bds1 == 2, bds2 == 0 def parseMB_id(data): #bds1 == 2, bds2 == 0
msg = "" msg = ""
for i in range(0, 8): for i in range(0, 8):
msg += self.charmap( data["ais"] >> (42-6*i) & 0x3F) msg += self.charmap( data["ais"] >> (42-6*i) & 0x3F)
return (msg) return (msg)
def parseMB_TCAS_resolutions(self, data): def parseMB_TCAS_resolutions(data):
#these are LSB because the ICAO are asshats #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", 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", 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 #mte is 1 if multiple threats indicated
#tti is threat type: 1 if ID, 2 if range/brg/alt #tti is threat type: 1 if ID, 2 if range/brg/alt
#tida is threat altitude in Mode C format #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), #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)} # "mte": (60,1), "tti": (61,2), "tida": (63,13), "tidr": (76,7), "tidb": (83,6)}
(resolutions, complements) = self.parseMB_TCAS_resolutions(data) (resolutions, complements) = self.parseMB_TCAS_resolutions(data)
return (resolutions, complements, data["rat"], data["mte"], data["tid"]) 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) (resolutions, complements) = self.parseMB_TCAS_resolutions(data)
threat_alt = decode_alt(data["tida"], True) threat_alt = decode_alt(data["tida"], True)
return (resolutions, complements, data["rat"], data["mte"], threat_alt, data["tidr"], data["tidb"]) return (resolutions, complements, data["rat"], data["mte"], threat_alt, data["tidr"], data["tidb"])
#type 16 Coordination Reply Message #type 16 Coordination Reply Message
def parse_TCAS_CRM(self, data): def parse_TCAS_CRM(data):
(resolutions, complements) = self.parseMB_TCAS_resolutions(data) (resolutions, complements) = self.parseMB_TCAS_resolutions(data)
return (resolutions, complements, data["rat"], data["mte"]) return (resolutions, complements, data["rat"], data["mte"])