30 agosto 2018

Creo il mio ROBOT con Raspberry Pi #006 - Guida Autonoma!


Benvenuti nella sesta puntata della serie #Ro-Pi: creo il mio ROBOT con Raspberry Pi.

Continua la serie di appuntamenti con il fai-da-te smanettoso in compagnia dei single board computer della fondazione inglese raspberry pi. In particolare, partendo da quanto costruito negli episodi precedenti, oggi vedremo come rendere in qualche modo autonomo il nostro robottino nei suoi movimenti, sfruttando una coppia di sensori di tracciamento.

Prima di entrare nel merito, vi riporto il video abbinato a questo articolo che ho pubblicato sul mio canale YouTube nel quale sono mostrati i risultati in esecuzione e spiegata a grandi linee la sesta estensione al progetto:


Il sesto step di questa avventura ha visto una sistemazione del display che avevo aggiunto in precedenza (cosicché sia ora finalmente stabile sulla struttura) e l'aggiunta di due tracking sensor posizionati nella parte frontale del robot.

Nota: ho quasi completato la riscrittura di tutto il codice modulare, e la gestione delle nuove componenti è stata già pensata in questa ottica. Purtroppo c'è ancora qualcosa che non funziona al 100% relativamente al display LCD (la libreria utilizzata per il suo funzionamento non è compatibile con python3) per questo motivo non mi è ancora possibile caricare tutto online. Ma pian piano ci stiamo arrivando!


Componenti hardware necessarie


Una volta realizzati tutti e cinque i passi precedenti, per poter migliorare ancora una volta il nostro robot occorreranno due sensori di tracciamento.


Un tracking sensor è formato da almeno una componente emittente che trasmette raggi di luce ed una ricevente che è in grado di rilevarli: se il raggio colpisce una superficie bianca verrà riflesso ed il nostro sensore di tracciamento lo otterrà indietro; al contrario, se il raggio colpisce una superficie scura allora esso sarà assorbito ed il sensore di tracciamento non sarà in grado di rilevare nulla. A questi due stati corrispondono due valori differenti sul PIN di output, valori che è possibile sfruttare via codice per capire se è stato rilevato del bianco o del nero, e quindi compiere azioni di conseguenza.


Nota: questi sensori funzionano a distanze relativamente piccole dal piano, quindi vanno posizionati molto vicini ad esso altrimenti non si riuscirà ad ottenere alcuna informazione utile.

Come detto, un sensore di tracciamento ha un PIN con il quale comunica il suo stato ed altri due classici PIN: uno per il ground e l'altro per la corrente (il componente richiede 5V per funzionare, quindi il sensore va collegato al flusso corretto). Ogni sensore di tracciamento ha poi un LED che si attiva o disattiva in base allo stato rilevato.



Usare il sensore è cosa davvero semplice visto che con un immediato codice python si può creare un ciclo infinito nel quale viene analizzato lo stato del sensore che informerà se è stato rilevato oppure no del nero:

import RPi.GPIO as GPIO

TrackPin = 11

GPIO.setmode(GPIO.BOARD)
GPIO.setup(TrackPin, GPIO.IN)

try:
    while True:
        if GPIO.input(TrackPin) == GPIO.HIGH:
            print 'Nero'
        else:
            print 'Bianco'
except KeyboardInterrupt:
    pass

GPIO.cleanup()


Sfruttare le nuove componenti con #Ro-Pi


L'idea è quella di far avanzare il robottino finché viene rilevata la presenza della linea guida nera, oppure di tentare a ruotare a sinistra o destra per cercarla qualora essa diventi curva.

Nota: ovviamente in questo esempio si dà per scontato che il robottino si trovi in prossimità della linea guida e che non si allontani mai da essa.


Attivando la guida automatica, i sensori di tracking verranno avviati e forniranno costantemente informazioni sulla presenza o meno della linea guida nera. Ro-Pi avanzerà secondo una logica ben precisa: cerca la linea a sinistra, se la trova si riallinea ed avanza; in alternativa torna indietro e tenta a destra, se trova la linea si riallinea ed avanza; e così via...
I due sensori di tracciamento servono perciò a rilevare da sinistra e da destra la presenza della linea guida, cosa che con un solo sensore (posto centralmente) sarebbe un po' più arduo fare.

Nota: visto che la macchinina non è ben bilanciata e che comunque i movimenti non hanno una precisione millimetrica, è necessario fare un certo numero di tentativi, terminati i quali si può tornare indietro di un passo per ricominciare.



L'algoritmo così progettato non è sicuramente tra i più efficienti: il robottino farà una marea di piccoli passetti, tutti più o meno uguali, per avanzare. Sicuramente potrebbe farne di meno, almeno nei rettilinei... Agendo sui tempi di accelerazione, valutazione dello stato dei sensori, etc, si può nettamente migliorare l'intelligenza del nostro robottino. Argomento che potrebbe essere interessante toccare in futuri focus, così come la possibilità di sfruttare altri sensori o la camera per aumentare la precisione dei movimenti.


Un po' di codice...


In attesa di rilasciare tutto il codice sviluppato, questo è un estratto rielaborato di un possibile algoritmo da eseguire per far muovere autonomamente Ro-Pi:

[...] # import e codice restante

count = 0
reverse = 0
t = .5

while True:

    # black line already here
    if isOnTrack() == True :
        # go forward
        motor.forward()
        time.sleep(t)
        count = 0

    # no black line, so check sides...
    else :

        # check to the left
        if reverse == 1 :

            motor.forwardright()
            time.sleep(t)

            # black line not found
            if getTrack1() == 0 :

                # go back and set to check to the right
                motor.backwardright()
                time.sleep(t)
                reverse = 0
                count = count + 1

                # 5 try? go back and reset
                if count > 5 :
                    time.sleep(t)
                    motor.backward()
                    count = 0

            # black line found
            else :

                # re-align and go forward
                motor.forwardleft()
                time.sleep(t)
                motor.forward()
                count = 0

        # check to the right
        else :

            motor.forwardleft()
            time.sleep(t)

            # black line not found
            if getTrack2() == 0 :

                # go back and set to check to the left
                motor.backwardleft()
                time.sleep(t)
                reverse = 1
                count = count + 1

                # 5 try? go back and reset
                if count > 5 :

                    time.sleep(t)
                    motor.backward()
                    count = 0

            # black line found
            else :

                # re-align and go forward
                motor.forwardright()
                time.sleep(t)
                motor.forward()
                count = 0


Conclusioni


Bene, termina qui il sesto episodio della serie!

Prima di chiudere la puntata, ha senso sottolineare che i sensori di tracciamento possono essere utilizzati come base per rendere il robot un po' più autonomo. Ma essi possono anche essere sfruttati esattamente al contrario di come visto in questa guida: cioè per cercare due linee bianche poste ai lati della corsia e tentare di stare all'interno della stessa. Insomma fare un po' come fanno le vetture reali o i macchinari industriali in fabbrica che si muovono autonomamente in corsie a loro preposte. In questo caso un sensore si occuperà della linea sinistra della corsia e l'altro di quella destra, cosicché il robottino possa muoversi in avanti finché venga rilevato un rettilineo bianco, oppure deviare traiettoria in caso di curve. Per fare ciò chiaramente è sufficiente invertire il controllo sullo stato e tenere in considerazione i valori rilevati da entrambi i sensori.

A presto :-)

Nessun commento:

Posta un commento