viernes, 4 de abril de 2014

Implementación ligera de método alineación 2-3 estrellas (Algoritmo de Taki ) para microcontroladores(2)

Datos de entrada


 Coordenadas ecuatoriales
Mini-STM32 
Empezamos creando una mini-base de datos con las coordenadas de las estrellas mas destacadas del cielo para que puedan seleccionarse como referencia para la alineación.Se pueden extraer de cualquier catálogo. En el caso de un microcontrolador ,si no se quiere desperdiciar recursos se pueden almacenar, en una tabla en  memoria de programa en Flash  las 20 ó 30 más brillantes de firmamento:

Diphda (Bet Cet) 00:43.6 -17:59
Achenar (Alp Eri) 01:37.7 -57:14
Hamal (Alp Ari) 02:07.2 +23:28
Polaris(Alp Umi) 02:14.7 +89:17
...
...
....
Deneb     (Alp Cyg) 20:41.5 +45:17   
Enif      (Eps Peg) 21:44.2 +09:53   
Fomalhaut (Alp Psa) 22:57.7 -29:38   
Markab    (Alp Peg) 23:04.8 +15:12  

Coordenadas instrumentales (alt-azimutales).
Para  clarificar, cuando mencionemos altitud y azimut en este contexto NO nos  estamos refiriendo a las posición aparente  de la estrella , la que mediríamos con una brújula y sextante, estaría determinada por la coordenadas geográficas ,fecha y hora. Nos referimos a las coordenadas instrumentales

Definimos coordenadas instrumentales a los valores que resultan de medir la posición de los ejes de la montura ,como ejemplos

  • Los valores leídos en unos círculos graduados .
  • Unos codificadores de ángulos  acoplados a los ejes.(hay varios tipos óptico,resistivos, sensores Hall...)
  • Los  registros de contador de unos motores  de pasos.
  • Otros dispositivos  mas exóticos.: Encoder Laser,giroscopio electrónico..


Si la montura fuera perfecta y estuviera perfectamente nivelada (no calcularemos el efecto refracción atmosférica por el momento) coincidirían , pero la razón de usar esta transformación es, precisamente. que no sea  imprescindible disponer de los datos geográficos, ni disponer una montura perfectamente nivelada con ejes perfectamente ortogonales.


Definimos una estructura de datos  para almacenar  las coordenadas de cada estrella de alineación con su  marca temporal.
La estructura c_star  incluye el valor de las coordenadas ecuatoriales,ascensión recta declinación, de la estrella y las coordenadas instrumentales ,azimut altitud y el valor contador de tiempo correspondiente a esa medida.

Todos los valores  coordenadas  se almacenan como radianes. Sólo se emplearán grados sexagesimales para la introducción y  presentación de datos al usuario.
También  nuestro propio  tipo de coma flotante, c_double, con el propósito de poder  modificarlo en cualquier momento  en tiempo de compilación para seleccionar mayor o menor precisión en el cálculo definiéndolo como float, double o long double .
Incluimos un procedimiento set_star para rellenar la estructura con la datos de entrada en formato sexagesimal

typedef  double c_double ;
#define GR (180.0/M_PI)//  57.2958
typedef struct
{
    c_double ra ;
    c_double dec ;
    c_double alt ;
    c_double  az ;
    c_double    timer_count ;
} c_star ;

void set_star(c_star *st,c_double ra,c_double dec,c_double az,c_double alt,c_double ticks)
{
    st->ra=ra/GR;
    st->dec=dec/GR;
    st->az=az/GR;
    st->alt=alt/GR;
    st->timer_count=ticks;

}
Inclinación ejes de la montura/ Errores Constructivos. 

Se modelan mediante la introducción de de tres parámetros  que se corresponden con los valores angulares de error.
  • Z1 angulo error de perpendicularidad entre el eje de altitud y azimut
  • Z2 error de paralelismo entre el eje óptico de telescopio  y el eje vertical (según el caso polar o azimutal) es lo que se denomina a veces error de cono.
  • Z3 error de offset en el eje de altitud.

Lo ideal es poder determinar los errores constructivos de nuestra montura e incluirlos.Existen diversos métodos de medición de errores que no voy describir aquí.
 En este caso vamos emplear la solución mas rápida que es aceptable  solo cuando  los valores  del angulo  de error Z1 y Z2 están por debajo de un grado.
Aún así ,sin incluir el cálculo de estos parámetros, si la montura esta razonablemente bien construida y el telescopio bien colimado, a efectos prácticos para la observación visual, la precisión es suficiente para colar los objetos dentro del ocular o la cámara y un seguimiento visual correcto.

Añadimos tres variables globales z1,z2 z3 para almacenar el valor de los errores y un procedimiento para almacenarlas y añadir otra booleana  (perfect_mount )para indicar en posteriores funciones si es necesario compensar  las correcciones de error .


static c_double z1, z2, z3; 
static char perfect_mount;

void init_errors(c_double az1,c_double az2,c_double az3)
{
    align_star_index = 0;
    z1 = az1;
    z2 = az2;
    z3 = az3;
    perfect_mount= (z1==0.0)&&(z2==0.0);
}

Cálculo de Matrices de trasformación

Tantos las coordenadas ecuatoriales como las instrumentales se pueden considerar como sistemas de coordenadas esféricas,si a la dupla de ángulos le añadimos una tercera componente que seria el módulo o radio.
Para simplificar los cálculos  establecemos la unidad como el radio del vector.

Disponemos de dos  sistemas de coordenadas esféricas:

  1. Celestes o ecuatoriales (ascensión recta,declinación,1).
  2. Instrumentales (azimut, altitud,1) 

Para calcular las matrices de transformación de un vector de un sistema a otro:

Convertimos las coordenadas de cada una  las estrellas de alineación  de esféricas a cartesianas.

En el caso de las coordenadas celestes hemos de considerar restar al valor de ángulo de ascensión recta  el valor del angulo proporcional al intervalo tiempo trascurrido desde el instante que consideramos inicial. Esto es cuando el contador de tiempo es cero.Además este intervalo lo multiplicamos por una  constante KTIME para convertir el intervalo  a tiempo sideral.

ar=ar-KTIME · t
EQ(ar,dec,1)=>(x1,x2,x3)=( cos(ar) · cos(dec) , cos(dec) · sen(ar) , sen(dec));

Para pasar de coordenadas instrumentales a cartesianas, antes de convertir el vector restamos de 360º el valor de azimut para  ser congruentes con sentido de azimuth que se emplea en astronomía ,y añadimos el error de offset al ángulo de altitud.
az=360º-az 
alt=alt+z3
IN(az,alt)=> (y0,y1,y2) = ( cos(az) · cos(alt) , cos(alt) · sen(az) , sen(alt) )

Si la montura no es perfecta calculamos la corrección mínima( y la sumamos al vector


y0 = y0 + sen (az) · cos(alt) · Z1- sen(az) · Z2
y1 = y1 + cos (az) · Z2 - cos(az) · sen (alt) · Z1


Almacenaremos los vectores resultantes en dos matrices 3x3,que emplearemos posteriormente para calcular las matrices de transformación.

typedef c_double MAT3x3 [3] [3];
typedef c_double VECT3 [3];

static MAT3x3
eq_trans_mat, //to equatorial transform matrix
altz_trans_mat, //to alt-az transform matrix
y,              //telescope
x;              //actual


static VECT3 vector ;
static char align_star_index;
void init_star(unsigned char index, const c_star *star)
{
    align_star_index=index--;
    c_double ra=star->ra - (KTIME*star->timer_count) ;
    c_double cosdec=cos(star->dec);
    x[0][index] = cos(ra) * cosdec;
    x[1][index] = cosdec * sin(ra);
    x[2][index] = sin(star->dec);


    spher_to_rect(star->az,star->alt);
    y[0][index] = vector[0];
    y[1][index] = vector[1];
    y[2][index] = vector[2];
}

void spher_to_rect(c_double az,c_double alt)
{
    az=M_2PI-az;
    alt+=z3;
    c_double cos_az=cos(az);
    c_double cos_alt=cos(alt);
    c_double sin_az=sin(az);
    c_double sin_alt=sin(alt);

    vector[0] = cos_az * cos_alt;
    vector[1] = sin_az * cos_alt;
    vector[2] = sin_alt;

    if (!perfect_mount)
    {
        vector[0] +=  sin_az * cos_alt * z1 - sin_az * z2;
        vector[1] +=  cos_az * z2  - cos_az * sin_alt * z1;
    }
}

(Continuará)


No hay comentarios:

Publicar un comentario