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:
parent
a1e2297134
commit
d84c0c3204
@ -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(':')
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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"])
|
||||||
|
Loading…
Reference in New Issue
Block a user