Duncan Golicher’s weblog

Research, scripts and life in Chiapas

Posts Tagged ‘GPS

Accuracy of an Android cell phone GPS in the UK

with 4 comments

Even cheap smart phones in the UK now have GPS capability. The rapid expansion in spatially aware devices has been driven by the potential for commercial use of location data.  Location to nearest postcode is good enough for many of these purposes, but more accurate fixes are needed for Sat Nav. Contemporary phones therefore use a combination of network based methods and satellite GPS to obtain a fix. Accuracy, once a GPS fix has been obtained, is assumed to be within 10m.

Students carrying out field research projects could therefore potentially use their own mobile phones to log positions. However are phones suitable for scientific use? Do they provide reliable data? In order to be used for research is vitally important to have some measure of the reliability of positional information. How accurate are cell phone GPS fixes? How does accuracy vary?

I recently acquired two new, but low end Android phones (Hyundai Pulse Mini) for family use. These cost just thirty pounds (600 pesos) each, plus ten pounds phone credit. Almost unbelievably cheap. These phones are clearly bottom end devices. Nevertheless I have been pleasantly surprised by how useful they are.  They provide me with all the usual smart phone services I need, including perfectly acceptable Sat Nav and  good general mapping capability including the recording of apparently reliable track logs and waypoints in gpx format.  The Android operating system is very intuitive to use. The only real problem with the devices themselves is short battery life. But, could they be used for georeferencing research sites?

This was not an easy question to answer as I could find no detailed information online regarding the specifications of the GPS chipset that they contain. It is not even clear whether such phones use EGNOS (the European equivalent of WAAS). All cell phones have “enhanced GPS”, but this refers to the method used for improving the speed of the fix by using network signals in built up areas. EGPS does not improve accuracy as such. So the main issue for research applications is lack of knowledge regarding how precision may vary and what factors influence variability.

The android Market has a large number of useful GPS tools, including the default Google maps,a useful app called “GPS essentials” and the Locus app. A promising little tool for analysing positional error and correcting it is GPS averaging.This tool logs the position at regular intervals and calculates the mean position over a time period. If errors were random over time then the mean should provide a very accurate fix. I tested this by running the app for several ten minute periods.

The good news was that the overall accuracy of the GPS was always within 4 metres of the target. The bad news was that positional errors were correlated over relatively short time periods, so taking a mean did not increase accuracy by much, due to the overall bias over all the measurements.

First run. The mean distance from the known position was 3.28 metres.

Second run. The mean distance was 2.24 metres, but note that the bias has now shifted to the South East.


I tried this test several times over the space of a few days. The pattern was always similar. The GPS fixes tended to have a correlated bias over a period of up to an hour or more. Overall accuracy was always within 5m, but apart from removing the effect of odd extreme outlier, averaging did not improve the precision by much.  A more systematic study over a longer period would provide more quantitative details and even reveal patterns in the bias that may be associated with the satellite positions.

However, I had another idea. I have two very similar phones. It occurred to me that if the positional error turns out to be the same for both I could build my own differential GPS by connecting them using Blue Tooth and sending the position of one to the other. I couldn’t find a pre-built app for this so I tried out the Python scripting environment for Android. This can be downloaded and installed here.

I had never programmed in Python, so the code is very scrappy. However it was not difficult to adapt some of the code given in the example scripts in order to cobble together a very rough and ready proof of concept script.

It ran fine, but the results were  not as I expected. I found that each phone registered quite different positions when placed together (something I could in fact have easily tested before by taking a tracklog or using GPS averaging without  the need to write the Python script!). The error turned out to be as much as 6m, but tended to fall over time to around 50 cm over the space of twenty minutes under a clear sky. So the two phones could not really be used as a differential GPS, although the overall accuracy of either seems to be acceptable for many general types of field work that do not involve site surveying.

Anyway the Python code I came up with is provided below in case it is of use to anyone. The script can be downloaded by clicking here — differentialgps.py

There are some known issues with the code. If these were tackled it might be possible to improve the results I got. The most important defect was that the readLocation() method did not always return a result, so I used getLastKnownLocation() instead, in order to get the script working. This meant that the two fixes may not have been calculated at identical times. Even taking this into account the readings from the two phones had much larger differences than I expected. Another obvious issue with the general approach I used here is the limited range of blue tooth and the fact that I did not add any way of handling exceptions when the Bluetooth signal was lost.

The script must be placed on both phones and run in a console in SL4A. First run the script on one phone to make it a server then connect the second as a client. Close the server first for a clean exit. The results are written to two files on the client phone.

import android
import time
import math

droid = android.Android()
droid.startLocating()

fclient = open('GpsClientLog.txt', 'w')
fserver = open('GpsServerLog.txt', 'w')

droid.toggleBluetoothState(True)
droid.dialogCreateAlert('Be a server or client?')
droid.dialogSetPositiveButtonText('Server')
droid.dialogSetNegativeButtonText('Client')
droid.dialogShow()
result = droid.dialogGetResponse()
is_server = result.result['which'] == 'positive'
if is_server:
 droid.bluetoothMakeDiscoverable()
 droid.bluetoothAccept()
 timelapse = droid.getInput('GPS server', 'Enter number of seconds between readings').result
 while True:
  time.sleep(int(timelapse))
  event=droid.readLocation()
  location = droid.getLastKnownLocation().result
  if location['gps'] is not None:
   location = location['gps']
   method="gps"
  else:
   location = location['network']
   method="network"
  lat=location['latitude']
  lon=location['longitude']
  print method+','+str(lon)+','+str(lat)
  fserver.write(str(lon)+','+str(lat)+'\n')
  droid.bluetoothWrite(method+','+str(lon) +','+str(lat)+ '\n')
 fserver.close()

else:
 droid.toggleBluetoothState(True)
 droid.bluetoothConnect()
 while True:
  ServerPosition = droid.bluetoothReadLine().result
  print ServerPosition
  event=droid.readLocation()
  location = droid.getLastKnownLocation().result
  if location['gps'] is not None:
   location = location['gps']
   method="gps"
  else:
   location = location['network']
   method="network"
  lat=location['latitude']
  lon=location['longitude']
  slon=float(ServerPosition.split(',')[1])
  slat=float(ServerPosition.split(',')[2])
  dist=round(math.sqrt(math.pow((slon-lon)*69930,2)+math.pow((slat-lat)*111122,2)),2)
  print "Approximate distance="+str(dist)+"metres"
  print method+','+str(lon)+','+str(lat)
  fclient.write(time.asctime()+','+method+','+str(lon)+','+str(lat)+'\n')
  fserver.write(time.asctime()+','+ServerPosition+'\n')
 fserver.close()
 fclient.close()

Written by Duncan Golicher

May 8, 2011 at 6:47 am

Como georeferenciar fotos con precisión sin costo ni esfuerzo

with 3 comments

Camaras digitales con un GPS integrado siguen siendo bastante costosas para proyectos de investigación de bajos recursos. Pero acabo de descubrir como se puede usar cualquier camara digital y cualquier GPS en exactamente la misma forma. El secreto es sincronizar la hora de ambos aparatos exactamente. Luego el software gpicsync hace toda la operación de añadir un código geográfico al encabezado EXIF e incluso escribe un kml para Google Earth con las fotos integradas. Un programa alternativo es gpscorrelate (que hace algo parecido a lo que se me ocurrió tratar de hacer si no habia encontrado gipsync antes). Gpicsync es muy fácil de usar y parece bien confiable. Hay versiones de gpicsync para Windows y Linux disponibles.

http://code.google.com/p/gpicsync/

No hay un instalador automatica para Ubuntu, pero se puede bajar con subversión.

svn checkout http://gpicsync.googlecode.com/svn/trunk/ gpicsync

Nota que para la versión Linux hay que asegurar que tienes todas las dependencias. En Ubuntu dado de que no se instala usando aptitude el proceso no es automático. El archivo “readme.txt” tampoco es muy específico cuales son. La instalación de python-wxgtk2.8, libexif12 y libimage-exiftool-perl debe solucionar los problemas. Se arranca el programa con python, entonces en en mi caso tengo un “launcher” con

python /home/duncan/gpicsync/gpicsync-GUI.py

La otra herramienta necesaria es gpsbabel. Esta programa maravilloso puede hacer la conversión entre casi cualquier formato de gps. No tiene GUI. Funciona en la mism forma desde la linea de comandos tanto en Windows como Linux. Aunque hay que revisar un poco su documentaticón antes de empezar, el uso rutinario no es nada complicado.

Obviamente el primer paso es asegurar que la hora de la camara es correcta al segundo. Nota que los gps graban la hora en UTC, pero gpicsync tiene una opción para ajustar a diferentes zonas, asi que deja la camera con la hora local.

Todavía no he probado el uso del programa ni en Windows ni con un Garmin, pero si el aparato esta conectado al puerto serial este comando debe bajar los datos del “tracklog” guardándolo en el formato gpx, lo cual es necesario para el programa.

gpsbabel -t -i garmin -f com1 -o gpx -F tracklog.gpx

Para mi uso personal tengo un gps NMEA basico que compré por $US30 en los Estado Unidos. Se conecta al USB del laptop. Estos aparatos económicos son tan precisos como cualquier Garmin o Magellan (usa WAAS si es disponible), pero requieren una laptop o palm para su uso, no funcionan independientemente.  Dado el costo bajo de la tecnología se supone que dentro de muy poco sería rutinario tener un GPS integrado en las laptops. Hay varios programas  disponibles en Linux que proveen un interface gráfico para un GPS de este tipo.

Viking, GPSDrive y gpsman son ejemplos. Son funcionales, pero para decir la verdad podrían beneficiarse de mejores interfaces para ser mas amigables. Nota que debes instalar un pequeño programa de conversión primero llamado gpsd. Esta forma un interface entre el aparato y el laptop con el comando  gpsd /dev/ttyUSB0 (suponiendo el aparato esta en el USB). Se puede ver si esta funcionando con el programa xgps. Un aviso. He encontrado que si se desconecta el gps y se reconecta a veces, pero no siempre, se abre la conexión de nuevo en /dev/ttyUSB1 en vez de /dev/ttyUSB0. (Con mas pruebas, errores, frustraciones y busquedas en foros viejos al fin me di cuenta que este problema desaparece con la desinstalación de brltty, un daemon para teclados de braille que solamente Ubuntu tiene instalado “por default”. No entiendo como lo hace pero parece que causa un conflicto). De todos modos siempre hay que asegurar que el gps esta conectado bien viendo o xgps o echo rw | nc localhost 2947, y si no cambiar el comando.

Un problema que encontré era no podía guardar el tracklog en formato gpx para la sincronización con el software de visualización. GPSDrive usa su propio formato .sav y no podia entender como hacerlo en Viking. Aunque gpsbabel puede convertir entre los dos, hay problemas cuando se pierde la señal y se graba con ceros.

La solución mas robusta que encontré fue el uso de gpsd directo para grabar el output del aparato a un archivo. Si el gps esta en el usb empiezas gpsd con

gpsd /dev/ttyUSB0

Luego el comando abajo produce un archivo ligero con todos los datos crudos del GPS.  Se puede apagar la pantalla del laptop y dejarla funcionando  hasta que se acabe la batería

echo rw | nc localhost 2947 > raw.dump

Desafortunadamente en el caso de mi pobre vieja Toshiba la batería dura  menos de 30 minutos. Estoy esperando la entrega de una pequeña Acer one precisamente para este tipo de uso. Se venden estas minilaptops económicas con Linux preinstalado, asi que las instrucciones son relevantes para sus usuarios.

Al terminar de grabar se convierte el archivo en gpx con gpsbabel. (Si quieres una explicación técnica del formato nmea esta diponible aqui http://en.wikipedia.org/wiki/NMEA_0183)

gpsbabel -i nmea -f raw.dump -o gpx -F tracklog.gpx

Ahora lo único que tienes que hacer es correr GPicSync. El interface es intuitivo y no requiere explicación.

He incluido un archivo kmz de Google Earth que acabo de producir con fotos de alta resolución de mi casa aqui.

http://duncanjg.files.wordpress.com/2008/08/casakmzquitaelresto.doc

Este archivo es de 24MB. WordPress no acepta el sufixo de .kmz. Asi que esta disfrazado como doc. Si quieres ver lo hay que esperar un rato para que se baje y luego cambiar el nombre a casa.kmz y luego abrirlo en Google Earth.

Written by Duncan Golicher

August 31, 2008 at 10:20 am

Follow

Get every new post delivered to your Inbox.