Temp commit while adding a modes_report class using named tuples. Mlat server definitely broken as a result.

This commit is contained in:
Nick Foster 2013-01-09 23:26:49 -08:00
parent 7f6a3c7779
commit 1a0ebab29c
9 changed files with 102 additions and 79 deletions

View File

@ -43,29 +43,6 @@ import bisect
pickle_prot = 0 pickle_prot = 0
#pickle_prot = pickle.HIGHEST_PROTOCOL #pickle_prot = pickle.HIGHEST_PROTOCOL
class stamp:
def __init__(self, clientinfo, secs, frac_secs):
self.clientinfo = clientinfo
self.secs = secs
self.frac_secs = frac_secs
def __lt__(self, other):
if self.secs == other.secs:
return self.frac_secs < other.frac_secs
else:
return self.secs < other.secs
def __gt__(self, other):
if self.secs == other.secs:
return self.frac_secs > other.frac_secs
else:
return self.secs > other.secs
def __eq__(self, other):
return self.secs == other.secs and self.frac_secs == other.frac_secs
def __ne__(self, other):
return self.secs != other.secs or self.frac_secs != other.frac_secs
#good to within ms for comparison
def tofloat(self):
return self.secs + self.frac_secs
def ordered_insert(a, item): def ordered_insert(a, item):
a.insert(bisect.bisect_right(a, item), item) a.insert(bisect.bisect_right(a, item), item)

View File

@ -27,6 +27,8 @@ from optparse import OptionParser
import time, os, sys, threading import time, os, sys, threading
from string import split, join from string import split, join
import air_modes import air_modes
from air_modes.types import modes_report, stamp
from air_modes.parse import modes_reply
import gnuradio.gr.gr_threading as _threading import gnuradio.gr.gr_threading as _threading
import csv import csv
from air_modes.exceptions import * from air_modes.exceptions import *
@ -240,9 +242,12 @@ if __name__ == '__main__':
if not queue.empty_p() : if not queue.empty_p() :
while not queue.empty_p() : while not queue.empty_p() :
msg = queue.delete_head() #blocking read msg = queue.delete_head() #blocking read
[data, ecc, reference, timestamp_int, timestamp_frac] = msg.to_string().split()
#error handling? creating a modes_reply can throw NoHandlerError, but you really want that to be handled by the output plugin in question.
msg_tuple = modes_report(modes_reply(long(data, 16)), long(ecc, 16), float(reference), stamp(int(timestamp_int), float(timestamp_frac)))
for out in outputs: for out in outputs:
try: try:
out(msg.to_string()) out(msg_tuple)
except air_modes.ADSBError: except air_modes.ADSBError:
pass pass

View File

@ -46,6 +46,7 @@ GR_PYTHON_INSTALL(
rx_path.py rx_path.py
sbs1.py sbs1.py
sql.py sql.py
types.py
Quaternion.py Quaternion.py
DESTINATION ${GR_PYTHON_DIR}/air_modes DESTINATION ${GR_PYTHON_DIR}/air_modes
) )

View File

@ -61,6 +61,7 @@ from raw_server import raw_server
from mlat_client import mlat_client from mlat_client import mlat_client
from exceptions import * from exceptions import *
from az_map import * from az_map import *
from types 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

View File

@ -27,37 +27,34 @@ class output_flightgear(air_modes.parse):
self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.sock.connect((self.hostname, self.port)) self.sock.connect((self.hostname, self.port))
def output(self, message): def output(self, msg):
[data, ecc, reference, timestamp_int, timestamp_frac] = message.split()
timestamp = int(timestamp_int) + float(timestamp_frac)
data = air_modes.modes_reply(long(data, 16))
try: try:
msgtype = data["df"] msgtype = msg.data["df"]
if msgtype == 17: #ADS-B report if msgtype == 17: #ADS-B report
icao24 = data["aa"] icao24 = msg.data["aa"]
bdsreg = data["me"].get_type() bdsreg = msg.data["me"].get_type()
if bdsreg == 0x08: #ident packet if bdsreg == 0x08: #ident packet
(ident, actype) = self.parseBDS08(data) (ident, actype) = self.parseBDS08(msg.data)
#select model based on actype #select model based on actype
self.callsigns[icao24] = [ident, actype] self.callsigns[icao24] = [ident, actype]
elif bdsreg == 0x06: #BDS0,6 pos elif bdsreg == 0x06: #BDS0,6 pos
[ground_track, decoded_lat, decoded_lon, rnge, bearing] = self.parseBDS06(data) [ground_track, decoded_lat, decoded_lon, rnge, bearing] = self.parseBDS06(msg.data)
self.positions[icao24] = [decoded_lat, decoded_lon, 0] self.positions[icao24] = [decoded_lat, decoded_lon, 0]
self.update(icao24) self.update(icao24)
elif bdsreg == 0x05: #BDS0,5 pos elif bdsreg == 0x05: #BDS0,5 pos
[altitude, decoded_lat, decoded_lon, rnge, bearing] = self.parseBDS05(data) [altitude, decoded_lat, decoded_lon, rnge, bearing] = self.parseBDS05(msg.data)
self.positions[icao24] = [decoded_lat, decoded_lon, altitude] self.positions[icao24] = [decoded_lat, decoded_lon, altitude]
self.update(icao24) self.update(icao24)
elif bdsreg == 0x09: #velocity elif bdsreg == 0x09: #velocity
subtype = data["bds09"].get_type() subtype = data["bds09"].get_type()
if subtype == 0: if subtype == 0:
[velocity, heading, vert_spd, turnrate] = self.parseBDS09_0(data) [velocity, heading, vert_spd, turnrate] = self.parseBDS09_0(msg.data)
elif subtype == 1: elif subtype == 1:
[velocity, heading, vert_spd] = self.parseBDS09_1(data) [velocity, heading, vert_spd] = self.parseBDS09_1(msg.data)
turnrate = 0 turnrate = 0
else: else:
return return

View File

@ -29,39 +29,33 @@ class output_print(air_modes.parse):
def __init__(self, mypos): def __init__(self, mypos):
air_modes.parse.__init__(self, mypos) air_modes.parse.__init__(self, mypos)
def parse(self, message): def parse(self, msg):
[data, ecc, reference, timestamp_int, timestamp_frac] = message.split()
timestamp = int(timestamp_int) + float(timestamp_frac)
ecc = long(ecc, 16) if msg.reference == 0.0:
reference = float(reference)
if reference == 0.0:
refdb = -150.0 refdb = -150.0
else: else:
refdb = 20.0*math.log10(reference) refdb = 20.0*math.log10(msg.reference)
output = "(%.0f %.10f) " % (refdb, timestamp); output = "(%.0f %.10f) " % (refdb, float(msg.timestamp));
try: try:
data = air_modes.modes_reply(long(data, 16)) msgtype = msg.data["df"]
msgtype = data["df"]
if msgtype == 0: if msgtype == 0:
output += self.print0(data, ecc) output += self.print0(msg.data, msg.ecc)
elif msgtype == 4: elif msgtype == 4:
output += self.print4(data, ecc) output += self.print4(msg.data, msg.ecc)
elif msgtype == 5: elif msgtype == 5:
output += self.print5(data, ecc) output += self.print5(msg.data, msg.ecc)
elif msgtype == 11: elif msgtype == 11:
output += self.print11(data, ecc) output += self.print11(msg.data, msg.ecc)
elif msgtype == 17: elif msgtype == 17:
output += self.print17(data) output += self.print17(msg.data)
elif msgtype == 20 or msgtype == 21 or msgtype == 16: elif msgtype == 20 or msgtype == 21 or msgtype == 16:
output += self.printTCAS(data, ecc) output += self.printTCAS(msg.data, msg.ecc)
else: else:
output += "No handler for message type %i from %x (but it's in modes_parse)" % (msgtype, ecc) output += "No handler for message type %i from %x (but it's in modes_parse)" % (msgtype, msg.ecc)
return output return output
except NoHandlerError as e: except NoHandlerError as e:
output += "No handler for message type %s from %x" % (e.msgtype, ecc) output += "No handler for message type %s from %x" % (e.msgtype, msg.ecc)
return output return output
except MetricAltError: except MetricAltError:
pass pass

View File

@ -100,27 +100,21 @@ class output_sbs1(air_modes.parse):
else: else:
return ",,," return ",,,"
def parse(self, message): def parse(self, msg):
#assembles a SBS-1-style output string from the received message #assembles a SBS-1-style output string from the received message
msgtype = msg.data["df"]
[data, ecc, reference, timestamp_int, timestamp_frac] = message.split()
timestamp = int(timestamp_int) + float(timestamp_frac)
data = air_modes.modes_reply(long(data, 16))
ecc = long(ecc, 16)
msgtype = data["df"]
outmsg = None outmsg = None
if msgtype == 0: if msgtype == 0:
outmsg = self.pp0(data, ecc) outmsg = self.pp0(msg.data, msg.ecc)
elif msgtype == 4: elif msgtype == 4:
outmsg = self.pp4(data, ecc) outmsg = self.pp4(msg.data, msg.ecc)
elif msgtype == 5: elif msgtype == 5:
outmsg = self.pp5(data, ecc) outmsg = self.pp5(msg.data, msg.ecc)
elif msgtype == 11: elif msgtype == 11:
outmsg = self.pp11(data, ecc) outmsg = self.pp11(msg.data, msg.ecc)
elif msgtype == 17: elif msgtype == 17:
outmsg = self.pp17(data) outmsg = self.pp17(msg.data)
else: else:
raise NoHandlerError(msgtype) raise NoHandlerError(msgtype)
return outmsg return outmsg

View File

@ -86,21 +86,13 @@ class output_sql(air_modes.parse):
except ADSBError: except ADSBError:
pass pass
def make_insert_query(self, message): def make_insert_query(self, msg):
#assembles a SQL query tailored to our database #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 #this version ignores anything that isn't Type 17 for now, because we just don't care
[data, ecc, reference, timestamp_int, timestamp_frac] = message.split()
timestamp = int(timestamp_int) + float(timestamp_frac)
data = air_modes.modes_reply(long(data, 16))
ecc = long(ecc, 16)
# reference = float(reference)
query = None query = None
msgtype = data["df"] msgtype = msg.data["df"]
if msgtype == 17: if msgtype == 17:
query = self.sql17(data) query = self.sql17(msg.data)
return query return query

62
python/types.py Normal file
View File

@ -0,0 +1,62 @@
#
# Copyright 2013 Nick Foster
#
# This file is part of gr-air-modes
#
# gr-air-modes is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# gr-air-modes is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with gr-air-modes; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
#
from collections import namedtuple
#this is a timestamp that preserves precision when used with UTC timestamps
#ordinary double-precision timestamp would lose significant fractional precision
#when the mantissa is as large as necessary for UTC timestamps.
class stamp:
def __init__(self, secs, frac_secs):
self.secs = secs
self.frac_secs = frac_secs
def __lt__(self, other):
if self.secs == other.secs:
return self.frac_secs < other.frac_secs
else:
return self.secs < other.secs
def __gt__(self, other):
if self.secs == other.secs:
return self.frac_secs > other.frac_secs
else:
return self.secs > other.secs
def __eq__(self, other):
if isinstance(other, self.__class__):
return self.secs == other.secs and self.frac_secs == other.frac_secs
elif isinstance(other, float):
return float(self) == other
else:
raise TypeError
def __ne__(self, other):
return self.secs != other.secs or self.frac_secs != other.frac_secs
def __le__(self, other):
return (self == other) or (self < other)
def __ge__(self, other):
return (self == other) or (self > other)
#to ensure we don't hash by stamp
__hash__ = None
#good to within ms for comparison
def __float__(self):
return self.secs + self.frac_secs
modes_report = namedtuple('modes_report', ['data', 'ecc', 'reference', 'timestamp'])