Descrizione del codice per il movimento

Cominciamo a fare un po' di conti con la meccanica :

La ruota ha un diametro di 58mm, quindi una circonferenza di 182,212mm
L'encoder è su uno degli assi del gruppo riduttore e fa 20 giri ogni giro della ruota
questo ha 40 finestrelle che danno due interrupt ognuna (fronte di salita e di discesa)
quindi 40 x 2 x 20 = 1600 tick per giro (o CPR, count per revolution)

di conseguenza la risoluzione teorica è di 0,1138827336926 mm

Il MAIN è semplicemente uno scheduler che lancia le diverse routine con le giuste priorità.

Il programma lavora in una versione semplificata di "Real Time Operating System", sono state seguite quindi le seguenti regole per lo sviluppo di un "Sistema Operativo Multitasking Cooperativo":

-Ogni routine collabora con tutte le altre, ed in particolare con il main, per il buon funzionamento del sistema.
-Ogni routine occupa il sistema per il minor tempo possibile
-Non ci sono loop lunghi o ritardi a SW
-Il main si preoccupa di schedulare i vari task, le routine si chiamano raramente tra loro
-Lo scambio di informazioni tra task avviene tramite flag e variabili globali
-Le temporizzazioni sono realizzate usando come "Real Time Clock" l'interrupt overflow del TIMER0 che è il vero "hearth-beat" del sistema
-L'esecuzione dei vari task è condizionata dai relativi semafori, il main o un altro task
possono disabilitare una certa funzione

Per approfondimenti sull'argomento si può vedere la pagina dei miei primi studi sull'argomento, da allora qualcosa è cambiato ma i concetti di base sono gli stessi.

Il Main è sempre attivo e, visto che le operazioni di movimento sono molto lente rispetto ai tempi di esecuzione del PIC, per la maggior parte del tempo non farà niente.
L'evento che occupa di più il PIC è l'interrupt degli encoder: alla massima velocità ci sono circa 1600 impulsi per ogni encoder ogni secondo, nella condizione peggiore quindi 1 / 3200 = 1 impulso ogni 312,5 uSec che corrispondono comunque a 1562 istruzioni.

IntServiceRoutine

Il cuore di tutto è il timer (TMR0) che ogni 1mSec genera un interrupt.
Nella ISR vengono incrementati i timer (a 8, 16, 24 bit secondo la durata necessaria) che servono per le temporizzazioni delle varie routine.
Anche il computo dello spazio percorso tramite encoder ottici in quadratura, funziona ad interrupt,ognuno dei due encoder genera il proprio interrupt che, analizzato e confrontato con il flag di direzione, incrementa o decrementa le variabili di conteggio dello spazio.
Nella stessa ISR viene calcolata, ogni 50mSec, la velocità di avanzamento attuale,dividendo lo spazio percorso per il tempo.

PID


Una di queste è la MotSpeed che lavora in background e, ogni 50 mSec (dopo la misura della velocità), imposta il PWM (calcolato tramite un algoritmo PID) per fare in modo che la velocità attuale corrisponda con quella desiderata, .

/*MotSpeed ****************************************************************************
Controllo velocit‡ motori PID (Proportional + Integral + Derivative)
il ponte ad H Ë usato in modalit‡ "Locked Anti Phase" (LAP):
PWM = 128 -> motore fermo
PWM = 255 -> velocit‡ massima FWD (circa 200 mm/sec)
PWM = 0 -> velocit‡ massima REW (circa -200 mm/sec)
CCPR2L collegato al motore R
CCPR1L collegato al motore L
*/
void MotSpeed (void)
{
/* const divisore =((200-0)/(255-128)); rapporto tra range velocit‡ e range PWM = 1,57
viene moltiplicato per 100, il risultato finale Ë poi diviso per 100,
per mantenere la precisone di due decimali nei calcoli intermedi senza usare la virgola mobile
*/

A questo punto abbiamo un sistema a loop chiuso nel quale sappiamo la velocit‡, lo spazio
percorso ed il tempo trascorso.

Anche la routine PATH lavora in background e, se abilitata, controlla la sequenza di
operazioni da effetuare per seguire il percorso impostato da qualche altra routine che
decide il comportamento del bot.
La routine che decida di eseguire un percorso diverso dal normale, deve:
- impostare il flag di attivazione della routine Path
- scrivere nell'array PathSeq la sequenza di codici della manovra da effettuare
(0=fine sequenza)
- azzerare il puntatore della sequenza
Path comincer‡ allora a scandire l'array chiamando le routine in funzione del codice
impostato (cammina X cm, ruota Y gradi, cammina W mm/sec).
La routine chiamata (Walk, Turn) calcola lo spazio che deve percorrere ogni ruota prima
di ripassare il comando a Path.
A questo punto si Ë attivata Space2Run (schedulata da main) che si disattiva, ripassando
il controllo a Path, solo quando le ruote si sono mosse dello spazio desiderato.
Path controlla la sequenza successiva ripetendo le operazioni o restituendo il controllo
quando il codice Ë = 0.

/*Path ********************************************************************************
viene chiamata solo se (Space2RunFlag==0 & PathSeq[PathSeqPointer] != 0)
se Space2RunFlag = 1, sono ancora in esecuzione routine movimento e quindi non puÚ
passare allo step successivo
se PathSeq[PathSeqPointer]= 0 la sequenza Ë terminata e rilascia il controllo

routine che deve usare Path
-Imposta DesSpeedX = 0; // ferma motori
-imposta PathSeq con passi da fare in ordine (fine seq = 0)
-imposta PathSeqPointer = 0; // inizializza sequenza passi
-imposta Space2RunFlag = 0; // reset di qualsiasi routine di movimento

Se deve avanzare a velocit‡ costante si imposta semplicemente la velocit‡

*/

/*Turn ********************************************************************************

routine per girare a destra o a sinistra di un angolo desiderato

la rotazione è intorno al centro del bot senza avanzamento quindi le ruote girano una

in senso opposto all'altra, alla stessa velocità.

Qui calcola e imposta i valori per girare dell'angolo desiderato.

L'interasse del bot è di 140mm, la circonferenza lungo la quale girano le ruote è quindi

di PI * 140 = 439,823mm. Per ruotare di 180° ogni ruota deve fare metà circonferenza:

219.911micron (millesimi di millimetro), dividendo per 180 sappiamo che un grado

corrisponde a 1.222micron di spostamento di ogni ruota ((D * PI)/2/180).

Si considera:

0° la direzione di avanzamento

da +1 a +180° la rotazione in senso orario

da -1 a -180° la rotazione in senso antiorario


operazioni:

imposta: Space2RunXstart

calcola e imposta: Space2RunX

imposta velocità: DesSpeedX

imposta: Space2RunFlag a 1

*/

/*Walk ********************************************************************************

Calcola e inizializza le variabili per Space2Run, per camminare dello spazio desiderato

operazioni:

imposta: Space2RunXstart

Space2RunX è impostata dalla routine chiamante

imposta velocità: DesSpeedX

imposta: Space2RunFlag a 1

*/

/*Space2Run ***************************************************************************

controlla continuamente lo spazio percorso per pilotare i motori fino al raggiungimento

della posizione desiderata


operazioni:

controlla se spazio percorso >= spazio desiderato:

if yes, ferma motore corrispondente

se entrambi motori fermi: Space2RunFlag a 0 (si autodisabilita)


/* qualche routine ha abilitato il controllo dello spazio percorso,

ha impostato la velocità (DesSpeedX), lo spazio da percorrere (Space2RunX)

e la posizione di partenza (Space2RunXstart).

Questa routine sarà eseguita continuamente fino al raggiungimento della

posizione desiderata, dopodichè fermerà i motori e disabiliterà il flag

*/

/*Stop ********************************************************************************
Ferma i motori per X millisecondi (fino a 30 Sec)
*/
/*Bumpers ****************************************************************************
Controllo dei sensori di collisione
*/
------------------------------------------------------------------Links
"Where am I" sensors and methods for mobile robot positioning [1]
ftp://ftp.eecs.umich.edu/people/johannb/pos96rep.pdf
Encoders [2]
Understanding quadrature www.gpi-encoders.com/Understanding_Quadrature.pdf
Square wave and pulses www.gpi-encoders.com/Square_vs_Pulse_Waves.pdf
Pulsed sensor usage mobots.com/EeC194/Notes/1999_10_14.html
Description of shaft encoders www.mil.ufl.edu/imdl/papers/IMDL_Report_Spring_02/louis_brandy/shaft.pdf
PID & Motion control [4]
Manuale propedeutico sulle tecniche di regolazione, Prof. Livio S. Orsini [3]
www.plcforum.info/didattica/conreg/pagina1.htm
www.plcforum.info/didattica/conreg/pagina2.htm
www.plcforum.info/didattica/conreg/pagina3.htm
www.plcforum.info/didattica/conreg/pagina6.htm
www.plcforum.info/didattica/conreg/appendice.htm
Single motor speed control abrobotics.tripod.com/ControlLaws/singlemotor.htm
The Dilbert motion control www.barello.net/Papers/Motion_Control/
PID Without a PhD www.embedded.com/2000/0010/0010feat3.htm
Designing a PID Motor Controller www.seattlerobotics.org/encoder/200205/PIDmc.html
Control Theory Terminology www.newport.com/file_store/PDFs/tempPDFs/Control_Theory_e3987.pdf
Proportional - Integral - Derivative (PID) Theory and Fabrication www.mechatronics.me.vt.edu/book/Section3/PID.html
PID in detail www.mechatronics.me.vt.edu/book/Section5/PIDindetail.html
PID academic1.bellevue.edu/robots/mogotut/PID.htm
A Simple DC Motor Controller academic1.bellevue.edu/robots/mogotut/simplemotor.htm
Quick and Easy Motor Control www.circuitcellar.com/
PID motor control with Zilog Z8PE003 www.zilog.com/docs/z8/appnotes/pid_motor_control.pdf
PWM [6]
Pololu micro dual serial motor controller www.pololu.com/products/pololu/0401/
Choosing the right PWM frequency www.seattlerobotics.org/encoder/200011/pwm.html
PWM speed control www.4qdtec.com/pwm-01.html
Some power PWM drivers for DC motors www.picotech.com/applications/pwm_drivers/
Locked Anti Phase & sign magnitude[7] www.national.com/an/AN/AN-694.pdf
PWM forum www.seattlerobotics.org/encoder/sep99/pwmmail.html
Microchip AN594 ( usingCCP modules) [5] www.microchip.com/
H-Bridge Demystified www.barello.net/Papers/H-Bridge.ppt
Piccoli motori DC www.vincenzov.net/tutorial/motoridc/motoridc.htm
Robot Circuits www.geocities.com/robodave2000/circuits.htm
[DPRG] PWM wanderings nimon.ncc.com/pipermail/dprglist/2000-November/001560.html
Dead reckoning [8]
Implementing Dead Reckoning by Odometry… www.seattlerobotics.org/encoder/200010/dead_reckoning_article.html
A Tutorial and Elementary Trajectory Model… rossum.sourceforge.net/papers/DiffSteer/DiffSteer.html