Return data works. Just need a reasonable way to get mlat data into the output plugins.
This commit is contained in:
parent
fd12402462
commit
7f6a3c7779
@ -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)
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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:
|
||||||
|
Loading…
Reference in New Issue
Block a user