Autor Tema: Hacer un cuentakilómetros con un modulo gps neo6mv  (Leído 3481 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado remi04

  • PIC24F
  • *****
  • Mensajes: 657
Hacer un cuentakilómetros con un modulo gps neo6mv
« en: 11 de Agosto de 2017, 12:48:56 »
Hola a todos. Me hice una función en ccs utilizando cosenos y pitágora que dándole las coordenadas grados,minutos, segundos de dos puntos distintos me determina qué distancia en kilómetros hay entre esos dos puntos.  Esa me funciona bastante bien, por ejemplo, de Cádiz a Nueva York me da una diferencia de 12 Km respecto a lo que dice Google Earth que hay entre esos dos puntos, en distancias cortas lo clava.

  Para hacer un medidor de distancia recorrida (cuentakilómetros) se me ha ocurrido hacer una función que cuando la velocidad sea superior a cero vaya marcando puntos (grabados en distintas variables) y midiendo distancia entre ellas, de A - B luego de B a C, luego de C a D y así sucesivamente, el resultado de cada medición se va sumando a una variable que se llama distancia.

  En principio funciona, pero acumula error. Cada 100 Km medidos por otro gps o por el coche, mi función mide 129 Kmts.

  ¿ Hay otra forma mejor de poder hacerlo??

   

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Hacer un cuentakilómetros con un modulo gps neo6mv
« Respuesta #1 en: 11 de Agosto de 2017, 15:07:18 »
Si uno pudiera definir el punto de partida entonces seria todo mas simple. No me imagino un GPS por ejemplo que cuando pares reinicie todo kilometraje.

Sino que al encenderlo, ya sea de forma automatica apenas recibe la primer coordenada, o de forma manual esperando la entrada del usuario. Se setee el punto inicial.

El mayor problema que tendrias es que no es un cuenta kilometros per se, te va a dar la distancia entre 2 puntos, pero no la cantidad de kilometros recorridos. Un ejemplo muy burdo seria si me realizo 100 vueltas a una manzana(cuadra o como se llame) la distancia entre los 2 puntos es 0 pero las 100 vueltas las di. Se podria considerar vectores cuando cambie el rumbo en mas de 45 grados. Aunque eso tampoco quita el error. Sino buscar alguna alternativa que posea el vehiculo para poder medir el kilometraje.

Siempre buscando simplificar al maximo el procedimiento para obtener la cantidad de kilometros.
« Última modificación: 11 de Agosto de 2017, 15:13:34 por KILLERJC »

Desconectado remi04

  • PIC24F
  • *****
  • Mensajes: 657
Re:Hacer un cuentakilómetros con un modulo gps neo6mv
« Respuesta #2 en: 11 de Agosto de 2017, 16:06:57 »
Claro, a cero lo pongo yo, la medicion se podria hacer por ejemplo punto a punto. Si yo por ejemplo recorro 100 km a 100 kmh y cada segundo leo posicion y pongo el punto en el mapa "a modo de ejemplo" en esos 100 km tendria 3600 puntos. Se habria ido midiendo la distancia entre cada uno de ellos con el siguiente y acumulando la suma en una variable. La logica me dice que deberia poderse hacer asi.

  Lo de medir con otro sensor es inviable. Se trata de un paramotor. Parapente propulsado por motor. No puedo poner nada que no sea un gps para registrar la distancia recorrida.

  M pregunto como lo haran los gps por ejemplo, un Garmin.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Hacer un cuentakilómetros con un modulo gps neo6mv
« Respuesta #3 en: 11 de Agosto de 2017, 16:20:00 »
Tal ves tambien esto te pueda servir:

https://electronics.stackexchange.com/questions/195200/calculate-distance-travelled-by-vehicle-using-knots-of-nmea-data

Habla de calcular la distancia recorrida sabiendo cuando el tiempo entre cada toma de coordenadas, con sus desventajas.

Y realmente ya no se que mas decirte.

Desconectado remi04

  • PIC24F
  • *****
  • Mensajes: 657
Re:Hacer un cuentakilómetros con un modulo gps neo6mv
« Respuesta #4 en: 12 de Agosto de 2017, 05:00:13 »
Gracias por el enlace KillerJc.  Según el post parece que estoy bien encaminado. Te dejo la función del calculo de distancia que he implementado yo y que me funciona bastante bien por si le quieres hechar un vistazo. Mas abajo te pongo también la función para el cuentakilómetros, que en este caso es lo que no me está midiendo bien.

Código: C
  1. float distance(a1,a2,a3,a4,a5,b1,b2,b3,b4,b5,c1,c2,c3,c4,c5,d1,d2,d3,d4,d5) {   // calculo de distancias a partir de coordenadas.
  2.                                                                                
  3.         /* a1,a2,a3,a4,a5 = Latitud origen    a1-Grados, a2-minutos, a3-segundos, a4-mantisa de segundos, a5-(0 = Sur, 1= Norte)          
  4.            b1,b2,b3,b4,b5 = Longitud origen   b1-grados,b2- minutos, b3-segundos, b4-mantisa de segundos  b5-(0 = Oeste 1 = este)
  5.            c1,c2,c3,c4,c5 = Latitud destino   c1-Grados,c2- minutos, c3-segundos, c4-mantisa de segundos  c5-(0 = Sur, 1= Norte)
  6.            d1,d2,d3,d4,d5 = Longitud destino  d- 1grados,d2- minutos, d3-segundos,d4- mantisa de segundos d5-(0 = Oeste 1 = este)
  7.          */
  8.        
  9.         // lo primero que hacemos es unir las variables (segundos y mantisa de segundos) en un float
  10.         float lat_or_sec =  a3 + ((float)a4/100);  // creamos nueva variable (latitud origen segundos)
  11.             // sumo a los segundos, las decimas de segundos dividido entre 100. Si por ejemplo los segundos son = 13, y las mantisa es 20, esto rersulta: 13,20  
  12.         // hacemos lo mismo con las de longitud, y con las dos del destino.
  13.         float long_or_sec = b3 + ((float)b4/100);   // longitus del origen
  14.         float lat_des_sec = c3 + ((float)c4/100);  // latitud del destino        
  15.         float long_des_sec = d3 + ((float)d4/100);   // longitud del destino
  16.        
  17.        
  18.        
  19.         // ahora tenemos las coordenadas en formato grados, minutos y segundos, las vamos a convertir a grados sexageximales.
  20.         float orlatdeg = a1 + ((float)a2/60) + (lat_or_sec/3600);           // creamos variable para latitud de origen
  21.                                                     // sumamos a los grados, los minutos divididos entre 60 y los segundos divididos entre 3600.
  22.                                                                    
  23.         // hacemos lo mismo con la longitud y con las del destino
  24.         float orlongdeg = b1 + ((float)b2/60) + (long_or_sec/3600);                                               // longitud del origen
  25.         float deslatdeg = c1 + ((float)c2/60) + (lat_des_sec/3600);                                              // latitud del destino          
  26.         float deslongdeg = d1 + ((float)d2/60) + (long_des_sec/3600);                                               // longitud del destino
  27.                        
  28.         // ya tenemos las coordenadas en grados decimales.  ( orlatdeg y orlongdec son la latitud y longitud del origen,  deslatdeg y deslongdeg son latitud y longitud del destino)
  29.        
  30.         // Ahora vamos a calcular la distancia que separa ambos puntos (origen y destino) en el meridiano, es decir, la distancia en grados de las latitudes de ambos puntos. Para ello, tomaremos en cuenta la posicion Norte o Sur de ambos
  31.         // puntos.   Si los dos tienen latitud norte:
  32.        
  33.         float difdeg;                     // cargaremos aqui la diferencia en grados que separan origen y destino en grados.
  34.         if (a5 == c5) {         // si la latitud del origen y de destino están en el mismo hemisferio
  35.            difdeg = orlatdeg - deslatdeg;       // hallamos la diferencia entre ambas latitudes.
  36.            if (difdeg < 0) difdeg = difdeg * (-1);     // si nos da negativo el resultado lo invertimos para que siempre sea positivo ya que no nos interesa saber cual está arriba y cual abajo, solo la distancia que los serpara.
  37.            
  38.             }
  39.         else {                      // si las latitudes estan en distintos hemisferios entonces tenemos que sumar ambas latitudes para obtener la distancia total entre origen y destino
  40.            difdeg = orlatdeg + deslatdeg;
  41.            
  42.         }
  43.        
  44.         // ya tenemos hallada la diferencia en grados que separan origen y destino en meridiano.
  45.         // ahora lo vamos a pasar a kilómetros, para ello, tenemos la longitud total de la circunsferencia de un meridiano
  46.         // esa longitud meridiano es: 39941,58068 Kmts.
  47.        
  48.         // si dividimos esa distancia entre los 360º que tiene una circunsferencia tendremos la distancia por grado. Luego multiplicaremos por la distancia en grados obtenida arriba y asi obtendremos la distancia en Kmts
  49.         // que separan ambas latitudes entre origen y destino.
  50.        
  51.         float difkm = (39941.58068 / 360) * difdeg;     // aqui la diferencia ya en Kmts
  52.        
  53.        
  54.        
  55.         // ahora vamos a obtener la diferencia entre origen y destino, pero en el paralelo. A diferencia del meridiano, que miden todos lo mismo, los paralelos miden menos cuanto mas a los polos nos acercamos.
  56.         // vamos a determinar cual es la longitud del paralelo donde se encuenta el destino.
  57.         // para ello usaremos la siguiente formula: 2 * pi * radio del paralelo . para calcular el radio del paralelo usare la formula: cos(latitud) * radio de la tierra
  58.         // el radio de la tierra varía según ecuador, tropicos o circulos polares, para el ecuador el radio es : 6378,3 km mientras que para los polos es de 6357,6
  59.         // de modo que para elegir el que mas nos conviene para aproximarnos lo mas posible, dividiremos los 90º de latitud entre la diferencia entre los dos valores y llamaremos elipsoide al resultado.
  60.         // la diferencia entre los dos radios es de 20,7 que hay que dividir entre los 90º que los representan dando como resultado 0,23 unidades a incrementar por grado de latitud del destino.
  61.        
  62.         float32 elipsoide = (0.23 * deslatdeg) + 6357.6;    //    ya tenemos la elipsoide que mejor nos conviene usar segun latitud. En adelante la trataremos como "radio de la tierra"
  63.        
  64.        
  65.        
  66.         // la funcion cos(); nos dará el coseno pero hay que darselo en radianes. por lo que primero tenemos que pasar los grados de la latitud a radianes usando la formula radianes = grados * (pi/180).)
  67.         float radianes = deslatdeg * (PI / 180);    // ya tenemos los radianes para calcular el radio del paralelo:
  68.        
  69.        
  70.         float radio_paralelo = (cos(radianes) * elipsoide);   // obtengo el coseno en radianes y lo multiplico por la elipsoide elegida para la latitud y obtengo así el radio del circulo equivalente a esa latitud.
  71.        
  72.         float longitud_paralelo = (2 * PI) * radio_paralelo;    // ya tenemos la longitud del paralelo del destino
  73.        
  74.         // ahora hay que determinar la distancia en el paraleo que separan origen y destino.
  75.        
  76.         // al igual que para el meridiano, tenemos que identificar si origen y destino están a un lado u otro de grenwich
  77.         float difdegparal;                   // cargaremos aqui la diferencia en grados entre origen y destino en el paralelo.
  78.         if (b5 == d5) {            // si origen y destino están en el mismo lado de grenwich
  79.             difdegparal = orlongdeg - deslongdeg;       // se restan sus valores.
  80.             if (difdegparal < 0) difdegparal = difdegparal * (-1);     // si el resultado es negativo invertimos y lo pasamos a positivo ya que nos da igual quien está a un lado grenwich y quien al otro, solo queremos saber si están los dos o no en el mismo lado.    
  81.         }
  82.         else {
  83.             difdegparal = orlongdeg + deslongdeg;                // si están en distintos lados de genwich entonces sumamos los grados de ambos
  84.         }
  85.        
  86.        
  87.         // ya sabemos la distancia en grados que separan origen y destino en el paralelo. Ahora lo pasamos a Kmts
  88.           float difkmparal = (longitud_paralelo / 360) * difdegparal;           // ya tenemos la distancia en Kmts que separan origen y destino en el paralelo.
  89.          
  90.          
  91.          
  92.         // finalmente para obtener la distancia final entre ambos puntos se aplica teorema de pitágoras:
  93.          
  94.           float dab = sqrt(pow(difkmparal,2) + pow(difkm,2));   // Raiz cuadrada de (distancia en del meridiano al cuadrado + distancia en el paralelo al cuadrado) = Distancia final.      // aqui cargaremos la distancia desde A a B
  95.          
  96.                                                                  
  97.           return dab;
  98.        
  99.      
  100.     }



   Y esta es la función para el odometro:

 
Código: C
  1. float cuentakilometros() {                 // cuando se inicia la unidad, este cuentakilometros se pone a cero. El cuentakilómetros comenzará a avanzar cuando se detecte que se ha iniciado el vuelo.
  2.                                              // Lo primero que comprobamos es que tenemos señal precisa de gps.   (status = 1), de lo contrario cancelamos la función y esperamos a otro momento.
  3.      
  4.  if (status == 0) return;                   // una vez que tenemos gps determinaremos nuestra posición por primera vez y lo cargo como vector inicial en las variables de memoria para tal fin
  5.                                                          
  6.       if (first == 0) {                          // first indica que es el primer barrido por esta función, asi que grabamos posicion, indicamos first = 1 y regresamos)
  7.         lat = latdeg;
  8.         lmin = latmin;
  9.         lsec = latsec;
  10.         lsecdec = latsedec;
  11.         lpol = latpol;
  12.        
  13.         lon = longdeg;
  14.         lonmin = longmin;
  15.         lonsec = longsec;
  16.         lonsedec = longsecdec;
  17.         lonpol = longpol;
  18.         first = 1;
  19.         return;
  20.         }      
  21.      
  22.      
  23.                                                 //detectamos modo vuelo o tierra, para modo vuelo las condiciones son:
  24.                                                 //  -  que la velocidad indicada por el gps sea superior a 8 km/h (speed > 8)
  25.                                              //  -  que el regimen de motor sea superior a 6000 rpm  (rpm > 6000)
  26.                                              //  - Hay tasa de ascenso/desecenso      (verticalspeed != 0);
  27.        
  28.                                              // el cuentakilómetros se detendrá cuando se detecten condiciones que indiquen que el vuelo ha finalizado, esas condiciones son:
  29.                                              //    - La velocidad cae por debajo de 5 km/h       (speed < 5)
  30.                                              //    - el motor gira a ralentí o está apagado.     (rpm < 2800)
  31.                                             //    - no hay tasa de ascenso/descenso indicado por el bmp085   (verticalspeed = 0)
  32.        
  33.                                             // el bit de control para detectar en vuelo o en tierra es "flight", 1 = en vuelo, 0 = en tierra
  34.        
  35.        if (flight == 0) {              // si consta que no se está volando, evaluaremos las condiciones por si activamos o no el modo vuelo.
  36.            
  37.            if ((speed >= 8) & (rpm >= 6000) & (verticalspeed >0) flight = 1;             // si se cumplen las tres condiciones activamos modo vuelo
  38.            return;                                                                   // retornamos a main sin hacer nada    
  39.           }
  40.        
  41.  
  42.            if ((speed <= 5) & (rpm <= 2800) & (verticalspeed = 0) flight = 0;             // comprobamos si hay condiciones que indiquen que el vuelo ha finalizado.
  43.            
  44.            
  45.            // una vez que se está en modo vuelo procedemos con el cuentakilometros..  se pone a cero cuando se inicia la unidad.  
  46.        
  47.        // primeramente determinamos si hay velocidad
  48.      
  49.        
  50.        
  51.       float disttemporal;
  52.      
  53.       if (speed != 0) {              // si hay velocidad llamamos a la funcion medir distancia. La distancia medida será la que ha transcurrido desde el vector arriba guardado
  54.                                             // hasta la posición actual
  55.           disttemporal = distance(latdeg,latmin,latsec,latsedec,latpol,longdeg,longmin,longsec,longsecdec,longpol,lat,lmin,lsec,lsecdec,lpol,lon,lonmin,lonsec,lonsedec,lonpol);
  56.           distancia = distancia + disttemporal;    
  57.      
  58.  lat = latdeg;          // cambiamos el vector anterior por la nueva posición para la siguiente medición y así sucesivamente.
  59.  lmin = latmin;
  60.  lsec = latsec;
  61.  lsecdec = latsedec;
  62.  lpol = latpol;
  63.        
  64.  lon = longdeg;
  65.  lonmin = longmin;
  66.  lonsec = longsec;
  67.  lonsedec = longsecdec;
  68.  lonpol = longpol;
  69.                  
  70.       }
  71.                                      
  72.    }
« Última modificación: 12 de Agosto de 2017, 05:02:17 por remi04 »

Desconectado EdoNork

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 616
    • ElektroQuark
Re:Hacer un cuentakilómetros con un modulo gps neo6mv
« Respuesta #5 en: 12 de Agosto de 2017, 10:15:57 »
¿Cada cuánto tiempo mides la posición?
Mi blog sobre electrónica y cosillas afines: www.elektroquark.com
EQVideo en Youtube
El foro de KiCad en castellano.
Mi librería para KiCad ¡AQUÍ!

Desconectado remi04

  • PIC24F
  • *****
  • Mensajes: 657
Re:Hacer un cuentakilómetros con un modulo gps neo6mv
« Respuesta #6 en: 12 de Agosto de 2017, 10:19:37 »
Aproximadamente cada 2 segundos.

Desconectado xocas

  • Administrador
  • PIC24H
  • *******
  • Mensajes: 2312
Re:Hacer un cuentakilómetros con un modulo gps neo6mv
« Respuesta #7 en: 12 de Agosto de 2017, 12:01:13 »
Estuve buscando hace tiempo algo de información sobre Tripmeters para un amigo que participa en rallies y creo que está relacionado con lo que necesitas.

Dale un ojo al enlace a ver si hay suerte y te sirve de algo: https://goo.gl/8hi7Z4

un saludo

Desconectado remi04

  • PIC24F
  • *****
  • Mensajes: 657
Re:Hacer un cuentakilómetros con un modulo gps neo6mv
« Respuesta #8 en: 14 de Agosto de 2017, 04:56:08 »
Gracias a todos por las respuestas. He estado viendo los enlaces en arduino y basicamente lo que hace es leer la velocidad indicada por el gps a intervalos de segundos y estimar a partir de ese dato la distancia. No me convence ese metodo por que a la larga seguramente acumulará  mas error que el otro sistema.

 No obstante sigo haciendo pruebas. Voy a implementar los dos sistemas para compararlos, probando distintos intervalos a ver donde se aproxima mas a la cifra real a ver si damos con la tecla..   

  Saludos

Desconectado Geo

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 922
    • Mexchip
Re:Hacer un cuentakilómetros con un modulo gps neo6mv
« Respuesta #9 en: 15 de Agosto de 2017, 02:27:37 »
La imaginación es el límite.
Visita mi blog, en inglés o en español :).
Mini curso de introducción a VHDL en MEXCHIP :-/


 

anything