Reorganize CPR decoder as a class to keep it simple
This commit is contained in:
parent
105950c176
commit
a43d8ee3a7
118
python/cpr.py
118
python/cpr.py
@ -154,59 +154,6 @@ def cpr_resolve_global(evenpos, oddpos, mostrecent, surface): #ok this is consid
|
||||
|
||||
return [rlat, rlon]
|
||||
|
||||
def weed_poslist(poslist):
|
||||
for key, item in poslist.items():
|
||||
if time.time() - item[2] > 900:
|
||||
del poslist[key]
|
||||
|
||||
def cpr_decode(my_location, icao24, encoded_lat, encoded_lon, cpr_format, evenlist, oddlist, lkplist, surface, longdata):
|
||||
#add the info to the position reports list for global decoding
|
||||
if cpr_format==1:
|
||||
oddlist[icao24] = [encoded_lat, encoded_lon, time.time()]
|
||||
else:
|
||||
evenlist[icao24] = [encoded_lat, encoded_lon, time.time()]
|
||||
|
||||
[decoded_lat, decoded_lon] = [None, None]
|
||||
|
||||
#okay, let's traverse the lists and weed out those entries that are older than 15 minutes, as they're unlikely to be useful.
|
||||
weed_poslist(lkplist)
|
||||
weed_poslist(evenlist)
|
||||
weed_poslist(oddlist)
|
||||
|
||||
if surface==1:
|
||||
validrange = 45
|
||||
else:
|
||||
validrange = 180
|
||||
|
||||
if icao24 in lkplist:
|
||||
#do emitter-centered local decoding
|
||||
[decoded_lat, decoded_lon] = cpr_resolve_local(lkplist[icao24][0:2], [encoded_lat, encoded_lon], cpr_format, surface)
|
||||
lkplist[icao24] = [decoded_lat, decoded_lon, time.time()] #update the local position for next time
|
||||
|
||||
elif ((icao24 in evenlist) and (icao24 in oddlist) and abs(evenlist[icao24][2] - oddlist[icao24][2]) < 10):
|
||||
# print "debug: valid even/odd positions, performing global decode."
|
||||
newer = (oddlist[icao24][2] - evenlist[icao24][2]) > 0 #figure out which report is newer
|
||||
[decoded_lat, decoded_lon] = cpr_resolve_global(evenlist[icao24][0:2], oddlist[icao24][0:2], newer, surface) #do a global decode
|
||||
if decoded_lat is not None:
|
||||
lkplist[icao24] = [decoded_lat, decoded_lon, time.time()]
|
||||
|
||||
elif my_location is not None: #if we have a location, use it
|
||||
[local_lat, local_lon] = cpr_resolve_local(my_location, [encoded_lat, encoded_lon], cpr_format, surface) #try local decoding
|
||||
[rnge, bearing] = range_bearing(my_location, [local_lat, local_lon])
|
||||
if rnge < validrange: #if the local decoding can be guaranteed valid
|
||||
lkplist[icao24] = [local_lat, local_lon, time.time()] #update the local position for next time
|
||||
[decoded_lat, decoded_lon] = [local_lat, local_lon]
|
||||
|
||||
|
||||
#print "settled on position: %.6f, %.6f" % (decoded_lat, decoded_lon,)
|
||||
if decoded_lat is not None:
|
||||
[rnge, bearing] = range_bearing(my_location, [decoded_lat, decoded_lon])
|
||||
else:
|
||||
rnge = None
|
||||
bearing = None
|
||||
|
||||
return [decoded_lat, decoded_lon, rnge, bearing]
|
||||
|
||||
|
||||
#calculate range and bearing between two lat/lon points
|
||||
#should probably throw this in the mlat py somewhere or make another lib
|
||||
@ -237,3 +184,68 @@ def range_bearing(loc_a, loc_b):
|
||||
|
||||
|
||||
return [rnge, bearing]
|
||||
|
||||
|
||||
class cpr_decoder:
|
||||
def __init__(self, my_location):
|
||||
self.my_location = my_location
|
||||
self.lkplist = []
|
||||
self.evenlist = []
|
||||
self.oddlist = []
|
||||
|
||||
def set_location(new_location):
|
||||
self.my_location = new_location
|
||||
|
||||
def weed_poslists(self):
|
||||
for poslist in [self.lkplist, self.evenlist, self.oddlist]:
|
||||
for key, item in poslist.items():
|
||||
if time.time() - item[2] > 900:
|
||||
del poslist[key]
|
||||
|
||||
def decode(icao24, encoded_lat, encoded_lon, cpr_format, surface):
|
||||
#def cpr_decode(my_location, icao24, encoded_lat, encoded_lon, cpr_format, evenlist, oddlist, lkplist, surface):
|
||||
#add the info to the position reports list for global decoding
|
||||
if cpr_format==1:
|
||||
oddlist[icao24] = [encoded_lat, encoded_lon, time.time()]
|
||||
else:
|
||||
evenlist[icao24] = [encoded_lat, encoded_lon, time.time()]
|
||||
|
||||
[decoded_lat, decoded_lon] = [None, None]
|
||||
|
||||
#okay, let's traverse the lists and weed out those entries that are older than 15 minutes, as they're unlikely to be useful.
|
||||
self.weed_poslists()
|
||||
|
||||
if surface==1:
|
||||
validrange = 45
|
||||
else:
|
||||
validrange = 180
|
||||
|
||||
if icao24 in self.lkplist:
|
||||
#do emitter-centered local decoding
|
||||
[decoded_lat, decoded_lon] = cpr_resolve_local(self.lkplist[icao24][0:2], [encoded_lat, encoded_lon], cpr_format, surface)
|
||||
self.lkplist[icao24] = [decoded_lat, decoded_lon, time.time()] #update the local position for next time
|
||||
|
||||
elif ((icao24 in self.evenlist) and (icao24 in self.oddlist) and abs(self.evenlist[icao24][2] - self.oddlist[icao24][2]) < 10):
|
||||
# print "debug: valid even/odd positions, performing global decode."
|
||||
newer = (self.oddlist[icao24][2] - self.evenlist[icao24][2]) > 0 #figure out which report is newer
|
||||
[decoded_lat, decoded_lon] = cpr_resolve_global(self.evenlist[icao24][0:2], self.oddlist[icao24][0:2], newer, surface) #do a global decode
|
||||
if decoded_lat is not None:
|
||||
self.lkplist[icao24] = [decoded_lat, decoded_lon, time.time()]
|
||||
|
||||
elif self.my_location is not None: #if we have a location, use it
|
||||
[local_lat, local_lon] = cpr_resolve_local(self.my_location, [encoded_lat, encoded_lon], cpr_format, surface) #try local decoding
|
||||
[rnge, bearing] = range_bearing(self.my_location, [local_lat, local_lon])
|
||||
if rnge < validrange: #if the local decoding can be guaranteed valid
|
||||
self.lkplist[icao24] = [local_lat, local_lon, time.time()] #update the local position for next time
|
||||
[decoded_lat, decoded_lon] = [local_lat, local_lon]
|
||||
|
||||
|
||||
#print "settled on position: %.6f, %.6f" % (decoded_lat, decoded_lon,)
|
||||
if decoded_lat is not None:
|
||||
[rnge, bearing] = range_bearing(self.my_location, [decoded_lat, decoded_lon])
|
||||
else:
|
||||
rnge = None
|
||||
bearing = None
|
||||
|
||||
return [decoded_lat, decoded_lon, rnge, bearing]
|
||||
|
||||
|
@ -29,6 +29,7 @@ import math
|
||||
class modes_parse:
|
||||
def __init__(self, mypos):
|
||||
self.my_location = mypos
|
||||
self.cpr_decoder = cpr_decoder(self.my_location)
|
||||
|
||||
def parse0(self, shortdata, parity, ecc):
|
||||
# shortdata = long(shortdata, 16)
|
||||
@ -148,16 +149,6 @@ class modes_parse:
|
||||
|
||||
return retval
|
||||
|
||||
#lkplist is the last known position, for emitter-centered decoding. evenlist and oddlist are the last
|
||||
#received encoded position data for each reporting type. all dictionaries indexed by ICAO number.
|
||||
_lkplist = {}
|
||||
_evenlist = {}
|
||||
_oddlist = {}
|
||||
_evenlist_ground = {}
|
||||
_oddlist_ground = {}
|
||||
|
||||
#the above dictionaries are all in the format [lat, lon, time].
|
||||
|
||||
def parseBDS05(self, shortdata, longdata, parity, ecc):
|
||||
icao24 = shortdata & 0xFFFFFF
|
||||
|
||||
@ -169,7 +160,7 @@ class modes_parse:
|
||||
|
||||
altitude = decode_alt(enc_alt, False)
|
||||
|
||||
[decoded_lat, decoded_lon, rnge, bearing] = cpr_decode(self.my_location, icao24, encoded_lat, encoded_lon, cpr_format, self._evenlist, self._oddlist, self._lkplist, 0, longdata)
|
||||
[decoded_lat, decoded_lon, rnge, bearing] = cpr_decoder.decode(icao24, encoded_lat, encoded_lon, cpr_format, 0)
|
||||
|
||||
return [altitude, decoded_lat, decoded_lon, rnge, bearing]
|
||||
|
||||
@ -186,7 +177,7 @@ class modes_parse:
|
||||
|
||||
altitude = 0
|
||||
|
||||
[decoded_lat, decoded_lon, rnge, bearing] = cpr_decode(self.my_location, icao24, encoded_lat, encoded_lon, cpr_format, self._evenlist_ground, self._oddlist_ground, self._lkplist, 1, longdata)
|
||||
[decoded_lat, decoded_lon, rnge, bearing] = cpr_decoder.decode(icao24, encoded_lat, encoded_lon, cpr_format, 1)
|
||||
|
||||
return [altitude, decoded_lat, decoded_lon, rnge, bearing]
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user