PROGETTO DEL CORSO DI INTELLIGENZA ARTIFICIALE

Università "Roma Tre"

A.A. 1999/2000

Prof. M. Cialdea

Alessandro De Rosi, Caterina Dominijanni


 
 


INTRODUZIONE

Il sistema di base per usare l’ RCX consiste nell’ utilizzare oltre naturalmente l’ Rcx stesso un trasmettitore ad infrarossi e un PC. I componenti addizionali come motori e sensori permettono di costruire dispositivi robotici autonomi.

Il nucleo di RCX è costituito da un microprocessore Hitachi H8 con 32K di RAM. Il microprocessore è utilizzato per controllare tre motori, tre sensori e una porta seriale di comunicazione agli infrarossi. Nel chip c’ è una ROM di 16K contenente un driver che è lanciato quando RCX è stato acceso. Il driver è esteso scaricando all’ RCX 16K di firmware. Sia il firmware che il driver accettano ed eseguono i comandi inviati dal PC attraverso l’ interfaccia IR. Si possono anche scaricare programmi in byte code e memorizzarli in una regione di memoria di 6K. Il firmware in questo caso interpreta ed esegue il codice di questi programmi.

I byte code possono essere trasmessi utilizzando il protocollo di RCX direttamente dall’ interfaccia IR attaccata al PC. In questo modo attraverso l’ uso di un linguaggio di programmazione si può controllare l’ RCX in modo più interessante.

Ricordiamo in questa sezione che l’ invio dei byte code avviene in modalità BIG ENDIAN.
 

TRUSTY

Il linguaggio messo a disposizione dalla lego per programmare l’ RCX è il TRUSTY. Non consiste di un linguaggio di programmazione vero e proprio ma di un ambiente grafico in cui un programma è rappresentato da un insieme di mattoni messi in fila. I mattoni rappresentano le operazioni quali l’ accensione dei motori, il settaggio della loro potenza e della direzione. Sono previste istruzioni quali "repeat" ma comunque TRUSTY rappresenta un linguaggio limitato (ad esempio non si possono inserire due istruzioni repeat annidate) utile solamente a prendere pratica con le istruzioni RCX. I programmi scritti vengono quindi scaricati direttamente all’ RCX dopo di che possono essere da questo eseguiti. In figura è mostrato l’ ambiente di TRUSTY.


 

NQC

Per superare i limiti di TRUSTY (come ad esempio l’ assenza di dichiarazioni di variabili) è stato studiato un linguaggio dalla sintassi simile al C come d’ altronde ricorda il suo nome: Not Quite C.

NQC permette quindi di scrivere programmi per l’ RCX cosiddetti text-based. Per chi comunque conosce il C, NQC può sembrare molto familiare. Il codice sorgente di NQC è salvato in file di testo quindi NQC compila questi codici sorgenti in byte-code dopodiché può essere scarico nell’ RCX e quindi essere eseguito. Poiché NQC comunica con l’ RCX attraverso l’ IR tower è molto portabile. Può essere infatti fatto girare in ambienti tra cui MacOS, Linux e Windows 95, 98 e NT.

Se si lavora sotto Windows, NQC può essere utilizzato insieme con l’ RCX Command Center (RcxCC) che di fatto costituisce un editor ma che contiene simpatici strumenti per poter controllare l’ RCX utilizzando ad esempio un joystick visuale. In figura si può osservare una schermata di RcxCC con un semplice esempio di programma NQC.
 


 
 
 

legOS

Nella "LEGO Unofficial Guide" è scritto che legOS rappresenta il più potente tool disponibile per l’ RCX. legOS permette di programmare l’ RCX in molti linguaggi come l’ assembler, C o C++. legOS è un firmware che rimpiazza completamente quello di default di RCX. I programmi che si possono scrivere sono compilati con il codice sorgente di legOS per produrre un firmware. Per lanciare il programma basta scaricare tutto quanto nell ‘ RCX. Ogni volta che si deve cambiare il codice sorgente occorre ricompilare con logOS e scaricare l’ intero firmware. L’ ambiente ideale per legOS è Linux. Infatti legOS è costruito utilizzando egcs (il successore del compilatore GNU gcc). Comunque sono disponibili vari emulatori Linux per Windows in modo da utilizzare legOS anche sotto ambienti WIN32.
 
 

CONSIDERAZIONI FINALI PER TRUSTY, NQC, legOS

Nonostante questi tre "ambienti" (o linguaggi nel caso tale termine possa essere utilizzato) permettano di scaricare sull’ RCX programmi che eseguono operazioni anche abbastanza complesse (sicuramente con NQC e legOS), dal momento che tutti si basano sul fatto che il programma deve essere scaricato nella memoria di RCX, non consentono un controllo in linea dal PC che sicuramente rende più interessante l’ utilizzo dell’ RCX e apre per così dire nuove frontiere alle operazioni che può eseguire.
 
 

SPIRIT.OCX

Spirit.ocx è un ActiveX e quindi può essere utilizzato solamente in ambiente Windows. In particolar modo costituisce una libreria che può essere utilizzata attraverso Visual Basic e Visual C++. In questo modo l’ RCX può essere controllato in linea da un processo che è in esecuzione sul PC. Nella libreria sono presenti comandi che permettono di controllare la comunicazione che naturalmente avviene attraverso l’ interfaccia IR, controllare il firmware, comandi di tipo diagnostico (quali ad esempio un ping per controllare l’ esistenza dell’ RCX), comandi per così dire di sistema (come lo spegnimento dell’ RCX...) , comandi per controllare l’ input dei sensori o controllare l’ output come i motori...

Spirit.ocx dovrebbe rappresentare uno strumento abbastanza completo. Purtroppo abbiamo provato a richiamarlo attraverso Visual C++ 5 e in tutti i numerosi tentativi eseguiti il compilatore dava errori. D’ altra parte i molti esempi presenti in rete come d’ altra parte il "Technical Reference" della Lego che descrive accuratamente le funzioni disponibili, si riferiscono al Visual Basic.
 
 

JAVA

Per aggirare i numerosi ostacoli e le varie limitazioni incontrate con i precedenti linguaggi abbiamo preferito implementare il protocollo di trasmissione utilizzato dall’ RCX in JAVA.

In questo modo, utilizzando le Java Communication API fornite dalla SUN, abbiamo implementato un primo insieme di funzioni base che servono per inviare i byte-code che il microprocessore dell‘ RCX è in grado di interpretare. La comunicazione è gestita attraverso gli eventi in modo tale che ogni volta che l’ RCX risponde ad un comando inviatogli, il relativo byte-code che può rappresentare semplicemente la risposta al comando o il valore di una variabile (ad esempio il valore di un sensore), va a sovrascrivere il valore della variabile "lastvaluereceived". Tale primo insieme di funzioni è contenuto nella classe RCX.

Riportiamo di seguito una breve descrizione delle classi implementate. Per una comprensione migliore si rimanda ai commenti del codice.

Questa classe costituisce una interfaccia in cui sono dichiarate le funzioni per l’ invio e la ricezione dei dati attraverso una porta seriale. Questa classe implementa la classe RCXSerialPort in particolare le funzioni GetInputStream e GetOutputStream necessarie per l’ invio e la ricezione dei dati. Questa classe era stata prevista in un primo tempo ma comunque il suo utilizzo è necessario in quanto contiene il metodo parseString che converte una stringa (contenente il valore dei byte-code e dei relativi parametri) in un array di byte. Rappresenta l’ interfaccia dell’ ascoltatore relativo all’ evento di ricezione di un messaggio proveniente dall ‘RCX. Tale classe non solo implementa RCXListener ma rappresenta una libreria di funzioni a basso livello in cui sono implementati quasi tutti i messaggi relativi ai byte-code, e quindi alle operazioni, interpretabili dall’ RCX. Rappresenta una libreria a più alto livello, in cui quindi sono richiamati i metodi definiti nella classe RCX. E’ la classe in cui è definito il metodo main.
 

ARCHITETTURA, AMBIENTE E COMPITI SVOLTI DAL ROBOT

Attualmente il robot si muove su 2 cingoli, grazie a 2 motori (A e C), utilizza 3 sensori (due di tatto e uno di luce) e utilizza anche un motore che serve a far ruotare il sensore di luce.

 
 
 

 
 

Il motore di destra è il motore A, quello di sinistra il motore C. Il motore B è invece quello che fa ruotare il sensore di luce (sensore 3), grazie a 2 alberi e a delle riduzioni meccaniche che diminuiscono la velocità di rotazione del sensore (che risultava eccessiva anche a potenza minima del motore).

Il sensore 1 è il sensore di tatto posizionato sulla parte anteriore, utilizzato per urto frontale. Il sensore 2 è invece il sensore di tatto posizionato sulla parte posteriore, utilizzato per controllare la presenza o meno dell'oggetto da trasportare.

L'architettura attuale è stata molto alleggerita rispetto alla prima architettura sperimentata. E' stata alleggerita nella parte anteriore, anche per ridurre lo sbilanciamento introdotto da un eccessivo supporto per il sensore 1 e il sensore 3. Anche il supporto per l' RCX è stato alleggerito per ridurre il carico sui motori che azionano i cingoli.

Un grande miglioramento, soprattutto per quanto riguarda la stabilità dei valori restituiti dai sensori e dalla potenza dei motori, è stato riscontrato utilizzando un alimentatore al posto delle batterie. Naturalmente ciò comporta una limitazione, ma è necessario avere sempre un'alimentazione costante, soprattutto durante le prove, in quanto il movimento e i valori restituiti dal sensore di luce sono già resi instabili dai cingoli (che non hanno una stessa elasticità e dimensione) e le condizioni di luce (sono sufficienti delle nuvole per far variare considerevolmente i valori di luce letti dal sensore).

Per cercare di risolvere il problema dei cingoli, che a causa della loro elasticità creano una velocità sinusoidale nello spostamento del robot e che a causa della diversa elasticità tra un cingolo e l'altro creano asimmetria nel movimento, abbiamo provato a utilizzare altri pezzi per il movimento.

L'utilizzo di 4 ruote gommate con i motori destro e sinistro sulle rispettive ruote posteriori non permette però la rotazione. Con un'architettura abbastanza complicata (per le dimensioni e le imprecisioni dei pezzi LEGO) abbiamo costruito un sistema di locomozione 4x4. Purtroppo però il tentativo è fallito, essendo appunto poco stabile il sistema per l'eccessivo ma necessario utilizzo di pezzi (non molto precisi) e per l'attrito delle ruote anteriori che bloccano la rotazione. Nel tentativo di ridurre il peso sui motori che risultavano essere molto sotto sforzo a causa del 4x4, abbiamo utilizzato delle ruote anteriori più piccole, questo però rendeva ancora più complicata la rotazione. Per ridurre l'attrito delle ruote anteriori, quindi abbiamo utilizzato delle ruote posteriori di circonferenza maggiore. Ancora una volta la rotazione era difficoltosa e il carico sui motori eccessivo (saltavano addirittura le rotelline sui motori!).

Abbiamo quindi abbandonato l'idea di una locomozione 4x4 e abbiamo provato a montare un ruotino anteriore libero di girare a destra e sinistra. In questo caso si aveva un'ottima rotazione, molto veloce e pulita. Purtroppo però una volta ruotato era molto difficile riportare il robot su un cammino "retto".

Era necessario infatti che il ruotino si rimettesse in linea con le ruote posteriori, e questo era possibile solo dopo un "assestamento" poco controllabile: il robot deve andare avanti e grazie alla uguale velocità delle ruote posteriori il ruotino ritorna in posizione; è necessario però uno spostamento poco prevedibile.

Accantonata anche l'idea del ruotino libero anteriore abbiamo pensato di rendere più stabile lo spostamento con i cingoli. Abbiamo quindi tentato con un cingolo a 3 ruote, per cercare di tendere i cingoli (la tensione poteva essere aumentata solo in questo modo in quanto i LEGO permettono posizionamenti prestabiliti dei pezzi, essendo composti da fori e incastri che hanno distanze fisse e che non possono essere modificate, ma semplicemente incrementate o decrementate in maniera discreta).

Tentativo fallito anche questo poiché anche in questo caso si riscontrava un'asimmetria tra il lato destro e sinistro e sempre eccessivo lo sforzo a cui erano sottoposti i motori. Inoltre bisogna anche considerare il fatto che tutti i pezzi e in particolare gli assi sono costruiti in plastica e soggetti quindi a deformazioni.

La struttura attuale ci è sembrata quindi il miglior compromesso, rispetto alle prove realizzate, benché rimangano dei grossi problemi sulle rotazioni. Anche regolando i motori sulla massima potenza infatti, il robot non riesce a ruotare in modo costante e regolare, anzi riesce a fare solo piccole rotazioni alla volta.

Abbiamo avuto problemi anche nel costruire l'ambiente in cui il robot si muove, sempre per il problema dei valori restituiti dal sensore di luce.

Attualmente l'ambiente è costituito da un terreno di cartone bianco, su cui si trova un percorso nero e degli "incroci" in un colore "molto bianco". Le terminazioni della pista prevedono delle superfici verticali. Tali superfici sono bianche o nere per le "porte". E' infatti attraverso il colore delle porte che il robot capisce se vi è richiesta o meno. La "casa" (ossia il punto di partenza del robot e il luogo in cui ritorna per prendere l'oggetto da portare ove richiesto) e le "porte" vengono riconosciuti attraverso l'urto frontale che modifica il valore del sensore di tatto anteriore.


 
 

Il robot, partendo dalla posizione iniziale ("casa"), seguendo la pista nera, raggiunge il primo di un serie di incroci (che attualmente è impostato a 2, ma può facilmente essere modificato). Riconosciuto l'incrocio, attraverso il sensore di luce controlla che ci sia richiesta nella stanza di destra. Se vede "nero" capisce che c'è richiesta e torna alla "casa" ruotando e riposizionandosi sulla pista, che segue fin quando sente di aver raggiunto il muro della "casa" attraverso il sensore di tatto anteriore. Si ferma e aspetta che l'oggetto sia posizionato sul sensore di tatto posteriore, inverte nuovamente la sua direzione tornando all'incrocio in cui aveva letto la richiesta. Prosegue verso la porta da cui aveva ricevuto la richiesta finché urta con il sensore anteriore. Attende che l'oggetto venga sollevato dal sensore posteriore e ritorna nuovamente all'incrocio, controllando se l'altra stanza abbia necessità dell'oggetto. Se legge una richiesta torna torna alla "casa", porta l'oggetto alla stanza richiedente e continua a cercare le richieste. Se non ci sono richieste continua il suo giro tra i vari incroci senza tornare alla "casa" finché non ci sia una nuova richiesta.

Per il percorso nero, dopo aver provato il nastro isolante in plastica abbiamo poi optato per un nastro in stoffa, in quanto il colore nero viene letto più "chiaramente" (il valore letto è minore).

Per gli incroci abbiamo invece scelto delle superfici riflettenti, come i CD o la carta alluminio.

Il resto è invece in cartone bianco. Il sensore di luce è stato settato per restituire i valori in percentuale (tra 0 e 100). Mentre i sensori di tatto restituiscono 1 o 0.

Anche cambiando il terreno in cui il robot si muove, non siamo riusciti a migliorare la rotazione che risulta appunto diversa a seconda del terreno.
 
 

Ricerche future potrebbero svilupparsi quindi su un'architettura diversa che migliori la rotazione, basandosi comunque sulla nostra esperienza che vede fallimenti con:

    - ruote gommate,

    - 4x4,

    -cingoli con 3 ruote.

Si potrebbe continuare a sperimentare una struttura che preveda un ruotino anteriore, pilotato con un motore e un sensore di angolo (si potrebbe eliminare il sensore di tatto anteriore e avere il riconoscimento della "porta" e della "casa" attraverso il sensore di luce), oppure effettuando ancora delle prove con il ruotino libero e tentando di controllare il movimento e il riconoscimento della pista nera attraverso il sensore di luce (che risulta essere il migliore mezzo di controllo del robot, anche se forse andrebbe migliorato per riuscire a distinguere un maggior numero di colori, e per avere quindi una maggiore libertà nella costruzione dell'ambiente).

Altro aspetto da sviluppare potrebbe essere la ricerca di un ambiente migliore, studiando il comportamento del robot sulle diverse superfici.
 
 

DOCUMENTAZIONE

Clicca qui per scaricare il file jar contenente il codice da noi sviluppato.

Il sito principale del Lego MindStorms Robotics Kit è

http://www.legomindstorms.com Informazioni riguardo l’ architettura interna dell’ RCX si possono trovare in: http://www.crynwr.com/lego-robotics L’ insieme completo dei byte-code utilizzati dall’ RCX e la descrizione del loro utilizzo si possono trovare in: http://graphics.stanford.edu/~kekoa/rcx/opcodes.html Per quanto riguarda una descrizione più completa di TRUSTY, NQC e legOS si rimanda alla "LEGO Unofficial Guide" in cui oltre alla descrizione della sintassi dei vari linguaggi sono presenti numerosi link in cui trovare maggiori informazioni o per scaricare software.

In particolare riportiamo il link da cui scaricare RcxCC:

http://www.cs.uu.nl/people/markov/lego/rcxcc Le Java Communication API possono essere scaricate da: http://java.sun.com/products/javacomm/index.html