Il Nao e la pallina verde.

Chi conosce il NAO?
Il nao è un robot umanoide con 25 gradi di libertà e con 2 videocamere. (I device di cui dispone sono molti di più, ma al nostro scopo sono stati utilizzati sono i motori e le videcamere).

È Stato utilizzato de me e dal mio collega Andrea Vannini per passare l’esame di Robotica. Il nostro intento è stato quello di permettere alla macchina di individuare la posizione della palla nello spazio circostante, fare avvicinare il robot alla palla con il piede sinistro e farlo calciare.

Il Robot è dotato anche di un sistema capace di calcolare in modo dinamico la proiezione del suo baricentro sulla superficie che gli fa da supporto. Lo stesso sistema permette di compensare il controllo diretto dei giunti con altri movimenti non controllati direttamente dall’utente che gli permettono di mantenere l’equilibrio sulla sua base d’appoggio.
Ossia , se il robot è in piedi con questo sistema attivato e gli impartisco il comando muovere la gamba destra verso l’esterno, il sistema autonomamente fa muovere il braccio sinistro per mantenerlo in equilibrio.

Non essendo riusciti, io e il mio collega, a fare funzionare nel modo corretto questo sistema abbiamo pensato di far calciare il Nao attraverso un semplice passo. In questo modo ci siamo concentrati più su l’aspetto riguardante l’intelligenza del nostro robot.

Un grosso collo di bottiglia con il quale abbiamo dovuto fare i conti è il fatto che il robot attraverso la connessione wifi riesce ad inviare al massimo 2 immagini al secondo ad una risoluzione di 640 x 480 pixel.
Tenendo conto del fatto che queste immagini dovevano poi essere elaborate dalla nostra applicazione per individuare se la pallina fosse presente nella scena, c’era a disposizione un dato ogni 0.8 secondi all’incirca per poter prendere una decisione.

Il risultato finale del nostro lavoro è che per effettuare il task il robot effettua questi passi:

-Si alza in piedi
-Cerca la pallina nello spazio circostante ruotando la testa e ruotando l’intero tramite l’uso delle gambe.
-Raggiunge la palla camminando
-Si allinea con la palla per calciarla
-Arretra e fa diversi passi avanti per calciarla.

Ma veniamo alle questioni più tecniche:  L’algoritmo.
Le seguenti elaborazioni avvengono tutte tramite l’utilizzo delle librerie OpenCV,  abbastanza conosciute nel mondo della computer vision.
Per consentire al robot di riconoscere la palla in qualsiasi condizione di luce,  e conoscendo noi a priori la precisa colorazione della palla, abbiamo fatto in modo di trasformare la normale immagine inviata dalla telecamera del robot (descritta tramite le cordinate dello spazio RGB) in un altra immagine descritta tramite lo spazio HSV. In questo modo è stato possibile imporre dei vincoli per delineare i pixel della palla senza imporre alcun vincolo sulla quantità di luce riflessa da essa. In questo modo il robot riconosce i pixel appartenenti alla palla in qualsiasi condizione di luce bianca.

foto1246

Il risultato di questo è un immagine “sogliata” ovvero un immagine nella quale i pixel che sicuramente non appartengono alla palla sono disegnati in nero mentre gli altri sono bianchi.
foto1248

A questo punto il problema diventa fare decidere al calcolatore se un gruppo di pixel bianchi di questa foto, costituiscono oppure no i pixel di una sfera.  Una sfera proiettata su di un piano corrisponde ad un cerchio. Quindi il problema si trasforma nel decidere se un gruppo di pixel bianchi presenti nella foto approssima sufficientemente bene un cerchio.

La cosa più ovvia per fare questo sarebbe utilizzare la “trasformata circolare di Houg” che segue (la falsa riga :D) della Trasformata di Hough. Tuttavia, la versione della trasformata fornita con le librerie OpenCV non funziona bene come si potrebbe pensare, o perlomeno non come desidereremmo che funzionasse per il nostro task.
Per questo motivo, ho personalmente riscritto una mia versione di questo algoritmo,che guarda caso è perfettamente funzionante!!!

Il problema però sta nel fatto che la mia versione è molto, molto lenta…
Da questo ne deduco che la versione fornita da OpenCV è un giusto compromesso tra affidabilità e velocità adottato dagli sviluppatori .

Per poter fare prendere decisioni al robot usando il mio codice , era necessario porre dei vincoli nella ricerca dei cerchi. Per questo abbiamo utilizzato questo stratagemma.

Tramite degli opportuni operatori ( Sobel) calcoliamo per ogni pixel facente parte del contorno dell’ipotetico cerchio, a direzione con massimo gradiente. (in parole povere la direzione attreaverso la quale si raggiunge un pixel bianco partendo da uno nero, percorrendo la minor distanza possibile). In un cerchio perfetto tutte queste direzioni convergono nel centro preciso del cerchio.

foto1249

foto1251

Detto tutto questo, calcolando il punto nel quale passano il maggior numero di queste linee, troviamo un punto che sarà probabilmente il centro di un cerchio.
Questo test però, origina un gran numero di falsi positivi. Ma per risolvere questo problema possiamo usare la mia versione della trasformata circolare di Hough riducendo lo spazio di ricerca con vincoli derivati dai valori appena trovati con il metodo dei gradienti.

foto1252

Il risultato è molto buono.