…e velocità sia!

Nell’articolo precedente eravamo rimasti al calcolo della velocità ed all’utilizzo della periferica del dsPIC chiamata QEI per l’interfacciamento del sensore. Adesso partiremo con l’analisi ed il calcolo della velocità attraverso l’encoder.

Modello Encoder

Perché sia possibile sapere la velocità del motore bisogna utilizzare un timer che possa contare quanto tempo passa tra l’intercorrere di una cella ed un’altra.

La Velocità misurata diventa quindi [tex] V_m = frac{N_thetatheta_c}{T}[/tex]

La misura però è soggetta ad un errore di quantizzazione, in quanto l’angolo è definito con una precisa risoluzione.

[tex] theta_m = N_thetatheta_c = theta pm epsilon_theta[/tex]

Dove [tex]epsilon_theta[/tex] è l’errore dovuto alla quantizzazione ed è compreso [tex]|epsilon_theta| < theta_c[/tex]

Due modi per calcolare la velocità

Esistono due modi per poter calcolare la velocità, un primo che tenuto il tempo costate si contano il numero di celle passate in quel periodo, ed un secondo complementare che tenuto il numero di celle costante si conta l’intercalare del tempo tra esse.

  1. [tex] V = frac{N_thetatheta_c + epsilon_theta}{T}[/tex]
  2. [tex] V = frac{N_thetatheta_c}{T + epsilon_T}[/tex]

Perché l’errore sià più piccolo possibe, l’errore deve essere ovviamente più piccolo possibile.

Fissato un tempo di campionamento [tex]T = N_cT_c[/tex]

Sviluppando in serie di Taylor il secondo punto

  1. [tex] V = frac{N_thetatheta_c + epsilon_theta}{N_cT_c} = frac{N_thetatheta_c}{N_cT_c} + frac{epsilon_theta}{N_cT_c} = frac{N_thetatheta_c}{N_cT_c}(1 + frac{epsilon_theta}{N_thetatheta_c})[/tex]
  2. [tex] V = frac{N_thetatheta_c}{N_cT_c + epsilon_T} simeq frac{N_thetatheta_c}{N_cT_c} – frac{N_thetatheta_c}{(N_cT_c)^2}epsilon_T = frac{N_thetatheta_c}{N_cT_c}(1 – frac{epsilon_T}{N_cT_c})[/tex]

Perché la velocità effettiva sia più affidabile possibile l’errore in entrambi casi deve essere il più possibile nullo.

Perché l’errore sia più piccolo possibile

  1. Il motore deve girare a grandi velocità
  2. Il motore deve girare a basse velocità

Per il robot è stato scelto il secondo modello di calcolo della velocità, questo perché il robot sarà più spesso impegnato a muoversi in ambienti stretti e con poche possibilità di andare a grandi velocità

Sul Robot

Dopo aver trattato il caso analitico del calcolo della velocità, passiamo alla sua realizzazione effettiva sul programma di controllo del robot.
Una importante periferica presente sul dsPIC che è stata scelta per poter contare il tempo intercorso tra una cella ed un’altra è l’Input Capture.

Questo dispositivo collegato con un timer di riferimento conta ogni fronte di salita e/o di discesa e ne memorizza il valore su di un registro o su di un piccolo buffer FIFO che memorizza due istanti e genera un interrupt.

Input Capture

La modalità scelta per il robot è la “Edge Detection Mode” che genera un interrupt inviando il valore del timer in quell’istante. Questo comporta che la velocità minima e massima misurabile sono in funzione dell’overflow del timer e del contaggio tra un istante ed un altro del contatore.

Il timer (timer 2) inizializzato in FreeRunning ed alla massima frequenza di clock, ha un conteggio massimo di:

La dimensione del registro è di [tex]N_{max} = 2^{16} = 65536[/tex] e la velocità del clock di [tex] f_c = 80Mhz[/tex]

[tex]T_2 = N_{max} * (f_{cy})^{-1} = 65536*2.5806451612903*10^{-8} s[/tex]
[tex]T_2 = simeq 0,00169 s[/tex]

Il salvataggio dei campioni viene eseguito attraverso il buffer FIFO presente nella periferica che genera un singolo interrupt una volta che il buffer è stato riempito, in modo tale da ridurre drasticamente il numero di interruzioni.

Buffer FIFO

Un esempio di inizializzazione della periferica è presente sul manuale della periferica:

// Initialize Capture Module
IC1CONbits.ICM= 0b00;    // Disable Input Capture 1 module
IC1CONbits.ICTMR= 1;     // Select Timer2 as the IC1 Time base
IC1CONbits.ICI= 0b00;    // Interrupt on every second capture event
IC1CONbits.ICM= 0b001;   // Generate capture event on every Rising edge
// Enable Capture Interrupt And Timer2
IPC0bits.IC1IP = 1;      // Setup IC1 interrupt priority level
IFS0bits.IC1IF = 0;      // Clear IC1 Interrupt Status Flag
IEC0bits.IC1IE = 1;      // Enable IC1 interrupt
// Capture Interrupt Service Routine
unsigned int timePeriod = 0;
void __attribute__((__interrupt__)) _IC1Interrupt(void) {
    unsigned int t1,t2;
    t2=IC1BUF;
    t1=IC1BUF;
    IFS0bits.IC1IF=0;
    if(t2>t1)
       timePeriod = t2-t1;
    else
       timePeriod = (PR2 - t1) + t2
}

Stimare la velocità ed i suoi limiti

Una volta che la perifericha è in funzione poter tener conto del tempo diventa molto facile, basta usare i giusti coefficienti moltiplicativi per dimensionare i valori e la velocità è facilmente

[tex] V = K_vfrac{tex{sign}}{tex{timeperiod}}[/tex]

Dove il coeffiente moltiplicativo è:

[tex] K_v = frac{frac{2pi}{CPR*RAPP}}{T_{cy}} simeq 27052.6034059frac{rad}{s}[/tex]

Sign = è il verso di rotazione del motore, stimabile attraverso il metodo di quadratura o l’utilizzo del modulo QEI spiegato nell’articolo “Partiamo dalla posizione…
timeperiod = attraverso l’utilizzo del metodo sopra esposto usando l’input capture

La velocità minima e massima misurabile sono:

[tex] |V_{min}| = K_vfrac{1}{tex{timeperiod}_{max}} = frac{K_v}{65536} simeq 0,41279frac{rad}{s}[/tex]

[tex] |V_{max}| = K_vfrac{1}{tex{timeperiod}_{min}} = K_v simeq 27052frac{rad}{s}[/tex]

Per quanto riguarda la velocità massima, questa non la raggiungerà mai in quanto il motore come spiegato nella pagina dedicato all’attuatore raggiunge una velocità massima di [tex] |V_{max}| simeq 20 frac{rad}{s}[/tex].

Nel primo caso la velocità minima misurabile può portare problemi di misura, in quanto il sistema non è più in grado di misurare velocità più basse e non eseguire correttamente le azioni di controllo richieste. Questo fenomeno chiamato Jitter è uno dei limiti difficilmente scavalcabile in problematiche del genere.

Copyright © 2009. All Rights Reserved.

Leave a Reply