mercoledì 4 novembre 2015

Terminato lo sviluppo del software

Ho finalmente completato il software di gestione del  telescopio con le parti minori che erano rimaste da fare. Ora tutto è approntato e posso quindi rilasciare la prima versione definitiva del software TCS2015.









Tutte le aggiunte rispetto al versione precedente  sono state fatte nel programma principale main, queste le nuove parti:

Apertura e chiusura della copertura

Il telescopio fissato a terra è coperto da una casetta mobile su rotaie. L’apertura e la chiusura sono comandate da due relè montati sul sistema. Entrambi possono essere comandati sia da protocollo LX200 sia da un pulsante. Una volta avviato il comando il relè rimane attivo per un tempo fisso scaduto il quale si spegne automaticamente. I tempi sono impostati tramite due define.

#define DOME_OPEN_TIME    3000000    // time for dome opening
#define DOME_CLOSE_TIME   3000000    // time for dome closing

Per ora impostate al valore di 3 secondi, in fase di istallazione dovranno essere tarati opportunamente


Homing del telescopio.

Quando il comando di homing del telescopio è ricevuto dal protocollo LX200, è interrotto il tracking ed iniziata una procedura che muove i motori alla massima velocità nella direzione di oscuramento delle rispettive forcelle ottiche. Una volta oscurata la forcella, il motore inverte il moto a bassa velocità sino a che la stessa è nuovamente scoperta. Un ulteriore avanzamento del motore a bassa velocità permette di fermarsi con precisione sul punto esatto di oscuramento. Regolando la posizione delle lunette che oscurano le forcelle è possibile definire la posizione di homing. La posizione risulta essere quindi ripetitiva e nota.


Messa a fuoco


Il comando di messa a fuoco ricevuto dal protocollo LX200 contiene la posizione relativa in step che dove deve essere posizionato il CCD lungo l’asse di fuoco. Finché la posizione del motore è diversa da quella richiesta uno step è dato al motore ogni 1/100 di secondo.


Gestione timeout

La gestione del timeout serve a mettere in sicurezza il telescopio in caso di guasto del PC connesso al TCS2015 oppure al crash del programma di controllo. L’evento è identificato dalla mancata comunicazione tramite LX200. Quando il controllo timeout è attivato e nessuna comunicazione è pervenuta da un minuto è attivata la procedura di messa in sicurezza. Essa prevede in homing automatico del telescopio e la chiusura della copertura.




Questa versione di software si può scaricare all'indirizzo


Ora aspettiamo la meccanica per verificare un test reale sul campo…….




martedì 6 ottobre 2015

Correzione dell'errore periodico nel sistema di tracking del telescopio (PEC)

Tutti i sistemi di tracking di telescopio sono affetti da errori periodici dovuti principalmente a piccole eccentricità negli ingranaggi. Questo provoca problemi durante le esposizioni fotografiche prolungate generando un "mosso" nel senso della ascensione retta dovuto ai periodismi con tempi comparabili alla durata dell'esposizione fotografica. L'elemento che spesso disturba di più è la vite senza fine del riduttore che è connessa meccanicamente con l'albero del motore. Nel caso del telescopio che stiamo realizzando l'albero del motore completa un giro in 78 secondo, un tempo che direttamente comparabile con la durata tipica delle esposizioni da 120 a 240 secondi.

Per risolvere questo problema adottiamo una soluzione meccanica/elettronica già applicata con successo al telescopio Schmidt dell'Osservatorio di Bassano Bresciano.

Insieme dei pezzi meccanici del gruppo motore riduttore

Nella progettazione del gruppo motore riduttore è stato inserito sull'albero un disco con una piccola fessura ed una forcella ottica che sente il passaggio della fessura nel giro del motore.

Particolare della forcella ottica

Particolare del disco con fessura 

Per effettuare la correzione occorre rilevare sperimentalmente il valore dell'errore e metterlo in relazione con la fase della rotazione del motore rilevata dal segnale della forcella ottica.
L'errore più essere ben approssimato con una sinusoide della quale occorre calcolare ampiezza e sfasamento.

Errore rilevato per telescopio Schmidt

In questo progetto l'albero del motore compie una rotazione con 3200 passi da 1/16.
All'oggetto StepAxis è stato aggiunto una funzione che riceve ingresso l'ampiezza e la fase della sinusoide. Con questi valori è compilata una tabella di 3200 elemento con il numero di passi di compensazione dell' errore per ogni punto della rotazione.

/*---------------------------------------------------------------------------

  enable/disable PEC

---------------------------------------------------------------------------*/

void StepAxis::PEC( bool Enable, int Amplitude, int Phase, int StepOneRotation)
{
  double                        CurrPhase;              // current Phase
  double                        CurrAmplitude;      // current Amplitude;
  int                               Offset;                    // sin offset fo soft start
  int                               i;

  PECEnable = Enable;                               // store enable
  PECStepOneRotation = StepOneRotation;   // store StepOneRotation

  if ( PECEnable == true )                              // other actions only when enabled
  {      
    PECSyncDone = false;                                // sync need to be renew
    if ( StepOneRotation > STEPEXIS_MAX_PEC_TABLE )     // clamp for maximum steps
      StepOneRotation = STEPEXIS_MAX_PEC_TABLE;
      CurrPhase = Phase + (double)i*360.0/(double)StepOneRotation; // current phase in degree
      CurrPhase /= 180.0/M_PI;
      CurrAmplitude = sin(CurrPhase) * (double)Amplitude;
    // table computing
    for ( i=0; i<StepOneRotation; i++ )
    {
      CurrPhase = Phase + (double)i*360.0/(double)StepOneRotation; // current phase in degree
      CurrPhase /= 180.0/M_PI;
      CurrAmplitude = sin(CurrPhase) * (double)Amplitude;
      if ( i == 0 )
        Offset = CurrAmplitude;
      PECTable[i] = CurrAmplitude - Offset;    
    }
  }
}


Nella gestione del movimento è rilevata la posizione in cui arriva il segnale dalla forcella ottica e memorizzato il valore dell'encoder virtuale nella variabile (PECSyncPhase).

// detect strobe rising when PEC enabled and positioning is finished
if ( PECStrobe == true && PECOldStrobe == false && PECEnable == true && Phase == PHASE_STOPPED )  
  {
    PECSyncPhase = Encoder;             // store sync value from encoder      
    PECSyncDone = true;                     // PEC syncronization is done 
  }
  PECOldStrobe = PECStrobe;

A questo punto la correzione dell'errore diventa un gioco da ragazzi. E' ricavato PECIndex come modulo sulla distanza tra il setpoint di posizione che si intende impostare (Temp3) e la posizione individuata dalla forcella ottica (PECSyncPhase). Il modulo è fatto sul numero di passi per un giro di rotazione (PECStepOneRotation). Il valore di PECIndex sarà in questo caso sempre compreso tra 0 e 3199.
Con questo valore si consulta la tabella e si ricava il valore di correzione (PECValue) e lo si aggiunge al set point di posizione stesso.

 if ( TrackingEnable == true && PECEnable == true && PECSyncDone == true )
  {
    PECIndex = (Temp3 - PECSyncPhase) % PECStepOneRotation;
    PECValue = PECTable[PECIndex];
    Temp3 += PECValue;
  }

  ApplySetpoints( Temp3, VelocitySetpoint ); 

Questa tenica applicata al telescopio Schmidt ha portato a questo risultato


Alla sinistra un ingrandimento di una foto ad un campo stellare senza controllo PEC abilitato, a destra lo stesso campo con controllo PEC abilitato

Questa versione di software si può scaricare all'indirizzo
http://www.osservatoriobassano.org/TCS2015/SoftV05.zip

mercoledì 30 settembre 2015

Tracking e puntamento con lo stesso motore

Nuovo passo nello sviluppo del software,:ho aggiunto la gestione del tracking con lo stesso motore che esegue il puntamento dell’ascensione retta. Il tutto si basa sul principio che la rotazione siderea avviene in 86164 secondi (23 ore, 56 minuti, 4 secondi) anziché 86400 (24 ore ). Il rapporto tra i due tempi è 1.002737908. Dato che il motore di ascensione retta permette la rotazione di 360° dell’asse con 3456000 impulsi, per compensare la rotazione della Terra al motore di ascensione retta devono essere dati 3456000 * 1.002737908 = 3465462 impulsi addizionali nel giro di 24 ore. Tale valore è memorizzato nella variabile SidealSteps.

L’implementazione nel codice è avvenuta intervenendo in due diversi ambiti.

1) Ogni 10 millisecondi è incrementata la variabile SkyTrackingTime del valore 10 in modo da tenere un conteggio dei millisecondi dalla accensione del sistema. Con questo valore è eseguta la proporzione tra i millisecondi trascorsi e quelli totali in un giorno:
 
SkyTrackingStep = (SkyTrackingTime * SidealSteps) / 86400000

Il valore SkyTrackingStep è sommato alla coordinata correntemente puntata. In questo modo nel caso di motore di ascensione fermo (tracking disabilitato) la coordinata puntata dal telescopio s’incrementa di 24 ore di ascensione retta ogni giorno siderale.

2) Se il tracking è abilitato, una volta completato un puntamento è mantenuto un conteggio di millisecondi trascorsi (variabile MotorTrackingTime) incrementato ogni 10 millisecondi. Con questo valore è eseguta la proporzione tra i millisecondi trascorsi e quelli totali in un giorno:
 
MotorTrackingStep = (MotorTrackingTime * SidealSteps) / 86400000

Il valore MotorTrackingStep è quindi sottratto a setpoint di posizione per il motore di scensione retta in questo modo ogni volta che la formula produce un incremento di 1 del valore il motore indietreggia di un passo alla frequenza di 40.1095 Hz.

La combinazione delle due azioni fa si che in caso di tracking attivo il telescopio si muove con la giusta velocità e la coordinata puntata risulta invariata.



In questo video è possibile vedere il motore di ascensione retta:
  • il motore esegue il tracking muovendosi a 1/16 di passo a circa 40Hz
  • il motore si muove a 1/16 di passo sino ad un punto di sincronismo in cui è possibile cambiare il passo
  • cambia la movimentazione in passi interi
  • accelera la velocità da 200hz a 500hz
  • mantiene la velocità sino nel pressi della coordinata finale
  • decelera da 500hz a 200hz
  • cambia la movimentazione a 1/16 di passo
  • esegue il posizionamento finale di precisione
  • il motore riprende il tracking 
Questa versione di software si può scaricare all'indirizzo


giovedì 17 settembre 2015

Terzo passo: posizionamento con regolazione della velocità

Terza versione provvisoria del software.

Dopo la pausa estiva ho ripreso il lavoro implementando il puntamento con la gestione completa degli assi di ascensione retta e di declinazione. Il movimento ora avviene con la possibilità di selezionare la velocità massima, tale  velocità è raggiunta con una rampa di accelerazione. La stessa rampa è usata durante la decelerazione. E' gestito il cambio dinamico del passo da intero a 1/16 di passo.
Il cuore della è l’oggetto StepAxis (in linguaggio C++) che permette di muovere un motore passo passo come un asse di telescopio. Sono istanziati due di questi oggetti, uno per l’ascensione retta ed uno per la declinazione. La gestione prevede in varie situazioni delle attese temporali, queste sono realizzate senza introdurre ritardi (tipo funzione Delay), ma con una serie di macchine a stati. Così l’esecuzione risulta essere veloce senza bloccare le altre operazioni svolte dalla CPU

Lo schema mostra le parti più rilevanti del software nell'oggetto StepAxis.

Due sono le funzioni ad alto livello che l’oggetto dispone per il posizionamento del motore:
Goto.  Riceve in ingresso la coordinata da raggiungere e la velocità massima da utilizzare (in percentuale sulla massima possibile). Converte la coordinata da Ore/minuti/secondi (o gradi/minuti/secondi) in passi di motore. Converte la velocità massima in step al tempo di campionamento. La funzione termina rapidamente lasciando le informazioni all’interno dell’oggetto insieme il comando di esecuzione del movimento. Quando la funzione esce il movimento non è ancora iniziato
Stop. La funzione termina rapidamente lasciando il comando di stop con rampa di decelerazione  all’interno dell’oggetto. Quando la funzione esce lo stop non è ancora iniziato.
Le altre funzioni coinvolte nella movimentazione sono:
MoveManagement. E' chiamata rigorosamente una volta ogni 1/100 di secondo. Il suo campito è di gestire la generazione della traiettoria di posizionamento. Riceve in ingresso: la velocità di partenza, l’accelerazione, la velocità massima e la posizione da raggiungere. Con questi parametri, tramite una macchina a stati costruisce un profilo trapezoidale con rampa di accelerazione, velocità di crociera e rampa di decelerazione. La rampa di decelerazione inizia quando lo spazio residuo del movimento è quello corretto per terminare la decelerazione sulla posizione finale. Il movimento inizia applicando immediatamente la velocità di 200 hz in modo da superare di getto le frequenze di risonanza tipiche del motori passo passo. Quando è ricevuto un comando di stop la rampa di decelerazione inizia immediatamente.
ApplySetpoints. E' chiamata esclusivamente da MoveManagement. Riceve in ingresso i setpoint di posizione e velocità da applicare ai motori.  Quando la velocità è superiore ad un certo valore essa viene usata in modo esclusivo per la determinazione della frequenza di clock (controllo di velocità). Quando la velocità è inferiore, è utilizzato solo il set point di posizione (controllo di posizione). In caso di ascensione retta la funzione è in grado di cambiare dinamicamente lo step tra intero e 1/16. Tutte queste funzionalità sono realizzate tramite un’altra macchina a stati. In alcune commutazioni di segnali la macchina ha bisogno di tempi di attesa. In queste condizioni è attivato un segnale di attesa che raccolto dalla funzione MoveManagement che sospende la generazione del profilo di posizionamento. Così facendo si evita accumulo di errore tra la posizione richiesta e quella effettiva.
OutputForDriver. E' la più critica. E’ chiamata all’interno dell’interrupt temporizzato che scatta ogni 100 us. Lo scopo è quello di creare il segnale di clock regolare con jitter pressoché nullo. I motori passo passo sono piuttosto permalosi e non sopportano segnali di clock irregolari o brusche variazioni di velocità, specie alle alte velocità. La funzione riceve in ingresso : il numero di impulsi che devono essere emessi, la distanza temporale tra un impulso ed il successivo e di quanto varia il conteggio ad ogni colpo di clock (nel caso di cambio tra passo intero e 1/16). La funzione restituisce il valore di conteggio encoder (simulato) relativo alla posizione del motore e l’indicazione di emissione impulsi di clock termina. All’interno è attiva una ulteriore macchina a stati.


In questo video è possibile vedere il software Polypus ce gira su PC, connesso al sistema TCS105. In partenza il telescopio e puntato sulla stella Belatrix, eseguendo in puntamento sulla stella Betelgeuse si può vedere:

  • il motore di ascensione retta che si muove a 1/16 di passo sino ad un punto di sincronismo in cui è possibile cambiare il passo
  • cambia la movimentazione in passi interi
  • accelera la velocità da 200hz a 500hz
  • mantiene la velocità sino nel pressi della coordinata finale
  • decelera da 500hz a 200hz
  • cambia la movimentazione a 1/16 di passo
  • esegue il posizionamento finale di precisione
Questa versione di software si può scaricare all'indirizzo
http://www.osservatoriobassano.org/TCS2015/SoftV03.zip



domenica 26 luglio 2015

Secondo passo: si muove !!!

Seconda versione provvisoria del software. Ora i motori si muovono ed effettuano correttamente il puntamento.
Ho sviluppato il software in modo da generare tramite un interrupt temporizzato a 100 us gli step di movimentazione dei motori, questi non devono essere disturbati in nessun modo da altre operazioni per cui la scrittura del display avviene sempre a motori fermi e le operazioni di lettura e scrittura dei port non utilizza le funzioni standard fornite dall'ambiente di sviluppo (digitalRead  e digitalWrite). Queste funzioni infatti per costruire l'interfaccia che utilizza la numerazione dei pin generano un notevole overhead e per alcuni istanti bloccano gli interrupt. Ho utilizzando quindi l'accesso diretto ai registi ( tipo PIOB->PIO_CODR, PIOB->PIO_SODR, PIOC->PIO_ODSR).

Il display l'ho gestito in modo da visualizzare le seguenti informazioni

La prima linea riporta la ascensione retta e un testo che può essere: Pos (posizione corrente), Goto (posizione in corso di puntamento) o Alig (posizione su cui effettuato allineamento).
La seconda linea riporta la declinazione ed una serie di segnalatori:
T se tracking è attivo, spazio se non attivo
F se luce flat accesa, spazio se spenta
C se alimentazione CCD accesa, spazio se spenta
H se telescopio in posizione di homing, spazio se in altra posizione
C se casetta è chiusa, c se in fase di chiusura, O se aperta, o se in fase di apertura.
t se timeout è attivo, spazio se non attivo.

Il software non è definitivo, infatti:

  • La movimentazione è eseguita sempre alla stessa velocità (100hz), senza rampe di accelerazione.
  • Non è utilizzato il cambio di velocità sull'ascensione retta.
  • Il tracking non è ancora implementato.
  • Non è gestita la correzione dell'errore periodico.
  • Non è gestita l'apertura e chiusura della casetta (solo simulata)
  • Non è gestita la posizione di home

Però, connettendo il software Polypus è possibile eseguire un allineamento su di un oggetto


e puntare un'altro oggetto.


I motori si muovono nella gusta direzione fino alla posizione stabilita e sul display appare il relativo messaggio


La parte di generazione del clock di movimentazione, il settaggio della posizione ed i calcoli di trasformazione tra impulsi e ore, minuti, secondi ( o gradi, minuti, secondi) sono correttamente implementati e funzionanti.

Questa versione di software si può scaricare all'indirizzo http://www.osservatoriobassano.org/TCS2015/SoftV02.zip

giovedì 2 luglio 2015

Protocollo LX200 con Arduino

Ormai l'hardware è definitivo, sono quindi passato a sviluppare il software di controllo del telescopio.
Per fare questo ho scaricato l'ultima versione dell'ambiente di sviluppo 1.6.5 ed il package aggiuntivo per compilare per Arduino Due.
Intendo realizzare il software nel modo più modulare possibile, utilizzando ove utile, il C++ in  modo da incapsulare il codice in oggetti con una responsabilità ben definita. Il codice sarà scritto completamente in inglese (nomi di funzioni, variabili e commenti) adottando il CamelCase.
Il software sarà disponibile in forma sorgente con licenza GPL.

Ho realizzato quindi il primo mattone (versione 0.1) di questo software, si tratta del protocollo di comunicazione LX200. In questo modo è possibile connettere il sistema a qualsiasi client che lo supporta e lanciare i comandi.


Il protocollo è completamente incapsulato in un oggetto C++ di nome LX200, che è stato testato in via definitiva. Il test è stato eseguito connettendo il software di gestione dell'osservatorio "Polypus" sviluppato ed in funzione già da tempo presso l'Osservatorio di Bassano Bresciano.


Il software contenuto nel programma principale ha lo scopo di testare LX200.cpp e di mostrare come deve essere usato.
L'inizializzazione prevede:
  • L'attivazione del display utilizzato per visualizzare i comandi ricevuti, 
  • La creazione di un interrupt temporizzato che sarà usato per la generazione degli impulsi per i motori passo passo, ma ora serve a generare un contatore (SysTime) di sistema con la risoluzione del microsecondo.
  • La creazione dell'oggetto LX200 (chiamato LX200Server) ed assegnazione della linea seriale 3 e sua inizializzazione


// global variables
LiquidCrystal                 *Lcd;                        // LCD driver
int                           SysTime;                     // sistem time counter in microseconds
LX200                         *LX200Server;                // communication server for LX200 server
LX200::TELESCOPE              CurrentTelescopePosition;    // current telescope position
LX200::TELESCOPE              TargetTelescopePosition;     // goto target telescope position
LX200::STATUS                 Status;                      // telescope and dome status for LX200 server 

......... 

/*---------------------------------------------------------------------------

   Inizialization

---------------------------------------------------------------------------*/

void setup() 
  // display inizialization
  Lcd = new LiquidCrystal( 13, 12, 11, 10, 9, 8);           // lcd driver creation
  Lcd->begin(16, 2);                                        // lcd has 16 columns and 2 lines
  Lcd->setCursor(0, 0);                                     
  Lcd->write("--");
  
  // LX200 server initialization
  Serial3.begin ( 9600 );                                   // open communication line 
  LX200Server = new LX200(&Serial3);                        // LX200 server creation and serial 
  memset( &Status, 0, sizeof(Status) );                     // clear  telescope and dome status

.......
}


Il software che gira ciclicamente provvede a:
  • Fornire all'oggetto LX200Server il contatore SysTime (funzione SetSysTime) con il tempo che scorre, questo è essenziale perché esso possa calcolare correttamente i timeout di comunicazione.
  • Fornire all'oggetto LX200Server la posizione correntemente puntata dal telescopio (funzione SetCurrentPosition). In questo modo quando un applicazione client chiede al sistema TCS2015 la posizione puntata il protocollo LX200 è in grado di fornirla.
  • Fornire all'oggetto LX200Server lo stato di alcuni elementi di telescopio e cupola (telescopio calibrato, tracking abilitato, telescopio in movimento, valore corrente di correzione errore periodico, fase corrente della rotazione vite senza fine, telescopio in posizione di home, stato luci flat, accensione CCD). In questo modo quando un applicazione client chiede al sistema TCS2015 queste informazioni il protocollo LX200 è in grado di fornirle. 
  • Gestire il protocollo (funzione ManageProtocol). In questa funzione si esplica tutta la gestione della comunicazione. La funzione risponde a tutte richieste in ingresso dalla linea di comunicazione e restituire in output il codice dell'eventuale comando arrivato dal client. E' cura del programma gestire l'esecuzione del comando. 
Nell'esempio il comando ricevuto è selezionato della linea switch ( Command ) dopo è possibile capire come procedere. Alcuni comandi hanno bisogno della richiesta al protocollo di ulteriore informazioni per poter essere eseguiti:
  • La funzione GetGotoVelocities permette di conoscere la velocità (1%-100% che è stata selezionata per il puntamento.
  • La funzione GetTargetPosition permette di conoscere la posizione richiesta per un posizionamento o un allineamento. 
  • La funzione GetManualMovement permette di conoscere i parametri per un movimento manuale.
  • La funzione GetPECParams permette di conoscere i parametri per la sinusoide di correzione dell'errore periodico.

Credo che la spiegazione sia esauriente, se ci sono dubbi non esitate a scrivermi 

void loop() 
{
  int                       Int1;
  char                      Message[20];
  char                      Str1[10];
  LX200::COMMAND            Command;
  LX200::GOTOVELOCITIES     GotoVelocities;
  LX200::MANUALMOVEMENT     ManualMovement;
  LX200::PECPARAMETERS      PECParameters;

  LX200Server->SetSysTime( SysTime );  
  
  CurrentTelescopePosition.RAHours = 23;
  CurrentTelescopePosition.RAMinutes = 34;
  CurrentTelescopePosition.RASeconds = 45;
  CurrentTelescopePosition.DecSign = '-';
  CurrentTelescopePosition.DecDegrees = 12;
  CurrentTelescopePosition.DecMinutes = 34;
  CurrentTelescopePosition.DecSeconds = 56;
  LX200Server->SetCurrentPosition( &CurrentTelescopePosition );
  
  Status.PECIndex++;
  if ( Status.PECIndex >= 3200 )
    Status.PECIndex = 0;
  Status.PECValue = Status.PECIndex/10 - 16;  
  LX200Server->SetStatus( &Status );
  
  Command = LX200Server->ManageProtocol();
  
  switch ( Command )
  {
    case LX200::GOTO:

..................




sabato 27 giugno 2015

Ultime modifiche hardware


Alcune modifiche sono state aggiunte all'ultimo minuto:
Il display da 16 caratteri per 2 linee è stato montato sullo chassis in modo da essere visibile frontalmente.
L'ingresso per un ulteriore forcella ottica che permette di rilavare una posizione fissa nella rotazione della vite in modo da poter fasare un segnale di correzione dell'errore periodico.

Nella foto si può vedere il display e motori connessi per iniziare la fase di test e di sviluppo software.

Le modifiche hanno richiesto la modifica dello schema elettrico che ora assumo questo aspetto.

La morsettiera frontale fornisce tutte le connessioni elettriche di segnale e di potenza:
Sulla pagina "Documenti progetto TCS2015" è possibile trovare tutti i documenti e schemi aggiornati