From 0c197e962aecd9866fa34f02e47be4cd43ef249d Mon Sep 17 00:00:00 2001 From: Gergely Imreh Date: Fri, 26 Sep 2008 16:41:52 +0100 Subject: [PATCH] Change: separating core functions from server Concentrating all core functions in gsmpos.py, while keeping gsmpos_server.py to the bare minimum it needs. This gets rid of previous code duplication. So now: gsmpos - gsm (and optional gps) positioning gsmpos_server - asking for gsm position and send it out on a socket in NMEA format --- gsmpos/gsmpos.py | 145 +++++++++++++++++++++++++------------------- gsmpos/gsmpos_sever.py | 159 ++++--------------------------------------------- 2 files changed, 98 insertions(+), 206 deletions(-) diff --git a/gsmpos/gsmpos.py b/gsmpos/gsmpos.py index 4896760..27d5dd5 100755 --- a/gsmpos/gsmpos.py +++ b/gsmpos/gsmpos.py @@ -26,7 +26,7 @@ from cell_locator_bare import Terminal from cell_locator_bare import GPS -__version__ = '0.1' +__version__ = '0.2' ############### @@ -112,16 +112,70 @@ class GSMpos(): self.numtower = 0 self.tottower = 0 +def getgsmpos(gsmpos,gsmterm,cells): + """ Positioning loop, based on cell_locator.py """ + neigh = gsmterm.get_neighbour_cell_info() + loc = gsmterm.get_location_and_paging_info() + cell = gsmterm.get_service_cell_info() + + mcc = loc['mcc'] + mnc = loc['mnc'] + cellpresent = [] + if cell['cell_id'] > 0: + d = {} + d['cell_id'] = cell['cell_id'] + d['rxlev'] = cell['rxlev'] + cellpresent.append(d) + + for k in range(len(neigh)): + if neigh[k]['cell_id'] != 0: + d = {} + d['cell_id'] = neigh[k]['cell_id'] + d['rxlev'] = neigh[k]['rxlev'] + cellpresent.append(d) + gsmpos.lat,gsmpos.lon,gsmpos.numtower,gsmpos.tottower = getpos(cells,cellpresent,mcc,mnc) + + +def looping(gsmterm,gsm,cells,gps=None): + """ Displaying results """ + try: + getgsmpos(gsm,gsmterm,cells) + if (gsm.lat != None) and (gsm.lon != None): + print "GSM: Pos:",round(gsm.lat,posdigits),",",round(gsm.lon,posdigits),"T:",gsm.numtower,"/",gsm.tottower + else: print "GSM: No fix" + if gps != None: + if (gps.lat != None) and (gps.lon != None): + print "GPS: Pos:",round(gps.lat,posdigits),",",round(gps.lon,posdigits),"HDOP:",gps.hdop + else: print "GPS: No fix" + if (gps.lat != None) and (gps.lon != None) and (gsm.lat != None) and (gsm.lon != None): + dist,ns,ew = calcdist(gps.lon,gps.lat,gsm.lon,gsm.lat) + print "GSM-GPS Diff: ",round(dist),"m" + print "N/S : ",round(ns),"m | E/W: ",round(ew),"m" + gps.clear() + print '' + sys.stdout.flush() + return True + except (KeyboardInterrupt, SystemExit): + print "Keyboard Quit - please press Ctrl-C once more" + return False + except: + etype = sys.exc_info()[0] + evalue = sys.exc_info()[1] + etb = traceback.extract_tb(sys.exc_info()[2]) + print "Exception in main loop: ", str(etype), " : ", str(evalue) , ' : ', str(etb) + print "Looping stopped - press Ctrl-c to quit" + self_exit = 1 + return False -if __name__ == "__main__": + - ####### - # Load cell information - ####### - f = open('cellinfo.dat','r') +def loadcellinfo(celldatafile): + """ Load cell information """ cells = [] - for line in f: + try: + f = open(celldatafile,'r') + for line in f: params = ('mcc','mnc','cell_id','lat','lon') data = line.split(',') @@ -132,14 +186,25 @@ if __name__ == "__main__": d[params[3]] = float(data[3]) d[params[4]] = float(data[4]) cells.append(d) - ######## + except: + etype = sys.exc_info()[0] + evalue = sys.exc_info()[1] + etb = traceback.extract_tb(sys.exc_info()[2]) + print "Error while loading GSM tower database: ", str(etype), " : ", str(evalue) , ' : ', str(etb) + finally: + return cells + +if __name__ == "__main__": + + cells = loadcellinfo('cellinfo.dat') from dbus.mainloop.glib import DBusGMainLoop DBusGMainLoop(set_as_default=True) import gobject loop = gobject.MainLoop() + context = loop.get_context() # Start GPS gps = GPS() @@ -151,59 +216,19 @@ if __name__ == "__main__": # Init GSM position storage gsm = GSMpos() - - def posloop(pos): - """ Positioning loop, based on cell_locator.py """ - neigh = t.get_neighbour_cell_info() - loc = t.get_location_and_paging_info() - cell = t.get_service_cell_info() - - mcc = loc['mcc'] - mnc = loc['mnc'] - cellpresent = [] - if cell['cell_id'] > 0: - d = {} - d['cell_id'] = cell['cell_id'] - d['rxlev'] = cell['rxlev'] - cellpresent.append(d) - - for k in range(len(neigh)): - if neigh[k]['cell_id'] != 0: - d = {} - d['cell_id'] = neigh[k]['cell_id'] - d['rxlev'] = neigh[k]['rxlev'] - cellpresent.append(d) - pos.lat,pos.lon,pos.numtower,pos.tottower = getpos(cells,cellpresent,mcc,mnc) - - - - def looping(): - """ Displaying results """ - posloop(gsm) - if (gps.lat != None) and (gps.lon != None): - print "GPS: Pos:",round(gps.lat,posdigits),",",round(gps.lon,posdigits),"HDOP:",gps.hdop - else: print "GPS: No fix" - if (gsm.lat != None) and (gsm.lon != None): - print "GSM: Pos:",round(gsm.lat,posdigits),",",round(gsm.lon,posdigits),"T:",gsm.numtower,"/",gsm.tottower - else: print "GSM: No fix" - if (gps.lat != None) and (gps.lon != None) and (gsm.lat != None) and (gsm.lon != None): - dist,ns,ew = calcdist(gps.lon,gps.lat,gsm.lon,gsm.lat) - print "GSM-GPS Diff: ",round(dist),"m" - print "N/S : ",round(ns),"m | E/W: ",round(ew),"m" - gps.clear() - print '' - sys.stdout.flush() - return True - # Do positioning ever 3s - gobject.timeout_add(3000, looping) - loop.run() - - + self_exit = 0 + gobject.timeout_add(3000, looping, t, gsm, cells, gps, loop) + try: + loop.run() + except KeyboardInterrupt: + print "Keyboard Quit" + pass + except: + pass + # Closing down + print "Closing GSM" t.close() + print "Closing GPS - wait for it!!" gps.uninit() - - - - diff --git a/gsmpos/gsmpos_sever.py b/gsmpos/gsmpos_sever.py index b87902a..8344362 100755 --- a/gsmpos/gsmpos_sever.py +++ b/gsmpos/gsmpos_sever.py @@ -24,9 +24,9 @@ from math import * ### GPS import functions from stripped down version of cell_locator.py from cell_locator_bare import Terminal from cell_locator_bare import GPS +from gsmpos import * - -__version__ = '0.1' +__version__ = '0.2' ############### @@ -34,84 +34,9 @@ __version__ = '0.1' # Debugging output debug = False -# Number of digits after decimal point when printing location -posdigits = 6 - ################ -def getpos(cells,cellpresent,mcc,mnc): - """ Calculating position based on GSM cell data """ - """ - Signal converted to relative distances with assumptions: - - Equal tower power output - - Free space propagation: signal strength scales with d^(-1/2) - : These are of course not true - but there is a priori knowledge of proper signal strengh/distance scaling - """ - - lon = 0 - lat = 0 - sumweight = 0 - have = 0 - - for k in range(len(cellpresent)): - # Signal strength in dB -> linear scale - sig = 10**(int(cellpresent[k]['rxlev'])/10.0) - # Linear scale -> distance scale (1/2 means assuming free space propagation) - dist = sig**(1/2.) - if debug: print "DEBUG:",cellpresent[k]['cell_id'],":signal:",cellpresent[k]['rxlev'],"Sig-linear:",sig,"Distance scale:",dist - for i in range(len(cells)): - if (mcc == cells[i]['mcc']) and (mnc == cells[i]['mnc']) and (cellpresent[k]['cell_id'] == cells[i]['cell_id']): - sumweight += dist - lon += dist*cells[i]['lon'] - lat += dist*cells[i]['lat'] - if debug: print "DEBUG:",cellpresent[k]['cell_id'],":CellFound: ",cells[i]['lat'], cells[i]['lon'] - have += 1 - break - if debug: print "DEBUG:","Cells-found:",have,"Sum-weight:",sumweight - if (sumweight > 0): - lon = lon/sumweight - lat = lat/sumweight - else: - lon = None - lat = None - if debug: print "DEBUG:","getpos:return:",lat,lon,have,len(cellpresent) - return lat,lon,have,len(cellpresent) - - - -def calcdist(lon1,lat1,lon2,lat2): - """ Calculate (approximate) distance of two coordinates on Earth """ - """ - Returns distance, and North/South difference, Average East/West difference - --- if lat2 / lon2 are more North / East : positive, if more South / East : negative - """ - # Earth mean radius (m) - r = 6372795 - # From Wikipedia :) - # Distance on sphere - dist = r*acos( cos(lat1/180*pi)*cos(lat2/180*pi)*cos(lon1/180*pi - lon2/180*pi) + sin(lat1/180*pi)*sin(lat2/180*pi)) - # North/South difference - ns = r*acos( cos(lat1/180*pi)*cos(lat2/180*pi) + sin(lat1/180*pi)*sin(lat2/180*pi)) - if (lat1 > lat2): - ns = -1*ns - # Usually don't need to, only at big distances: East/West difference, at both lattitudes, take the average - ew1 = r*acos( cos(lat1/180*pi)*cos(lat1/180*pi)*cos(lon1/180*pi - lon2/180*pi) + sin(lat1/180*pi)*sin(lat1/180*pi)) - ew2 = r*acos( cos(lat2/180*pi)*cos(lat2/180*pi)*cos(lon1/180*pi - lon2/180*pi) + sin(lat2/180*pi)*sin(lat2/180*pi)) - avew = (ew1+ew2)/2.0 - if (lon1 > lon2): - avew = -1*avew - return dist,ns,avew - - -class GSMpos(): - """ Class to store GSM positioning information """ - def __init__( self): - self.lat = None - self.lon = None - self.numtower = 0 - self.tottower = 0 - def nmealocform(pos,padd=2): """ Convert location into NMEA format """ if pos == '': @@ -122,7 +47,7 @@ def nmealocform(pos,padd=2): nmeapos = str(a).zfill(padd)+'%02.5f'%b return nmeapos -def nmeasentence(lon,lat,numfixtower=0,numtottower=0,hdop=99): +def nmeasentence(gsmpos,hdop=99): """ Prepare minimal information needed for tangoGPS location display """ """ Shows: location, date, time, number of seen/known towers (at seen/fixed satellite fields """ """ for info on sentences: http://gpsd.berlios.de/NMEA.txt and check gpsd output """ @@ -130,6 +55,11 @@ def nmeasentence(lon,lat,numfixtower=0,numtottower=0,hdop=99): nmeatime = strftime("%H%M%S.00") nmeadate = strftime("%d%m%y") + lon = gsm.lon + lat = gsm.lat + numfixtower = gsm.numtower + numtottower = gsm.tottower + if (lon == None) or (lat == None): ## When no GSM position: send 'Navigation device warning' and 'no fix' sentences sentence = "$GPRMC,"+nmeatime+",V,,,,,0.0,0.0,"+nmeadate+",,\n" @@ -159,24 +89,7 @@ def nmeasentence(lon,lat,numfixtower=0,numtottower=0,hdop=99): if __name__ == "__main__": - ####### - # Load cell information - ####### - f = open('cellinfo.dat','r') - cells = [] - for line in f: - params = ('mcc','mnc','cell_id','lat','lon') - data = line.split(',') - - d = {} - d[params[0]] = int(data[0]) - d[params[1]] = int(data[1]) - d[params[2]] = int(data[2]) - d[params[3]] = float(data[3]) - d[params[4]] = float(data[4]) - cells.append(d) - ######## - + cells = loadcellinfo('cellinfo.dat') from dbus.mainloop.glib import DBusGMainLoop DBusGMainLoop(set_as_default=True) @@ -195,55 +108,6 @@ if __name__ == "__main__": gsm = GSMpos() - def posloop(pos): - """ Positioning loop, based on cell_locator.py """ - neigh = t.get_neighbour_cell_info() - loc = t.get_location_and_paging_info() - cell = t.get_service_cell_info() - - mcc = loc['mcc'] - mnc = loc['mnc'] - cellpresent = [] - if cell['cell_id'] > 0: - d = {} - d['cell_id'] = cell['cell_id'] - d['rxlev'] = cell['rxlev'] - cellpresent.append(d) - - for k in range(len(neigh)): - if neigh[k]['cell_id'] != 0: - d = {} - d['cell_id'] = neigh[k]['cell_id'] - d['rxlev'] = neigh[k]['rxlev'] - cellpresent.append(d) - pos.lat,pos.lon,pos.numtower,pos.tottower = getpos(cells,cellpresent,mcc,mnc) - - - - def looping(): - """ Displaying results """ - posloop(gsm) - if (gps.lat != None) and (gps.lon != None): - print "GPS: Pos:",round(gps.lat,posdigits),",",round(gps.lon,posdigits),"HDOP:",gps.hdop - else: print "GPS: No fix" - if (gsm.lat != None) and (gsm.lon != None): - print "GSM: Pos:",round(gsm.lat,posdigits),",",round(gsm.lon,posdigits),"T:",gsm.numtower,"/",gsm.tottower - else: print "GSM: No fix" - if (gps.lat != None) and (gps.lon != None) and (gsm.lat != None) and (gsm.lon != None): - dist,ns,ew = calcdist(gps.lon,gps.lat,gsm.lon,gsm.lat) - print "GSM-GPS Diff: ",round(dist),"m" - print "N/S : ",round(ns),"m | E/W: ",round(ew),"m" - gps.clear() - print '' - nmea = nmeasentence(gsm.lon,gsm.lat,gsm.numtower,gsm.tottower) - print nmea - return nmea - sys.stdout.flush() - - - return True - - ################## # Quick and dirty server section ################# @@ -296,7 +160,10 @@ if __name__ == "__main__": if data: while 1: try: - conn.send(looping()) + looping(t,gsm,cells) + nmeaout = nmeasentence(gsm) + print nmeaout + conn.send(nmeaout) time.sleep(2.0) except (KeyboardInterrupt, SystemExit): conn.close() -- 2.11.4.GIT