Altitude now taken from types 4, 5, 20 short replies as well, for ADS-B-equipped aircraft. Bearing/heading updated real-time.
TODO: figure out how to filter aircraft list for ADS-B-equipped aircraft only
This commit is contained in:
parent
923651f69a
commit
cb4c91aee1
@ -76,32 +76,47 @@ class mainwindow(QtGui.QMainWindow):
|
|||||||
self.dashboard_mapper.addMapping(self.ui.line_longitude, 4)
|
self.dashboard_mapper.addMapping(self.ui.line_longitude, 4)
|
||||||
self.dashboard_mapper.addMapping(self.ui.line_alt, 5)
|
self.dashboard_mapper.addMapping(self.ui.line_alt, 5)
|
||||||
self.dashboard_mapper.addMapping(self.ui.line_speed, 6)
|
self.dashboard_mapper.addMapping(self.ui.line_speed, 6)
|
||||||
self.dashboard_mapper.addMapping(self.ui.compass_heading, 7)
|
#self.dashboard_mapper.addMapping(self.ui.compass_heading, 7)
|
||||||
self.dashboard_mapper.addMapping(self.ui.line_climb, 8)
|
self.dashboard_mapper.addMapping(self.ui.line_climb, 8)
|
||||||
self.dashboard_mapper.addMapping(self.ui.line_ident, 9)
|
self.dashboard_mapper.addMapping(self.ui.line_ident, 9)
|
||||||
self.dashboard_mapper.addMapping(self.ui.line_type, 10)
|
self.dashboard_mapper.addMapping(self.ui.line_type, 10)
|
||||||
|
self.dashboard_mapper.addMapping(self.ui.line_range, 11)
|
||||||
|
|
||||||
compass_palette = QtGui.QPalette()
|
compass_palette = QtGui.QPalette()
|
||||||
compass_palette.setColor(QtGui.QPalette.Foreground, QtCore.Qt.white)
|
compass_palette.setColor(QtGui.QPalette.Foreground, QtCore.Qt.white)
|
||||||
self.ui.compass_heading.setPalette(compass_palette)
|
self.ui.compass_heading.setPalette(compass_palette)
|
||||||
|
self.ui.compass_bearing.setPalette(compass_palette)
|
||||||
#TODO: change the needle to an aircraft silhouette
|
#TODO: change the needle to an aircraft silhouette
|
||||||
self.ui.compass_heading.setNeedle(Qwt.QwtDialSimpleNeedle(Qwt.QwtDialSimpleNeedle.Ray, False, QtCore.Qt.black))
|
self.ui.compass_heading.setNeedle(Qwt.QwtDialSimpleNeedle(Qwt.QwtDialSimpleNeedle.Ray, False, QtCore.Qt.black))
|
||||||
self.ui.compass_heading.setValue(315.0)
|
self.ui.compass_bearing.setNeedle(Qwt.QwtDialSimpleNeedle(Qwt.QwtDialSimpleNeedle.Ray, False, QtCore.Qt.black))
|
||||||
|
#TODO FIXME do not release
|
||||||
|
self.ui.line_my_lat.insert("37.7623")
|
||||||
|
self.ui.line_my_lon.insert("-122.442527")
|
||||||
|
|
||||||
#hook up the update signal
|
#hook up the update signal
|
||||||
self.ui.list_aircraft.selectionModel().currentRowChanged.connect(self.dashboard_mapper.setCurrentModelIndex)
|
self.ui.list_aircraft.selectionModel().currentRowChanged.connect(self.dashboard_mapper.setCurrentModelIndex)
|
||||||
self.ui.list_aircraft.selectionModel().currentRowChanged.connect(self.update_heading_widget)
|
self.ui.list_aircraft.selectionModel().currentRowChanged.connect(self.update_heading_widget)
|
||||||
self.datamodel.dataChanged.connect(self.update_heading_widget_data)
|
self.ui.list_aircraft.selectionModel().currentRowChanged.connect(self.update_bearing_widget)
|
||||||
|
self.datamodel.dataChanged.connect(self.compass_widgets_dataChanged)
|
||||||
self.ui.list_aircraft.selectionModel().currentRowChanged.connect(self.update_rssi_widget)
|
self.ui.list_aircraft.selectionModel().currentRowChanged.connect(self.update_rssi_widget)
|
||||||
|
|
||||||
def update_heading_widget(self, index):
|
def update_heading_widget(self, index):
|
||||||
if index.model() is not None:
|
if index.model() is not None:
|
||||||
heading = index.model().data(index.model().index(index.row(), 7)).toDouble()[0]
|
heading = index.model().data(index.model().index(index.row(), self.datamodel._colnames.index("heading"))).toDouble()[0]
|
||||||
self.ui.compass_heading.setValue(heading)
|
self.ui.compass_heading.setValue(heading)
|
||||||
|
|
||||||
def update_heading_widget_data(self, startIndex, endIndex):
|
def update_bearing_widget(self, index):
|
||||||
|
if index.model() is not None:
|
||||||
|
bearing = index.model().data(index.model().index(index.row(), self.datamodel._colnames.index("bearing"))).toDouble()[0]
|
||||||
|
self.ui.compass_bearing.setValue(bearing)
|
||||||
|
|
||||||
|
def compass_widgets_dataChanged(self, startIndex, endIndex):
|
||||||
index = self.ui.list_aircraft.selectionModel().currentIndex()
|
index = self.ui.list_aircraft.selectionModel().currentIndex()
|
||||||
|
if index.row() in range(startIndex.row(), endIndex.row()+1): #the current aircraft was affected
|
||||||
|
if self.datamodel._colnames.index("heading") in range(startIndex.column(), endIndex.column()+1):
|
||||||
self.update_heading_widget(index)
|
self.update_heading_widget(index)
|
||||||
|
if self.datamodel._colnames.index("bearing") in range(startIndex.column(), endIndex.column()+1):
|
||||||
|
self.update_bearing_widget(index)
|
||||||
|
|
||||||
def update_rssi_widget(self, index):
|
def update_rssi_widget(self, index):
|
||||||
if index.model() is not None:
|
if index.model() is not None:
|
||||||
@ -274,9 +289,9 @@ class dashboard_data_model(QtCore.QAbstractTableModel):
|
|||||||
QtCore.QAbstractTableModel.__init__(self, parent)
|
QtCore.QAbstractTableModel.__init__(self, parent)
|
||||||
self._data = []
|
self._data = []
|
||||||
self.lock = threading.Lock()
|
self.lock = threading.Lock()
|
||||||
self._colnames = ["icao", "seen", "rssi", "latitude", "longitude", "altitude", "speed", "heading", "vertical", "ident", "type"]
|
self._colnames = ["icao", "seen", "rssi", "latitude", "longitude", "altitude", "speed", "heading", "vertical", "ident", "type", "range", "bearing"]
|
||||||
#custom precision limits for display
|
#custom precision limits for display
|
||||||
self._precisions = [None, None, None, 6, 6, 0, 0, 0, 0, None, None]
|
self._precisions = [None, None, None, 6, 6, 0, 0, 0, 0, None, None, 2, 0]
|
||||||
for field in self._colnames:
|
for field in self._colnames:
|
||||||
self.setHeaderData(self._colnames.index(field), QtCore.Qt.Horizontal, field)
|
self.setHeaderData(self._colnames.index(field), QtCore.Qt.Horizontal, field)
|
||||||
def rowCount(self, parent=QtCore.QVariant()):
|
def rowCount(self, parent=QtCore.QVariant()):
|
||||||
@ -332,7 +347,9 @@ class dashboard_data_model(QtCore.QAbstractTableModel):
|
|||||||
#create index to existing row and tell the model everything's changed in this row
|
#create index to existing row and tell the model everything's changed in this row
|
||||||
#or inside the for loop, use dataChanged on each changed field (might be better)
|
#or inside the for loop, use dataChanged on each changed field (might be better)
|
||||||
self.dataChanged.emit(self.createIndex(row, 0), self.createIndex(row, len(self._colnames)-1))
|
self.dataChanged.emit(self.createIndex(row, 0), self.createIndex(row, len(self._colnames)-1))
|
||||||
else:
|
|
||||||
|
#only create records for ICAOs with ADS-B reports
|
||||||
|
elif ("latitude" or "speed" or "ident") in record:
|
||||||
#find new inserted row number
|
#find new inserted row number
|
||||||
icaos.append(record["icao"])
|
icaos.append(record["icao"])
|
||||||
newrowoffset = sorted(icaos).index(record["icao"])
|
newrowoffset = sorted(icaos).index(record["icao"])
|
||||||
@ -370,7 +387,12 @@ class dashboard_output(air_modes.modes_parse.modes_parse):
|
|||||||
msgtype = data["df"]
|
msgtype = data["df"]
|
||||||
now = time.time()
|
now = time.time()
|
||||||
newrow = {"rssi": rssi, "seen": now}
|
newrow = {"rssi": rssi, "seen": now}
|
||||||
if msgtype == 17:
|
if msgtype in [0, 4, 20]:
|
||||||
|
newrow["altitude"] = air_modes.altitude.decode_alt(data["ac"], True)
|
||||||
|
newrow["icao"] = ecc
|
||||||
|
self.model.addRecord(newrow)
|
||||||
|
|
||||||
|
elif msgtype == 17:
|
||||||
icao = data["aa"]
|
icao = data["aa"]
|
||||||
newrow["icao"] = icao
|
newrow["icao"] = icao
|
||||||
subtype = data["ftc"]
|
subtype = data["ftc"]
|
||||||
@ -384,11 +406,17 @@ class dashboard_output(air_modes.modes_parse.modes_parse):
|
|||||||
newrow["latitude"] = decoded_lat
|
newrow["latitude"] = decoded_lat
|
||||||
newrow["longitude"] = decoded_lon
|
newrow["longitude"] = decoded_lon
|
||||||
newrow["altitude"] = 0
|
newrow["altitude"] = 0
|
||||||
|
if rnge is not None:
|
||||||
|
newrow["range"] = rnge
|
||||||
|
newrow["bearing"] = bearing
|
||||||
elif 9 <= subtype <= 18:
|
elif 9 <= subtype <= 18:
|
||||||
(altitude, decoded_lat, decoded_lon, rnge, bearing) = self.parseBDS05(data)
|
(altitude, decoded_lat, decoded_lon, rnge, bearing) = self.parseBDS05(data)
|
||||||
newrow["altitude"] = altitude
|
newrow["altitude"] = altitude
|
||||||
newrow["latitude"] = decoded_lat
|
newrow["latitude"] = decoded_lat
|
||||||
newrow["longitude"] = decoded_lon
|
newrow["longitude"] = decoded_lon
|
||||||
|
if rnge is not None:
|
||||||
|
newrow["range"] = rnge
|
||||||
|
newrow["bearing"] = bearing
|
||||||
elif subtype == 19:
|
elif subtype == 19:
|
||||||
subsubtype = data["sub"]
|
subsubtype = data["sub"]
|
||||||
velocity = None
|
velocity = None
|
||||||
|
@ -81,8 +81,8 @@ class data_field:
|
|||||||
>> (self.get_numbits() - startbit - num + self.offset)) \
|
>> (self.get_numbits() - startbit - num + self.offset)) \
|
||||||
& ((1 << num) - 1)
|
& ((1 << num) - 1)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
#pass
|
pass
|
||||||
print "Got short packet but expected long retrieving bits (%i, %i) with type %i" % (startbit, num, self.get_type())
|
#print "Got short packet but expected long retrieving bits (%i, %i) with type %i" % (startbit, num, self.get_type())
|
||||||
return bits
|
return bits
|
||||||
|
|
||||||
class bds09_reply(data_field):
|
class bds09_reply(data_field):
|
||||||
|
Loading…
Reference in New Issue
Block a user