Moved SBS1, az_map, and SQL modules to new parser interface. Not tested.

This commit is contained in:
Nick Foster 2013-06-18 18:57:24 -07:00
parent 72ae3abf12
commit 9563972591
5 changed files with 73 additions and 80 deletions

View File

@ -63,15 +63,21 @@ def main():
#ok now relay is gonna get all those tasty strings
#internally we want to distribute parsed data instead, lighten the load
#TODO obviously this should go somewhere besides the main app. But where?
publisher = pubsub()
def send(message):
def make_report(pub, message):
[data, ecc, reference, timestamp] = message.split()
try:
ret = air_modes.modes_report(air_modes.modes_reply(int(data, 16)), int(ecc, 16), 20.0*math.log10(float(reference)), air_modes.stamp(0, float(timestamp)))
publisher["modes_dl"] = ret
publisher["type%i_dl" % ret.data.get_type()] = ret
ret = air_modes.modes_report(air_modes.modes_reply(int(data, 16)),
int(ecc, 16),
20.0*math.log10(float(reference)),
air_modes.stamp(0, float(timestamp)))
pub["modes_dl"] = ret
pub["type%i_dl" % ret.data.get_type()] = ret
except ADSBError:
pass
send = lambda msg: make_report(publisher, msg)
relay.subscribe("dl_data", send)
@ -84,12 +90,10 @@ def main():
if options.kml is not None:
dbname = 'adsb.db'
lock = threading.Lock()
sqldb = air_modes.output_sql(my_position, dbname, lock) #input into the db
sqldb = air_modes.output_sql(cpr_dec, dbname, lock, publisher) #input into the db
kmlgen = air_modes.output_kml(options.kml, dbname, my_position, lock) #create a KML generating thread to read from the db
relay.subscribe("dl_data", sqldb.insert)
if options.no_print is not True:
#relay.subscribe("dl_data", air_modes.output_print(my_position).output)
printer = air_modes.output_print(cpr_dec, publisher)
if options.multiplayer is not None:
@ -98,8 +102,7 @@ def main():
relay.subscribe("dl_data", fgout.output)
if options.sbs1 is True:
sbs1port = air_modes.output_sbs1(my_position, 30003)
relay.subscribe("dl_data", sbs1port.output)
sbs1port = air_modes.output_sbs1(cpr_dec, 30003, publisher)
tb.run()
tb.close()

View File

@ -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

View File

@ -169,29 +169,26 @@ class az_map(QtGui.QWidget):
self.ringsize = ringsize
self.drawPath()
class az_map_output(air_modes.parse):
def __init__(self, mypos, model):
air_modes.parse.__init__(self, mypos)
class az_map_output:
def __init__(self, cprdec, model, pub):
self._cpr = cprdec
self.model = model
pub.subscribe("type17_dl", output)
def output(self, msg):
try:
[data, ecc, reference, timestamp] = msg.split()
data = air_modes.modes_reply(long(data, 16))
ecc = long(ecc, 16)
rssi = 10.*math.log10(float(reference))
msgtype = data["df"]
msgtype = msg.data["df"]
now = time.time()
if msgtype == 17:
icao = data["aa"]
subtype = data["ftc"]
icao = msg.data["aa"]
subtype = msg.data["ftc"]
distance, altitude, bearing = [0,0,0]
if 5 <= subtype <= 8:
(ground_track, decoded_lat, decoded_lon, distance, bearing) = self.parseBDS06(data)
(ground_track, decoded_lat, decoded_lon, distance, bearing) = air_modes.parseBDS06(msg.data, self._cpr)
altitude = 0
elif 9 <= subtype <= 18:
(altitude, decoded_lat, decoded_lon, distance, bearing) = self.parseBDS05(data)
(altitude, decoded_lat, decoded_lon, distance, bearing) = air_modes.parseBDS05(msg.data, self._cpr)
self.model.addRecord(bearing, altitude, distance)
except ADSBError:

View File

@ -47,9 +47,8 @@ class dumb_task_runner(threading.Thread):
self.shutdown.set()
self.finished.wait(self._interval)
class output_sbs1(air_modes.parse):
def __init__(self, mypos, port):
air_modes.parse.__init__(self, mypos)
class output_sbs1:
def __init__(self, cprdec, port, pub):
self._s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self._s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self._s.bind(('', port))
@ -59,6 +58,13 @@ class output_sbs1(air_modes.parse):
self._aircraft_id_map = {} # dictionary of icao24 to aircraft IDs
self._aircraft_id_count = 0 # Current Aircraft ID count
self._cpr = cprdec
#it could be cleaner if there were separate output_* fns
#but this works
for i in (0, 4, 5, 11, 17):
pub.subscribe("type%i_dl" % i, output)
#spawn thread to add new connections as they come in
self._runner = dumb_task_runner(self.add_pending_conns, 0.1)
@ -124,35 +130,30 @@ class output_sbs1(air_modes.parse):
else:
return ",,,"
def parse(self, message):
def parse(self, msg):
#assembles a SBS-1-style output string from the received message
[data, ecc, reference, timestamp] = message.split()
data = air_modes.modes_reply(long(data, 16))
ecc = long(ecc, 16)
msgtype = data["df"]
msgtype = msg.data["df"]
outmsg = None
if msgtype == 0:
outmsg = self.pp0(data, ecc)
outmsg = self.pp0(msg.data, msg.ecc)
elif msgtype == 4:
outmsg = self.pp4(data, ecc)
outmsg = self.pp4(msg.data, msg.ecc)
elif msgtype == 5:
outmsg = self.pp5(data, ecc)
outmsg = self.pp5(msg.data, msg.ecc)
elif msgtype == 11:
outmsg = self.pp11(data, ecc)
outmsg = self.pp11(msg.data, msg.ecc)
elif msgtype == 17:
outmsg = self.pp17(data)
outmsg = self.pp17(msg.data)
else:
raise NoHandlerError(msgtype)
return outmsg
def pp0(self, shortdata, ecc):
[datestr, timestr] = self.current_time()
[vs, cc, sl, ri, altitude] = self.parse0(shortdata)
aircraft_id = self.get_aircraft_id(ecc)
retstr = "MSG,7,0,%i,%06X,%i,%s,%s,%s,%s,,%s,,,,,,,,,," % (aircraft_id, ecc, aircraft_id+100, datestr, timestr, datestr, timestr, altitude)
retstr = "MSG,7,0,%i,%06X,%i,%s,%s,%s,%s,,%s,,,,,,,,,," % (aircraft_id, ecc, aircraft_id+100, datestr, timestr, datestr, timestr, air_modes.decode_alt(shortdata["ac"], True))
if vs:
retstr += "1\r\n"
else:
@ -161,23 +162,20 @@ class output_sbs1(air_modes.parse):
def pp4(self, shortdata, ecc):
[datestr, timestr] = self.current_time()
[fs, dr, um, altitude] = self.parse4(shortdata)
aircraft_id = self.get_aircraft_id(ecc)
retstr = "MSG,5,0,%i,%06X,%i,%s,%s,%s,%s,,%s,,,,,,," % (aircraft_id, ecc, aircraft_id+100, datestr, timestr, datestr, timestr, altitude)
return retstr + self.decode_fs(fs) + "\r\n"
retstr = "MSG,5,0,%i,%06X,%i,%s,%s,%s,%s,,%s,,,,,,," % (aircraft_id, ecc, aircraft_id+100, datestr, timestr, datestr, timestr, air_modes.decode_alt(shortdata["ac"], True))
return retstr + self.decode_fs(shortdata["fs"]) + "\r\n"
def pp5(self, shortdata, ecc):
[datestr, timestr] = self.current_time()
[fs, dr, um, ident] = self.parse5(shortdata)
aircraft_id = self.get_aircraft_id(ecc)
retstr = "MSG,6,0,%i,%06X,%i,%s,%s,%s,%s,,,,,,,,%04i," % (aircraft_id, ecc, aircraft_id+100, datestr, timestr, datestr, timestr, ident)
return retstr + self.decode_fs(fs) + "\r\n"
retstr = "MSG,6,0,%i,%06X,%i,%s,%s,%s,%s,,,,,,,,%04i," % (aircraft_id, ecc, aircraft_id+100, datestr, timestr, datestr, timestr, air_modes.decode_id(shortdata["id"]))
return retstr + self.decode_fs(shortdata["fs"]) + "\r\n"
def pp11(self, shortdata, ecc):
[datestr, timestr] = self.current_time()
[icao24, interrogator, ca] = self.parse11(shortdata, ecc)
aircraft_id = self.get_aircraft_id(icao24)
return "MSG,8,0,%i,%06X,%i,%s,%s,%s,%s,,,,,,,,,,,,\r\n" % (aircraft_id, icao24, aircraft_id+100, datestr, timestr, datestr, timestr)
return "MSG,8,0,%i,%06X,%i,%s,%s,%s,%s,,,,,,,,,,,,\r\n" % (aircraft_id, shortdata["aa"], aircraft_id+100, datestr, timestr, datestr, timestr)
def pp17(self, data):
icao24 = data["aa"]
@ -191,12 +189,12 @@ class output_sbs1(air_modes.parse):
if bdsreg == 0x08:
# Aircraft Identification
(msg, typestring) = self.parseBDS08(data)
(msg, typestring) = air_modes.parseBDS08(data)
retstr = "MSG,1,0,%i,%06X,%i,%s,%s,%s,%s,%s,,,,,,,,,,,\r\n" % (aircraft_id, icao24, aircraft_id+100, datestr, timestr, datestr, timestr, msg)
elif bdsreg == 0x06:
# Surface position measurement
[ground_track, decoded_lat, decoded_lon, rnge, bearing] = self.parseBDS06(data)
[ground_track, decoded_lat, decoded_lon, rnge, bearing] = air_modes.parseBDS06(data, self._cpr)
altitude = 0
if decoded_lat is None: #no unambiguously valid position available
retstr = None
@ -206,7 +204,7 @@ class output_sbs1(air_modes.parse):
elif bdsreg == 0x05:
# Airborne position measurements
# WRONG (rnge, bearing), is this still true?
[altitude, decoded_lat, decoded_lon, rnge, bearing] = self.parseBDS05(data)
[altitude, decoded_lat, decoded_lon, rnge, bearing] = air_modes.parseBDS05(data, self._cpr)
if decoded_lat is None: #no unambiguously valid position available
retstr = None
else:
@ -217,7 +215,7 @@ class output_sbs1(air_modes.parse):
# WRONG (heading, vert_spd), Is this still true?
subtype = data["bds09"].get_type()
if subtype == 0 or subtype == 1:
parser = self.parseBDS09_0 if subtype == 0 else self.parseBDS09_1
parser = air_modes.parseBDS09_0 if subtype == 0 else air_modes.parseBDS09_1
[velocity, heading, vert_spd] = parser(data)
retstr = "MSG,4,0,%i,%06X,%i,%s,%s,%s,%s,,,%.1f,%.1f,,,%i,,,,,\r\n" % (aircraft_id, icao24, aircraft_id+100, datestr, timestr, datestr, timestr, velocity, heading, vert_spd)

View File

@ -26,11 +26,10 @@ import sqlite3
from air_modes.exceptions import *
from gnuradio.gr.pubsub import pubsub
class output_sql(air_modes.parse, pubsub):
def __init__(self, mypos, filename, lock):
air_modes.parse.__init__(self, mypos)
pubsub.__init__(self)
class output_sql:
def __init__(self, cpr, filename, lock, publisher):
#pubsub.__init__(self)
self._cpr = cpr
self._lock = lock;
#create the database
self.filename = filename
@ -63,6 +62,7 @@ class output_sql(air_modes.parse, pubsub):
#we close the db conn now to reopen it in the output() thread context.
self._db.close()
self._db = None
publisher.subscribe("type17_dl", self.insert)
def insert(self, message):
with self._lock:
@ -84,19 +84,14 @@ class output_sql(air_modes.parse, pubsub):
except ADSBError:
pass
def make_insert_query(self, message):
def make_insert_query(self, msg):
#assembles a SQL query tailored to our database
#this version ignores anything that isn't Type 17 for now, because we just don't care
[data, ecc, reference, timestamp] = message.split()
data = air_modes.modes_reply(long(data, 16))
ecc = long(ecc, 16)
# reference = float(reference)
query = None
msgtype = data["df"]
msgtype = msg.data["df"]
if msgtype == 17:
query = self.sql17(data)
self["new_adsb"] = data["aa"] #publish change notification
query = self.sql17(msg.data)
#self["new_adsb"] = data["aa"] #publish change notification
return query
@ -111,20 +106,20 @@ class output_sql(air_modes.parse, pubsub):
def sql17(self, data):
icao24 = data["aa"]
bdsreg = data["me"].get_type()
self["bds%.2i" % bdsreg] = icao24 #publish under "bds08", "bds06", etc.
#self["bds%.2i" % bdsreg] = icao24 #publish under "bds08", "bds06", etc.
if bdsreg == 0x08:
(msg, typename) = self.parseBDS08(data)
(msg, typename) = air_modes.parseBDS08(data)
return "INSERT OR REPLACE INTO ident (icao, ident) VALUES (" + "%i" % icao24 + ", '" + msg + "')"
elif bdsreg == 0x06:
[ground_track, decoded_lat, decoded_lon, rnge, bearing] = self.parseBDS06(data)
[ground_track, decoded_lat, decoded_lon, rnge, bearing] = air_modes.parseBDS06(data, self._cpr)
altitude = 0
if decoded_lat is None: #no unambiguously valid position available
raise CPRNoPositionError
else:
return "INSERT INTO positions (icao, seen, alt, lat, lon) VALUES (" + "%i" % icao24 + ", datetime('now'), " + str(altitude) + ", " + "%.6f" % decoded_lat + ", " + "%.6f" % decoded_lon + ")"
elif bdsreg == 0x05:
[altitude, decoded_lat, decoded_lon, rnge, bearing] = self.parseBDS05(data)
[altitude, decoded_lat, decoded_lon, rnge, bearing] = air_modes.parseBDS05(data, self._cpr)
if decoded_lat is None: #no unambiguously valid position available
raise CPRNoPositionError
else:
@ -132,10 +127,10 @@ class output_sql(air_modes.parse, pubsub):
elif bdsreg == 0x09:
subtype = data["bds09"].get_type()
if subtype == 0:
[velocity, heading, vert_spd, turnrate] = self.parseBDS09_0(data)
[velocity, heading, vert_spd, turnrate] = air_modes.parseBDS09_0(data)
return "INSERT INTO vectors (icao, seen, speed, heading, vertical) VALUES (" + "%i" % icao24 + ", datetime('now'), " + "%.0f" % velocity + ", " + "%.0f" % heading + ", " + "%.0f" % vert_spd + ")"
elif subtype == 1:
[velocity, heading, vert_spd] = self.parseBDS09_1(data)
[velocity, heading, vert_spd] = air_modes.parseBDS09_1(data)
return "INSERT INTO vectors (icao, seen, speed, heading, vertical) VALUES (" + "%i" % icao24 + ", datetime('now'), " + "%.0f" % velocity + ", " + "%.0f" % heading + ", " + "%.0f" % vert_spd + ")"
else:
raise NoHandlerError