Indice |
Presentazione del progetto
Primo semestre del primo anno del mio percorso di studi specialistico in Ingegneria Robotica e dell'Automazione. Tra i vari corsi che mi trovo a seguire ce n'è uno con un nome molto affascinante del quale, onestamente, prima non avevo mai sentito parlare: Informatica e Sistemi in Tempo Reale (per gli addetti ai lavori, lo studio dei sistemi operativi Real Time). La materia è apparsa sin da subito molto interessante e con un vasto campo di applicazioni, ma la cosa ancora più affascinante era che l'esame prevedeva una parte scritta "teorica" e la presentazione di un progetto: lo sviluppo di un'applicazione (in C++) utilizzando la libreria grafica Allegro e la libreria di gestione dei processi PThread (per esempio un videogame o un software di controllo per un set di motori). Nella "lista della spesa" proposta dal professore, io ed il mio compagno Dario con il quale ho sviluppato il progetto, siamo rimasti subito colpiti dalla sezione delle applicazioni per il dispositivo LEAP MOTION, in particolare dalla LEAP DRUM.
LEAP DRUMS è una batteria “virtuale” da suonare attraverso il dispositivo Leap Motion e rappresentata graficamente da un’interfaccia grafica sviluppata con la libreria Allegro su ambiente Linux Ubuntu. Le specifiche del progetto erano di creare un software capace di acquisire e gestire i dati provenienti dalla Leap Motion, avere un’interfaccia grafica intuitiva che simulasse la batteria e le bacchette; completa di statistiche relative all’esecuzione dei processi aggiornate in tempo reale, ed avere delle funzionalità aggiuntive come la possibilità di attivare un metronomo con tre diversi tempi.
L'idea prende spunto da un'applicazione già esistente della quale vi pubblicherò un video dimostrativo
Leap Motion
Ma che cosa è questo dispositivo con un nome anglosassone molto criptico?
Leap Motion è una piccola periferica USB ideata e disegnata ottimizzandone gli spazi per prendere posto sulle nostre scrivanie.
È composta da due telecamere e tre LED infrarossi che le permettono di osservare un’area semisferica di circa un metro di diametro.
Il device è progettato per riconoscere dita ed altri oggetti simili (per esempio nel nostro caso la punta di una bacchetta) con una precisione altissima; questo la differenzia da dispositivi come Kinect di Microsoft (che fa del raggio di azione il suo punto forte a discapito della precisione) e permette di utilizzare Leap per azioni come disegno ad alta precisione,navigazione, pinch-to-zoom, tap-screen, controllo di realtà aumentata, giochi e molto altro.
Ogni secondo la Leap fornisce 60 frames nei quali sono racchiuse tutte le informazioni relative a ciò che la Leap rileva nel suo raggio di azione: il numero di mani, la posizione di ogni giunto, la direzione delle dita di ogni mano, la presenza dei tool con tutte le relative specifiche e l’eventuale presenza di una gesture. Questo permette di avere una discretizzazione dei movimenti e di poterne prelevare informazioni relative a determinate posizioni o parti delle mani con una precisione nell’ordine del millimetro e del centesimo di secondo.
Analisi delle problematiche e struttura del programma
Questo articolo sarà "divulgativo", quindi non mi dilungherò a scrivere le parti di codice che compongono il software per non tediare troppo i lettori e perchè spesso il codice scritto da "altri" è di difficile comprensione. Mi limiterò a spiegarne la struttura e le funzionalità per lasciare nel lettore la curiosità e magari la voglia di cimentarsi con un progetto simile.
Come prima cosa è stato suddiviso lo sviluppo del progetto nelle diverse aree di interesse e ad ognuna assegnato un task: la sezione GRAFICA (allegro_task) e la parte di ACQUISIZIONE (leap_task) che rappresentano la base del progetto, mentre la gestione delle STATISTICHE (stats_task) e l’utility METRONOMO (metro_task) completano il software rendendolo più “interattivo”. I vari task accedono a strutture e variabili condivise, scrivendo e leggendo le variabili in continuo aggiornamento, implementando così le interazioni necessarie tra i task. I 4 task vengono eseguiti ciclicamente e ad ognuno di essi viene dato un periodo fisso in cui occupa il processore diventando il processo in esecuzione.
Lo schema di seguito è una rappresentazione della struttura del software, nel quale i rettangoli bianchi rappresentano le strutture o le variabili condivise, mentre i riquadri arancioni rappresentano i task che compongono il software.
Leap Task
Il leap task è uno dei due task principali ed è quello dedicato all’acquisizione dati (frames) dalla Leap Motion e alla riproduzione dei suoni. Il periodo è fissato a 4ms; la scelta è stata fatta empiricamente, tenendo di conto della latenza e soprattutto del rispetto della deadline. Questo task come prima cosa verifica la connessione della Leap Motion e successivamente richiama periodicamente la funzione gestione_leap che racchiude tutte le “operazioni” necessarie.
La funzione gestione_leap si occupa di selezionare i dati provenienti dalla Leap Motion e compiere le azioni adeguate all’accadere di determinati eventi. Ogni secondo riceve circa 60 frame, ognuno dei quali contiene tutte le informazioni relative alle mani, alle dita, ai tool ed alle gesture.
Per ottimizzare le prestazioni, la prima fase è stata quella di filtraggio del frame concentrandosi solo sui dati utili al nostro scopo: i tools (le bacchette), le dita (più precisamente la falange distale del dito indice) e una gesture specifica (tap screen), scartando così le informazioni relative ai movimenti della mano e dell’avambraccio. Ad ogni frame la funzione scrive nella struttura condivisa pointer la posizione (in coordinate x,y) della punta del dito indice (se presente) per poterne disegnare il “puntatore” sullo schermo.
Se nel frame viene rilevata l’eventuale presenza della gesture tap screen la funzione aggiorna una delle variabili bool (click_ma, click_mb, click_mc) presenti nella struttura pointer, comunicando ad allegro_task di dare un feedback su schermo di avvenuta pressione del corrispondente tasto all’utente (tramite l’ingrandimento temporaneo del puntatore). La gesture tap screen da all’utente la possibilità di attivare i vari metronomi e di chiudere l’applicazione. In questa parte avviene anche il settaggio dei parametri di metro_task , quali periodo e attivazione/disattivazione del ‘tick’ del metronomo.
La seconda parte della funzione gestione_leap è quella riguardante il rilevamento degli eventuali tool ed alla riproduzione dei suoni.
La batteria è composta da quattro strumenti (Charleston, Rullante, Grancassa e Crash) di conseguenza lo spazio soprastante la Leap Motion è stato diviso in quattro aree sul piano XZ: le due aree anteriori si trovano ad un’altezza di 20 cm (asse Y) separate l’una dall’altra di 2cm e le due posteriori a 22cm separate anche queste da una soglia di 2cm tra di esse e tra le due anteriori. Quando uno dei tool “entra” in una delle quattro aree oltrepassandone la soglia, viene richiamata la funzione playsample della libreria Allegro che permette di riprodurre il suono (i suoni utilizzati sono dei file WAVE) relativo allo strumento “colpito” e viene comunicato al task grafico lo strumento colpito tramite la variabile condivisa (array di bool) cond[]. Le aree sono state separate da una “soglia di sicurezza” di 2cm per ridurre la sensibilità del software, facilitando l’utente che non può vedere realmente le zone da colpire.
La funzione gestione_leap si occupa anche di calcolare la velocità del movimento in modo da poter regolare il volume della riproduzione (e quindi la dinamica del suono); tramite la struttura altezzatool ogni due frame (per avere una sensibilità maggiore) viene calcolato lo spostamento verticale e questo viene approssimato alla velocità considerando costante il periodo tra i vari frame. La struttura pointertool permette a leap_task di comunicare ad allegro_task la posizione delle bacchette sui ‘piatti’ virtuali nonché l’altezza.
Allegro Task
Allegro_task ha la funzione principale di disegnare su schermo lo sfondo, le immagini relative agli strumenti (quando viene suonato uno strumento il task legge nella variabile cond[], aggiornata dal leap_task, e lo sfondo diventa giallo), le statistiche relative ai task (slack e deadline miss), i pulsanti di attivazione dei metronomi, il pulsante di uscita dal programma e i puntatori delle bacchette e del dito. Tutte le volte che questo task viene eseguito, richiama la funzione blit che disegna sullo schermo tutto quello che è stato scritto su un buffer (buf), come lo sfondo e le immagini degli strumenti. Successivamente leggendo dalla struttura pointertool disegna i puntatori delle bacchette. Da questa struttura prende le coordinate X,Z della punta di ogni bacchetta, nonché l’altezza (Y) per poter variare il raggio del puntatore restituendo una sensazione di allontanamento del tool dalla Leap Motion (quando il puntatore si ingrandisce significa che la bacchetta si sta allontanando dalla soglia). Oltre ai puntatori delle bacchette, allegro_task si occupa anche di disegnare il puntatore del dito quando si vuole ‘spingere’ uno dei tasti virtuali.
Tutte queste azioni (e anche le operazioni svolte dagli altri task) vengono svolte fino a quando la variabile pointer.esc, aggiornata dal leap_task, viene trovata true: questa rappresenta la condizione di uscita dal ciclo while all’interno del task di allegro e di conseguenza la disattivazione dell’interfaccia grafica, lasciando attive alcune funzionalità dal terminale.
Metro Task
Questo task ha un periodo predefinito di 1sec, ma non viene eseguita alcuna operazione se non sono verificate le condizioni relative all’attivazione dei tre metronomi. Questo avviene tramite la struttura pointer; il leap_task scrive su dei valori bool (pointer.metroa, pointer.metrob, pointer.metroc) in seguito al riconoscimento della gesture tap screen, questi vengono letti dal task metro che decide se riprodurre il ‘tick’ o meno. In seguito allo screen tap viene inoltre modificato, dal leap_task, il periodo del metro_task con i 3 tempi selezionabili per il metronomo: 60, 120 e 180 bpm corrispondenti a tre periodi diversi (rispettivamente 1000ms, 500ms e 333ms).
Stats Task
Le statistiche effettuate riguardano:
- lo slack, ovvero il tempo ‘avanzato’ prima della deadline, le deadline miss per i 2 task principali (leap_task e allegro_task).
- le deadline miss dei 2 task principali.
- l’ avg_delay, il ritardo che intercorre tra la prima rilevazione software di un colpo su un ‘piatto’ e la riproduzione dell’audio.
La gestione è effettuata tramite dei buffer, gestiti come array circolari, che raccolgono, rispettivamente, gli ultimi MAX_REMTIME_SAMPLES e MAX_DELAY_SAMPLES campioni (fissati a 20 e 10). Il buffer per le statistiche sullo slack viene aggiornato ad ogni fine periodo, aggiungendo il nuovo campione calcolato sovrascrivendo il campione più vecchio, sia da leap_task sia da allegro_task. Il buffer per l’ avg_delay viene aggiornato ad ogni colpo battuto sulla batteria allo stesso modo.
Le statistiche vere e proprie vengono fatte dallo stats_task il quale usa delle funzioni che fanno la media su tutti i campioni presenti nei buffer e aggiorna delle variabili globali ogni 800 ms; queste variabili vengono poi lette da allegro_task che le disegna su schermo.
Video dimostrativo
Purtroppo, avendo girato il video in un laboratorio, il volume non poteva essere troppo "spinto". Spero comunque che sia un buon video dimostrativo, e che possa far capire il funzionamento e la particolarità di questo dispositivo.
Conclusioni
Durante lo sviluppo di questa applicazione sono rimasto affascinato dalle potenzialità della Leap Motion, ed è proprio su queto che vorrei concentrarmi in questo ultimo paragrafo del mio articolo.
Come prima cosa si nota che il prezzo di questo dispositivo (si aggira intorno agli 80$), è una cifra alla portata di molti, ma a mio avviso questo prezzo sarà destinato ad abbassarsi col tempo vista la crescente popolarità che sta guadagnando Leap Motion (HP l'ha già inserito in alcune tastiere e notebook). Inoltre è nata una collaborazione con l'altro "astro nascente" dei dispositivi per realtà aumentate: Oculus Rift. Oculus Rift è uno schermo da indossare sul viso per la realtà virtuale caratterizzato da una bassa latenza e da un ampio campo visivo adesso in mano al colosso Facebook che ne ha percepito l'enorme potenzialità. L'accoppiamento dei due oggetti (Oculus Rift+Leap Motion) permette un'esperienza di realtà virtuale che comprende la vista, l'udito e il movimento delle mani generando sensazioni molto forti a detta di chi ha potuto provare la cosa.
L'altro punto di forza del Leap Motion è che gli sviluppatori hanno messo a disposizione degli utenti le API in modo che chiunque possa sviluppare applicazioni che si interfacciano con il dispositivo. Questo fa si che la diffusione sia più facilitata e che il il prezzo da pagare sia relativo solo all'hardware, con la possibilità di sviluppare molteplici applicazioni in modo totalmente gratuito.
Cosa ci si aspetta nel prossimo futuro da questo piccolo ma potentissimo oggetto?
Le potenzialità della Leap Motion sono vastissime. Il futuro sta andando sempre di più verso le Realtà Aumentate: Operazioni chirurgiche a distanza, visite guidate in musei virtuali, guida di veicoli o droni con semplici gesti, sfogliare un e-book con un semplice swipe, ma non solo.. Un esempio applicativo che potrebbe facilitare la routine di persone sorde potrebbe essere quello di sviluppare un "traduttore" di Lingua dei Segni: la Leap Motion riconosce il gesto ed un elaboratore riproduce la parola corrispondente in modo che una persona sordomuta possa comunicare anche con persone che non conoscono la lingua dei segni. Questa è solo un'applicazione, ma se ne potrebbero trovare moltissime altre.
Insomma, concludendo, ritengo che questo "oggetto" possa rappresentare nel prossimo futuro una nuova frontiera in molti ambiti della vita quotidiana, aiutando persone con disabilità o riducendo delle normali operazioni in gesti semplici e veloci. Spero quindi di avervi messo addosso un po' di curiosità verso la Leap Motion e tutto il mondo della Realtà Aumentata. Vi saluto con alcuni video dimostrativi che mostrano le potenzialità di questi oggetti. Buona Visione!