Pagina 1 di 3

Automa a stati finiti

MessaggioInviato: 17 mag 2016, 10:37
da paofanello
Salve a tutti O_/
Avrei voluto rispondere a Foto UtenteTardoFreak direttamente qui, ma preferisco fare una domanda aperta a tutti :D
Sto lavorando ad un progetto di robotica di cui ora non voglio spiegarvi tutto, non perché mi state antipatici, ma semplicemente perché voglio fare un discorso più generale.
Mi è stato detto che un approccio di programmazione di macchina a stati finiti potrebbe essere ciò di cui ho bisogno, il problema è che cercando su internet ho trovato un po' di nozioni che poi si riducono sempre ad esempi di analisi di stringhe, test di password...
Vorrei un po' capire quali vantaggi porta questo approccio (è corretto chiamarlo così? ?% ), in quali applicazioni lo utilizzate voi, quanto sia difficile (e utile) implementarlo su un controllo di robotica e soprattutto se avete da consigliarmi materiale a riguardo (anche in inglese, preferibilmente online :roll: ).
C'è la difficoltà che non ho mesi per studiarmi l'argomento in tutto il suo splendore (che mi pare di capire sia abbastanza vasto) :( quindi vorrei indirizzarmi su uno studio (per ora) molto specifico...
Spero di non aver detto troppe cavolate, scusate il disturbo O_/ O_/

Re: Automa a stati finiti

MessaggioInviato: 17 mag 2016, 11:17
da DanteCpp
Dovresti essere più specifico sui gradi di libertà del tuo robot. Per un controllo discreto (dove le possibili situazioni a cui deve reagire il tuo drone sono finite e contenute), allora un automa a stati finiti mi sembra una soluzione pratica e veloce; come ad esempio il sistema di controllo di un ascensore.
Per qualcosa di più reattivo gli strumenti offerti dall'automatica classica sono sicuramente più appropriati.


Re: Automa a stati finiti

MessaggioInviato: 17 mag 2016, 11:39
da TardoFreak
Provo a risponderti anche se non sono la persona più titolata a farlo.
Ho studiato e sto studiando gli automi a stati finiti nel corso di linguaggi formali e traduttori. In effetti come hai potuto notare, questi automi vengono insegnati come base torica per il riconoscimento di stringhe e, di conseguenza, per i traduttori ed i compilatori.
Li ho trovati anche in un libro sul VHDL, applicati alla logica ed alle macchine a stati finiti.
ATTENZIONE: io sono un manovale e quindi prendi quello che ti dico "as is". Questo è semplicemente uno dei metodi che uso per scrivere programmi.
Io uso questa tecnica di programmazione perché la trovo comoda e veloce. In buona sostanza prendo carta e matita e disegno il funzionamento della macchina evidenziando gli stati. Gli stati sono collegati uno all'altro mediante degli archi, delle linee insomma, che indicano il perché l'esecuzione si sta spostando da uno stato all'altro.
Faccio un esempio con un robottino. Siamo nello stato in cui il robottino sta avanzando. Questo vuol dire che è passato attraverso uno stato che ha azionato il motore (io li tengo molto staccati gli stati, a volte ne faccio alcuni che potrebbero sembrare superflui ma mi trovo bene così) ed è passato in uno stato di attesa dal quale può uscire per due condizioni: ha raggiunto il punto desiderato o ha incontrato un ostacolo.
Questo è a grandi linee la macchina a stati.

Il programma in C che implementa questa macchina è il seguente:
Codice: Seleziona tutto
int16:t posizione;
...
posizone = n;

uint8_t stato = 0;
for(;;)
{
  switch(stato)
  {
    case 0:
      stato = 5;
      break;
    case 1:
      motoreOn();
      stato = 2;
      break;
    case 2:
      if (incontratoOstacolo()) { stato = 3; break; }
      if (getPosizione() == posizione) { stato = 4; break; }
      break;
    case 3:
      motoreOff();
      segnalaErrore();
      stato = 5;
      break;
    case 4:
      motoreOff();
      stato = 5;
      break;
    case 5:
      if (getComando() == MUOVI) { stato = 1; break; }
      break;
  }
}

Come puoi notare il lavoro più grosso è quello di scrivere un buon diagramma, ricco di particolari, e con tutti i riferimenti agli stati ed alle operazioni che deve eseguire.
Tradurlo poi in un programma in C è un qualcosa di meccanico. Se non ci sono errori di sintassi e la logica del diagramma è fatta bene il programma funziona al primo colpo.
L'ultimo lavoro che ho fatto è un'apparecchiatura con una logica di funzionamento non banale. Prevede diversi modi di funzionamento: autotest, programmazione interattiva dei parametri di funzionamento, funzionamento in modalità utente. Tutti questi modi fanno riferimento ad altrettante macchine a stati ed alcuni di questi modi devono poter essere interrotti in modo asincrono da alcuni eventi esterni.
Ho passato tre giorni e consumato parecchia carta nel disegnare i diagrammi. poi ho implementato le varie funzioni e le ho provate per verificarne il funzionamento, infine ho tradotto i diagrammi in quello "switch" lunghissimo in due o tre ore.
Ho scaricato il programma nell'apparecchiatura e questa ha iniziato a funzionare in modo perfetto.
E' chiaro che i diagrammi sono parte integrante del programma, senza i diagrammi è molto difficile capire cosa fa la macchina, ma un bel chissenefrega lo metto volentieri, anche perché ho risparmiato un mucchio di tempo.

Re: Automa a stati finiti

MessaggioInviato: 17 mag 2016, 11:59
da TardoFreak
Ho dimenticato un particolare importante: utilizzando questa tecnica si possono scrivere diversi task che vengono eseguiti in modo concorrente.
Se noti bene il programma gira all'infinito e non si ferma mai in un punto specifico. Nell'esempio c'è un solo switch che definisce il funzionamento della macchina ma avrei potuto metterne un altro che avrebbe fatto qualcosa d'altro in parallelo al primo. Ovviamente la variabile che memorizza lo stato di funzionamento di questa seconda macchina avrebbe dovuto avere un nome diverso, "stato2" ad esempio (notare la gran fantasia nel trovare i nomi delle variabili :mrgreen: )

In buona sostanza si possono ottenere buoni risultati senza utilizzare sistemi operativi multitasking, e questo è un bene soprattutto lavorando con le varie ciofeche ad 8bit.

Re: Automa a stati finiti

MessaggioInviato: 17 mag 2016, 12:30
da paofanello
TardoFreak ha scritto:Ho dimenticato un particolare importante: utilizzando questa tecnica si possono scrivere diversi task che vengono eseguiti in modo concorrente.

Ecco dove volevo arrivare :ok:
E' proprio questo che mi interessava degli stati finiti... (forse perché lavoro con una "ciofeca ad 8 bit"? :mrgreen: )
Come viene normalmente spiegato (e come sembra dai grafi) la macchina sembra "ferma in uno stato" fino al prossimo input (o "freccia"), e in effetti è così, ma solo per quel particolare switch :-k
Quindi praticamente ad ogni passaggio di stato il programma controlla prima tutto il resto del codice, e solo dopo svolge quello che deve fare nel nuovo stato, giusto? ?%

DanteCpp ha scritto:Dovresti essere più specifico sui gradi di libertà del tuo robot.

3 o 6 :mrgreen:
Non penso comunque di utilizzare completamente un approccio a stati finiti, solo, per le ragioni dette sopra, per alcune parti di codice può essere una soluzione interessante...

Re: Automa a stati finiti

MessaggioInviato: 17 mag 2016, 12:40
da TardoFreak
Il micro continua a ciclare senza sosta e senza pause. Per questo si possono mettere diversi switch (che corrispondono a diverse macchine) uno di seguito all'altro.
Il termine "fermo in uno stato" è un termine logico perché lo stato di funzionamento della macchina non cambia. Cambierà per qualche motivo ma la cosa importante è che il micro non è mai "inlooppato" in un ciclo di attesa tipo questo
Codice: Seleziona tutto
while(!isTastoPremuto()) leggiTasto();

Da qui non si schioda fino a quando non verrà premuto questo benedetto tasto. Cosa diversa è
Codice: Seleziona tutto
uint8_t stato = 0;
for(;;)
{
  switch(stato)
  {
    case 0:
      if (isTastoPremuto()) { stato = 1; break; }
      break;
    case 1:
      ...
      break;
  }
  pippo();
}

La macchina è bloccata nello stato 0 e di li non si muoverò fino a quando non verrà premuto quel benedetto tasto ma nota che la funzione pippo() viene eseguita continuamente ad ogni ciclo.
In buona sostanza il micro non s'inchioda mai. ;-)

Re: Automa a stati finiti

MessaggioInviato: 17 mag 2016, 12:43
da TardoFreak
Per avere due macchine che funzionano in contemporanea il programma assomiglierà a questo:
Codice: Seleziona tutto
uint8_t statoA = 0;
uint8_t statoB = 0;
for(;;)
{
  // Macchina A
  switch(statoA)
  {
    case 0:
      if (isTastoPremuto()) { statoA = 1; break; }
      break;
    case 1:
      ...
      break;
  }
  // Macchina B
  switch(statoB)
  {
    case 0:
      if (isCuloChePrude()) { statoB = 1; break; }
      break;
    case 1:
      grattaCulo();
      ...
      break;
  }
}

Re: Automa a stati finiti

MessaggioInviato: 17 mag 2016, 12:53
da DanteCpp
paofanello ha scritto:Quindi praticamente ad ogni passaggio di stato il programma controlla prima tutto il resto del codice, e solo dopo svolge quello che deve fare nel nuovo stato, giusto? ?%


Tieni presente che il parallelismo è solo apparente.

Per esempio se abbiamo due automi o agenti: Alice e Bob, che lavorano in "parallelo". Si arriva ad un certo punto in cui Alice deve percorrere 5 metri, mentre Bob deve sventolare una bandiera.
Se Alice ha la priorità su Bob, allora prima essa percorrerà i 5 metri e solo dopo Bob sventolerà la bandiera.

Una lettura interessante ma un po formale sui sistemi reattivi multi agente è Reactive Systems:
Modelling, Specification and Verification
.

Re: Automa a stati finiti

MessaggioInviato: 17 mag 2016, 12:58
da paofanello
TardoFreak ha scritto:Il micro continua a ciclare senza sosta e senza pause.

Certo poi sta a me scrivere funzioni (all'interno e fuori degli stati) che non provochino pause o cicli inutili...
Intanto ti ringrazio davvero tantissimo per le info e gli esempi, sono stati davvero chiari e mi hanno aperto uno spicchio di un mondo :mrgreen:
In effetti è una cosa che ho sempre cercato di fare (non far incartare il micro), utilizzando però file di if non proprio comode ed efficienti (ed evitando delay), ma penso che questo approccio semplifichi, anche a livello logico, le cose.

DanteCpp ha scritto:Tieni presente che il parallelismo è solo apparente.

Certo :ok:
DanteCpp ha scritto:Una lettura interessante ma un po formale sui sistemi reattivi multi agente è Reactive Systems:
Modelling, Specification and Verification
.

Grazie mille anche a te :ok: Appena posso lo guardo

Re: Automa a stati finiti

MessaggioInviato: 17 mag 2016, 13:11
da TardoFreak
paofanello ha scritto:
TardoFreak ha scritto:Il micro continua a ciclare senza sosta e senza pause.

Certo poi sta a me scrivere funzioni (all'interno e fuori degli stati) che non provochino pause o cicli inutili...
Intanto ti ringrazio davvero tantissimo per le info e gli esempi, sono stati davvero chiari e mi hanno aperto uno spicchio di un mondo :mrgreen:
In effetti è una cosa che ho sempre cercato di fare (non far incartare il micro), utilizzando però file di if non proprio comode ed efficienti (ed evitando delay), ma penso che questo approccio semplifichi, anche a livello logico, le cose.

Questa è solo una parte della logica dell'apparecchiatura, la parte semplice.
IMG_4720.JPG

Lascio alla tua immaginazione la parte impestata.
E ti lascio anche immaginare cosa vorrebbe dire fare tutto con gli if e menate varie.