desarrolloMobile.NET Noticias

martes, enero 27, 2009

¿Cuán precisa es la señal de nuestros receptores GPS?

NOTA: Este post es Cross Posting desde http://geeks.ms/blogs/jmtorres/archive/2009/01/21/cuan-preciso-es-la-senyal-de-nuestros-receptores-gps.aspx. Si tiene problema de visualización, por favor visite el original.

Quién más o quién menos ha utilizado o utiliza un receptor GPS para uso lucrativo o personal, sean receptores compactos, con pantalla y software o sean a través de PDA’s con receptores conectado por Bluetooth, por ejemplo. Si es así, seguro que en muchas ocasiones hemos estado a punto de perder la paciencia debido a que los satélites aquél día, parecen no estar surcando los cielos.

En este post pretendo mostrar el porqué de esos comportamiento y cómo podemos evaluar la dilución de la precisión nosotros mismo con un dispositivos Windows Mobile y el SDK del mismo.

NOTA: Algunos de los términos explicados aquí son aproximados debido a la complejidad de su comprensión. Éstos pueden tener alguna interpretación errónea por mi parte así que si encontráis algún dato incorrecto, por favor, contactadme.

Conceptos previos

Antes de analizar la exactitud y tasa de errores que podemos encontrarnos en nuestros receptores GPS vamos a introducir unos cuantos conceptos que deberían tenerse en cuenta.

El sistema de posicionamiento global es un sistema arto complicado cuyos fundamentos matemáticos y físicos describen el comportamiento y aplicación del mismo. La parte fundamental del GPS son los satélites y éstos (unos 24 más lo de respaldo) andan por sus anchas describiendo planos orbitales alrededor de la esfera terrestre a una altitud de unos 20.200 kilómetros lo que permite que hasta 10 satélites sean visibles en un radio de unas 11.000 millas náuticas.

Triangulación

Para que un receptor obtenga un posicionamiento (sea cual sea su exactitud y tasa de error) se requiere la detección de 4 satélites, lo cual da lugar a la triangulación 3D. Con éstas cuatro señales el receptor es capaz de determinar la longitud (x), la latitud(y), la altitud (y) y el tiempo (t) con lo que en un entorno ideal sin errores, el receptor GPS se situará en la intersección de las 4 esferas definidas por las señales de los satélites. El uso de únicamente 3 satélites deriva en el posicionamiento en 2D (exento de z, altitud).

Es de vital importancia el llamado cuarto satélite puesto que éste es que determinará el valor de t. Esto es debido a que se determina la distancia del receptor al satélite en base a la velocidad de la luz más una constante de rectificación de errores y la sincronización de todos los satélites mediante un reloj atómico que incorporan.

Fuentes de error

Efectos atmosféricos

Como dije anteriormente la señales que emiten los satélites lo hacen a la velocidad de la luz, pero en el espacio exterior. De esta forma, existen errores relacionados a la refracción con la ionosfera y con la troposfera.

En la ionosfera es la capa dónde se produce una mayor tasa de error pudiendo llegar a ser de +/- 5 metros. Esto es debido a que en esta capa de la atmósfera se encuentra un alto nivel de electrones e iones positivos, producidos por la radiación solar, que interfieren negativamente sobre las señales. La Troposfera, por su parte, concentra una gran cantidad de vapor de agua lo que da lugar a otro tipo de refracción de las ondas con unos valores que oscilan entre los +/- 0.5 metros.

Errores de reloj

Pese a que los relojes equipados en los satélites son atómicos, no son 100% precisos y experimentan errores por ruidos o desfases con los errores del receptor, que no son atómicos. Estos errores pueden llega a producir una desviación de + o – 2 metros.

Relatividad

Por un lado tenemos que los satélites recorren la esfera terrestres a una altitud de más de 20.000 km a una velocidad de unos 12.000km/h lo que provoca que, según la teoría de la relatividad, los relojes de los satélites (el tiempo) corra más lentamente en los satélites que en la tierra por su velocidad (relatividad espacial) y por su altitud (relatividad potencial) lo que generará retardos del orden de 7,2 y 38 nanosegundos/día respectivamente.

Efecto Sagnac

Otro efecto relativístico es el efecto Sagnac que es causado por el posicionamiento, del receptor/observador, en la superficie terrestre relativo a la velocidad de rotación del globo terrestre. Este efecto, sin embargo, tiene una tasa de error ínfimo.

Efecto Multipath

Es muy común andar o circular por ciudades cuya altura de los edificios superan unas cuantas plantas, de la misma forma que se produce por cuestiones orográficas, montañas etc. Pese a que el receptor puede no obtener una señal con la calidad SNR (señal/ruido) óptima, puede ocurrir algo imprevisto, que la señal llegue con SNR optima pero provenga rebotada de un edificio o montaña cercana.

multipath

Este tipo de error es muy común en receptores en movimiento, pudiendo llegar a generar una tasa de error de hasta +/- 1 metro.

Disponibilidad Selectiva

Esta fuente de error es la inducida mediante la alteración o manipulación de la señal del satélite para que envíe datos erróneos en forma de mensajes NMEA al receptor, intencionadamente. Este tipo de fuente fue utilizada durante las guerras del Golfo de principio de los 90 y, evidentemente fueron inducidas adrede por el gobierno de los EEUU. A partir de mayo de 2000, el entonces presidente de los EEUU Bill Clinton, eliminó la disponibilidad selectiva haciendo público el uso del GPS sin alteración humana.

Geometría de los satélites y DOP

Tan importante es el posicionamiento de satélites como la geometría que describen entre ellos y emiten sus señales, me explico. En la siguiente imagen podemos observar como cuatro satélites emiten señales válidas a un receptor GPS.

DOP alto

Sin embargo la geometría de sus señales no es óptima debido a a la proximidad que existe entre ellos. En la siguiente imagen, ocurre todo lo contrario.

DOP bajo

La señales provenientes de los satélites geométricamente mejor posicionados generarán un mayor fiabilidad del posicionamiento. Así pues:

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. Existen diluciones de precisión para el posicionamiento horizontal (HDOP) , vertical (VDOP), el de posicionamiento (PDOP) y el de tiempo (TDOP) con lo que dentro del cada uno de dichos aspectos puede ofrecer un valor distinto. Los obstáculos urbanos y naturales puede aumentar el DOP de la señal del GPS—> Ver efecto Multipath.

¿Como se controlan todos estos errores?

La corrección de estos errores se llevan a cabo mediante complejas formulas fisicomatemáticas específicas para cada fuente de error. La mayoría de estos errores son transparente para mostros y ni siquiera debemos tenerlos en cuenta, en la mayoría de circunstancias.

Muchos de estas correcciones podríamos obtenerlas mediante las sentencias NMEA recibidas (pero nunca intervenir), sin embargo, el barómetro más común utilizado son los valores del DOP (Dilución de la precisión) y que podemos ver en este mismo post/ejemplo.

Uso de la clase GPSPosition del SDK de Windows Mobile 6

Junto con el SDK de Windows Mobile 6 podemos encontrar un ejemplo en código administrado de uso del GPS Intermediate Driver. Pese a que esta librería está en código nativo y forma parte, por lo tanto, del core de Windows CE para las versiones 5.01 y superiores, el ejemplo en cuestión incorpora un wrapper de todas estas funciones, enumeradores y estructuras en .NET.

SDK

Nos vamos a centrar en la clase GPSPosition la cual nos retorna los valores más significativos y necesarios para el posicionamiento y valores de navegación así como el estado de las señales, satélites y valores DOP. Veámoslos.

Valores que retorna

En la siguiente tabla se detallan todos los valores de la estructura/clase GPSPosition.

PropiedadDescripción
EllipsoidAltitudeAltitud elipsoidal (para saber que es la altitud elipsoidal ver Visualizando las altitudes)
EllipsoidAltitudeValidIndica si el valor de la altitud elipsoidal es valido/fiable.
HeadingRumbo en grados de 001-360
HeadingValidIndica si el valor del rumbo es valido/fiable.
HorizontalDilutionOfPrecisionDilución de precisión horizontal (1-50)
HorizontalDilutionOfPrecisionValidIndica si el valor del HDOP es valido/fiable.
LatitudeLatitud en grados
LatitudeValidIndica si el valor de la latitud es valido/fiable.
LatitudeInDegreesMinutesSecondsLatitud en grados/minutos/segundos
LongitudeLongitud en grados
LongitudeValidIndica si el valor de la longitud es valido/fiable.
LongitudeInDegreesMinutesSecondsLongitud en grados/minutos/segundos
PositionDilutionOfPrecisionDilución de precisión (1-50)
PositionDilutionOfPrecisionValidIndica si el valor del PDO es valido/fiable.
SatelliteCountNúmero de satélites
SatelliteCountValidIndica si el valor del recuento de satélites es valido/fiable.
SatellitesInSolutionNúmero de satélites utilizados
SatellitesInSolutionValidIndica si el valor del recuento de satélites utilizado es valido/fiable.
SatellitesInViewCountNúmero de satélites vistos
SatellitesInViewCountValidIndica si el valor del recuento de satélites visibles es valido/fiable.
SeaLevelAltitudeAltitud MSL a nivel del mar
SeaLevelAltitudeValidIndica si el valor de la altitud es valido/fiable.
SpeedVelocidad en nudos
SpeedValidIndica si el valor de la velocidad es valido/fiable.
TimeHora/Fecha
TimeValidIndica si el valor de la fecha es valido/fiable.
VerticalDilutionOfPrecisionDilución de precisión vertical (1-50)
VerticalDilutionOfPrecisionValidIndica si el valor del VDOP es valido/fiable.
MétodosDescripción
GetSatellitesInSolution()Retorna un array del tipo Satellite con los satélites que se están utilizando en ese momento.
GetSatellitesInView()Retorna un array del tipo Satellite con los satélites que se están viendo en ese momento.

Visualizando el tipo de señal (GPS_FIX_QUALITY)

Dentro de la clases GPSPosition encontramos un atributo (selectionType) del tipo FixSelection cuyo valor se define en el enumerador:

enum FixQuality : int
{
Unknown = 0,
Gps,
DGps
}




Dichos valores equivalen al tipo de señal que se obtiene. En este punto cabe remarcar la existencia de los GPS Diferenciales (DGPS) que son antenas que complementan y se comunican con los receptores y cuyas tasas de error son aun menor a las del receptor GPS tradicional. Por lo tanto selectionType determinará el tipo de señal i por consiguiente la calidad de la misma.



Visualizando el número de satélites



En cuanto a la información de los satélites contamos con dos métodos que nos retornan tanto los satélites en vista (GetSatellitesInView()) como los utilizados (GetSatellitesInSolution()). Los satélites descritos por la clase Satellite, contienen, así mismo, 4 propiedades:














































PropiedadDescripcion
IdIdentificador del satélite.
SignalStrenghCalidad de la señal/ruido (SNR) en decibelios.
AzimuthDescribe la posición radial relativa al receptor en grados. Un valor de 90 indica al Este de nuestra posición mientras que un valor 270 o 180, al Oeste o Sur.
ElevationEl ángulo descrito entre el satélite y el plano del receptor.







Visualizando las altitudes



Altitud elipsoidal


Antes de comprender la fiabilidad de la altitud, trataré de explicar que es la altitud elipsoidal.



La esfera terrestre no tiene una forma -geométricamente- esférica perfecta, mas bien tiene forma “de pera”. A partir de esta premisa, es obvio que en los cálculos de altitud de un receptor se harán en base al tiempo que tarde en viajar la señal desde el satélite al receptor, teniendo en cuenta la velocidad de la luz más las constantes y cálculos de rectificación de errores. Supongamos que un receptor está al nivel del mar en una magnífica playa de Argentina mientras que un segundo receptor esta al nivel del mar en el norte de Noruega. Ambos están a una altitud de 0 metros, sin embargo y debido a la forma de la tierra, la señal del receptor argentino indicará valores de altitud relativa a los satélites más altos que la real y el de Noruega valores más bajos (probablemente bajo 0 metros) que la real.



Para subsanarlo, el GPS representa la tierra de forma geométrica perfecta con una elipsoide referencial o Datum estándar utilizado en otras áreas como la topografía. Dicho estándar lo describe WGS84 en la actualidad y probablemente sea substituido en breve.



Conociendo la posición exacta relativa del receptor y satélite sobre la línea imaginaria que describe el datum, conoce las correcciones que debe realizar para conocer la altitud exacta del receptor. De esta forma, en España, por ejemplo, los valores de la altitud elipsoidal oscilan entre los 45 y 50 metros (* datos aproximados)



En la siguiente imágenes podemos ver como altitud elipsoidal puede ser distinta en una Lugar A (Noruega por ejemplo) y un Lugar B (Argentina por ejemplo).



altelipsoidal



Altitud (MSL)


La altitud, pues, es la distancia del receptor respecto al nivel del mar. Un valor mínimo de VDOP nos dará una mayor fiabilidad.



Visualizando el posicionamiento y velocidad


Los valores del posicionamiento (latitud + longitud) son absolutos y se especifican en grados/minutos/segundos o en únicamente en grados. La velocidad, por su parte, es enviada en nudos (esto es millas náutica por hora).



Conversiones nudos (fuente Wikipedia.)




  • 0,514444 metros por segundo (m·s−1)





  • 1,150779 milla (estatutaria) por hora (mph)





  • 1,852 kilómetros por hora



    Un valor mínimo de HDOP nos ofrecerá una mayor fiabilidad.



    Por último el rumbo describe la dirección en las agujas del reloj en forma de grados de nuestro movimiento. Dirección 360 es Norte, 90 es Este, 180 es Sur y 270 es Oeste.



    Visualizando los DOP



    Los indicadores de Dilución de Precisión de la posición (además del vertical y el horizontal) los podemos encontrar en la clase GPSPosition, con lo que dado un posicionamiento y altitud podemos evaluar su precisión según los valores:
















































    ValorDescripción
    1Ideal
    2-3Excelente. En este punto la fiabilidad de la posición es muy fiable.
    4-6Buena. La fiabilidad es buena pero con algún error (muy pequeño, sin embargo) de posicionamiento.
    7-8Moderada. La señal debe ser revisada. El posicionamiento es aproximado pero no fiable.
    9-20Pobre. Los posicionamientos deben ser descartados.
    21-50Muy Pobre. Los posicionamientos pueden tener un rango de error de +/- 300 metros.



    El ejemplo practico



    Ahora solo necesitamos dos cosas, bueno tres: el SDK de Windows Mobile 6, un nuevo proyecto Smart Device, y configurar el Fake GPS que viene con el SDK o el GPS con nuestro dispositivo móvil a través del GPS Intermediate Driver.



    Para configurar el Fake GPS, podemos ver cómo hacerlo en desarrolloMobile.NET, sección GPS Library. Hecho esto y creado un proyecto Smart Device para Windows Mobile 6 (indistintamente Classic o Professional) empezamos por agregar el proyecto Microsoft.WindowsMobile.Samples.Location.csproj que encontraremos en %PROGRAM_FILES%\Windows Mobile 6 SDK\Samples\PocketPC\CS\GPS. Seguidamente añadimos la referencia a dicho proyecto desde el nuestro y empezamos.



    Diseñamos una interfaz con un TabControl y un par de TabPage además de unos menús para abrir y cerrar el GPS y cerrar la aplicación. (Aquí a gusto de cada uno)



    app diseño



    Vamos a mostrar en el tab POSICION todos los datos de posicionamiento así como los DOP, y en el tab de SATELITES un ListView con los satelites, información y cuales son utilizados.










    app posicion app satelites



    Utilizaremos los siguiente atributos dentro de la clase Form1 e añadimos en el evento Form_Load el siguiente código para suscribir el EventHandler a los cambios de estado del dispositivo GPS y de posicionamiento.



    public partial class Form1 : Form
    {
    EventHandler _updateDataHandler;
    GpsDeviceState _dispositivo;
    GpsPosition _posicion;

    Gps gps = new Gps();

    public Form1()
    {
    InitializeComponent();

    _updateDataHandler = RefreshUI;
    }


    Con lo que toda la lógica la trasladamos al delegado del tipo EventHandler _updateDataHandler. Éste delegará sobre el método RefreshUI.



    public Form1()
    {
    InitializeComponent();

    _updateDataHandler = RefreshUI;
    }


    El método RefreshUI contempla las siguientes partes a destacar:



    Para el control de los datos de latitud, longitud, altitud, altitud elipsoidal, velocidad, rumbo y fecha lo haremos de la siguiente forma:



    if (_posicion.LatitudeValid)
    {
    str[0] += string.Format("Lat:\t{0}\n", _posicion.LatitudeInDegreesMinutesSeconds);
    }

    if (_posicion.LongitudeValid)
    {
    str[0] += string.Format("Lon:\t{0}\n", _posicion.LongitudeInDegreesMinutesSeconds);
    }

    if (_posicion.SpeedValid)
    str[0] += string.Format("Velocidad:\t\t{0} nudos\n", _posicion.Speed.ToString());

    if (_posicion.SeaLevelAltitudeValid)
    str[0] += string.Format("Altitud:\t\t{0} metros\n", _posicion.SeaLevelAltitude.ToString());

    if (_posicion.EllipsoidAltitudeValid)
    str[0] += string.Format("Altitud elipsoidal:\t{0} metros\n", _posicion.EllipsoidAltitude.ToString());

    if (_posicion.HeadingValid)
    str[0] += string.Format("Rumbo:\t\t{0} grados\n\n", _posicion.Heading.ToString());

    if (_posicion.TimeValid)
    {
    Text = _posicion.Time.ToString();
    }


    Para toda la información de satélites jugaremos con LINQ de cara a mostrar en un ListView, de forma ordenada descendente por Señal, los satélites vistos, resaltando con una Imagen en color los utilizados. El código es:



    //satelites
    if (_posicion.SatellitesInSolutionValid &&
    _posicion.SatellitesInViewValid &&
    _posicion.SatelliteCountValid)
    {
    lstSatelites.Items.Clear();
    _posicion.GetSatellitesInView()
    .OrderByDescending(s => s.SignalStrength)
    .ToList().ForEach(s =>
    {
    var lvi =
    new ListViewItem(
    new[]
    {
    s.Id.ToString(),
    s.SignalStrength.ToString(),
    s.Azimuth.ToString(),
    s.Elevation.ToString()
    })
    {
    ImageIndex =
    _posicion.GetSatellitesInSolution()
    .Contains(s, new SatelliteComparer())
    ? 0
    : 1,
    Selected = true
    };
    lstSatelites.Items.Add(lvi);
    });

    str[0] += string.Format("Satelites vistos: {0}\n", _posicion.GetSatellitesInView().Length);
    str[0] += string.Format("Satelites en uso: {0}\n\n", _posicion.GetSatellitesInSolution().Length);


    }


    Fijémonos que hago uso de un IEqualityComparer para la clase Satellite de cara a poder identificar los que están usados dentro de la lista de vistos. El SatelliteComparer es:



    class SatelliteComparer : IEqualityComparer<Satellite>
    {
    public bool Equals(Satellite x, Satellite y)
    {

    if (ReferenceEquals(x, y)) return true;

    if (ReferenceEquals(x, null) ReferenceEquals(y, null))
    return false;

    return x.Id == y.Id && x.Id == y.Id;
    }

    #region IEqualityComparer<Satellite> Members

    public int GetHashCode(Satellite obj)
    {
    if (ReferenceEquals(obj, null)) return 0;

    int hashSat = obj.Id.ToString() == null ? 0 : obj.Id.GetHashCode();


    int hashSatId = obj.Id.GetHashCode();

    return hashSat ^ hashSatId;
    }

    #endregion
    }


    Por último controlamos los DOP, HDOP y VDOP. He jugado con varios paneles y labels de forma que represente una especie de ProgressBar vertical en color. Si la señal del DOP esta entre 1 y 3 el color del panel será verde; entre 4 y 8 amarillo y superior a 8 hasta 50 rojo, de forma que el código quedaría tal que así:



    //ststus
    if (_posicion.HorizontalDilutionOfPrecisionValid)
    {
    lHDOP.Text = _posicion.HorizontalDilutionOfPrecision.ToString();
    pHDOPValue.UpdatePanel(_posicion.HorizontalDilutionOfPrecision);
    str[0] += string.Format("HDOP:\t\t{0}\n", _posicion.HorizontalDilutionOfPrecision.ToString());
    }

    if (_posicion.VerticalDilutionOfPrecisionValid)
    {
    lVDOP.Text = _posicion.VerticalDilutionOfPrecision.ToString();
    pVDOPValue.UpdatePanel(_posicion.HorizontalDilutionOfPrecision);
    str[0] += string.Format("VDOP:\t\t{0}\n", _posicion.VerticalDilutionOfPrecision.ToString());
    }

    if (_posicion.PositionDilutionOfPrecisionValid)
    {
    lPODValue.Text = _posicion.PositionDilutionOfPrecision.ToString();
    pPODValue.UpdatePanel(_posicion.HorizontalDilutionOfPrecision);
    str[0] += string.Format("DOP:\t\t{0}\n\n", _posicion.PositionDilutionOfPrecision.ToString());
    }


    He creado un método extensor para la clase Panel llamado UpdatePanel al cual le paso el valor float de DOP para que configure el comportamiento del Panel como hemos descrito anteriormente. El método en cuestión es:



    public static class ExtensionMethods
    {
    public static void UpdatePanel(this Panel panel, float value)
    {
    panel.Size =
    new Size(panel.Width, 20 + (int)value * 2);
    if (value > 8 && value <= 50)
    panel.BackColor = Color.Red;
    else if (value > 3 && value <= 8)
    panel.BackColor = Color.Yellow;
    else if (value > 0 && value <= 3)
    panel.BackColor = Color.Green;
    }
    }


    En definitiva, con la gestión de información en labels y control de estado del GPS el método RefreshUI quedaría así:



    void RefreshUI(object sender, EventArgs args)
    {
    if (gps.Opened)
    {
    string[] str = {""};
    if (_dispositivo != null)
    {
    str[0] = string.Format("Info Dispositivo:\n{0} {1}, {2}\n\n", _dispositivo.FriendlyName, _dispositivo.ServiceState, _dispositivo.DeviceState);
    }

    if (_posicion != null)
    {

    if (_posicion.LatitudeValid)
    {
    str[0] += string.Format("Lat:\t{0}\n", _posicion.LatitudeInDegreesMinutesSeconds);
    }

    if (_posicion.LongitudeValid)
    {
    str[0] += string.Format("Lon:\t{0}\n", _posicion.LongitudeInDegreesMinutesSeconds);
    }

    if (_posicion.SpeedValid)
    str[0] += string.Format("Velocidad:\t\t{0} nudos\n", _posicion.Speed.ToString());

    if (_posicion.SeaLevelAltitudeValid)
    str[0] += string.Format("Altitud:\t\t{0} metros\n", _posicion.SeaLevelAltitude.ToString());

    if (_posicion.EllipsoidAltitudeValid)
    str[0] += string.Format("Altitud elipsoidal:\t{0} metros\n", _posicion.EllipsoidAltitude.ToString());

    if (_posicion.HeadingValid)
    str[0] += string.Format("Rumbo:\t\t{0} grados\n\n", _posicion.Heading.ToString());

    if (_posicion.TimeValid)
    {
    Text = _posicion.Time.ToString();
    }


    //satelites
    if (_posicion.SatellitesInSolutionValid &&
    _posicion.SatellitesInViewValid &&
    _posicion.SatelliteCountValid)
    {
    lstSatelites.Items.Clear();
    _posicion.GetSatellitesInView()
    .OrderByDescending(s => s.SignalStrength)
    .ToList().ForEach(s =>
    {
    var lvi =
    new ListViewItem(
    new[]
    {
    s.Id.ToString(),
    s.SignalStrength.ToString(),
    s.Azimuth.ToString(),
    s.Elevation.ToString()
    })
    {
    ImageIndex =
    _posicion.GetSatellitesInSolution()
    .Contains(s, new SatelliteComparer())
    ? 0
    : 1,
    Selected = true
    };
    lstSatelites.Items.Add(lvi);
    });

    str[0] += string.Format("Satelites vistos: {0}\n", _posicion.GetSatellitesInView().Length);
    str[0] += string.Format("Satelites en uso: {0}\n\n", _posicion.GetSatellitesInSolution().Length);


    }

    //ststus
    if (_posicion.HorizontalDilutionOfPrecisionValid)
    {
    lHDOP.Text = _posicion.HorizontalDilutionOfPrecision.ToString();
    pHDOPValue.UpdatePanel(_posicion.HorizontalDilutionOfPrecision);
    str[0] += string.Format("HDOP:\t\t{0}\n", _posicion.HorizontalDilutionOfPrecision.ToString());
    }

    if (_posicion.VerticalDilutionOfPrecisionValid)
    {
    lVDOP.Text = _posicion.VerticalDilutionOfPrecision.ToString();
    pVDOPValue.UpdatePanel(_posicion.HorizontalDilutionOfPrecision);
    str[0] += string.Format("VDOP:\t\t{0}\n", _posicion.VerticalDilutionOfPrecision.ToString());
    }

    if (_posicion.PositionDilutionOfPrecisionValid)
    {
    lPODValue.Text = _posicion.PositionDilutionOfPrecision.ToString();
    pPODValue.UpdatePanel(_posicion.HorizontalDilutionOfPrecision);
    str[0] += string.Format("DOP:\t\t{0}\n\n", _posicion.PositionDilutionOfPrecision.ToString());
    }

    lblPosition.Text = str[0];

    }
    }
    }


    Para hacer pruebas con el Fake GPS de la aplicación, podemos utilizar el conjunto de sentencias NMEA que viene con el FAKE GPS mediante dos archivos o podemos insertar una captura de un GPS real tomada por mí mismo y que podéis encontrar aquí. El archivo se llama outgps2.txt y solo tenéis que copiarlo a vuestro emulador, en la carpeta Fake GPS de archivos de programa, junto a los otros dos y configurarlo para que lo utilice.



    Si queréis probarlo en un PDA real, lo único que tenéis que hacer es configurar apropiadamente el GPS Intermediate Driver desde la configuración –> Settings.



    El código completo lo podéis obtener desde aquí, y se llama GPSStatus.



    Fuentes:


    Uso de GPS desde Windows Mobile – dotNetMania num .49



    http://www.isa.cie.uva.es/gps/GPSerrores.html



    http://www.kowoma.de/en/gps/errors.htm



    http://www.upv.es/satelite/trabajos/pracGrupo4/errors.htm



    http://msdn.microsoft.com/en-us/library/ms850332.aspx












  • 2 comentarios:

    Alberto Silva dijo...

    Hola Jose,
    There are some pictures missing

    José Miguel Torres dijo...

    Obrigado Alberto.

    This post has been written with Live Writer for Community Server Blog. I'm experiencing problems with format and other issues (as images references) whith some posts when trying to cross the posting between both platforms, so please, visit the original if you are insterested on in http://geeks.ms/blogs/jmtorres. Thank you again, and hope to see you in Seattle next month.