sabato 28 gennaio 2012

Studio GPS per DGPS

Sto lavorando ad una idea su come poter utilizzare telefoni Android o GPS Bluetooth a basso costo per creare un sistema di GPS Differenziale (DGPS) per migliorare le prestazioni e ridurre l'errore di localizzazione.

Il primo passo che ho fatto e' stato quello di studiare un sensore GPS Bluetooth della BlueSoleil
Per stimare l'errore sono state fatte circa 700 misure mantenendo il sensore fermo e leggendo con uno script Python i codici NMEA che vengono generati sulla seriale

Lo script di acquisizione e' il seguente
Per la definizione dei codici NMEA e' stato utilizzato questo sito
Per il calcolo del checksum della stringa NMEA e' stato modificato il codice trovato qui
La parte principale del codice e' accreditata a http://www.robertprice.co.uk/robblog/archive/2007/1/Using_A_Bluetooth_GPS_From_Python.shtml
(il mio contributo e' modesto ma nessuno dei codici da solo era completo e corretto..diciamo che ho messo insieme i pezzi giusti)
-----------------------------------------------------------------------

import bluetooth
import re


def checksum(sentence):
    if re.search("\n$", sentence):
        sentence = sentence[:-1]


    nmeadata,cksum = re.split('\*', sentence)
    nmeadata = nmeadata[1:]
    calc_cksum = 0
    print "nmeadata "+nmeadata
    print "check :"+str(int(cksum,16))


    for s in nmeadata:
        calc_cksum ^= ord(s)
    print "check calc :"+str(calc_cksum)
    return nmeadata,int(cksum,16),calc_cksum






# bluetooth address of the GPS device.
addr = "00:0A:3A:1F:A4:2E"


# port to use.
port = 1


# create a socket and connect to it.
socket = bluetooth.BluetoothSocket(bluetooth.RFCOMM)
socket.connect((addr, port))
data = ""
olddata = ""


f = open('dati_gps.txt','w')


while True:
data = socket.recv(1024)
#print data
  # make sure we actually have some data.
if len(data) > 0:
  
    # append the old data to the front of data.
data = olddata + data


    # split the data into a list of lines, but make
    # sure we preserve the end of line information.
    lines = data.splitlines(1)


    # iterate over each line
    for line in lines:
    
      # if the line has a carriage return and a
      # linefeed, we know we have a complete line so
      # we can remove those characters and print it.
      if line.find("\r\n") != -1 :
        line = line.strip()
       
gpsstring = line.split(',')
if gpsstring[0] == '$GPRMC':
#print line
data,cksum,calc_cksum = checksum(line)
#print cksum
#print calc_cksum
if cksum == calc_cksum:
#print "GPRMC-------------"

print "Tempo: " + gpsstring[1]
#print "Stato: " + gpsstring[2]
print gpsstring[3][:2]
print gpsstring[3][2:]
print gpsstring[5][:3]
print gpsstring[5][3:]

  lat_d = float(gpsstring[3][:2])+(float(gpsstring[3][2:])/60)
lon_d = float(gpsstring[5][:3])+(float(gpsstring[5][3:])/60)
  print "Lat:  " + gpsstring[3]+gpsstring[4]
  print "Long: " + gpsstring[5]+gpsstring[6]
print str(lat_d)
print str(lon_d)
  #print "Nodi: " + gpsstring[7]
print "Data : "+ gpsstring[9]
#print "Checksum : "+ gpsstring[12]
#print "------------------\n"
f.write(gpsstring[1]+";"+str(lat_d)+";"+str(lon_d)+"\n")




#if gpsstring[0] == '$GPGGA' :
#print "GPGGA-------------"
#print  line
  #print "Tempo :  " + gpsstring[1]

  #print "Lat:  " + gpsstring[2]+gpsstring[3]
  #print "Long: " + gpsstring[4]+gpsstring[5]
#print "Fix: " + gpsstring[6]
#print "Satelliti in vista: " + gpsstring[7]
#print "HDOP: " + gpsstring[7]
#print "Altezza: " + gpsstring[8]
#print "------------------\n"




#if gpsstring[0] == '$GPGSA' :
#print "GPGSA-------------"
#print  line
  #print "PDOP: " + gpsstring[14]
  #print "HDOP: " + gpsstring[15]
  #print "VDOP: " + gpsstring[16]
#print "------------------\n"




        # empty the olddata variable now we have
        # used the data.
        olddata = ""
      # else we need to keep the line to add to data
      else :
        olddata = line
-----------------------------------------------------------------------
Il sensore GPS acquisisce una volta al secondo (sembra impossibile modificare tale valore) in un formato gradi, minuti, decimi di minuto. I dati vengono salvati su file con ora,latitudine,longitudine

Per vedere la fluttuazione del segnale e' stata fatta una prova con una acquisizione di 10 minuti in condizioni non ottimali (il sensore era posto sul davanzale di una finestra e riusciva a vedere solo la meta' del cielo)

In figura sono riportati i punti delle varie misure ed in rosso il valore della misura media. La distribuzione lungo un solo asse e' da imputare alla visione del cielo da parte del sensore