Lost negative sign in gps latitude and longitude in NMEA

This forum is dedicated to software development related to MultiWii.
It is not the right place to submit a setup problem.
Software download
Post Reply
User avatar
baco
Posts: 13
Joined: Thu Mar 12, 2015 11:47 pm

Lost negative sign in gps latitude and longitude in NMEA

Post by baco »

Sometimes saw that on the map made me jump the gps and after analyzing it for a few days, I noticed that is because if I'm in an area where both latitude and longitude have the negative sign, this is lost occasionally. I thought that was my MTK3329 GPS module, but after several tests, it works correctly, that I decided to remove my copter gps module and manually inject a gps signal.

To my surprise, still doing the same, so I'm pretty sure the problem comes MultiWii software.

I am researching into the software and so far I have not found where it loses the negative sign.

If anyone can help me, thanks. Do not think it's the only one who has thought about this.

-------------------------------------------------------------------------------------------------------------

En ocasiones veia que en el mapa me hacia un salto el gps y despues de analizarlo durante unos cuantos dias, he observado que es debido a que si estoy en una zona donde tanto la latitud como la longitud tengan el signo negativo, este se pierde de vez en cuando. Yo creia que era de mi modulo Gps MTK3329, pero despues de varias comprobaciones, este funciona correctamente, por que que decidi retirar el modulo gps de mi coptero e inyectar manualmente una señal gps.

Para mi sorpresa, sigue haciendo lo mismo, por lo cual estoy muy seguro de que el problema viene del software del multiwii.

Estoy investigando dentro del propio software y de momento no he encontrado donde pierde el signo negativo.

Si alguien me puede ayudar, gracias. No creo que sea el unico que le ha ocurrido esto.

User avatar
baco
Posts: 13
Joined: Thu Mar 12, 2015 11:47 pm

Re: Lost negative sign in gps latitude and longitude in NMEA

Post by baco »

¡¡¡SOLVED!!!

This error is given by the MultiWii software version 2.2, 2.3 and 2.4, using a GPS with NMEA protocol. See if correct it in future updates.

This is the part of the code which breaks down the GGA frame sent by the GPS NMEA protocol module as:


About line 1030 of the file GPS.cpp

Code: Select all

bool GPS_newFrame(uint8_t c) {
  uint8_t frameOK = 0;
  static uint8_t param = 0, offset = 0, parity = 0;
  static char string[15];
  static uint8_t checksum_param, frame = 0;

  if (c == '$') {
    param = 0; offset = 0; parity = 0;
  } else if (c == ',' || c == '*') {
    string[offset] = 0;
    if (param == 0) { //frame identification
      frame = 0;
      if (string[0] == 'G' && string[1] == 'P' && string[2] == 'G' && string[3] == 'G' && string[4] == 'A') frame = FRAME_GGA;
      if (string[0] == 'G' && string[1] == 'P' && string[2] == 'R' && string[3] == 'M' && string[4] == 'C') frame = FRAME_RMC;
    } else if (frame == FRAME_GGA) {
      if      (param == 2)                     {GPS_coord[LAT] = GPS_coord_to_degrees(string);}
      else if (param == 3 && string[0] == 'S') GPS_coord[LAT] = -GPS_coord[LAT];
      else if (param == 4)                     {GPS_coord[LON] = GPS_coord_to_degrees(string);}
      else if (param == 5 && string[0] == 'W') GPS_coord[LON] = -GPS_coord[LON];
      else if (param == 6)                     {f.GPS_FIX = (string[0]  > '0');}
      else if (param == 7)                     {GPS_numSat = grab_fields(string,0);}
      else if (param == 9)                     {GPS_altitude = grab_fields(string,0);}  // altitude in meters added by Mis
    } else if (frame == FRAME_RMC) {
      if      (param == 7)                     {GPS_speed = ((uint32_t)grab_fields(string,1)*5144L)/1000L;}  //gps speed in cm/s will be used for navigation
      else if (param == 8)                     {GPS_ground_course = grab_fields(string,1); }                 //ground course deg*10
    }
    param++; offset = 0;
    if (c == '*') checksum_param=1;
    else parity ^= c;
  } else if (c == '\r' || c == '\n') {
    if (checksum_param) { //parity checksum
      uint8_t checksum = hex_c(string[0]);
      checksum <<= 4;
      checksum += hex_c(string[1]);
      if (checksum == parity) frameOK = 1;
    }
    checksum_param=0;
  } else {
     if (offset < 15) string[offset++] = c;
     if (!checksum_param) parity ^= c;
  }
  return frameOK && (frame==FRAME_GGA);
}
#endif //NMEA



This code reads what makes GGA frame in several steps, which each is read in a cycle other than the processor. By using the command "else if", arriving at Step 2, the coordinate of the latitude of GPS module is read, but do not read if your sign is positive or negative until the next cycle, so for an entire cycle we will to give a misreading of our GPS position. This happens also with gps length.

I made a small modification to the MultiWii code so that it does not enter the variable that stores the data (GPS_coord [LAT] and GPS_coord [LON]) until you have also read the sign:

Latitude
N=Positive
S=Negative

Longitude
E=Positive
W=Negative.


Code: Select all

bool GPS_newFrame(uint8_t c) {
  uint8_t frameOK = 0;
  static uint8_t param = 0, offset = 0, parity = 0;
  static char string[15];
  static uint8_t checksum_param, frame = 0;

  static int32_t LAT_TEMP;
  static int32_t LON_TEMP;

  if (c == '$') {
    param = 0; offset = 0; parity = 0;
  } else if (c == ',' || c == '*') {
    string[offset] = 0;
    if (param == 0) { //frame identification
      frame = 0;
      if (string[0] == 'G' && string[1] == 'P' && string[2] == 'G' && string[3] == 'G' && string[4] == 'A') frame = FRAME_GGA;
      if (string[0] == 'G' && string[1] == 'P' && string[2] == 'R' && string[3] == 'M' && string[4] == 'C') frame = FRAME_RMC;
    } else if (frame == FRAME_GGA) {
      if      (param == 2)                     {LAT_TEMP = GPS_coord_to_degrees(string);}
      else if (param == 3)                     { if (string[0] == 'S') {GPS_coord[LAT] = LAT_TEMP * (-1);} else {GPS_coord[LAT] = LAT_TEMP;}}
      else if (param == 4)                     {LON_TEMP = GPS_coord_to_degrees(string);}
      else if (param == 5)                     { if (string[0] == 'W') {GPS_coord[LON] = LON_TEMP * (-1);} else {GPS_coord[LON] = LON_TEMP;}}
      else if (param == 6)                     {f.GPS_FIX = (string[0]  > '0');}
      else if (param == 7)                     {GPS_numSat = grab_fields(string,0);}
      else if (param == 9)                     {GPS_altitude = grab_fields(string,0);}  // altitude in meters added by Mis
    } else if (frame == FRAME_RMC) {
      if      (param == 7)                     {GPS_speed = ((uint32_t)grab_fields(string,1)*5144L)/1000L;}  //velocidad gps en cm/s que seran usados para la navegacion
      else if (param == 8)                     {GPS_ground_course = grab_fields(string,1); }                 //orientacion en tierra deg*10
    }
    param++; offset = 0;
    if (c == '*') checksum_param=1;
    else parity ^= c;
  } else if (c == '\r' || c == '\n') {
    if (checksum_param) { //parity checksum
      uint8_t checksum = hex_c(string[0]);
      checksum <<= 4;
      checksum += hex_c(string[1]);
      if (checksum == parity) frameOK = 1;
    }
    checksum_param=0;
  } else {
     if (offset < 15) string[offset++] = c;
     if (!checksum_param) parity ^= c;
  }
  return frameOK && (frame==FRAME_GGA);
}
#endif //NMEA


I have not found much information about this error, which I found odd that anyone what happened, even though many people use GPS to Ublox protocol instead of NMEA, since a gps module that has been widely used is the MTK3329 which is what I have which uses the NMEA protocol.

I hope it's helpful.

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

¡¡¡SOLUCIONADO!!!

Este fallo lo daba el propio software de MultiWii tanto en la version 2.2, 2.3 y 2.4, al usar un Gps con el protocolo NMEA. A ver si en posteriores actualizaciones lo corrigen.

Esta es la parte del código donde desglosa la trama GGA emitida por el módulo gps según el protocolo NMEA:


Aproximadamente en la línea 1030 del archivo GPS.cpp

Code: Select all

bool GPS_newFrame(uint8_t c) {
  uint8_t frameOK = 0;
  static uint8_t param = 0, offset = 0, parity = 0;
  static char string[15];
  static uint8_t checksum_param, frame = 0;

  if (c == '$') {
    param = 0; offset = 0; parity = 0;
  } else if (c == ',' || c == '*') {
    string[offset] = 0;
    if (param == 0) { //frame identification
      frame = 0;
      if (string[0] == 'G' && string[1] == 'P' && string[2] == 'G' && string[3] == 'G' && string[4] == 'A') frame = FRAME_GGA;
      if (string[0] == 'G' && string[1] == 'P' && string[2] == 'R' && string[3] == 'M' && string[4] == 'C') frame = FRAME_RMC;
    } else if (frame == FRAME_GGA) {
      if      (param == 2)                     {GPS_coord[LAT] = GPS_coord_to_degrees(string);}
      else if (param == 3 && string[0] == 'S') GPS_coord[LAT] = -GPS_coord[LAT];
      else if (param == 4)                     {GPS_coord[LON] = GPS_coord_to_degrees(string);}
      else if (param == 5 && string[0] == 'W') GPS_coord[LON] = -GPS_coord[LON];
      else if (param == 6)                     {f.GPS_FIX = (string[0]  > '0');}
      else if (param == 7)                     {GPS_numSat = grab_fields(string,0);}
      else if (param == 9)                     {GPS_altitude = grab_fields(string,0);}  // altitude in meters added by Mis
    } else if (frame == FRAME_RMC) {
      if      (param == 7)                     {GPS_speed = ((uint32_t)grab_fields(string,1)*5144L)/1000L;}  //gps speed in cm/s will be used for navigation
      else if (param == 8)                     {GPS_ground_course = grab_fields(string,1); }                 //ground course deg*10
    }
    param++; offset = 0;
    if (c == '*') checksum_param=1;
    else parity ^= c;
  } else if (c == '\r' || c == '\n') {
    if (checksum_param) { //parity checksum
      uint8_t checksum = hex_c(string[0]);
      checksum <<= 4;
      checksum += hex_c(string[1]);
      if (checksum == parity) frameOK = 1;
    }
    checksum_param=0;
  } else {
     if (offset < 15) string[offset++] = c;
     if (!checksum_param) parity ^= c;
  }
  return frameOK && (frame==FRAME_GGA);
}
#endif //NMEA



Este código lo que hace lee la trama GGA en varios pasos, los cuales, cada uno es leído en un ciclo distinto del procesador. Al usar el comando "else if", al llegar al paso 2, se lee la coordenada de la Latitud del módulo Gps, pero no lee si su signo es positivo o negativo hasta el siguiente ciclo, por lo que durante un ciclo entero nos va a dar una lectura errónea de nuestra posición Gps. Esto ocurre igualmente con la Longitud del gps.

He hecho una pequeña modificación en el código de MultiWii, para que no se introduzca en la variable que almacena dichos datos (GPS_coord[LAT] y GPS_coord[LON]) hasta que no se ha leído también el signo:

Latitud
N=Positivo
S=Negativo

Longitud
E=Positivo
W=Negativo.


Code: Select all

bool GPS_newFrame(uint8_t c) {
  uint8_t frameOK = 0;
  static uint8_t param = 0, offset = 0, parity = 0;
  static char string[15];
  static uint8_t checksum_param, frame = 0;

  static int32_t LAT_TEMP;
  static int32_t LON_TEMP;

  if (c == '$') {
    param = 0; offset = 0; parity = 0;
  } else if (c == ',' || c == '*') {
    string[offset] = 0;
    if (param == 0) { //frame identification
      frame = 0;
      if (string[0] == 'G' && string[1] == 'P' && string[2] == 'G' && string[3] == 'G' && string[4] == 'A') frame = FRAME_GGA;
      if (string[0] == 'G' && string[1] == 'P' && string[2] == 'R' && string[3] == 'M' && string[4] == 'C') frame = FRAME_RMC;
    } else if (frame == FRAME_GGA) {
      if      (param == 2)                     {LAT_TEMP = GPS_coord_to_degrees(string);}
      else if (param == 3)                     { if (string[0] == 'S') {GPS_coord[LAT] = LAT_TEMP * (-1);} else {GPS_coord[LAT] = LAT_TEMP;}}
      else if (param == 4)                     {LON_TEMP = GPS_coord_to_degrees(string);}
      else if (param == 5)                     { if (string[0] == 'W') {GPS_coord[LON] = LON_TEMP * (-1);} else {GPS_coord[LON] = LON_TEMP;}}
      else if (param == 6)                     {f.GPS_FIX = (string[0]  > '0');}
      else if (param == 7)                     {GPS_numSat = grab_fields(string,0);}
      else if (param == 9)                     {GPS_altitude = grab_fields(string,0);}  // altitude in meters added by Mis
    } else if (frame == FRAME_RMC) {
      if      (param == 7)                     {GPS_speed = ((uint32_t)grab_fields(string,1)*5144L)/1000L;}  //velocidad gps en cm/s que seran usados para la navegacion
      else if (param == 8)                     {GPS_ground_course = grab_fields(string,1); }                 //orientacion en tierra deg*10
    }
    param++; offset = 0;
    if (c == '*') checksum_param=1;
    else parity ^= c;
  } else if (c == '\r' || c == '\n') {
    if (checksum_param) { //parity checksum
      uint8_t checksum = hex_c(string[0]);
      checksum <<= 4;
      checksum += hex_c(string[1]);
      if (checksum == parity) frameOK = 1;
    }
    checksum_param=0;
  } else {
     if (offset < 15) string[offset++] = c;
     if (!checksum_param) parity ^= c;
  }
  return frameOK && (frame==FRAME_GGA);
}
#endif //NMEA


No he encontrado mucha información respecto a este fallo, cosa que me ha parecido raro que a nadie lo ocurriera, a pesar de que mucha gente utiliza Gps con protocolo Ublox en vez de NMEA, ya que un modulo gps que se ha utilizado mucho es el MTK3329 que es el que yo tengo el cual usa el protocolo NMEA.

Espero que sea de gran ayuda.

User avatar
Plüschi
Posts: 433
Joined: Thu Feb 21, 2013 6:09 am

Re: Lost negative sign in gps latitude and longitude in NMEA

Post by Plüschi »

Baco please check if i understand it:

The sign of the gps coords CAN be wrong for 4 cycles using NMEA.
It WILL be wrong if coords are negative and the gps parser is interrupted between reading coord and reading N-S or W-E. The error will correct as soon as N-S or E-W is parsed. Means we will occasionally have totally wrong gps coords for about 12ms.

But doesent the "frame_ok" parameter solve this issue? If you use gps data ONLY if "frame_ok = true" there should be no error.

User avatar
baco
Posts: 13
Joined: Thu Mar 12, 2015 11:47 pm

Re: Lost negative sign in gps latitude and longitude in NMEA

Post by baco »

Please. Write well and without abbreviations. this is not my language and I can not understand correctly as also cost me write in another language so that more people understand it. Thanks

These jumps (You can see in the pictures) performed them quite often and were clearly visible on the map of WIN-GUI or EZ-GUI.

In some forum I read that because of this error, change the MKT gps module with one of ublox to not happen to them again. Since I've made the change, it has not been seen doing any jumping more.

The "FrameOk" i think that is to verify the checksum

--------------------------------------------------------------------------------------------------

Por Favor. Escribir bien y sin abreviaturas. Esta no es mi lengua y no la entiendo correctamente, como también me cuesta escribir en otro idioma para que más gente lo entienda. gracias

Estos saltos (Se pueden apreciar en las imágenes) los realizaba bastante a menudo y eran claramente apreciables en el mapa del WIN-GUI o de EZ-GUI.

En algun foro he leido que debido a este error, cambian el módulo gps MKT por uno de ublox para que no les vuelva a ocurrir. Desde que le he hecho la modificación, no ha vuelto ha hacer ningun salto mas.

El "FrameOk" creo que es para la comprobación del checksum

Image .............. Image

User avatar
baco
Posts: 13
Joined: Thu Mar 12, 2015 11:47 pm

Re: Lost negative sign in gps latitude and longitude in NMEA

Post by baco »

According to my latest tests, MultiWii software ignores the checksum of the frames sent by NMEA GPS modules.

I've been manually injecting a frame for gps port and manually change values on the latitude and the longitude, without changing the checksum, and these are reflected in the MultiWii_Conf, which should not happen and that would not be valid frames.

-------------------------------------------------------------

Según mis ultimas pruebas, el software de MultiWii no tiene en cuenta el checksum del las tramas emitidas por los módulos gps NMEA.

He estado inyectando manualmente unas tramas por el puerto del gps, y cambio valores manualmente en la latitud y en la longitud, sin cambiar el checksum, y estos se reflejan en el MultiWii_Conf, los cuales no deberia ocurrir ya que no serian tramas validas.

User avatar
baco
Posts: 13
Joined: Thu Mar 12, 2015 11:47 pm

Re: Lost negative sign in gps latitude and longitude in NMEA

Post by baco »

According to my latest tests, MultiWii software ignores the checksum of the frames sent by NMEA GPS modules.

I've been manually injecting a frame for gps port and manually change values on the latitude and the longitude, without changing the checksum, and these are reflected in the MultiWii_Conf, which should not happen and that would not be valid frames.

-------------------------------------------------------------

Según mis ultimas pruebas, el software de MultiWii no tiene en cuenta el checksum de las tramas emitidas por los módulos gps NMEA.

He estado inyectando manualmente unas tramas por el puerto del gps, y cambio valores manualmente en la latitud y en la longitud, sin cambiar el checksum, y estos se reflejan en el MultiWii_Conf, los cuales no deberia ocurrir ya que no serian tramas validas.

User avatar
Plüschi
Posts: 433
Joined: Thu Feb 21, 2013 6:09 am

Re: Lost negative sign in gps latitude and longitude in NMEA

Post by Plüschi »

baco wrote:MultiWii software ignores the checksum of the frames sent by NMEA GPS modules


This is true for the data sent to multiwii_conf. Its not true for the GPS calculations.

I dont think the devs here care, they are busy chasing another femtosecond :)

User avatar
shikra
Posts: 783
Joined: Wed Mar 30, 2011 7:58 pm

Re: Lost negative sign in gps latitude and longitude in NMEA

Post by shikra »

Not sure if its related but I was having a look at some of the GPS parsing a couple of weeks ago.

I noticed some random unexpected values which should not have been there as was sending it in through a simulator.
Will be going back to take a look once current project has finished. See if it was a simulator error or the GPS parsing

User avatar
baco
Posts: 13
Joined: Thu Mar 12, 2015 11:47 pm

Re: Lost negative sign in gps latitude and longitude in NMEA

Post by baco »

Then we can bring erroneous data telemetry.

I find it strange because if you use the checksum calculations to verify that data is correctly received gps module, the work would be done and no would cost nothing to send to multiwii_conf these verified data.

I is not know much about programming, but I try to defend a little, and something that other'm already getting.

I eagerly await your review.

Thank you very much.

-----------------------------------------------------------------------------

Entonces nos pueden llegar datos de telemetría erróneos.

Me parece raro ya que, si usa el checksum en los cálculos para comprobar que se reciben correctamente los datos del modulo gps, el trabajo ya estaría hecho y no costaría nada que enviase al multiwii_conf estos datos verificados.

Yo no es que entienda mucho de programación, pero me intento defender un poco, y alguna cosa que otra ya voy consiguiendo.

Esperaré impacientemente vuestra revisión.

Muchas gracias.

User avatar
baco
Posts: 13
Joined: Thu Mar 12, 2015 11:47 pm

Re: Lost negative sign in gps latitude and longitude in NMEA

Post by baco »

Then we can bring erroneous data telemetry.

I find it strange because if you use the checksum calculations to verify that data is correctly received gps module, the work would be done and no would cost nothing to send to multiwii_conf these verified data.

I is not know much about programming, but I try to defend a little, and something that other'm already getting.

I eagerly await your review.

Thank you very much.

-----------------------------------------------------------------------------

Entonces nos pueden llegar datos de telemetría erróneos.

Me parece raro ya que, si usa el checksum en los cálculos para comprobar que se reciben correctamente los datos del modulo gps, el trabajo ya estaría hecho y no costaría nada que enviase al multiwii_conf estos datos verificados.

Yo no es que entienda mucho de programación, pero me intento defender un poco, y alguna cosa que otra ya voy consiguiendo.

Esperaré impacientemente vuestra revisión.

Muchas gracias.

Alexinparis
Posts: 1630
Joined: Wed Jan 19, 2011 9:07 pm

Re: Lost negative sign in gps latitude and longitude in NMEA

Post by Alexinparis »

Hi baco,

You are right, the current parser could lead to the effects you mention.
The problem: data are updated immediately with the current NMEA parser, and some data like coordinates need 2 parsed info to be fully trusted.
Hopefully, as Plüschi says, there is no impact on navigation computation because a valid checksum is needed for each frame.
(in fact, not totally true if GPS update rate is very high and the beginning of a new frame is parsed after a valid checksum, but not a problem with 10Hz because nav computation will occur before)
The problem is only in GUI or in telemetry display

In fact, the whole parser should be rewritten to put tmp data in a sctruct like the ublox one.

User avatar
baco
Posts: 13
Joined: Thu Mar 12, 2015 11:47 pm

Re: Lost negative sign in gps latitude and longitude in NMEA

Post by baco »

Thanks Alexparis. Then these jumps you see in the GUI does not affect the navigation of the cuadcopter?

Have a problem the solution I have given, wait two cycles to validate the latitude and longitude?

In the GUI is not very nice to see those jumps, and thought that if activated the GPS_HOLD the cuadcopter if I could get out of control.

---------------------------------------------------------------------------------

Gracias Alexinparis. Entonces estos saltos que se ven en el GUI no afectan a la navegación del cuadcoptero?

¿Tiene algun problema la solución que yo he dado, esperar dos ciclos para validar la latitud y la longitud?

En el GUI no es muy bonito ver esos saltos, y pensaba que si activaba el GPS_HOLD el cuadcoptero si podia descontrolar.
Last edited by baco on Wed Apr 08, 2015 6:21 pm, edited 2 times in total.

User avatar
Plüschi
Posts: 433
Joined: Thu Feb 21, 2013 6:09 am

Re: Lost negative sign in gps latitude and longitude in NMEA

Post by Plüschi »

Alexinparis wrote:rewritten to put tmp data in a sctruct like the ublox one.


Right, buffer not only long and lat, but alt, numsat etc as well.
Since Baco did discover this i think he should do the fix and get proper credits.

Post Reply