Cálculo para distância GPS

Programação C em geral

Moderadores: 51, guest2003

Cálculo para distância GPS

Mensagempor jeanfernandes » 26 Dez 2006 17:23

Depois de ver que a formula "oficial" num vira no ARM (KEIL) por conta do ponto nada flutuante eheheehehehe resolvi dar uma pescada na net....
achei isso ae.....e tirando uns errinhos de metragem (que nao eh importante para q eu to fazendo) ficou premera....

Bom eu comecei por aqui e achei que tava no papo (mas não era bem assim)

http://mathforum.org/library/drmath/view/51711.html

e aqui

http://jan.ucc.nau.edu/~cvm/latlon_formula.html


O negocio esbarrou no calculo de acos(x), para x = 0.9999999661
nao vira sem Float 64 bits (pelo menos no keil/arm nao virou)....e como nao tenho o real view fui atras de outros caminhos menos perversos....


Bom, passou natal.....e tals....

Depois fui por aqui (e de quebra achei o projetinho dos caras legal)

http://www.ce.rit.edu/research/projects ... /algos.htm

Depois só pra ver o porque das constantes (que ainda nao entendi...ehehehe)

http://www.meridianworlddata.com/Distan ... lation.asp

E finalmente aqui foi o que mais me agradou

http://www.math.montana.edu/frankw/ccp/ ... /learn.htm

Dai fiz uns testes iniciais e tals ....

Só pra exemplificar eu fiz uma doideira aqui que acho que por hora ta no grau.....depois se for o caso eu otimizo (nao eh objetivo do lance agora)

As declarações

Código: Selecionar todos
   typedef   struct _cgps {
      byte   g;
      byte   m;
      word   s;
      byte   d;
   } T_CGPS;



   /* Para calculo de distancia */
   typedef struct _tdistancia {
      byte      ativo;
      byte      valido;
      dword    dmin;
      dword      datual;
      T_CGPS   lat_g;      
      T_CGPS   lon_g;      
      T_CGPS   lat_p;      
      T_CGPS   lon_p;      
   } T_DISTANCIA;



as constantes

Código: Selecionar todos
   #define         GPS_ANTENA_LAT      0
   #define         GPS_ANTENA_LON      1
   #define         GPS_PONTO_LAT         2
   #define         GPS_PONTO_LON         3





Código: Selecionar todos
/*************************************************************************
   * Função
         rota_distancia_inicializa
   * Parâmetros
         distancia - distancia minima de atuação
   * Retorno
         nenhum
   * Descrição
         inicializa o calculador de distancia
**************************************************************************/
void rota_distancia_inicializa (dword distancia)
{
   app_distancia.ativo      = FALSE;
   app_distancia.valido   = FALSE;
   app_distancia.dmin       = distancia;
   app_distancia.datual   = 0;

   /* Antena GPS - Latitude */
   app_distancia.lat_g.g   =   0;
   app_distancia.lat_g.m   =   0;
   app_distancia.lat_g.s   =   0;
   app_distancia.lat_g.d   =   'S';

   /* Antena GPS - Longitude */
   app_distancia.lon_g.g   =   0;
   app_distancia.lon_g.m   =   0;
   app_distancia.lon_g.s   =   0;
   app_distancia.lon_g.d   =   'W';

   /* Ponto - Latitude */
   app_distancia.lat_p.g   =   0;
   app_distancia.lat_p.m   =   0;
   app_distancia.lat_p.s   =   0;
   app_distancia.lat_p.d   =   'S';

   /* Ponto - Longitude */
   app_distancia.lon_p.g   =   0;
   app_distancia.lon_p.m   =   0;
   app_distancia.lon_p.s   =   0;
   app_distancia.lon_p.d   =   'W';



}

/*************************************************************************
   * Função
         rota_distancia_calcula
   * Parâmetros
         nenhum
   * Retorno
         1 - distancia calculada ok, 0 - nao pode calcular
   * Descrição
         calcula distancia
**************************************************************************/
byte rota_distancia_calcula(void)
{
   
   static double a,b,c,d,x1,x2,y1,y2,z1,z2,pi,dist;

   if (!app_distancia.ativo)
      return FALSE;

   pi = (double) 3.1415926;

   /* Processamento do ponto */

   // Latitude
   a = (double)app_distancia.lat_p.g + ((double)app_distancia.lat_p.m)/60.0 +
         ((double)app_distancia.lat_p.s)/600000.0;

   if (app_distancia.lat_p.d == 'N')
      a = 90.0 - a;
   else
      a = 90.0 + a;

   // Longitude
   b = (double)app_distancia.lon_p.g + ((double)app_distancia.lon_p.m)/60.0 +
         ((double)app_distancia.lon_p.s)/600000.0;

   if (app_distancia.lon_p.d == 'W')
      b = -b;


   /* Processamento do gps */

   // Latitude
   c = (double)app_distancia.lat_g.g + ((double)app_distancia.lat_g.m)/60.0 +
         ((double)app_distancia.lat_g.s)/600000.0;

   if (app_distancia.lat_g.d == 'N')
      c = 90.0 - c;
   else
      c = 90.0 + c;

   // Longitude
   d = (double)app_distancia.lon_g.g + ((double)app_distancia.lon_g.m)/60.0 +
         ((double)app_distancia.lon_g.s)/600000.0;

   if (app_distancia.lon_g.d == 'W')
      d = -d;


   x1 = 6367.0*cos(b*pi/180.0)*sin(a*pi/180.0);
   y1 = 6367.0*sin(b*pi/180.0)*sin(a*pi/180.0);
   z1 = 6367.0*cos(a*pi/180.0);

   x2 = 6367.0*cos(d*pi/180.0)*sin(c*pi/180.0);
   y2 = 6367.0*sin(d*pi/180.0)*sin(c*pi/180.0);
   z2 = 6367.0*cos(c*pi/180.0);

   // para medida em mmmmm.cc   
   app_distancia.datual = floor(100000.0*sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) + (z1-z2)*(z1-z2)));

   if (app_distancia.datual < 20000000) {
      app_distancia.valido = TRUE;
   }
   else {
      app_distancia.valido = FALSE;
   }
      
   return app_distancia.valido;

}

/*************************************************************************
   * Função
         rota_distancia_ref
   * Parâmetros
         tipo - tipo da referencia
         grau
         min
         seg
         direcao
   * Retorno
         nenhum
   * Descrição
         altera parametros de referencia
**************************************************************************/
void   rota_distancia_ref(byte tipo, byte g, byte m, word s, byte d)
{
   switch (tipo) {
      case GPS_ANTENA_LAT:
            app_distancia.lat_g.g = g;
            app_distancia.lat_g.m = m;
            app_distancia.lat_g.s = s;
            app_distancia.lat_g.d = d;
         break;

      case GPS_ANTENA_LON:
            app_distancia.lon_g.g = g;
            app_distancia.lon_g.m = m;
            app_distancia.lon_g.s = s;
            app_distancia.lon_g.d = d;
         break;

      case GPS_PONTO_LAT:
            app_distancia.lat_p.g = g;
            app_distancia.lat_p.m = m;
            app_distancia.lat_p.s = s;
            app_distancia.lat_p.d = d;
         break;

      case GPS_PONTO_LON:
            app_distancia.lon_p.g = g;
            app_distancia.lon_p.m = m;
            app_distancia.lon_p.s = s;
            app_distancia.lon_p.d = d;
         break;

   }                                                         
}







Bom vou ver se virou depois ...ainda to escrevendo o mizera do codigo eheheheheh

Thank you for all.
Jean P. Fernandes - Eng. Eletrônico - (83) 2102-2116 - APEL - www.apel.com.br - Campina Grande - PB
jeanfernandes
Word
 
Mensagens: 539
Registrado em: 11 Out 2006 15:36
Localização: Campina Grande - PB

Mensagempor jeanfernandes » 26 Dez 2006 18:06

Bom medida do google (mais ou menos eheheheheeh)

Deu 5.836,09 m (feita no olho com a ruler)

No programa 5.868,1 m (um erro basico infimo 32 metros) que eh desprezivel eheheheheheeh

Na formuleta oficial 5.879,51 m (o que minimiza mais o erro uns 12 metros).

Tá aprovada ehehehehehehehe.

Como minhas distancias pra efeito de calculo vai num range de 2 a 3 Km...entao esses metrinhos a mais ou a menos sao despreziveis eheheheheh.....
Jean P. Fernandes - Eng. Eletrônico - (83) 2102-2116 - APEL - www.apel.com.br - Campina Grande - PB
jeanfernandes
Word
 
Mensagens: 539
Registrado em: 11 Out 2006 15:36
Localização: Campina Grande - PB

Mensagempor proex » 26 Dez 2006 18:16

Precisa melhorar isso ae, 32 metros é uma margem de erro muito grande.
proex
Dword
 
Mensagens: 2101
Registrado em: 11 Out 2006 14:05
Localização: São Paulo

Mensagempor jeanfernandes » 26 Dez 2006 18:36

Jr. precisa nao....
a ideia nao eh localizacao....mas sim ...raio de disparo de eventos onde a antena esta num ponto X1 se movendo em relacao a X2 (ja determinado)....

Quando |X1-X2| < Dmin....disparo o evento......

Essa distancia vai em torno de 150 a 200 metros .....
Entao o erro vai ser na casa de centimetros eheheheheehheeh
Jean P. Fernandes - Eng. Eletrônico - (83) 2102-2116 - APEL - www.apel.com.br - Campina Grande - PB
jeanfernandes
Word
 
Mensagens: 539
Registrado em: 11 Out 2006 15:36
Localização: Campina Grande - PB


Voltar para Visual C++/C/C++/C#

Quem está online

Usuários navegando neste fórum: Nenhum usuário registrado e 1 visitante

x