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

  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.

DOP

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.

Propiedad Descripción
EllipsoidAltitude Altitud elipsoidal (para saber que es la altitud elipsoidal ver Visualizando las altitudes)
EllipsoidAltitudeValid Indica si el valor de la altitud elipsoidal es valido/fiable.
Heading Rumbo en grados de 001-360
HeadingValid Indica si el valor del rumbo es valido/fiable.
HorizontalDilutionOfPrecision Dilución de precisión horizontal (1-50)
HorizontalDilutionOfPrecisionValid Indica si el valor del HDOP es valido/fiable.
Latitude Latitud en grados
LatitudeValid Indica si el valor de la latitud es valido/fiable.
LatitudeInDegreesMinutesSeconds Latitud en grados/minutos/segundos
Longitude Longitud en grados
LongitudeValid Indica si el valor de la longitud es valido/fiable.
LongitudeInDegreesMinutesSeconds Longitud en grados/minutos/segundos
PositionDilutionOfPrecision Dilución de precisión (1-50)
PositionDilutionOfPrecisionValid Indica si el valor del PDO es valido/fiable.
SatelliteCount Número de satélites
SatelliteCountValid Indica si el valor del recuento de satélites es valido/fiable.
SatellitesInSolution Número de satélites utilizados
SatellitesInSolutionValid Indica si el valor del recuento de satélites utilizado es valido/fiable.
SatellitesInViewCount Número de satélites vistos
SatellitesInViewCountValid Indica si el valor del recuento de satélites visibles es valido/fiable.
SeaLevelAltitude Altitud MSL a nivel del mar
SeaLevelAltitudeValid Indica si el valor de la altitud es valido/fiable.
Speed Velocidad en nudos
SpeedValid Indica si el valor de la velocidad es valido/fiable.
Time Hora/Fecha
TimeValid Indica si el valor de la fecha es valido/fiable.
VerticalDilutionOfPrecision Dilución de precisión vertical (1-50)
VerticalDilutionOfPrecisionValid Indica si el valor del VDOP es valido/fiable.
   
Métodos Descripció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:

 

Propiedad Descripcion  
Id Identificador del satélite.  
SignalStrengh Calidad de la señal/ruido (SNR) en decibelios.  
Azimuth Describe 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. app satelites
Elevation El á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:

     

    Valor Descripción
    1 Ideal
    2-3 Excelente. En este punto la fiabilidad de la posición es muy fiable.
    4-6 Buena. La fiabilidad es buena pero  con algún error (muy pequeño, sin embargo) de posicionamiento.
    7-8 Moderada. La señal debe ser revisada. El posicionamiento es aproximado pero no fiable.
    9-20 Pobre. Los posicionamientos deben ser descartados.
    21-50 Muy 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 SDKSamplesPocketPCCSGPS. 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:tt{0} nudosn", _posicion.Speed.ToString());
    
    if (_posicion.SeaLevelAltitudeValid)
        str[0] += string.Format("Altitud:tt{0} metrosn", _posicion.SeaLevelAltitude.ToString());
    
    if (_posicion.EllipsoidAltitudeValid)
        str[0] += string.Format("Altitud elipsoidal:t{0} metrosn", _posicion.EllipsoidAltitude.ToString());
    
    if (_posicion.HeadingValid)
        str[0] += string.Format("Rumbo:tt{0} gradosnn", _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}nn", _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:tt{0}n", _posicion.HorizontalDilutionOfPrecision.ToString());
    }
    
    if (_posicion.VerticalDilutionOfPrecisionValid)
    {
        lVDOP.Text = _posicion.VerticalDilutionOfPrecision.ToString();
        pVDOPValue.UpdatePanel(_posicion.HorizontalDilutionOfPrecision);
        str[0] += string.Format("VDOP:tt{0}n", _posicion.VerticalDilutionOfPrecision.ToString());
    }
    
    if (_posicion.PositionDilutionOfPrecisionValid)
    {
        lPODValue.Text = _posicion.PositionDilutionOfPrecision.ToString();
        pPODValue.UpdatePanel(_posicion.HorizontalDilutionOfPrecision);
        str[0] += string.Format("DOP:tt{0}nn", _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}nn", _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:tt{0} nudosn", _posicion.Speed.ToString());
    
                if (_posicion.SeaLevelAltitudeValid)
                    str[0] += string.Format("Altitud:tt{0} metrosn", _posicion.SeaLevelAltitude.ToString());
    
                if (_posicion.EllipsoidAltitudeValid)
                    str[0] += string.Format("Altitud elipsoidal:t{0} metrosn", _posicion.EllipsoidAltitude.ToString());
    
                if (_posicion.HeadingValid)
                    str[0] += string.Format("Rumbo:tt{0} gradosnn", _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}nn", _posicion.GetSatellitesInSolution().Length);
    
    
                }
    
                //ststus
                if (_posicion.HorizontalDilutionOfPrecisionValid)
                {
                    lHDOP.Text = _posicion.HorizontalDilutionOfPrecision.ToString();
                    pHDOPValue.UpdatePanel(_posicion.HorizontalDilutionOfPrecision);
                    str[0] += string.Format("HDOP:tt{0}n", _posicion.HorizontalDilutionOfPrecision.ToString());
                }
    
                if (_posicion.VerticalDilutionOfPrecisionValid)
                {
                    lVDOP.Text = _posicion.VerticalDilutionOfPrecision.ToString();
                    pVDOPValue.UpdatePanel(_posicion.HorizontalDilutionOfPrecision);
                    str[0] += string.Format("VDOP:tt{0}n", _posicion.VerticalDilutionOfPrecision.ToString());
                }
    
                if (_posicion.PositionDilutionOfPrecisionValid)
                {
                    lPODValue.Text = _posicion.PositionDilutionOfPrecision.ToString();
                    pPODValue.UpdatePanel(_posicion.HorizontalDilutionOfPrecision);
                    str[0] += string.Format("DOP:tt{0}nn", _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

     

  • 16 comentarios sobre “¿Cuán precisa es la señal de nuestros receptores GPS?”

    1. Elegante artículo apañero!!

      (En otro ya nos cuentas quienes son los graciosos que no ponen las direcciones prohibidas de las calles en los navegadores :P)

    2. @Maestro Alejandro, gracias!!!

      @Jose Antonio: esos son politicos, un especie rara pero, desgraciadamente, muy común ;-))

      @José Ignacio, tu eres Doctor en Física no?? son correctas las definiciones que hacen referencia a la Relatividad y el efecto Sagnac? me han llevado de culo,, jodido Einstein…

    3. Jajaja… Sí, pero en física de plasmas, no en relatividad. Y ¿no dijiste que obviásemos los pequeños problemas que tenía tu explicación? 😉

      Decirte que la explicación relativista está incompleta. Verás, hay 2 teorías de la relatividad: la especial y la general. La relatividad especial habla de una dilatación/contracción del tiempo entre 2 sistemas que se mueven uno con respecto al otro siempre con velocidad constante (es decir, ningún sistema tiene aceleración). Los satélites se mueven a una velocidad de 12.000 Km/h, que aunque es muy grande son sólo 3 Km/seg. La velocidad de la luz son de 300.000 Km/seg, por tanto esos satélites se mueven con un 0,001% de la velocidad de la luz.

      A estas velocidades la corrección relativista es despreciable, pero se puede medir: 7 microsegundos por día. Es decir, como el reloj en el satélite se mueve más rápido que uno en Tierra, el reloj del satélite se retrasa 7 microsegundos cada día. Es decir, el reloj del satélite va más lento que el de la Tierra.

      Sin embargo hay otra relatividad, que es la general. Ésta no habla de velocidades, sino de aceleraciones y habla por tanto de campos gravitatorios y cómo afectan estos al espacio y al tiempo.

      En la superficie de la Tierra, al ser el campo gravitatorio más intenso que en el espacio, la relatividad general dice que el tiempo transcurrirá más lentamente. De hecho, cuando la gravedad es gigantesca (como en el caso de un agujero negro, el tiempo casi se detiene).

      Como nosotros tenemos un reloj en el satélite que transmite la señal, podríamos ver que ese reloj del satélite va más rápido que un reloj gemelo que existiese en la superfie de la Tierra puesto que la gravedad allí arriba es menor. En concreto 46 microsegundos por día.

      Es decir, la relatividad especial dice que el reloj se atrasa 7 microsegundos por día y la general dice que se adelanta 46 microsegundos por día. ¿Resultado? Ambos efectos se suman (o más bien se restan) y el reloj se adelanta 39 microsegundos por día.

      Lo del efecto Sagnac es más fácil de lo que parece. Los satélites GPS están emitiendo señales a intervalos de tiempo regular. Como tú has dicho, los satélites se mueven con respecto a tí y van emitiendo señales. Un satélite emite una señal, pero tienes que tener en cuenta que tú te estás moviendo con respecto a esa señal.

      Imagina un sátélite que se acerca con respecto a tí y otro que se aleja. Ambos emiten una señal en el mismo instante y que en ese preciso momento en el que emiten la señal da la casualidad que estás a la misma distancia de uno que de otro. Ellos emiten la señal y en el intervalo de tiempo que transcurre hasta que recibes la señal tú te has acercado a un satélite y te has alejado de otro. Por tanto recibirás la señal de uno antes que la de otro cuando en realidad en el momento en el que se emitieron tú estabas a la misma distancia de uno que de otro. En el ecuador, esta corrección es de 200 microsegundos, así que como ves es más importante que incluso la corrección relativista.

      Estos microsegundos pueden significar poco, pero hay que tener en cuenta que estamos calculando retardos de una señal que se mueve a la velocidad de la luz. Cada microsegundo representa un error de 300 metros en la posición. Así que eso te da una idea del error que introduce cada una de estas correcciones.

    4. Impresionante!!. Muchisismas gracias José Ignacio!!

      Te explico:

      En algunos textos encontré muy poca información sobre el efecto Sagnac y uno en concreto decía que el efecto es menor que el realtivista, sin embargo tu explicación lo deja clarísimo.

      En cuanto al relativista he de reconocer que me cuesta entender, he leído muchas definiciones y me queda un poco lejos. Pensaba en modificar su exposición pero con el comentario que has dejado creo que queda más claro y será mucho más enriquecedor que si trato de explicarlo yo mismo.

      En cualquier caso, muchísimas gracias por tu ayuda,,,,te debo una 😉

    5. He estado leyendo tu artículo y en el tema de los errores atmosféticos tampoco es exactamente así. Verás, todos los GPSs hacen los cálculos suponiendo que la velocidad de la luz es de 300.000 Km/seg. No obstante, esa es la velocidad de la luz en el vacío. Cuando la luz atraviesa un medio (como es el aire o el agua), se ralentiza. Bueno, en realidad no se ralentiza, la luz siempre va a la misma velocidad, pero cuando traviesa un medio hay átomos que se interponen en su camino. Esos átomos absorben y reemiten fotones. Esa absorción/reemisión lleva un tiempo (que es de nanosegundos), pero eso hace que la luz parezca que va más lenta en ese medio.

      El valor que mide esa velocidad es el índice de refracción que es la relación entre la velocidad de la luz en el vacío y en el medio. El que haya más o menos vapor de agua hace variar el índice de refracción.

    6. Por cierto, tengo una pequeña cuestión sobre la plataforma de Windows Mobile (de verdad que es pequeña, tan sólo es si es posible o no hacerlo).

      He visto que la forma más común de posicionar un móvil es mediante un GPS. También hay móviles que permiten posicionarse mediante la potencia de señal que reciben de distintas celdas. Y también hay otro método que es que el operado es quien te posiciona (esto también es mediante la potencia en las celdas, pero has de mandar un mensaje de móvil registrándote en el servicio).

      La pregunta es si es posible posicionarte sin tener que registrarte con anterioridad y sin tener que tener ningún programa instalado en el móvil. Verás la idea es más o menos mediante el envío de un SMS. Ese SMS se enviaría mediante la celda más próxima a tí (o al menos una celda en un radio de un par de kilómetros). Al recibir ese mensaje ¿sería posible saber el ID de la celda desde la que se envió?

      Dudo mucho que en un mensaje de móvil a móvil (es decir, de abonado a abonado) el que recibe el mensaje también reciba el ID de la celda en la que se originó el mensaje (aunque bueno, todo es posible). Pero en un servicio esos de «mande nosqué al 5555» ¿el operador te envía ese cell ID para que los servicios de telemárketing puedan localizar la región desde la que se envió el mensaje?

    7. @José Ignacio. El envío de un SMS sin más no incluye información de celdas, pero siempre puedes hacerte tú una aplicación que capture la celda que te da mayor cobertura y enviar un SMS que incluya esa información. En el receptor deberás saber el formato del mensaje para extraer la información de la celda y el resto del mensaje, con la limitación de 160 caracteres. De todas formas, siempre que vayas a capturar la información de localización de una persona debería ser con consentimiento de la misma, si no, podrías tener problemas. Los servicios de localización del operador siempre pasan por dar permiso por parte del usuario.

    8. Gracias Alejandro por tu respuesta.

      La verdad que esa sería una posible solución, pero habría que instalar «algo» en el teléfono que envía el mensaje y por tanto requeriría un paso previo que no sería aceptable para usuarios «anónimos».

      Tal y como dices, los servicios que ofrecen las operadores de localización necesitan el permiso del usuario, pero creo que esos van en función de las celdas en las que te encuentras registrado (es decir, no tienes que mandar ningún SMS, símplemente con tener el teléfono encendido saben dónde estás).

      Pero si te fijas, en los concursos televisivos (tipo OT y esas cosas), saben perfectamente el número de mensajes que se envía desde una determinada región. Y a eso es a lo que voy.

      El objetivo sería similar: que el departamento de márketing pueda conocer el impacto que tiene una determinada campaña desde una determinada región sin necesidad que deban saber mucho más. Para eso, obviamente se necesitaría conocer desde qué celda se envían los mensajes.

      Dado que en los concursos televisivos saben eso, supongo que la contratación de un 5555 o un número de esos implica que te envíen «algo» más que el propio mensaje.

      He intentado ver algo en la Web de algunos operadores y no hay nada específico sobre la contratación de números especiales de ese tipo, así que no se si realmente eso «va de serie» o hace falta algún acuerdo más específico con el operador.

      Desde el punto de vista legal, no se si servirá el aclarar previamente que al enviar ese mensaje se registrará la zona desde la que se envía ese mensaje únicamente con una finalidad estadística. Desde luego la LOPD no dice nada sobre que haya que proteger datos estadísticos, es decir, la zona de Sevilla Norte tiene x mensajes, etc… Así que (desde mi poco entendimiento legal) entiendo que ni siquiera haría falta especificarlo.

    9. Hola otra vez,
      Hás comprobado con equipos Windows Mobile que tengam la carpeta ‘Program Files’ traducida – en Portugues, Programas – , que el FakeGPS no marcha? Hay que crear una carpeta llamada Program Files y copiar los ficheros de FakeGPS para essa carpeta.

      Muy buón artículo!

    10. Hola Alberto,

      Si, de hecho sucede lo mismo con las carpetas en Español. Esto es debido a que Fake GPS va a buscar los archivos txt de sequencias NMEA en la carpeta fija «Program Files», no a través de la variable de sistema %PROGRAM_FILES%.

      No recuerdo exactamente dónde (en qué Blog de msdn) hablaban sobre ello gente de Microsoft. Esperemos que lo tengan en cuenta y lo solucionen en proximas versiones,,

      Obrigado Alberto!!

    11. How to pick my wife?
      «How can I do?» «Young people who wants to marry his friend said:» Every girl I brought home, my mother does not like. «» This easy to handle. «His friend said:» You just need to find someone like your mother on the line. «» Already tried, «he said:» But my father did not like it. «

    Deja un comentario

    Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *