Return data works. Just need a reasonable way to get mlat data into the output plugins.

This commit is contained in:
Nick Foster 2012-12-19 18:47:47 -08:00
parent fd12402462
commit 7f6a3c7779
4 changed files with 40 additions and 51 deletions

View File

@ -43,22 +43,6 @@ import bisect
pickle_prot = 0 pickle_prot = 0
#pickle_prot = pickle.HIGHEST_PROTOCOL #pickle_prot = pickle.HIGHEST_PROTOCOL
class rx_data:
secs = 0
frac_secs = 0.0
data = None
class mlat_data:
data = None
secs = 0
frac_secs = 0.0
numstations = 0
lat = 0
lon = 0
alt = 0
hdop = 0.0
vdop = 0.0
class stamp: class stamp:
def __init__(self, clientinfo, secs, frac_secs): def __init__(self, clientinfo, secs, frac_secs):
self.clientinfo = clientinfo self.clientinfo = clientinfo
@ -116,14 +100,15 @@ class mlat_server:
self._s.close() self._s.close()
def get_messages(self): def get_messages(self):
num=0
for conn in self._conns: for conn in self._conns:
pkt = None pkt = None
try: try:
pkt = conn.sock.recv(4096) pkt = conn.sock.recv(16384)
except socket.error: except socket.error:
print "%s disconnected" % conn.clientinfo.name
self._conns.remove(conn) self._conns.remove(conn)
if not pkt: break if not pkt: break
#print "Received message from %s with length %i" % (conn.clientinfo.name, len(pkt))
try: try:
for msg in pkt.splitlines(True): for msg in pkt.splitlines(True):
if msg.endswith("\n"): if msg.endswith("\n"):
@ -139,6 +124,7 @@ class mlat_server:
ordered_insert(self._reports[data], st) ordered_insert(self._reports[data], st)
if st.tofloat() > self._lastreport: if st.tofloat() > self._lastreport:
self._lastreport = st.tofloat() self._lastreport = st.tofloat()
num += 1
else: else:
if self._remnant is not None: if self._remnant is not None:
raise Exception("Malformed data: " + msg) raise Exception("Malformed data: " + msg)
@ -150,6 +136,7 @@ class mlat_server:
print e print e
#self.prune() #self.prune()
return num
#prune should delete all reports in self._reports older than 5s. #prune should delete all reports in self._reports older than 5s.
#not really tested well #not really tested well
@ -205,15 +192,13 @@ class mlat_server:
return None return None
#issue multilaterated positions #issue multilaterated positions
def output(self, txlist): def output(self, msg):
#TODO: buffer this like the client does
msg = pickle.dumps(txlist, pickle_prot)
if msg is not None: if msg is not None:
try: try:
for conn in self._conns[:]: #iterate over a copy of the list for conn in self._conns[:]: #iterate over a copy of the list
conn.sock.send(msg) conn.sock.send(msg)
except socket.error: except socket.error:
print "Client %s disconnected" % conn.clientinfo.name print "%s disconnected" % conn.clientinfo.name
self._conns.remove(conn) self._conns.remove(conn)
print "Connections: ", len(self._conns) print "Connections: ", len(self._conns)
@ -235,7 +220,6 @@ class mlat_server:
print "Invalid datatype received from client" print "Invalid datatype received from client"
return return
conn.send("OK")
self._conns.append(connection(addr[0], conn, clientinfo)) self._conns.append(connection(addr[0], conn, clientinfo))
print "New connection from %s: %s" % (addr[0], clientinfo.name) print "New connection from %s: %s" % (addr[0], clientinfo.name)
except socket.error: except socket.error:
@ -251,16 +235,18 @@ def get_modes_altitude(data):
elif df == 17: elif df == 17:
bds = data["me"].get_type() bds = data["me"].get_type()
if bds == 0x05: if bds == 0x05:
#return f2m*air_modes.altitude.decode_alt(data["me"]["alt"], False) return f2m*air_modes.altitude.decode_alt(data["me"]["alt"], False)
return 8000
else: else:
return None return None
position = [37.76, -117.443, 100]
if __name__=="__main__": if __name__=="__main__":
srv = mlat_server("nothin'", 19005) srv = mlat_server(position, 19005)
while 1: while 1:
#srv.output("Buttes") nummsgs = srv.get_messages()
srv.get_messages() if len(srv._conns) > 0:
print "Received %i messages" % nummsgs
srv.add_pending_conns() srv.add_pending_conns()
reps = srv.get_eligible_reports() reps = srv.get_eligible_reports()
if reps: if reps:
@ -274,7 +260,6 @@ if __name__=="__main__":
#it's expecting a list of tuples [(station[], timestamp)...] #it's expecting a list of tuples [(station[], timestamp)...]
#also have to parse the data to pull altitude out of the mix #also have to parse the data to pull altitude out of the mix
if reps: if reps:
txlist = []
for rep in reps: for rep in reps:
alt = get_modes_altitude(air_modes.modes_reply(rep["data"])) alt = get_modes_altitude(air_modes.modes_reply(rep["data"]))
if (alt is None and len(rep["stamps"]) > 3) or alt is not None: if (alt is None and len(rep["stamps"]) > 3) or alt is not None:
@ -285,22 +270,19 @@ if __name__=="__main__":
pos, senttime = air_modes.mlat.mlat(mlat_list, alt) pos, senttime = air_modes.mlat.mlat(mlat_list, alt)
if pos is not None: if pos is not None:
print "Resolved position: ", pos print "Resolved position: ", pos
#add to message stack #send a report!
msg = mlat_data() msg = "%x %i %i %f %f %f %f %f %f\n" % \
msg.data = rep["data"] (rep["data"], len(mlat_list), int(senttime), \
#TODO: fix loss of precision in mlat() timestamp output float(senttime) - int(senttime), \
msg.secs = int(senttime) pos[0], pos[1], pos[2], 0.0, 0.0)
msg.frac_secs = float(senttime) - msg.secs srv.output(msg)
msg.numstations = len(mlat_list)
msg.lat = pos[0]
msg.lon = pos[1]
msg.alt = pos[2]
msg.hdop = 0.0
msg.vdop = 0.0
txlist.append(msg)
except Exception as e: except air_modes.exceptions.MlatNonConvergeError as e:
print e print e
srv.output(txlist)
#DEBUG
# else:
# msg = "0921354 4 2 0.12345 36.671234 -112.342515 9028.1243 0.0 0.0\n"
# srv.output(msg)
time.sleep(0.3) time.sleep(0.3)

View File

@ -30,6 +30,7 @@ import air_modes
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 *
import pickle
class top_block_runner(_threading.Thread): class top_block_runner(_threading.Thread):
def __init__(self, tb): def __init__(self, tb):
@ -132,9 +133,7 @@ def printraw(msg):
print msg print msg
def printmlat(msg): def printmlat(msg):
msglist = pickle.loads(msg) print "Mlat report: %s" % msg
for msg in msglist:
print "mlat message: %x at [%f, %f]" % (msg.data, msg.lat, msg.lon)
if __name__ == '__main__': if __name__ == '__main__':
usage = "%prog: [options] output filename" usage = "%prog: [options] output filename"
@ -241,14 +240,23 @@ 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
for out in outputs: for out in outputs:
try: try:
out(msg.to_string()) out(msg.to_string())
except air_modes.ADSBError: except air_modes.ADSBError:
pass pass
elif runner.done: if mlat_queue:
if not mlat_queue.empty_p():
while not mlat_queue.empty_p():
msg = mlat_queue.delete_head()
for out in mlat_outputs:
try:
out(msg.to_string())
except air_modes.ADSBError:
pass
if runner.done:
raise KeyboardInterrupt raise KeyboardInterrupt
else: else:
time.sleep(0.1) time.sleep(0.1)

View File

@ -44,4 +44,3 @@ class CPRBoundaryStraddleError(CPRNoPositionError):
class FieldNotInPacket(ParserError): class FieldNotInPacket(ParserError):
def __init__(self, item): def __init__(self, item):
self.item = item self.item = item

View File

@ -113,7 +113,7 @@ def mlat_iter(stations, prange_obs, guess = [0,0,0], limit = 20, maxrounds = 100
guess += xerr[:3] #we ignore the time error for xguess guess += xerr[:3] #we ignore the time error for xguess
rounds += 1 rounds += 1
if rounds > maxrounds: if rounds > maxrounds:
raise Exception("Failed to converge!") raise MlatNonConvergeError("Failed to converge!")
return (guess, xerr[3]) return (guess, xerr[3])
#func mlat: #func mlat: