Ruzzle e Lego Mindstorm. Storia del robot di mattoncini che usando un tablet sfida gli uomini, problemi affrontati e qualche indicazione per costruirne uno analogo.
Una notte di qualche settimana fa, mentre stavo riordinando il classico mucchio di mattoncini colorati cercando di non far rumore, mi è venuta un’idea illuminante.
Vuoi per l’hobby dei Lego Mindstorm, vuoi per il mio lavoro di programmatore, vuoi perché nell’aria si sentivano gli inconfondibili suoni di Ruzzle, mi è balenato per la mente che avrei potuto unire le mie passioni in qualcosa di mai fatto: costruire sia la parte meccanica sia il software di un robot che giocasse a Ruzzle contro persone in carne ed ossa.
Il piano era ambizioso e il tempo a disposizione poco, ma l’idea di farcela era troppo allettante per non fare almeno un tentativo! E così ho iniziato da ciò che meno conoscevo…
Pronti, partenza, via!
Il primo problema è stato simulare il comportamento elettrico di un dito umano sullo schermo capacitivo del tablet che avevo a disposizione.
Dopo alcune ricerche, ho scoperto che le spugne conduttive assolvono egregiamente il compito, e per di più che le spugne vegetali per lavare i piatti (quelle gialle e verdi dal prezzo di circa 1€) sono conduttive. Credo di non essere mai andato al supermarket con così tanta voglia a fare la spesa.
Il secondo problema è stato riconoscere i caratteri: serviva fare una foto al tablet e riconoscere le lettere della ‘scacchiera’ di Ruzzle. Per fortuna per i cellulari android esiste il tool adb, e in un paio di istruzioni il gioco è fatto:
adb shell screencap -p /sdcard/screenshot.png
adb pull /sdcard/screenshot.png ruzzle_screenshot.png
Per riconoscere i caratteri ho usato Tesseract: si tratta di un OCR open source, lanciabile da linea di comando, che se opportunamente configurato permette di trasformare una immagine in un file di testo.
Trovare parole in una frazione di secondo
A questo punto sono partito con la parte di programmazione vera e propria, costruendo qualcosa che, data una griglia di 4×4 lettere e un dizionario, estraesse tutte le parole possibili. Se anche avessi trovato difficoltà insormontabili più avanti, avrei potuto comunque rendere pubblico il codice che avevo scritto, per permettere ad altri di continuare l’impresa.
Ho realizzato la logica di ricerca in Javascript, con NodeJS, ottenendo ottime prestazioni: il mio algoritmo in un decimo di secondo caricava oltre mezzo milione di parole da un dizionario, effettuava la ricerca e produceva come output le posizioni di alcune centinaia di parole, che avrei poi inviato al robot via bluetooth.
Dati gli ottimi tempi di risposta, ho deciso di raffinare il tutto introducendo un ordinamento alle mosse, da un lato per massimizzare il punteggio (partiamo dalle parole che danno più punti), dall’altro per minimizzare la distanza (non sprechiamo tempo in spostamenti inutili).
I robot costruiti
Non restava che costruire il robot, e questa è la parte che mi ha occupato più tempo.
L’idea di base è stata costruire un robot in grado di muoversi su 3 assi, usando i 3 servomotori a dispsizione del Mindstorm NXT.
Ho costruito un primo modello, ispirato ad un escavatore da cava, che aveva la spugna conduttiva al posto della pala, ma non era abbastanza rigido: durante le partite subiva alcune torsioni che rendevano poco preciso il movimento della spugna (in Ruzzle un errore di mezzo centimetro è sufficiente per perdere le mosse in diagonale).
A malincuore, ho distrutto il robot per costruirne un altro. Più bilanciato, estremamente rigido, con una forma che per certi versi può ricordare quella di una gru a ponte bitrave e per certi altri un plotter industriale.
I movimenti sugli assi X e Y erano precisi, con errori di pochi millimetri.
Il software del robot l’ho realizzato con NXC, un linguaggio di programmazione con una sintassi simile al C, che permette di leggere i dati restituiti da sensori e controllare i servomotori in dotazione. Per ottenere dei movimenti estremamente fluidi dai motori ho usato la libreria Absolute Position Regulation, che permette di regolare con un passo molto fine l’accelerazione e la velocità massima che ciascun motore dovrà raggiungere.
Ho acceso tutto, dedicato moolte notti al fine tuning, e il resto potete vederlo nel video postato su youtube e sul mio blog personale :)
Tutto il codice è open source: chiunque voglia proseguire l’impresa, può scaricarlo da github qua:
- Lego plays Ruzzle (albertosarullo.com)