martes, 12 de marzo de 2013

Reconociendo coordenadas (4)

En astronomía,  los sistemas clásicos de coordenadas empleados para determinar la posición de un objeto utilizan valores angulares ya sean sexagesimales ,  horarios o una combinación de ambos.

Sistemas de coordenadas que  utiliza  el protocolo:

  1. Coordenadas geográficas, correspondientes a la ubicación física de observatorio.Ambos se expresan en grados sexagesimales Longitud (de 0 a 360) y latitud ( de -90º a 90º).
  2. Coordenadas ecuatoriales (absolutas) especifican la posición de un punto determinado en la esfera celeste :Ascensión recta (expresada en angulo horario 0 a 24h) y declinación  en grados sexagesimales (expresados en grados de -90º a 90º).
  3. Coordenadas Altacimutales locales u horizontales,su valor está en función de la hora sideral local,y las coordenadas geográficas.Se expresan en grados sexagesimales son componentes son azimuth (de 0º a 360º) y altitud (-90º a 90º).
Sistemas de coordenadas ecuatoriales (celeste)y altacimutales(naranja) proyectados sobre la esfera celeste para una latitud de 36º43'12"

Grados Sexagesimales.
El formato es similar al que aprendimos en la escuela :grados <º> minutos < '> segundos<">.
En LX200 debemos indicar el signo y según la precisión actual podemos especificar o no los segundos.
Por  ejemplo,para el valor 45º20'30
    • Cadena LX200 precisión  alta:  +54ß20'30#
    • Cadena LX200 precisión baja:  +54ß20#

Angulo Horario.
También el habitual :  horas <:>minutos <:>segundos.
Cuando se usan como coordenada de ascensión recta en baja precisión ,los segundos se expresan como décimas de minuto.
Para el valor 18:42:30:

    • Cadena LX200 precisión alta : 18:42:30#
    • Cadena LX200 precision baja: 18:42.5#
Expresiones regulares
Ahora construiremos los bloques para reconocer ambos formatos.
En Ragel, un dígito decimal se puede especificar por la palabra clave "digit" que es equivalente a la expresión [0-9].
    • digit=[0-9]
Un entero de longitud arbitraria se especificaría, añadiendo el operador '+' que en indica una o más ocurrencias de la expresión inmediatamente a la izquierda
    • entero=digit+;
    • entero=[0-9]+;

En nuestro caso para minutos y segundo  necesitamos especificar que necesitamos un entero de dos dígitos entre 0 y 59:
    • minuto=[0-5]digit;
    • segundo=[0-5][0-9]; 
Coordenada en formato grados sexagesimales
En el caso de los grados distiguimos dos formatos modulo 360º ó cuadrante con signo.
    • grado =(([\+]|[\-])digit) digit{2};
En lenguaje natural ,grado acepta dos tipos cadenas:
  1.  Las empiecen por el signo '+' ó '-' seguidas de dos digitos.
  2. Cadenas de  tres digitos.
Para reconocer el formato aceptado por el protocolo la expresión seria la siguiente:
    • degformat=(([\+]|[\-])[0-3]) digit{2}'ß' [0-5]digit ([\`][0-5][0-9])?;
expresion equivalente a :
    • degformat=grado ß minuto ([\']segundo)? ;
Esta expresión reconocería cadenas tales como 359ß12'38 , +23ß40'00 , -00ß19'56 , +36ß43
y rechazaría cadenas mal formadas como +345ß12'80 ó 45ßa'7f


Para ser exactos la expresión que reconoce exactamente el formato seria bastante mas complicada que la propuesta para limitar las cadenas reconocidas a las que estrictamente son válidas, manteniendo los rangos de cada sub-expresión.por ejemplo +90ß36'12 es aceptada aunque  no esta en rango -90º, 90º.

FSM reconocimiento formato de grados sexagesimales
Tratándose de coordenadas  supondremos, como Descartes, un  programa cliente "bueno y no engañador" por lo que no es estrictamente necesario ya que podemos rechazar el resultado  de la conversión en  fuera del propio parser.

Coordenadas formato angulo horario
Lo explicado para el formato anterior es válido para el presente.
Solo hemos de añadir  el reconocimiento de horas de 0 a 23 y el redondeo de segundos si ha lugar, en baja precisión

    • hora =('2'[0-3]) |[0-1]digit;
    • hourformat= hora ':' minuto ((':' segundo)|('.'digit));


FSM reconocimiento formato angulo horario
Como siempre incluyo el código Ragel que genera estas fermosuras.


long lx200( char *str )
{
 char *p = str, *pe = str + strlen( str );
 int cs;
 char stcmd;
 char neg = 1;
//---------------------------------------------------------------------------------------- 
%%{
 machine lx200;
 write data;
}%%
 %%{
  #Acciones 

   
 #definicion sintaxis LX terminos auxiliares
 minuto=[0-5]digit;
 segundo=[0-5][0-9]; 
 grado = (([\+]|[\-])|[0-3]) digit{2};
 hora =('2'[0-3]) |[0-1]digit;
 degformat = grado 'ß' minuto ([\']segundo)? ;
 hourformat= hora ':' minuto ((':' segundo)|('.'digit));
 
 main := (degformat|hourformat) '#'; 


  # Initialize and execute.
  write init;
  write exec;
 }%%

//-----------------------------------------------------------------------------------------
 if ( cs < command_first_final )
 // fprintf( stderr, "LX command:  error\n" );

 return  neg;
};
      Combinamos  las partes comunes a las dos máquinas y listo.Solo nos restan añadir "acciones" como en la entrada anterior




No hay comentarios:

Publicar un comentario