Fix modes_gui. Only thing which should be nonfunc. is the reports/sec box (no thread to run it).
This commit is contained in:
parent
bed2aa499e
commit
d508b39b31
239
apps/modes_gui
239
apps/modes_gui
@ -20,15 +20,17 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
import os, sys, time, threading, datetime, math, csv
|
import os, sys, time, threading, datetime, math, csv
|
||||||
|
from optparse import OptionParser
|
||||||
from PyQt4 import QtCore,QtGui
|
from PyQt4 import QtCore,QtGui
|
||||||
from PyQt4.Qwt5 import Qwt
|
from PyQt4.Qwt5 import Qwt
|
||||||
from gnuradio import gr, gru, optfir, eng_notation, blks2
|
from gnuradio import gr, gru, optfir, eng_notation, blks2
|
||||||
import gnuradio.gr.gr_threading as _threading
|
from gnuradio.eng_option import eng_option
|
||||||
import air_modes
|
import air_modes
|
||||||
from air_modes.exceptions import *
|
from air_modes.exceptions import *
|
||||||
from air_modes.modes_rx_ui import Ui_MainWindow
|
from air_modes.modes_rx_ui import Ui_MainWindow
|
||||||
from air_modes.gui_model import *
|
from air_modes.gui_model import *
|
||||||
import sqlite3
|
import sqlite3
|
||||||
|
import zmq
|
||||||
|
|
||||||
class mainwindow(QtGui.QMainWindow):
|
class mainwindow(QtGui.QMainWindow):
|
||||||
live_data_changed_signal = QtCore.pyqtSignal(QtCore.QString, name='liveDataChanged')
|
live_data_changed_signal = QtCore.pyqtSignal(QtCore.QString, name='liveDataChanged')
|
||||||
@ -39,7 +41,7 @@ class mainwindow(QtGui.QMainWindow):
|
|||||||
|
|
||||||
#set defaults
|
#set defaults
|
||||||
#add file, RTL, UHD sources
|
#add file, RTL, UHD sources
|
||||||
self.ui.combo_source.addItems(["UHD device", "RTL-SDR", "File"])
|
self.ui.combo_source.addItems(["UHD", "Osmocom", "File/UDP"])
|
||||||
self.ui.combo_source.setCurrentIndex(0)
|
self.ui.combo_source.setCurrentIndex(0)
|
||||||
|
|
||||||
#populate antenna, rate combo boxes based on source
|
#populate antenna, rate combo boxes based on source
|
||||||
@ -51,8 +53,8 @@ class mainwindow(QtGui.QMainWindow):
|
|||||||
#default to 5dB
|
#default to 5dB
|
||||||
self.ui.line_threshold.insert("5")
|
self.ui.line_threshold.insert("5")
|
||||||
|
|
||||||
self.ui.prog_rssi.setMinimum(-40)
|
self.ui.prog_rssi.setMinimum(0)
|
||||||
self.ui.prog_rssi.setMaximum(0)
|
self.ui.prog_rssi.setMaximum(40)
|
||||||
|
|
||||||
self.ui.combo_ant.setCurrentIndex(self.ui.combo_ant.findText("RX2"))
|
self.ui.combo_ant.setCurrentIndex(self.ui.combo_ant.findText("RX2"))
|
||||||
|
|
||||||
@ -71,15 +73,12 @@ class mainwindow(QtGui.QMainWindow):
|
|||||||
self.ui.check_adsbonly.setCheckState(QtCore.Qt.Unchecked)
|
self.ui.check_adsbonly.setCheckState(QtCore.Qt.Unchecked)
|
||||||
|
|
||||||
self.queue = gr.msg_queue(10)
|
self.queue = gr.msg_queue(10)
|
||||||
self.runner = None
|
self.running = False
|
||||||
self.fg = None
|
|
||||||
self.outputs = []
|
|
||||||
self.updates = []
|
|
||||||
self.output_handler = None
|
|
||||||
self.kmlgen = None #necessary bc we stop its thread in shutdown
|
self.kmlgen = None #necessary bc we stop its thread in shutdown
|
||||||
self.dbname = "air_modes.db"
|
self.dbname = "air_modes.db"
|
||||||
self.num_reports = 0
|
self.num_reports = 0
|
||||||
self.last_report = 0
|
self.last_report = 0
|
||||||
|
self.context = zmq.Context(1)
|
||||||
|
|
||||||
self.datamodel = dashboard_data_model(None)
|
self.datamodel = dashboard_data_model(None)
|
||||||
self.ui.list_aircraft.setModel(self.datamodel)
|
self.ui.list_aircraft.setModel(self.datamodel)
|
||||||
@ -167,11 +166,11 @@ class mainwindow(QtGui.QMainWindow):
|
|||||||
self.ratetext = []
|
self.ratetext = []
|
||||||
self.antennas = []
|
self.antennas = []
|
||||||
|
|
||||||
if sourceid == "UHD device":
|
if sourceid == "UHD":
|
||||||
try:
|
try:
|
||||||
from gnuradio import uhd
|
from gnuradio import uhd
|
||||||
self.src = uhd.single_usrp_source("", uhd.io_type_t.COMPLEX_FLOAT32, 1)
|
self.src = uhd.single_usrp_source("", uhd.io_type_t.COMPLEX_FLOAT32, 1)
|
||||||
self.rates = [rate.start() for rate in self.src.get_samp_rates()]
|
self.rates = [rate.start() for rate in self.src.get_samp_rates() if (rate.start() % 2.e6) == 0]
|
||||||
self.antennas = self.src.get_antennas()
|
self.antennas = self.src.get_antennas()
|
||||||
self.src = None #deconstruct UHD source for now
|
self.src = None #deconstruct UHD source for now
|
||||||
self.ui.combo_ant.setEnabled(True)
|
self.ui.combo_ant.setEnabled(True)
|
||||||
@ -184,15 +183,25 @@ class mainwindow(QtGui.QMainWindow):
|
|||||||
self.ui.combo_rate.setEnabled(False)
|
self.ui.combo_rate.setEnabled(False)
|
||||||
self.ui.stack_source.setCurrentIndex(0)
|
self.ui.stack_source.setCurrentIndex(0)
|
||||||
|
|
||||||
elif sourceid == "RTL-SDR":
|
elif sourceid == "Osmocom":
|
||||||
self.rates = [3.2e6]
|
try:
|
||||||
self.antennas = ["RX"]
|
import osmosdr
|
||||||
self.ui.combo_ant.setEnabled(False)
|
self.src = osmosdr.source_c("")
|
||||||
self.ui.combo_rate.setEnabled(False)
|
self.rates = [rate.start() for rate in self.src.get_sample_rates() if (rate.start() % 2.e6) == 0]
|
||||||
self.ui.stack_source.setCurrentIndex(0)
|
self.antennas = ["RX"]
|
||||||
|
self.src = None
|
||||||
|
self.ui.combo_ant.setEnabled(False)
|
||||||
|
self.ui.combo_rate.setEnabled(True)
|
||||||
|
self.ui.stack_source.setCurrentIndex(0)
|
||||||
|
except:
|
||||||
|
self.rates = []
|
||||||
|
self.antennas = []
|
||||||
|
self.ui.combo_ant.setEnabled(False)
|
||||||
|
self.ui.combo_rate.setEnabled(False)
|
||||||
|
self.ui.stack_source.setCurrentIndex(0)
|
||||||
|
|
||||||
elif sourceid == "File":
|
elif sourceid == "File/UDP":
|
||||||
self.rates = [2e6, 4e6, 6e6, 8e6, 10e6]
|
self.rates = [2e6*i for i in range(2,13)]
|
||||||
self.antennas = ["None"]
|
self.antennas = ["None"]
|
||||||
self.ui.combo_ant.setEnabled(False)
|
self.ui.combo_ant.setEnabled(False)
|
||||||
self.ui.combo_rate.setEnabled(True)
|
self.ui.combo_rate.setEnabled(True)
|
||||||
@ -215,37 +224,36 @@ class mainwindow(QtGui.QMainWindow):
|
|||||||
|
|
||||||
def on_button_start_released(self):
|
def on_button_start_released(self):
|
||||||
#if we're already running, kill it!
|
#if we're already running, kill it!
|
||||||
if self.runner is not None:
|
if self.running is True:
|
||||||
self.output_handler.done = True
|
self.on_quit()
|
||||||
self.output_handler = None
|
|
||||||
self.outputs = []
|
|
||||||
self.updates = []
|
|
||||||
self.fg.stop()
|
|
||||||
self.runner = None
|
|
||||||
self.fg = None
|
|
||||||
if self.kmlgen is not None:
|
|
||||||
self.kmlgen.done = True
|
|
||||||
#TODO FIXME need a way to kill kmlgen safely without delay
|
|
||||||
#self.kmlgen.join()
|
|
||||||
#self.kmlgen = None
|
|
||||||
|
|
||||||
self.num_reports = 0
|
self.num_reports = 0
|
||||||
self.ui.line_reports.setText("0")
|
self.ui.line_reports.setText("0")
|
||||||
|
|
||||||
self.ui.button_start.setText("Start")
|
self.ui.button_start.setText("Start")
|
||||||
|
self.running = False
|
||||||
|
|
||||||
else: #we aren't already running, let's get this party started
|
else: #we aren't already running, let's get this party started
|
||||||
options = {}
|
parser = OptionParser(option_class=eng_option)
|
||||||
options["source"] = str(self.ui.combo_source.currentText())
|
air_modes.modes_radio.add_radio_options(parser)
|
||||||
options["rate"] = float(self.ui.combo_rate.currentText()) * 1e6
|
(options, args) = parser.parse_args() #sets defaults nicely
|
||||||
options["antenna"] = str(self.ui.combo_ant.currentText())
|
if str(self.ui.combo_source.currentText()) != "File/UDP":
|
||||||
options["gain"] = float(self.ui.line_gain.text())
|
options.source = str(self.ui.combo_source.currentText()).lower()
|
||||||
options["threshold"] = float(self.ui.line_threshold.text())
|
else:
|
||||||
options["filename"] = str(self.ui.line_inputfile.text())
|
options.source = str(self.ui.line_inputfile.text())
|
||||||
options["pmf"] = self.ui.check_pmf.checkState()
|
options.rate = float(self.ui.combo_rate.currentText()) * 1e6
|
||||||
|
options.antenna = str(self.ui.combo_ant.currentText())
|
||||||
|
options.gain = float(self.ui.line_gain.text())
|
||||||
|
options.threshold = float(self.ui.line_threshold.text())
|
||||||
|
options.pmf = self.ui.check_pmf.checkState()
|
||||||
|
|
||||||
self.fg = adsb_rx_block(options, self.queue) #create top RX block
|
self._servers = ["inproc://modes-radio-pub"] #TODO ADD REMOTES
|
||||||
self.runner = top_block_runner(self.fg) #spawn new thread to do RX
|
self._relay = air_modes.zmq_pubsub_iface(self.context, subaddr=self._servers, pubaddr=None)
|
||||||
|
|
||||||
|
if self.ui.check_raw.checkState():
|
||||||
|
options.tcp = int(self.ui.line_rawport.text())
|
||||||
|
|
||||||
|
self._radio = air_modes.modes_radio(options, self.context)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
my_position = [float(self.ui.line_my_lat.text()), float(self.ui.line_my_lon.text())]
|
my_position = [float(self.ui.line_my_lat.text()), float(self.ui.line_my_lon.text())]
|
||||||
@ -253,9 +261,8 @@ class mainwindow(QtGui.QMainWindow):
|
|||||||
my_position = None
|
my_position = None
|
||||||
|
|
||||||
self.datamodelout = dashboard_output(my_position, self.datamodel)
|
self.datamodelout = dashboard_output(my_position, self.datamodel)
|
||||||
|
self._relay.subscribe("dl_data", self.datamodelout.output)
|
||||||
|
|
||||||
self.outputs = [self.datamodelout.output]
|
|
||||||
self.updates = []
|
|
||||||
self.lock = threading.Lock() #grab a lock to ensure sql and kml don't step on each other
|
self.lock = threading.Lock() #grab a lock to ensure sql and kml don't step on each other
|
||||||
|
|
||||||
#output options to populate outputs, updates
|
#output options to populate outputs, updates
|
||||||
@ -266,54 +273,43 @@ class mainwindow(QtGui.QMainWindow):
|
|||||||
if self.ui.check_sbs1.checkState():
|
if self.ui.check_sbs1.checkState():
|
||||||
sbs1port = int(self.ui.line_sbs1port.text())
|
sbs1port = int(self.ui.line_sbs1port.text())
|
||||||
sbs1out = air_modes.output_sbs1(my_position, sbs1port)
|
sbs1out = air_modes.output_sbs1(my_position, sbs1port)
|
||||||
self.outputs.append(sbs1out.output)
|
self._relay.subscribe("dl_data", sbs1.output)
|
||||||
self.updates.append(sbs1out.add_pending_conns)
|
|
||||||
|
|
||||||
if self.ui.check_fgfs.checkState():
|
if self.ui.check_fgfs.checkState():
|
||||||
fghost = "127.0.0.1" #TODO FIXME
|
fghost = "127.0.0.1" #TODO FIXME
|
||||||
fgport = self.ui.line_fgfsport.text()
|
fgport = self.ui.line_fgfsport.text()
|
||||||
fgout = air_modes.output_flightgear(my_position, fghost, int(fgport))
|
fgout = air_modes.output_flightgear(my_position, fghost, int(fgport))
|
||||||
self.outputs.append(fgout.output)
|
self._relay.subscribe("dl_data", fgout.output)
|
||||||
|
|
||||||
if self.ui.check_raw.checkState():
|
|
||||||
rawport = air_modes.raw_server(int(self.ui.line_rawport.text()))
|
|
||||||
self.outputs.append(rawport.output)
|
|
||||||
self.updates.append(rawport.add_pending_conns)
|
|
||||||
|
|
||||||
#add azimuth map output and hook it up
|
#add azimuth map output and hook it up
|
||||||
if my_position is not None:
|
if my_position is not None:
|
||||||
self.az_map_output = air_modes.az_map_output(my_position, self.az_model)
|
self.az_map_output = air_modes.az_map_output(my_position, self.az_model)
|
||||||
self.outputs.append(self.az_map_output.output)
|
self._relay.subscribe("dl_data", self.az_map_output.output)
|
||||||
|
|
||||||
self.livedata = air_modes.output_print(my_position)
|
self.livedata = air_modes.output_print(my_position)
|
||||||
#add output for live data box
|
#add output for live data box
|
||||||
self.outputs.append(self.output_live_data)
|
self._relay.subscribe("dl_data", self.output_live_data)
|
||||||
|
|
||||||
#create SQL database for KML and dashboard displays
|
#create SQL database for KML and dashboard displays
|
||||||
self.dbwriter = air_modes.output_sql(my_position, self.dbname, self.lock)
|
self.dbwriter = air_modes.output_sql(my_position, self.dbname, self.lock)
|
||||||
self.outputs.append(self.dbwriter.output) #now the db will update itself
|
self._relay.subscribe("dl_data", self.dbwriter.insert) #now the db will update itself
|
||||||
|
|
||||||
#output to update reports/sec widget
|
#output to update reports/sec widget
|
||||||
self.outputs.append(self.increment_reportspersec)
|
self._relay.subscribe("dl_data", self.increment_reportspersec)
|
||||||
self.updates.append(self.update_reportspersec)
|
#self.updates.append(self.update_reportspersec) #TODO FIXME
|
||||||
|
|
||||||
#create output handler thread
|
#start the flowgraph
|
||||||
self.output_handler = output_handler(self.outputs, self.updates, self.queue)
|
self._radio.start()
|
||||||
|
|
||||||
self.ui.button_start.setText("Stop")
|
self.ui.button_start.setText("Stop")
|
||||||
|
self.running = True
|
||||||
|
|
||||||
def on_quit(self):
|
def on_quit(self):
|
||||||
if self.runner is not None:
|
if self.running is True:
|
||||||
try:
|
self._relay.close()
|
||||||
self.output_handler.done = True
|
self._radio.close()
|
||||||
except:
|
self._relay = None
|
||||||
pass
|
self._radio = None
|
||||||
self.output_handler = None
|
|
||||||
self.outputs = []
|
|
||||||
self.updates = []
|
|
||||||
self.fg.stop()
|
|
||||||
self.runner = None
|
|
||||||
self.fg = None
|
|
||||||
try:
|
try:
|
||||||
self.kmlgen.done = True
|
self.kmlgen.done = True
|
||||||
#TODO FIXME need a way to kill kmlgen safely without delay
|
#TODO FIXME need a way to kill kmlgen safely without delay
|
||||||
@ -336,103 +332,12 @@ class mainwindow(QtGui.QMainWindow):
|
|||||||
self.ui.text_livedata.verticalScrollBar().setSliderPosition(self.ui.text_livedata.verticalScrollBar().maximum())
|
self.ui.text_livedata.verticalScrollBar().setSliderPosition(self.ui.text_livedata.verticalScrollBar().maximum())
|
||||||
|
|
||||||
def output_live_data(self, msg):
|
def output_live_data(self, msg):
|
||||||
msgstr = self.livedata.parse(msg)
|
try:
|
||||||
if msgstr is not None:
|
msgstr = self.livedata.parse(msg)
|
||||||
self.live_data_changed_signal.emit(msgstr)
|
if msgstr is not None:
|
||||||
|
self.live_data_changed_signal.emit(msgstr)
|
||||||
|
except ADSBError:
|
||||||
|
pass
|
||||||
#the output handler is a thread which runs the various registered output functions when there's a received message.
|
|
||||||
#it also executes registered updates at the sleep rate -- currently 10Hz.
|
|
||||||
class output_handler(threading.Thread):
|
|
||||||
def __init__(self, outputs, updates, queue):
|
|
||||||
threading.Thread.__init__(self)
|
|
||||||
self.setDaemon(1)
|
|
||||||
self.outputs = outputs
|
|
||||||
self.updates = updates
|
|
||||||
self.queue = queue
|
|
||||||
self.done = False
|
|
||||||
self.start()
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
while self.done is False:
|
|
||||||
for update in self.updates:
|
|
||||||
update()
|
|
||||||
while not self.queue.empty_p():
|
|
||||||
msg = self.queue.delete_head()
|
|
||||||
for output in self.outputs:
|
|
||||||
try:
|
|
||||||
output(msg.to_string())
|
|
||||||
except ADSBError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
time.sleep(0.1)
|
|
||||||
|
|
||||||
self.done = True
|
|
||||||
self.outputs = None
|
|
||||||
self.updates = None
|
|
||||||
self.queue = None
|
|
||||||
|
|
||||||
|
|
||||||
class top_block_runner(_threading.Thread):
|
|
||||||
def __init__(self, tb):
|
|
||||||
_threading.Thread.__init__(self)
|
|
||||||
self.setDaemon(1)
|
|
||||||
self.tb = tb
|
|
||||||
self.done = False
|
|
||||||
self.start()
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
self.tb.run()
|
|
||||||
self.done = True
|
|
||||||
|
|
||||||
#Top block for ADSB receiver. If you define a standard interface you
|
|
||||||
#can make this common code between the GUI app and the cmdline app
|
|
||||||
class adsb_rx_block (gr.top_block):
|
|
||||||
def __init__(self, options, queue):
|
|
||||||
gr.top_block.__init__(self)
|
|
||||||
|
|
||||||
self.options = options
|
|
||||||
rate = options["rate"]
|
|
||||||
print "Rate: %f" % rate
|
|
||||||
use_resampler = False
|
|
||||||
freq = 1090e6
|
|
||||||
|
|
||||||
if options["source"] == "UHD device":
|
|
||||||
from gnuradio import uhd
|
|
||||||
self.u = uhd.single_usrp_source("", uhd.io_type_t.COMPLEX_FLOAT32, 1)
|
|
||||||
time_spec = uhd.time_spec(0.0)
|
|
||||||
self.u.set_time_now(time_spec)
|
|
||||||
self.u.set_antenna(options["antenna"])
|
|
||||||
self.u.set_samp_rate(rate)
|
|
||||||
rate = self.u.get_samp_rate()
|
|
||||||
self.u.set_gain(int(options["gain"]))
|
|
||||||
self.u.set_center_freq(freq, 0)
|
|
||||||
|
|
||||||
elif options["source"] == "RTL-SDR":
|
|
||||||
import osmosdr
|
|
||||||
self.u = osmosdr.source_c()
|
|
||||||
self.u.set_sample_rate(3.2e6) #fixed for RTL dongles
|
|
||||||
rate = int(4e6)
|
|
||||||
self.u.set_gain_mode(0) #manual gain mode
|
|
||||||
self.u.set_gain(int(options["gain"]))
|
|
||||||
self.u.set_center_freq(freq, 0)
|
|
||||||
use_resampler = True
|
|
||||||
|
|
||||||
elif options["source"] == "File":
|
|
||||||
self.u = gr.file_source(gr.sizeof_gr_complex, options["filename"])
|
|
||||||
else:
|
|
||||||
raise NotImplementedError
|
|
||||||
|
|
||||||
self.rx_path = air_modes.rx_path(rate, options["threshold"], queue, options["pmf"])
|
|
||||||
|
|
||||||
if use_resampler:
|
|
||||||
self.lpfiltcoeffs = gr.firdes.low_pass(1, 5*3.2e6, 1.6e6, 300e3)
|
|
||||||
self.resample = blks2.rational_resampler_ccf(interpolation=5, decimation=4, taps=self.lpfiltcoeffs)
|
|
||||||
self.connect(self.u, self.resample, self.rx_path)
|
|
||||||
else:
|
|
||||||
self.connect(self.u, self.rx_path)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
app = QtGui.QApplication(sys.argv)
|
app = QtGui.QApplication(sys.argv)
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
from PyQt4 import QtCore, QtGui
|
from PyQt4 import QtCore, QtGui
|
||||||
import air_modes
|
import air_modes
|
||||||
import threading, math, time
|
import threading, math, time
|
||||||
|
from air_modes.exceptions import *
|
||||||
|
|
||||||
#fades the ICAOs out as their last report gets older,
|
#fades the ICAOs out as their last report gets older,
|
||||||
#and display ident if available, ICAO otherwise
|
#and display ident if available, ICAO otherwise
|
||||||
@ -146,53 +147,58 @@ class dashboard_output(air_modes.parse):
|
|||||||
self.model = model
|
self.model = model
|
||||||
def output(self, msg):
|
def output(self, msg):
|
||||||
[data, ecc, reference, timestamp] = msg.split()
|
[data, ecc, reference, timestamp] = msg.split()
|
||||||
data = air_modes.modes_reply(long(data, 16))
|
try:
|
||||||
ecc = long(ecc, 16)
|
data = air_modes.modes_reply(long(data, 16))
|
||||||
rssi = 10.*math.log10(float(reference))
|
ecc = long(ecc, 16)
|
||||||
msgtype = data["df"]
|
rssi = 10.*math.log10(float(reference))
|
||||||
now = time.time()
|
msgtype = data["df"]
|
||||||
newrow = {"rssi": rssi, "seen": now}
|
now = time.time()
|
||||||
if msgtype in [0, 4, 20]:
|
newrow = {"rssi": rssi, "seen": now}
|
||||||
newrow["altitude"] = air_modes.altitude.decode_alt(data["ac"], True)
|
if msgtype in [0, 4, 20]:
|
||||||
newrow["icao"] = ecc
|
newrow["altitude"] = air_modes.altitude.decode_alt(data["ac"], True)
|
||||||
self.model.addRecord(newrow)
|
newrow["icao"] = ecc
|
||||||
|
self.model.addRecord(newrow)
|
||||||
elif msgtype == 17:
|
|
||||||
icao = data["aa"]
|
elif msgtype == 17:
|
||||||
newrow["icao"] = icao
|
icao = data["aa"]
|
||||||
subtype = data["ftc"]
|
newrow["icao"] = icao
|
||||||
if subtype == 4:
|
subtype = data["ftc"]
|
||||||
(ident, actype) = self.parseBDS08(data)
|
if subtype == 4:
|
||||||
newrow["ident"] = ident
|
(ident, actype) = self.parseBDS08(data)
|
||||||
newrow["type"] = actype
|
newrow["ident"] = ident
|
||||||
elif 5 <= subtype <= 8:
|
newrow["type"] = actype
|
||||||
(ground_track, decoded_lat, decoded_lon, rnge, bearing) = self.parseBDS06(data)
|
elif 5 <= subtype <= 8:
|
||||||
newrow["heading"] = ground_track
|
(ground_track, decoded_lat, decoded_lon, rnge, bearing) = self.parseBDS06(data)
|
||||||
newrow["latitude"] = decoded_lat
|
newrow["heading"] = ground_track
|
||||||
newrow["longitude"] = decoded_lon
|
newrow["latitude"] = decoded_lat
|
||||||
newrow["altitude"] = 0
|
newrow["longitude"] = decoded_lon
|
||||||
if rnge is not None:
|
newrow["altitude"] = 0
|
||||||
newrow["range"] = rnge
|
if rnge is not None:
|
||||||
newrow["bearing"] = bearing
|
newrow["range"] = rnge
|
||||||
elif 9 <= subtype <= 18:
|
newrow["bearing"] = bearing
|
||||||
(altitude, decoded_lat, decoded_lon, rnge, bearing) = self.parseBDS05(data)
|
elif 9 <= subtype <= 18:
|
||||||
newrow["altitude"] = altitude
|
(altitude, decoded_lat, decoded_lon, rnge, bearing) = self.parseBDS05(data)
|
||||||
newrow["latitude"] = decoded_lat
|
newrow["altitude"] = altitude
|
||||||
newrow["longitude"] = decoded_lon
|
newrow["latitude"] = decoded_lat
|
||||||
if rnge is not None:
|
newrow["longitude"] = decoded_lon
|
||||||
newrow["range"] = rnge
|
if rnge is not None:
|
||||||
newrow["bearing"] = bearing
|
newrow["range"] = rnge
|
||||||
elif subtype == 19:
|
newrow["bearing"] = bearing
|
||||||
subsubtype = data["sub"]
|
elif subtype == 19:
|
||||||
velocity = None
|
subsubtype = data["sub"]
|
||||||
heading = None
|
velocity = None
|
||||||
vert_spd = None
|
heading = None
|
||||||
if subsubtype == 0:
|
vert_spd = None
|
||||||
(velocity, heading, vert_spd) = self.parseBDS09_0(data)
|
if subsubtype == 0:
|
||||||
elif 1 <= subsubtype <= 2:
|
(velocity, heading, vert_spd) = self.parseBDS09_0(data)
|
||||||
(velocity, heading, vert_spd) = self.parseBDS09_1(data)
|
elif 1 <= subsubtype <= 2:
|
||||||
newrow["speed"] = velocity
|
(velocity, heading, vert_spd) = self.parseBDS09_1(data)
|
||||||
newrow["heading"] = heading
|
newrow["speed"] = velocity
|
||||||
newrow["vertical"] = vert_spd
|
newrow["heading"] = heading
|
||||||
|
newrow["vertical"] = vert_spd
|
||||||
|
|
||||||
|
self.model.addRecord(newrow)
|
||||||
|
|
||||||
|
except ADSBError:
|
||||||
|
return
|
||||||
|
|
||||||
self.model.addRecord(newrow)
|
|
||||||
|
@ -68,7 +68,7 @@ class modes_radio (gr.top_block, pubsub):
|
|||||||
#Publish messages when they come back off the queue
|
#Publish messages when they come back off the queue
|
||||||
server_addr = ["inproc://modes-radio-pub"]
|
server_addr = ["inproc://modes-radio-pub"]
|
||||||
if options.tcp is not None:
|
if options.tcp is not None:
|
||||||
server_addr += ["tcp://*:%i"] % options.tcp
|
server_addr += ["tcp://*:%i" % options.tcp]
|
||||||
|
|
||||||
self._sender = air_modes.zmq_pubsub_iface(context, subaddr=None, pubaddr=server_addr)
|
self._sender = air_modes.zmq_pubsub_iface(context, subaddr=None, pubaddr=server_addr)
|
||||||
self._async_sender = gru.msgq_runner(self._queue, self.send)
|
self._async_sender = gru.msgq_runner(self._queue, self.send)
|
||||||
@ -83,7 +83,7 @@ class modes_radio (gr.top_block, pubsub):
|
|||||||
#Choose source
|
#Choose source
|
||||||
group.add_option("-s","--source", type="string", default="uhd",
|
group.add_option("-s","--source", type="string", default="uhd",
|
||||||
help="Choose source: uhd, osmocom, <filename>, or <ip:port> [default=%default]")
|
help="Choose source: uhd, osmocom, <filename>, or <ip:port> [default=%default]")
|
||||||
group.add_option("-t","--tcp", type="int", default=None,
|
group.add_option("-t","--tcp", type="int", default=None, metavar="PORT",
|
||||||
help="Open a TCP server on this port to publish reports")
|
help="Open a TCP server on this port to publish reports")
|
||||||
|
|
||||||
#UHD/Osmocom args
|
#UHD/Osmocom args
|
||||||
|
@ -111,7 +111,7 @@ class output_sql(air_modes.parse, pubsub):
|
|||||||
def sql17(self, data):
|
def sql17(self, data):
|
||||||
icao24 = data["aa"]
|
icao24 = data["aa"]
|
||||||
bdsreg = data["me"].get_type()
|
bdsreg = data["me"].get_type()
|
||||||
self["bds%.2i" % bdsreg] = icao24 #publish
|
self["bds%.2i" % bdsreg] = icao24 #publish under "bds08", "bds06", etc.
|
||||||
|
|
||||||
if bdsreg == 0x08:
|
if bdsreg == 0x08:
|
||||||
(msg, typename) = self.parseBDS08(data)
|
(msg, typename) = self.parseBDS08(data)
|
||||||
|
@ -365,7 +365,7 @@
|
|||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Raw</string>
|
<string>TCP</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QLineEdit" name="line_kmlfilename">
|
<widget class="QLineEdit" name="line_kmlfilename">
|
||||||
|
Loading…
Reference in New Issue
Block a user