No hace falta que enumere la cantidad de software de navegación
mediante GPS que existe actualmente en el mercado. Este tipo de
software se comunica con el dispositivo GPS, interpreta la señal
del mismo y procesa dicha información. En realidad, obtener la
señal del GPS es lo menos complejo; lo realmente complicado es el
desarrollo de la lógica de la aplicación en base a esa información.
La versatilidad de esa lógica implica que existan otros tipos de
software aplicados en ámbitos más específicos o menos
cotidianos.
GPS (su nombre completo es NAVSTAR GPS) es un sistema de 301
satélites situados a poco más de 20.000 km de altura que cubren, de
forma sincronizada, la totalidad de la esfera terrestre. Debido a
su carácter de origen militar, la información obtenida de los
satélites GPS permite no solo obtener las coordenadas
(longitud/latitud) de un objeto, sino también la altitud, así como
la velocidad, rumbo, información de los satélites, llegando incluso
a las inclinaciones de un objeto en el espacio con receptores más
sofisticados. Sin embargo, muchas características (en forma de
sentencias NMEA) dependen de que el receptor GPS las interprete. El
receptor que podemos adquirir hoy en día se centra principalmente
en la recepción de la información necesaria para el posicionamiento
y trayectoria.
Durante el desarrollo de este artículo he tratado de indagar algo
más sobre las características tecnológicas del GPS, en aspectos
concretos, con lo que además de mostrar las posibilidades de
utilización con Windows Mobile, se enumeran, a grandes rasgos (ergo
matemáticas aparte), los tecnicismos y parámetros a tener en cuenta
en distintos escenarios.
Podrá encontrar la aplicación y recursos de ejemplo utilizados en
este artículo en www.dotnetmania.com o desde mi Web en
www.desarrolloMobile.NET (Sección GPS).
Qué ofrece Windows Mobile
Como decía, la demanda es tal, que muchos dispositivos PDA vienen
con GPS incorporado y si no, evidentemente, con posibilidad de
conexión mediante Bluetooth. Esto ha permitido que muchas
aplicaciones empresariales e industriales saquen provecho de esta
capacidad. Pero, si deseáramos hacer lo mismo desde nuestra
aplicación Windows Mobile, ¿por dónde empezaríamos?
Con versiones anteriores a Windows CE 5.0, la obtención de la
señal GPS se hacía, ya fuera mediante Bluetooth o interno, por un
puerto COM de entrada (directamente por hardware). Un receptor GPS
emite señales (en forma de sentencias ASCII) hacia el dispositivo a
través del puerto COM con una frecuencia de entre 1 y 5 segundos.
En cada recepción se reciben varias sentencias NMEA (conoceremos
algunas más adelante). En la figura 1 podéis ver un ejemplo de
captura real de aproximadamente 3 segundos de un GPS.
Imagínese tener que procesar todo esto. Por un lado, debemos tener
un hilo dedicado en exclusiva a escuchar las sentencias de entrada.
Seguidamente, en función del tipo de sentencia (recuerden, son
varias) interpretamos el contenido (no necesariamente existe una
lógica en el orden de las secuencias) y hacemos uso de delegados y
eventos para alertas de cambios de posicionamiento en la interfaz
de usuario. Ardua tarea, sin duda.
A partir de Windows CE 5.0 se perfecciona el mecanismo de
obtención de datos de un GPS. Windows CE 5.0 ofrece una capa
intermedia (GPS Intermediate Driver, GPSID en adelante) que
controla el dispositivo GPS para facilitar la obtención de datos
del mismo a través de básicamente 4 funciones y de estructuras
nativas. Esta capa intermedia controla toda la "fontanería" de
eventos de actualización de datos y además ofrece las sentencias
NMEA en estructuras de datos, con lo que no es necesaria ya la
manipulación desde código de las mismas. Otra característica que
ofrece es la posibilidad de que varias aplicaciones consuman los
datos de un solo GPS a través de GPSID.
Pese a todas estas ventajas, el desarrollo de una aplicación .NET
Compact Framework que utilice estas librerías y estructuras no es
nada sencilla. Mi opinión es que son muchas estructuras, funciones
y punteros a eventos, y sin una base sólida de programación en C++
y control y conocimiento en los cálculos de referencia, la tarea
puede hacerse muy tediosa. En este artículo no vamos a desarrollar
una librería que encapsule la funciones del GPS Intermediate Driver
bajo código administrado; en el SDK de Windows Mobile 5.0 y 6.0 hay
un ejemplo de cómo se utiliza éste, y sinceramente no se me ocurre
una mejor forma de conocer su funcionamiento que explicar las
características de la clase administrada que engloba las funciones
nativas; al fin y al cabo, lo que nos interesa es utilizar la
librería, no desarrollarla desde cero. Sin embargo, lo que sí
haremos es tratar de entender el código de ejemplo que Microsoft
ofrece en el SDK a través del desarrollo de un pequeño ejemplo para
Pocket PC, con el fin de poner en práctica el uso de la clase Gps,
conocer los términos más utilizados en posicionamiento y utilizar
las herramientas de depuración para este tipo de proyectos.
Nociones básicas de NMEA
El protocolo estándar NMEA (National Marine Electronics
Association) es compatible con RS-232. Utiliza entre 4.800 y 9.600
bps, con 8 bits de datos, sin paridad y con un bit de parada. Todas
las sentencias NMEA 0183 están codificadas en ASCII, empiezan con
el símbolo $ y están precedidas por las letras "GP" y el nombre de
la sentencia, terminando con un retorno de carro
<CR><LF>. Los campos de la sentencias están delimitados
por comas, el último delimitado por un asterisco y precedido por el
valor hexadecimal de la suma de chequeo. Existen algo más de 50
sentencias NMEA, capaces de dar todo tipo de información a
aeronaves, embarcaciones y vehículos terrestres.
Los receptores utilizados para navegación hacen uso de unas pocas
sentencias, suficientes para obtener la localización, velocidad,
rumbo y estado de los satélites. Cada una de las sentencias aporta
información específica. Fijémonos en las secuencias $GPRMC de la
figura 1. RMC son las siglas de Recommended Minimum Specific
GPS/TRANSIT Data. Esta secuencia ofrece información de
posicionamiento en los campos precedentes (ver figura 3). De esta
forma, cada sentencia conlleva un tipo específico de información,
que junto a las demás sentencias conforman el posicionamiento y
estado de los satélites, entre otros.
Ejemplo práctico
Vamos a ver un ejemplo de cómo realizar un velocímetro en una PDA.
El objetivo es conocer las herramientas de emulación de secuencias
que emite un GPS; conocer en profundidad qué funciones y
estructuras nativas se utilizan, así como el uso de los eventos del
driver del GPS, todo lo cual podemos ver en el ejemplo
Microsoft.WindowsMobile.Simples.Location, que viene con el SDK, y
por último, familiarizarnos con todos los términos que ofrece el
GPS.
Microsoft FakeGPS para entorno de desarrollo
La depuración de este tipo de aplicaciones es bastante incómoda.
En un proyecto bajo Windows Mobile 2003SE, tuve que desarrollar un
pequeño programa que se comunicara por el puerto COM, donde tenía
emparejado el GPS Bluetooth, y guardara toda la información que
recibía en forma de sentencias NMEA a un archivo durante los
trayectos de casa a la oficina. Luego apareció Windows Mobile 6 y
con él su SDK. En el SDK se ofrece una herramienta que simula un
GPS, cuyo nombre es FakeGPS. FakeGPS emite unas sentencias NMEA
extraídas de un fichero y las emite como si de un GPS real se
tratara a través del GPSID del emulador. Podrá encontrar esta
herramienta dentro del directorio de instalación del SDK de Windows
Mobile versión 6, en el subdirectorio Tools\GPS. Observe que hay un
archivo Fake.Cab y otro Settings.exe. Éste último lo utilizará para
dispositivos Smartphone. Copie e instale Fake.Cab en el emulador
donde depurará el proyecto.
Una vez instalado el archivo Fake.Cab en el emulador, nos
dirigimos a "Programas" y ejecutamos FakeGPS (figura 4). Lo
habilitamos e indicamos uno de los dos archivos que vienen
preestablecidos inicialmente, y que son prácticamente iguales: el
archivo dixies.txt empieza a emitir sentencias NMEA de forma
inmediata, mientras que fakegpsdata.txt hace lo mismo, pero tarda
un cierto tiempo en emitir sentencias válidas. Puede añadir los
suyos propios, sencillamente copiándolos dentro del subdirectorio
GPSFiles donde se ha instalado FakeGPS. Debido a que estos dos
archivos de ejemplo son sencillos y no muestran con claridad la
velocidad, no nos serán útiles. Por esa razón, le recomiendo que
descargue el archivo outgps2.txt, que contiene sentencias NMEA
reales tomadas en un rutinario día de trabajo desde mi casa en
Igualada a la oficina en L'Hospitalet, y que capturé para el
desarrollo de este artículo, desde la www.dotnetmania.com o desde
mi Web en www.desarrolloMobile.NET (sección GPS).
Profundizando en
Microsoft.WindowsMobile.Samples.Location.dll
Centrándonos en el ejemplo del SDK, la clase Gps llama a 4
funciones nativas que residen en la librería Gpsapi.dll. Además,
existen otras estructuras y punteros a funciones para el control de
eventos a través de delegados (vea tabla 1). Este conjunto de
funciones y estructuras y las correspondientes constantes conforman
el GPS Intermediate Driver (para más información, consulte
Gpsapi.h).
Una de las peculiaridades de este driver es que ofrece dos formas
de presentar las secuencias NMEA. La más común, conocida como
Parsed, emite la información en forma de estructura GPSPOSITION,
en la que el propio driver interpreta las secuencias NMEA y crea la
estructura con datos de posicionamiento estructurados. Otra forma,
conocida como Raw, ofrece la transmisión directa de las secuencias
NMEA desde el GPS en forma de stream; posteriormente éstas son
capturadas mediante las funciones CreateFile y ReadFile, sin una
previa manipulación. En esta última, nosotros mismos debemos
interpretar todas las sentencias NMEA que nos lleguen; además,
podemos enviar sentencias de configuración desde nuestra aplicación
al GPS mediante WriteFile. En este ejemplo, obtendremos los datos
del posicionamiento a través de la estructura GPSPOSITION y a su
vez por la clase GpsPosition (tal y como se hace en el ejemplo del
SDK), con lo que haremos uso del modo Parsed.
Si observa el código, notará la continua llamada a las funciones,
también nativas, LocalAlloc y AllocFree, con las cuales se crean y
se destruyen en memoria administrada matrices de bytes que albergan
información de las estructuras nativas. Fíjese especialmente en las
estructura GPS_DEVICE. No existe como clase o estructura
administrada, ya que se crea como una matriz desde código y
posteriormente es consumida por la clase GpsDeviceState.
La recepción de los datos se realiza a través del método
GPSGetPosition de la clase Gps, cuyo hilo comienza al abrirse la
comunicación con el GPS. Este hilo permanecerá en continua escucha
y obtendrá tanto las modificaciones del estado del GPS, nuevos
posicionamientos o peticiones de parada en la comunicación. Por
otro lado, las aplicaciones que hagan uso de esta librería
recibirán en modo de eventos todos los cambios mencionados
anteriormente con los nuevos datos, siempre desde clases
administradas. Fíjese en la función nativa GPSOpen. Los dos
primeros argumentos son punteros a funciones manejadas como
delegados y propagadas como eventos desde .NET Compact Framework.
Otra de las características a nuestra disposición es la
posibilidad de obtener el estado de la triangulación de los
satélites, como el número y señal de los mismos. Además, existen
multitud de constantes en Gpsapi.dll, algunas expuestas como
enumeradores como FixQuality en la clase GpsPosition. Los eventos
que tengan lugar por la modificación del estado del GPS son de
vital importancia para determinar la validez, por ejemplo, de las
sentencias NMEA obtenidas.
Interfaz de usuario
Para el ejemplo, vamos generar un proyecto Windows Forms para
Windows Mobile 5/6. Lo único que necesitaremos se muestra en la
figura 6. Evidentemente, usted puede rediseñarlo a su propio gusto;
lo único que se necesita son controles para poder representar, por
ejemplo:
• La velocidad en km/h.
• Información de satélites.
• El posicionamiento (latitud/longitud).
• Altitud (por encima del nivel del mar).
• Rumbo.
Si desea mostrar más datos, tiene a su disposición las propiedades
de la clase GpsPosition con todos los datos necesarios.
Primer paso, y más importante, establecer el sistema de eventos.
Vamos a utilizar un objeto de la clase Gps privado para la clase
del formulario. Abriremos y cerraremos la comunicación con el GPS a
través de los menús y las llamadas a los métodos Open() y Close().
Cuando abramos la comunicación con el GPS, capturamos el evento
LocationChanged (el evento DeviceStateChanged no se muestra en este
ejemplo) que expone la clase Gps. En ambos casos, los delegados
propagan argumentos tanto con el estado del dispositivo, a través
de la clase GpsDeviceState (argumento del tipo
DeviceStateChangedEventArgs), como del posicionamiento a través de
la clase GpsPosition (argumento del tipo LocationChangedEventArgs).
Es muy importante que los eventos se declaren a través del
delegado EventHandler puesto que la clase Gps, internamente, crea
un hilo que propaga la llamada a través del respectivo delegado. De
esta forma, al residir en un proceso distinto la única alternativa
es la llamada a través de Control.Invoke (vea listado 1).
En cuanto a la actualización de datos por pantalla, es tan
sencillo como se puede ver en el listado 2.
Ejecución y depuración
Prácticamente no tenemos que hacer nada extraordinario para la
depuración de proyecto si hemos configurado correctamente FakeGPS y
éste está habilitado. Sencillamente ejecutamos, y empezarán a
mostrarse los datos por pantalla. Recuerde configurar FakeGPS con
el archivo outgps2.txt anteriormente mencionado.
Configuración del GPSID en tú PDA
Antes que nada, vamos a ver en profundidad la configuración del
driver desde el GPS. Como dije, podemos encontrarlo en
"Configuración" | "Sistema". Por un lado, tenemos que emparejar el
dispositivo GPS (en el caso que sea Bluetooth) y observar qué
puerto utiliza el servicio Serial Port (SPP) dentro de la
configuración de Bluetooth. Tenga en cuenta que el emparejamiento
de un GPS Bluetooth mediante SPP conlleva la utilización de 2
puertos, el de entrada del GPS y el de salida. Por otro lado, la
configuración del GPSID requiere otros dos puertos COM: el primero
el de programa, que será el que utilizarán las aplicaciones cliente
para obtener información del GPSID y el segundo, el de hardware,
que ha de ser el mismo que el de salida del servicio SPP del
emparejamiento del GPS (ver figura 7).
Algunos términos
importantes del GPS
El receptor GPS recibe la señal de los satélites que tiene a su
alcance, evalúa la calidad de la señal-ruido, determina si ésta es
válida y calcula la distancia a los mismos en base a la velocidad
de la luz en el vacío (aplicando una corrección de error). Cuando
el receptor obtiene información fiable de dos satélites, se obtiene
una posición inexacta ubicada en la zona de intersección de las dos
circunferencias de los satélites. Añadiendo un tercer satélite,
obtenemos el posicionamiento 2D (x, y, z) y con él la
triangulación; sin embargo, este posicionamiento no es preciso a
menos que exista un cuarto satélite con una señal-ruido aceptable.
La explicación reside en que cada uno de los satélites incorpora
dos relojes atómicos de altísima precisión. Estos relojes, cuyo
coste es elevadísimo, están sincronizados entre todos ellos pero no
lo están con el reloj del receptor (ya que éste no los incorpora
por cuestiones de abaratamiento del terminal), y como el cálculo de
distancias entre satélite-receptor se realiza en base a la hora
exacta en la que fue emitida una señal, la única forma de
establecer un posicionamiento fiable es con un cuarto satélite y
con ello se obtiene una triangulación en 3D (x, y, z, tiempo)
exacta.
Así pues, cuanto mejor sean las condiciones meteorológicas y mayor
sea el número de satélites utilizados por el receptor, mayor será
la precisión, cuyo rango oscila entre los 15 metros (existen varias
fuentes de error) y 1 metro. Dentro de los datos de posicionamiento
que ofrece el GPS se incorpora el estado de los satélites que el
receptor "visualiza", así como los que se están utilizando y la
dilución de cada uno de ellos.
La dilución de precisión (DOP) se emplea en cartografía y describe
la precisión del GPS en base a la geometría de los satélites.
Cuando la señal DOP es alta, los satélites están muy cerca entre
sí, con lo que la precisión disminuye y el valor DOP aumenta. Si
por el contrario los satélites son distantes, la precisión aumenta
y con ello el valor DOP disminuye. Los obstáculos urbanos y
naturales puede aumentar el DOP de la señal del GPS. Existen
diluciones de precisión para el posicionamiento horizontal (HDOP),
vertical (VDOP), el de posicionamiento (PDOP) y el de tiempo
(TDOP). Puede encontrar estos valores en la clase GpsPosition
(propiedades PositionDilutionOfPosition,
HorizontalDilutionOfPosition y VerticalDilutionOfPosition).
Otro factor que no hemos explicado es el que hace referencia a la
propiedad EllipsoidAltitude de la clase GpsPosition. El concepto de
elipsoide es utilizado matemáticamente para describir la superficie
terrestre en base a dos radios (polar y ecuatorial), es decir, algo
así como un sistema de coordenadas mundiales relativas a la norma
aplicada, en las que se basa el sistema GPS y que se estableció
bajo la norma o "datum" conocida con las siglas WGS84. Esto es
necesario puesto que la tierra no tiene una forma geométrica
regular, y por lo tanto, la altitud (a nivel del mar) se obtiene en
base a la altura del receptor respecto del elipsoide y el valor del
elipsoide, según WGS84, establece un valor entre 44 y 55 metros por
encima del nivel del mar en España. Ambos valores, el del elipsoide
y el de la altitud, se complementan, así que si su aplicación
requiriera de una precisión en cuanto a la altitud del receptor,
téngalo presente y consulte los manuales del receptor. Para el
resto de los mortales, nos conformamos con saber, aproximadamente,
qué es y para qué sirve el "datum" WGS84.
Uso de varias aplicaciones
Si ha utilizado el archivo de sentencias que le he indicado, uno
propio o sencillamente los que FakeGPS ofrece por defecto, trate de
hacer lo siguiente. Configure FakeGPS con outgps2.txt e instale
Google Maps para Pocket PC en el emulador. Debido a que Google Maps
requiere conexión a Internet, empareje el emulador a través del
Device Emulator Manager con ActiveSync o Windows Device Center
mediante DMA. Luego instálelo, y tras ejecutar Google Maps haga uso
del GPS mediante el menú "Use GPS". Ahora ejecute la aplicación del
velocímetro, y comprobará como ambas aplicaciones consumen todas
las secuencias NMEA tomadas "off line" e indicadas por
FakeGPS.
Finalizando
Siempre que quiera profundizar en algún término, ya sea específico
o general, acerca del funcionamiento del GPS, llegará a toparse con
alguna ecuación matemática que le demostrará el por qué. Si no
quiere más que saber acerca de cómo utilizarlo desde su aplicación,
quédese con la utilidad que puede sacar del GPSID, de los datos que
éste puede ofrecer y del significado exacto de los mismos. No
olvide en entornos de desarrollo el uso de FakeGPS, el cual es
sencillamente genial, y descargar el archivo de sentencias que
utilicé para el desarrollo de este ejemplo. La representación de la
aplicación en el emulador se aproximará al 95% de la realidad. El
único inconveniente es la latencia en la recepción del datos desde
su PDA, la cual será distinta (más lenta seguramente) que en el
emulador, según el receptor y la propia PDA. En dicho ejemplo,
podrá apreciar también los agotadores atascos que se producen en la
entrada a Barcelona a primera hora, y quizás algún exceso de
velocidad (justificados, lo prometo J). Hablando de imprudencias,
si utiliza su aplicación desde el coche, hágalo estando como
copiloto; podrá apreciar con mayor percepción los datos que se
muestran, y de paso se evitará algún que otro disgusto, se lo digo
por experiencia.