.it m bm m ar gi @ Programmare Lego Robots con NBC (Version 0.02, Oct 31, 2006) di Ross Crawford traduzione e adattamento a cura di Giovanni Marcianò versione 0.1 - 30 novembre 2006 liberamente distribuibile con licenza CC Creative Commons Ministero della Pubblica Istruzione - IRRE Piemonte - 2006 traduzione e adattamento di G. Marcianò versione 0.1 - 30 novembre 2006 ar gi @ bm m .it Programmare Lego Robots con NBC di Ross Crawford m Ministero della Pubblica Istruzione IRRE Piemonte – Istituto Regionale Ricerca Educativa “Uso didattico della robotica” progetto N. 1280/05 delibera n. 106 del 22/12/05 sito web: http://robotica.irrepiemonte.it Responsabile: prof. Giovanni Marcianò per contatti: [email protected] - tel. 011 5606400 - cell. 338 5901442 -2- Programmare Lego Robots con NBC di Ross Crawford traduzione e adattamento di G. Marcianò versione 0.1 - 30 novembre 2006 Prefazione Il robot Lego MindStorms NXT è un nuovo kit con cui poter realizzare un’ampia serie di robot, programmabili per svolgere tanti e complessi funzioni. Purtroppo il software distribuito con l’NXT, sebbene molto attraente alla vista e ben più potente del programma RIS dell’RCX, è ancora per certi aspetti limitato rispetto alle funzionalità del robot. Per sfruttare tutte le potenzialità dell’NXT vi serve un differente ambiente di programmazione. NBC è un linguaggio di programmazione, scritto da John Hansen, che è stato sviluppato appositamente per i robot LEGO. Se non avete mai scritto un programma informatico, non preoccupatevi. NBC è facile da usare, e questo tutorial vi mostrerà come procedere. Al momento programmare un robot con NBC è più semplice che programmare un computer, cosicché rappresenta anche un modo semplice per iniziare a fare il programmatore. .it Per rendere ancora più semplice la stesura dei programmi, c’è BCC - Bricx Command Center (Centro di Comando dei Mattoncini programmabili). Questa utilityvi aiuta nella stesura dei programmi, nell’inviarli al robot, nell’avviare e fermare l’NXT. BCC appare come un programma per la redazione di testi, con alcuni pulsanti speciali. Questo tutorial è scritto per essere seguito usando Bricx Command Center (versione 3.3.7.15 o successiva) come ambiente di programmazione. Potete scaricare gratuitamente BCC dal sito a lui dedicato: m http://bricxcc.sourceforge.net/ Bricx Command Center è eseguibile anche su pc Windows (95, 98, ME, NT, 2K, XP). Il linguaggo NBC può anche essere scaricato dal sito: Riconoscimenti bm http://bricxcc.sourceforge.net/nbc/ ar gi @ Voglio ringraziare John Hansen per lo sviluppo di NBC. Molti ringraziamenti vanno anche a Mark Overmars per la scrittura del tutorial di NQC, sulla cui traccia questo tutorial per NBC è stato sviluppato.. Adattamenti per l’uso nelle scuole italiane – NBCjunior_ita m La traduzione del testo di Ross Crawford è integrata dalle prime indicazioni sul linguaggio NBCjunior_ita che – come già avvenuto con NQC per il robot LEGO RCX – l’IRRE Piemonte propone agli insegnanti come strumento didattico per un impiego della robotica finalizzato a obiettivi cognitivi e apprendimenti in contesti ben più ampi di quelli prettamente tecnologici e scientifici. Si rimanda alla relazione agli Atti del convegno Didamatica 2006 (Università di Cagliari, 11-13 maggio 2006 Atti, p. 185) “Linguaggi robotici per la scuola” per approfondire gli aspetti pedagogici e metodologico-didattici di ispirazione di quest’opera. (http://robotica.irrepiemonte.it/robotica/linguaggi/doc/linguaggi_robotici_scuola_2006x.pdf) Si veda inoltre http://robotica.irrepiemonte.it/robotica/linguaggi/pubblicazioni.htm Per aggiornamenti e altre documentazioni più generali in tema si rimanda al sito del progetto di ricerca http://robotica.irrepiemonte.it -3- Programmare Lego Robots con NBC di Ross Crawford traduzione e adattamento di G. Marcianò versione 0.1 - 30 novembre 2006 Indice Prefazione _________________________________________________________________ 3 Riconoscimenti _______________________________________________________________________ 3 Adattamenti per l’uso nelle scuole italiane – NBCjunior_ita ____________________________________ 3 Indice_______________________________________________________________________________ 4 I. Scrivere il primo programma ________________________________________________ 5 .it Costruire un robot _____________________________________________________________________ 5 Avviare BCC - Bricx Command Center ____________________________________________________ 5 Scrivere il programma__________________________________________________________________ 6 Avviare il programma __________________________________________________________________ 7 Errori nel tuo programma _______________________________________________________________ 8 Cambiare la velocità ___________________________________________________________________ 9 Scrivere commenti ____________________________________________________________________ 9 Riepilogo___________________________________________________________________________ 10 Tutorial NBCjunior – indicazioni operative ________________________________________ 10 m NBCjunior – primo step – comandi di movimento___________________________________ 10 II. Usare le variabili ________________________________________________________ 12 bm Muoversi in modi diversi ______________________________________________________________ Mostrare risultati sullo schermo _________________________________________________________ Numeri casuali (random)_______________________________________________________________ Riepilogo___________________________________________________________________________ 12 14 14 15 III. Controllo di flusso ______________________________________________________ 16 Le funzioni cmp e tst__________________________________________________________________ Le funzioni brcmp e brtst ______________________________________________________________ La funzione jmp _____________________________________________________________________ Cicli – ripetere una routine _____________________________________________________________ Riepilogo___________________________________________________________________________ 16 17 18 19 21 ar gi @ NBCjunior – secondo step – cicli di comandi da ripetere più volte______________________ 21 IV. Sensori _______________________________________________________________ 22 Come avviare un sensore ______________________________________________________________ Azioni controllate dal sensore di contatto __________________________________________________ Sensore di luce ______________________________________________________________________ Riepilogo___________________________________________________________________________ 22 23 23 25 NBCjunior – terzo step – sensore di contatto _______________________________________ 25 NBCjunior – quarto step – sensore di luce _________________________________________ 25 V. Fare musica ____________________________________________________________ 27 Note musicali _______________________________________________________________________ Eseguire files musicali ________________________________________________________________ Creare i propri effetti sonori ____________________________________________________________ Riepilogo___________________________________________________________________________ 27 28 28 29 m NBCjunior – quinto step – eseguire file sonori ______________________________________ 29 VI. Note finali _____________________________________________________________ 31 -4- Programmare Lego Robots con NBC di Ross Crawford traduzione e adattamento di G. Marcianò versione 0.1 - 30 novembre 2006 I. Scrivere il primo programma In questo capitolo vi mostriamo come stendere un programma molto semplice. Vogliamo programmare il robot per procedure in avanti per 4 secondi, quindi indietro per altri 4 secondo, e quindi fermarsi. Niente di spettacolare ma serve per introdurvi ai primi concetti della programmazione. E a mostrarvi quanto sia semplice. Ma prima di scrivere il programma, serve un robot. Costruire un robot m ar gi @ bm m .it Il robot che useremo per tutto il tutorial sarà “Tribot”, realizzabile seguendo le istruzioni comprese nel kit NXT. Se sei alla prima esperienza di uso dei robot LEGO, ti raccomandiamo di seguire i tutorials compresi nel software LEGO, per avere una prima conoscenza delle potenzialità dell’NXT . Il robot dovrebbe avere questo aspetto: (Nota: il modello Tribot si sviluppa da come sopra illustrato con l’aggiunta di sensori e di una pinza anteriore. Sarebbe comunque meglio per ora avere Tribot senza altri componenti, che potrebbero essere solo un ostacolo per le prime prove che faremo) Avviare BCC - Bricx Command Center Scriveremo i nostri programmi usando BCC - Bricx Command Center. Avviatelo con un doppio clic sull’icona BricxCC; ovviamente avrete già provveduto a installare Bricx Command Center sul vostro pc. In caso contrario, -5- Programmare Lego Robots con NBC di Ross Crawford traduzione e adattamento di G. Marcianò versione 0.1 - 30 novembre 2006 bm m .it scaricatelo da Internet (come indicato nella Prefazione), e installatelo nella directory che desiderate. All’avvio il programma vi chiede come connettersi al robot. Accendete il robot e premete OK. Il programma (molto spesso) troverà automaticamente il robot. Quindi l’interfaccia utente apparirà così: (senza la finestra col programma già scritto). L’interfaccia appare come quella di un qualsiasi editor di testo, con i soliti menu e bottoni per aprire e salvare files, editarli, ecc. Ma vi sono anche alcuni menu speciali per compilare e scaricare i programmi nel robot, e per avere informazioni sul suo stato Per ora potete ignorare questi comandi speciali. ar gi @ Iniziamo un nuovo programma. Clic sul bottone New File per creare una nuova finestra vuota. Scrivere il programma Digitate nel nuovo foglio il seguente programma: #include "NXTDefs.h" m thread main OnFwd(OUT_B,100) OnFwd(OUT_C,100) wait 4000 OnRev(OUT_BC,100) wait 4000 Off(OUT_BC) exit endt Può apparire un po’ complicato a prima vista, per cui vediamo di comprenderlo. Un programma in NBC è formato da threads. In questo caso ne abbiamo uno solo, dal nome main. Ogni programma deve avere un thread dal nome main che è il primo eseguito dal robot. Potrete avere maggiori informazioni sui threads nel Capitolo V. un thread è formato da una serie di comandi, anche detti statements. Ogni statement sta su una sola riga, dal che una procedura completa appare così: -6- Programmare Lego Robots con NBC di Ross Crawford traduzione e adattamento di G. Marcianò versione 0.1 - 30 novembre 2006 thread main statement1 statement2 endt La prima linea del nostro programma carica il file NXTDefs.h, che contiene il codice del linguaggio, o meglio i singoli elementi (costanti, macro, brevi procedure come OnFwd, OUT_B, ecc.) che servono per sviluppare i nostri programmi . Tutti questi elementi sono spiegati man mano. Per ora il nostro primo programma ha sette statements. Vediamoli uno per uno: OnFwd(OUT_B,100) Questo statement dice al robot di avviare l’uscita B, quindi il motore connesso all’uscita dell’NXT identificata con B, e di avviarsi in avanti (Fwd=forward). La cifra 100 specifica la percentuale rispetto alla massima velocità, nel nostro caso quindi il motore si avvierà alla massima velocità (100%). .it OnFwd(OUT_C,100) Lo stesso statement ma che avvia il motore C. Dopo questi due statements, entrambi i motori saranno avviati, e il robot si muove in avanti. wait 4000 m Ora bisogna attendere un po’. Questo statement realizza una pausa di 4 secondi. L’argomento riporta il numero di millisecondi, ovvero 1/1000 di secondo. In questo modo si può essere molto precisi nel definire nel programma la durata di singole azioni. Nel nostro caso per 4 secondi, il program non fa nulla e il robot continuerà a muoversi in avanti. OnRev(OUT_BC,100) wait 4000 Di nuovo una pausa di 4 secondi. Off(OUT_BC) ar gi @ E infine spegniamo entrambi i motori. bm O anche il robot si è mosso in avanti quanto volevamo dobbiamo dirgli di tornare indietro (Rev= Reverse=indietro). Notate che possiamo dare il commando a entrambi i motori con un solo statement usando OUT_BC come argomento. Avremmo però potuto fae come prima, con due separati statements. Avremmo anche potuto scrivere OnFwd(OUT_BC,-100). exit Questo statement dice all’NXT che il thread è terminato. Anche se non è obbligatorio alla fine di ogni threads, è raccomandabile metterlo. Questo è tutto il programma. Avvia entrambi i motori in avanti per 4 secondi, poi indietro per 4 secondi, e infine li spegne. Avrete probabilmente notato i colori delle scritte mentre digitate i comandi. Appaiono automaticamente. Il colore e lo stile usato dall’editor per il controllo della sintassi è modificabile a piacere, tramite le “preferenze”. Avviare il programma m Dopo aver scritto il programma questo dev’essere compilato (ovvero tradotto nel codice proprio del robot) e inviato al robot NXT usando o il cavo USB o la connessione Bluetooth, se disponibile (questa operazione congiunta è denominata “scaricare” il programma). Ovviamente prima di scaricare il programma bisogna dargli un nome per poterlo salvare sul vostro hard disc. Dopo averlo salvato controllate che l’estensione sua “.nbc”, che indica un programma in linguaggio NBC editabile in BCC - Bricx Command Center. -7- traduzione e adattamento di G. Marcianò versione 0.1 - 30 novembre 2006 bm m .it Programmare Lego Robots con NBC di Ross Crawford Dopo averlo salvato, lo potete compilare e scaricare semplicemente con un clic sul bottene “download”. Se non avete fatto errori di battitura il programma sarà compilato correttamente e scaricato. (Se vi fossero invece degli errori li vedrete evidenziati e segnalati, come si spiega più avanti) ar gi @ Ora potete eseguire il programma nel robot. Per farlo accedete al menu “Software Files” del vostro NXT, e cercate “1-simple”, a questo punto col bottone arancione dell’NXT lo avviate. In alternative potete farlo direttamente da BCC-Bricx Command Center, cliccando il bottone verde “run” sulla barra dei pulsanti (vedere l’illustrazione sopra, due pagine prima di questa). Il robot si comporta come immaginavate programmandolo? Se così non fosse probabilmente avete connesso male l’NXT ai motori; controllate. Errori nel tuo programma m Quando si digita un programma esiste una buona probabilità di fare errori di battitura. Il compilatore vi avvisa degli errori indicandovi dove e cosa non va, come mostra l’illustrazione qui sotto: -8- Programmare Lego Robots con NBC di Ross Crawford traduzione e adattamento di G. Marcianò versione 0.1 - 30 novembre 2006 Automaticamente viene selezionato il primo errore (si è indicato un nome di motore inesistente). Quando ci sono più errori potete selezionarne uno a vostro piacere per individuarlo nel listato. Attenzione: spesso un errore all’inizio del programma causa altri errori a catena, nel corpo del programma. Per questo è bene cominciare a correggere gli errori a partire dal primo, e dopo ricompilare il programma una seconda volta, per verificare quali errori restano. **** Attenti: l’evidenziazione in colore dei comandi dovrebbe aiutarvi a evitare errori di battitura. Per esempio, nell’ultima riga abbiamo digitato Of invece di Off. Dato che questo è un comando sconosciuto non viene evidenziato e colorato, così potete vedere l’errore prima di procedure con la compilazione. Vi sono anche errori che il compilatore non rileva. Se avete digitato OUT_B questa parola non viene indicata come errore perché il motore esiste (anche se il robot non ce l’ha in uso). Se il vostro robot mostra un comportamento inatteso, può anche essere perché nel vostro programma c’e’ qualcosa di sbagliato dal punto di vista logico. .it Cambiare la velocità m Come avrete notato il robot si muove abbastanza velocemente. Di suo il robot si muove al massimo della sua velocità. Per cambiare questo aspetto bisogna usare un diverso valore nel comando OnFwd. La potenza del motore è un numero tra 0 e 100, e specifica la percentuale rispetto alla potenza massima. Eco una diversa versione del nostro programma, in cui il robot si muove lentamente: #include "NXTDefs.h" bm thread main OnFwd(OUT_BC,25) wait 4000 OnRev(OUT_BC,25) wait 4000 Off(OUT_BC) exit endt ar gi @ In questo esempio, potete osservare come il valore della velocità e dell’attesa vengono ripetuti più volte. Se vi venisse in mente di cambiarli, dovreste fare questa correzione più volte, ovunque il valore sia riportato, e potreste scordarne uno. Per questo in NQC si possono definire delle costanti come appare in questa altra versione del nostro programma. #include "NXTDefs.h" #define SPEED #define MOVE_TIME 25 4000 thread main OnFwd(OUT_BC, SPEED) wait MOVE_TIME OnRev(OUT_BC, SPEED) wait MOVE_TIME Off(OUT_BC) exit endt m A questo punto, per cambiare velocità o pausa, basta cambiare una volta sola il valore nella dichiarazione della costante. Scrivere commenti Per rendere un programma più comprensibile è buona pratica commentarlo. Ogni volta che mettete // in una linea, il resto di quella linea viene ignorato dal compilatore e quindi potete scrivere quello che volete. Un commento lungo, su più righe, può essere compreso tra /* e */. Anche i commenti possono essere evidenziati dal controllo di sintassi di BCC-Bricx Command Center. Alla fine il programma può apparire così: -9- Programmare Lego Robots con NBC di Ross Crawford /* traduzione e adattamento di G. Marcianò versione 0.1 - 30 novembre 2006 Forward and reverse by Ross Crawford This program makes the robot go forward and backward */ #include "NXTDefs.h" 25 4000 thread main OnFwd(OUT_BC, SPEED) wait MOVE_TIME OnRev(OUT_BC, SPEED) wait MOVE_TIME Off(OUT_BC) exit endt // // // // // // Drive forward Wait for 4 seconds Drive backward Wait for 4 seconds Stop moving Exit m Riepilogo .it #define SPEED #define MOVE_TIME bm In questo capitolo avete scritto il vostro primo programma in NBC, usando BCC-Bricx Command Center. Ora sapete come si può scrivere un programma, come scaricarlo nel robot NXT e farlo da questi eseguire. BCC-Bricx Command Center può anche fare molte alter cose. Per questo è bene leggere la documentazione che avrete scaricato con il software. Questo tutorial vuole soprattutto aiutarvi a usare il linguaggio NBC e accenna solo alle altre caratteristiche di BCC-Bricx Command Center, quando sono necessarie per il nostro lavoro. ar gi @ Avete anche appreso alcuni aspetti importanti del linguaggio NBC. Prima di tutto avete appreso che ogni programma ha una procedura (thread) di nome main che viene sempre eseguita dal robot.avete poi imparato i più importati comandi per il controllo di un motore:: OnFwd, OnRev e Off, e anche i comandi wait e exit. Infine, avete capito a che servono e come si possono usare delle costanti per semplificare le correzioni di un programma, e come commentare il vostro codice Tutorial NBCjunior – indicazioni operative Scaricando e installando la versione 3.3 di BCC-Bricx Command Center avete nella cartella “Examples/tutorials” tutti i listati che in questo testo servono a illustrare le funzionalità del linguaggio NBC. Potete a parte scaricare dal sito dell’IRRE Piemonte (http://robotica.irrepiemonte.it/robotica/linguaggi) i file che permettono di usare il macrolinguaggio NBCjunior, in italiano, con cui alunni della scuola elementare e media possono padroneggiare la programmazione del robot LEGO NXT. m Riporto in questo capitolo i macrocomandi e un esempio d’uso equivalente a quanto trattato sopra con il linguaggio nativo NBC. Allo stesso modo nei prossimi capitoli. NBCjunior – primo step – comandi di movimento - 10 - Programmare Lego Robots con NBC di Ross Crawford traduzione e adattamento di G. Marcianò versione 0.1 - 30 novembre 2006 Il file “NBC_itajunior1-AVANTIINDIETRO.nbc” riporta una semplice procedura che :permette di attivare i tre motori in dotazione all’NXT, e impiegati nel modello Tribot a cui questo tutorial fa riferimento. /* AVANTIINDIETRO.nbc di Giovanni Marcianò novembre 2006 */ m .it #include "NXTDefs.h" /* FOGLIO BIANCO NXT01baby - rel 22/11/06 in questo foglio si possono usare i comandi in italiano che vedete qui sopra non cambiate nulla in queste righe ... scrivete da qui in poi! */ ………… Robby avanti(30,1000) apripinza(30,300) destra(30,1000) sinistra(30,1000) afferra(30,500) indietro(30,2000) ciao Robby Questo macrocomando è obbligatorio all’inizio di ogni programma, sul piani informatico sostituisce thread main, sul piano didattico costituisce il vocativo che apre la lista dei comandi da dare al robot. . avanti(vel,tem) apripinza(vel,tem) bm Questo macrocomando dice al robot di avviare i motori collegati alle uscite B e C, quindi di avviarsi in avanti. Vi sono due parametri: vel specifica la percentuale rispetto alla massima velocità, nel nostro caso quindi il robot si avvierà lentamente (30% della potenza totale), e avanzerà per un secondo (1000 millesimi di secondo). Lo stesso macrocomando ma che avvia il motore A che nel Tribot controlla la pinza anteriore. Anche qui gli stessi parametri visti prima, che però determinano la velocità di apertura della pinza, e il tempo (quindi l’apertura) delle stesse. ar gi @ destra(vel,tem) Questo macrocomando dice al robot di gestire i motori collegati alle uscite B e C in modo da voltare a destra. Vi sono due parametri: vel specifica la percentuale rispetto alla massima velocità, nel nostro caso quindi il robot ruoterà lentamente (30% della potenza totale), e per un secondo (1000 millesimi di secondo). che al 30% della potenza è circa 90° - si tenga comunque sempre conto dei fattori come la carica delle batterie e l’attrito del suolo che influenzano molto il risultato finale. sinistra(vel,tem) Questo macrocomando dice al robot di gestire i motori collegati alle uscite B e C in modo da voltare a sinistra. Valgono le stesse osservazioni per destra(vel,tem). afferra(vel,tem) Macrocomando opposto a apripinza; avvia il motore A che nel Tribot controlla la pinza anteriore, facendola chiudere. Valgono le stesse osservazioni sul parametri del macrocomando apripinza(vel,tem) indietro(vel,tem) m Macrocomando opposto a avanti; avvia i motori BC all’indetro, facendo quindi arretrare il robot. Valgono le stesse osservazioni sul parametri del macrocomando avanti(vel,tem) ciao Questo macrocomando chiude il programma. Dice all’NXT che il thread è terminato. Anche se informaticamente non è obbligatorio, è comunque raccomandabile metterlo. Si raccomanda di considerarlo obbligatorio dato che sul piano didattico– salutando il robot – si realizza il senso di compiutezza del compito che l’alunno ha svolto nel programmare Robby - 11 - Programmare Lego Robots con NBC di Ross Crawford traduzione e adattamento di G. Marcianò versione 0.1 - 30 novembre 2006 II. Usare le variabili L’uso di variabili è un aspetto molto importante nella programmazione. Le variabili sono locazioni di memoria in è possibile conservare dei valori. Potremo quindi usare questi valori in ogni parte del programma e modificarne il valore in modo molto facile.Vi spiego come operare in questo esempio. Muoversi in modi diversi Poniamo che vogliamo adattare il programma che abbiamo scritto prima in modo che non ritorni alla stessa velocità con cui si è mosso all’andata. Questo potrebbe essere fatto mettendo un valore di velocità inferiore nel comando di ritorno. Come possiamo farlo? SPEED è una costante e le costanti non possono cambiare. Ci serve una nuova variabile. Le variabili possono essere facilmente definite in NBC. Ecco il programma. #include "NXTDefs.h" 4000 100 25 .it #define MOVE_TIME #define SPEED #define DECREMENT m dseg segment Speed byte dseg ends bm thread main set Speed SPEED OnFwd(OUT_BC, Speed) wait MOVE_TIME sub Speed, Speed, DECREMENT OnRev(OUT_BC, Speed) wait MOVE_TIME Off(OUT_BC) exit endt ar gi @ Abbiamo dichiarato la variabile Speed nel nostro programma. Ogni variabile del nostro programma deve essere dichiarata in una sezione “dati” (data segment). Si possono inserire tanti dati quanti si vuole, e quindi li si possono usare in ogni parte del programma. Tutte le variabili di NBC sono “globali”, quindi sono disponibili in tutto il codice e in ogni thread. Un “data segment” si avvia con il commando segment, e termina col commando ends. Ogni segment deve avere un nome e il nome di segment e di ends devono coincidere. Vediamo i nuovi comandi del nostro programma. dseg segment Qui si avvia un data segment di nome “dseg”. Nel nostro programma, è l’unico data segment contiene una sola variabile. Speed byte m Questo comando dichiara la variabile “Speed” di tipo “byte”. Il nome di una variabile deve cominciare con una lettera. ma può avere al suo interno delle cifre e il carattere “_”. Nessun altro simbolo è permesso (queste stesse regole si applicano a costanti, nomi dei thread, ecc.) dseg ends Questo comando chiude il data segment “dseg”. set Speed, SPEED Questo comando assegna il valore di SPEED (la costante definite prima) alla variabile Speed. Notate che questo può anche essere fatto nel dichiarare la variabile, aggiungendo il valore iniziale dopo aver indicato il tipo; esempio: Speed byte SPEED. sub Speed, Speed, DECREMENT - 12 - Programmare Lego Robots con NBC di Ross Crawford traduzione e adattamento di G. Marcianò versione 0.1 - 30 novembre 2006 Questo commando sottrae il valore di DECREMENT dal valore presente nella variabile Speed, e salva il risultato nella stessa variabile. Quando il programma viene eseguito, il vostro robot dovrebbe procedure in avanti a piena velocità per il tempo che avete stabilito, e poi tornare sempre per lo stesso tempo a una velocità inferiore. Oltre che sottrarre un valore da una variabile, possiamo anche moltiplicare la variabile per un numero, sommarla o dividerla. (Notate che nel caso della divisione il risultato viene arrotondato all’intero più vicino) Si può anche sommare più variabili, e anche scrivere complicate espressioni. ecco un esempio: dseg segment aaa byte bbb byte ccc byte dseg ends // // // // // aaa bbb ccc ccc ccc is is is is is now now now now now to to to to to 10 100 100 10 15 bm exit endt equal equal equal equal equal m thread main set aaa, 10 mul bbb, 20, 5 mov ccc, bbb div ccc, ccc, aaa add ccc, ccc, 5 .it #include "NXTDefs.h" Vediamo nel dettaglio questi nuovi comandi: set aaa, 10 L’abbiamo già visto ma ora comprendiamo che a un comando set deve seguire una costante. In questo set opera in modo diverso dal comando mov. mul bbb, 20, 5 ar gi @ In questo caso moltiplichiamo 20 per 5, e mettiamo il risultato nella variabile bbb. Il secondo e terzo elemento possono essere costanti o variabili. mov ccc, bbb Questo comando copia (muove) il valore della variabile bbb alla variabile ccc. Diversamente da set, il secondo argomento di mov può essere sia una costante che una variabile. div ccc, ccc, aaa Questo comando divide ccc per aaa e mette il risultato in ccc. Notate che il risultato è un numero intero, senza decimali. add ccc, ccc, 5 m Questo comando aggiunge 5 a ccc. - 13 - Programmare Lego Robots con NBC di Ross Crawford traduzione e adattamento di G. Marcianò versione 0.1 - 30 novembre 2006 Mostrare risultati sullo schermo Abbiamo visto che alla fine il valore di ccc dovrebbe essere 15. Ma come si può controllare? Il modo più semplice e far apparire questo valore sullo schermo dell’NXT. Questo è abbastanza semplice – c’e’ un comando si sistema per farlo. Ecco come si fa: #include "NXTDefs.h" // // // // // aaa bbb ccc ccc ccc NumOut(10, 8, 1, ccc) wait 2000 is is is is is now now now now now to to to to to 10 100 100 10 15 // wait so you get to see it! exit endt bm è facile da capire, comunque ecco la spiegazione dettagliata NumOut(10, 8, 1, ccc) equal equal equal equal equal m thread main set aaa, 10 mul bbb, 20, 5 mov ccc, bbb div ccc, ccc, aaa add ccc, ccc, 5 .it dseg segment aaa byte bbb byte ccc byte dseg ends Questo comando converte il valore numerico di ccc in una stringa, quindi chiama la funzione di sistema DrawText per scrivere la stringa sullo schermo. Il valore di ccc dovrebbe apparire in alto a sinostra dello schermo. wait 2000 ar gi @ Come abbiamo già visto questo comando serve a darci il tempo di leggere la scritta. Se non lo mettessimo il programma eseguirebbe il comando exit, e l’NXT sovrascriverebbe il proprio menu sullo schermo, cancellando quello che avevamo chiesto di mostrare! Numeri casuali (random) m In tutti I programmi sinora visti abbiamo esattamente cosa il robot doveva fare. Ma si possono anche programmare situazioni in cui il robot può svolgere azioni che noi stessi non possiamo esattamente predire. Ovvero possiamo programmare azioni casuali del robot.. In NBC è possibile utilizzare numeri casuali. Vediamo questa ulteriore versione del nostro primo programma, in cui la velocità di ritorno non sarà mai la stessa, ma casualmente definita. - 14 - Programmare Lego Robots con NBC di Ross Crawford traduzione e adattamento di G. Marcianò versione 0.1 - 30 novembre 2006 #include "NXTDefs.h" #define MOVE_TIME #define SPEED #define DECREMENT 4000 100 25 dseg segment Speed byte wRandom byte dseg ends m .it thread main set Speed SPEED OnFwd(OUT_BC, Speed) wait MOVE_TIME Random(wRandom,30) add wRandom, wRandom, 10 sub Speed, Speed, wRandom OnRev(OUT_BC, Speed) wait MOVE_TIME Off(OUT_BC) exit endt Il programma è sostanzialmente uguale al precedente, solo che invece di sottrarre 25 da Speed, usiamo un numero casuale compreso tra 10 e 40. Vediamo come funziona: Random(wRandom,30) add wRandom, wRandom, 10 bm È il comando che genera un numero intero casuale tra 0 e 29 (compreso), e restituisce il risultato nella variabile wRandom. Notate che il risultato sarà sempre inferiore al valore del 2° parametro. Con questa istruzione aggiungiamo 10 al risultato ottenuto, in modo che ora avremo wRandom compreso tra 10 e 39. sub Speed, Speed, wRandom ar gi @ Questa istruzione sottrae il risultato ottenuto dal valore corrente di Speed, in modo da cambiare la velocità casuale nel successivo comando OnRev. Riepilogo m In questo capitolo avete appreso come utilizzare le variabili nei vostri programmi. Le variabili sono molto utili, sebbene limitate ai soli valori interi. Ma per molti compiti robotici questo limite non ha nessuna influenza. Avete anche visto come far apparire un numero sul display dell’NXT. Questa tecnica può essere molto utile per controllare i vostri programmi (debugging). Infine avete imparato a impiegare i numeri casuali, in modo da programmare comportamenti non deterministici. - 15 - Programmare Lego Robots con NBC di Ross Crawford traduzione e adattamento di G. Marcianò versione 0.1 - 30 novembre 2006 III. Controllo di flusso Nel capitolo precedente abbiamo visto diversi modi di usare le variabili. Ma tutte le istruzioni del programma venivano eseguiti in sequenza, cosa ottima per certi semplici compiti, mentre spesso abbiamo bisogno di scegliere se fare una cosa o un’altra, in base a certe condizioni. Perciò dobbiamo poter controllare e comparare diverse variabili, e far svolgere al robot cose diverse in base al risultato del controllo. Le funzioni cmp e tst A volte serve registrare un risultato ottenuto da un controllo o confronto tra variabili, per poterlo usare in qualche punto della nostra programmazione. Questo può essere svolto facilmente usando le funzioni cmp e tst. Vediamo come possono essere usate in un programma. #include "NXTDefs.h" m .it dseg segment aaa byte bbb byte ccc byte wRandom byte dseg ends bm thread main set aaa, 10 Random(wRandom,20) mov bbb, wRandom cmp GT, ccc, bbb, aaa NumOut(10, 8, 1, bbb) NumOut(50, 8, 0, ccc) wait 2000 exit endt ar gi @ Avete riconosciuto questo programma? È simile a quello visto nel capitolo precedente. Però c’è una nuova istruzione, vediamo come opera. cmp GT, ccc, bbb, aaa Questa istruzione compara bbb con aaa usando la funzione “> ovvero maggiore di”. Dopo di che il risultato è salvato in ccc. Ne consegue che se bbb è maggiore di aaa, avremo un valore 1 presente in ccc (che per il firmware dell’NXT rappresenta “vero”), in caso contrario a ccc sarà dato un valore 0 (zero). In questo modo si svolge esattamente quello che volevamo – avere salvato il risultato di un confronto tra due variabili, da usare nel corso del nostro programma. Le linee che seguono quella del confronto scrivono sullo schermo dell’NXT I valori di bbb and ccc in modo che potete vedere come opera questa. Proseguite, avviate il programma alcune volte e verificate come il valore di ccc è influenzato dal valore casuale di bbb. m Veniamo ora all’istruzione tst. Questa è la “sorella povera” di cmp, e opera allo stesso modo con solo la differenza di avere 3 parametri, e assume un valore di zero per il quarto parametro. Quindi queste due righe di programma dovrebbero fare la stessa operazione: cmp GT, ccc, bbb, 0 tst GT, ccc, bbb Vi sono altri tipi di comparazioni che possono essere svolte da cmp e tst, pure. Ecco la lista: EQ uguale a LT minore di LTEQ minore o uguale a - 16 - Programmare Lego Robots con NBC di Ross Crawford traduzione e adattamento di G. Marcianò versione 0.1 - 30 novembre 2006 GT maggiore di GTEQ maggiore o uguale a NEQ diverso da Le funzioni brcmp e brtst Abbiamo quindi compreso come fare confronti tra variabili e conservare l’esito del confronto usando cmp o tst. E come poter visualizzare il risultato sullo schermo. Ma come usarlo per farci qualcosa? Generalmente un robot dovrebbe fare qualcosa di coerente con il risultato del test svolto, e questo può essere programmato con le funzioni brcmp e brtst. .it In NBC, possono essere definite routine di un programma caratterizzate da un proprio nome, l’etichetta. L’etichetta è di suo una stringa di caratteri seguita dai due punti. Una etichetta può stare su una linea a sé, oppure all’inizio di una nuova linea che comprende anche altri comandi NBC. Date un’occhiata a questo esempio: #include "NXTDefs.h" bm thread main set aaa, 10 Random(wRandom,20) mov bbb, wRandom m dseg segment aaa byte bbb byte wRandom byte dseg ends NumOut(10, 8, 1, bbb) ar gi @ brcmp GT, Bigger, bbb, aaa TextOut(50, 8, 0, 'small') brcmp LTEQ, Delay, bbb, aaa Bigger: TextOut(50, 8, 0, 'BIG') Delay: wait 2000 exit endt Nuovamente questo listato è simile a quello visto prima, solo che invece di usare cmp per memorizzare l’esito del confronto, si usa brcmp per avviare delle istruzioni “condizionate”. Analizziamo i due nuovi elementi del programma: brcmp GT, Bigger, bbb, aaa Assomiglia molto all’istruzione cmp dell’altro programma,vero? Infatti è così, e viene compiuta la stessa comparazione che avevamo visto prima, solo che invece di semplicemente memorizzare il risultato, questo viene usato per determinare se o meno procedere nel programma saltando all’etichetta “Bigger”, che è definita nelle righe seguenti. Se il confronto produce un risultato “vero”, il programma salta, altrimenti continua con l’istruzione successiva, che – come vedete – mostra la parola “small” sul display dell’NXT.. Bigger: m Questa è un’etichetta, e rappresenta il punto del programma a cui saltare se la funzione brcmp ha esito positivo (confronto = vero). Quindi, se l’esito del confronto è “vero”, l’esecuzione del programma salta alla prima istruzione dopo l’etichetta, alla routine che mostra la stringa “BIG”. In questo modo il programma mostrerà sul display il valore di bbb, che sia “BIG” o “small” dipende se questo è risultato maggiore o meno di aaa. Anche la funzione brtst è simile a brcmp, a parte il 4° parametro che si assume essere zero. - 17 - Programmare Lego Robots con NBC di Ross Crawford traduzione e adattamento di G. Marcianò versione 0.1 - 30 novembre 2006 La funzione jmp A volte capita che si debba far eseguire una routine del programma specifica, saltando altre routine del programma. Si può fare questo con la funzione jmp. È una funzione molto semplice: basta indicare l’etichetta della routine a cui vogliamo “saltare” (jump). .it Un uso comune delle routine obbligatorie è quello delle situazioni “if-then-else”, ovvero nei momenti in cui si deve valutare “se.. allora … altrimenti”. Si può quindi usare brcmp o brtst per l’analisi del “se”, saltando a una routine specifica per eseguire il codice coerente con “allora”. Se l’analisi dei dati risultasse invece “falsa” verrebbe eseguita invece la parte di codice “altrimenti”, collocata subito dopo l’analisi. Resta poi da saltare la routine “allora”, perché in caso di”falsa” condizione non deve essere eseguito quanto scritto per la condizione “vera”. Si può collocare un’etichetta alla routine che si trova dopo il codice da eseguire “allora”, e mettere dopo le istruzioni “altrimenti” un salto incondizionato a questa routine, saltando quindi la routine “allora”. Diamo un’occhiata a questo esempio: #include "NXTDefs.h" 4000 100 25 m #define MOVE_TIME #define SPEED #define DECREMENT bm dseg segment Speed byte wRandom byte dseg ends ar gi @ thread main set Speed SPEED OnFwd(OUT_BC, Speed) wait MOVE_TIME sub Speed, Speed, DECREMENT Random(wRandom,2) brtst EQ, Then, wRandom Else: OnRev(OUT_BC, Speed) jmp EndIf Then: OnFwd(OUT_BC, Speed) EndIf: wait MOVE_TIME Off(OUT_BC) exit endt Questo è un esempio di “if-then-else”. In questo esempio il nostro robot e programmato per avanzare a piena velocità per 4 secondi, e poi ancora avanti o indietro a velocità inferiore per altri 4 secondi, in base al numero casualmente estratto. Vediamo in dettaglio: brtst EQ, Then, wRandom Questa è la routine condizionale, che analizza la situazione, il “se”. Se wRandom è uguale a zero, il programma salta alla routine etichettata “allora”. m Else: Questa è l’etichetta che identifica la routine “altrimenti”, ovvero il codice da eseguire se la condizione risulta “falsa”. Notate che questa etichetta potrebbe essere inutile, se non si deve saltare a questa routine da altri punti del programma. Nell’esempio l’etichetta è stata messa per evidenziare la somiglianza col costrutto if-then-else, e anche per dimostrare come sia bene porre delle etichette nel vostro codice anche se non sono chiamate da altri punti del programma. L’istruzione OnRev sarà quindi eseguita se la condizione risulterà “falsa”, e il robot tornerà indietro. jmp EndIf - 18 - Programmare Lego Robots con NBC di Ross Crawford traduzione e adattamento di G. Marcianò versione 0.1 - 30 novembre 2006 Questo salto senza condizioni porta il programma a saltare a “Endif”, quindi evitando di eseguire la routine “Then”. Then: L’etichetta “Then” è il punto richiamato dall’istruzione brtst precedente, in modo che se la condizione risulterà vera, l’esecuzione del programma salterà a questo punto, evitando di eseguire la routine “Else”, e il robot proseguirà in avanti, come da comando OnFwd. EndIf: L’etichetta “Endif” indica il punto a cui salta il programma in base alla routine “Else”. Se provate a eseguire questo programma per alcune volte, noterete come il vostro robot a volte andrà in avanti, altre indietro. Per il calcolo delle probabilità i due andamenti hanno il 50% di possibilità di accadere. .it Cicli – ripetere una routine Abbiamo visto come per far svoltare il robot si blocca una ruota, o la si fa ruotare indietro, mentre l’altra procede in avanti. Vedete qui un esempio. Digitatelo, salvatelo e scaricatelo nel robot, per vedere come opera. Dovrebbe procedere per un pochino e poi svoltare a destra per 90 gradi circa. thread main OnFwd(OUT_BC,100) wait MOVE_TIME OnRev(OUT_C,100) wait TURN_TIME Off(OUT_BC) endt 800 200 bm #define MOVE_TIME #define TURN_TIME m #include "NXTDefs.h" ar gi @ Provate a cambiare i parametri, ad esempio il valore di TURN_TIME per avvicinarsi a 90 gradi esatti. Questi aggiustamenti sono necessari dato che al cambiare della superficie su cui il robot procede cambia l’attrito e quindi il tempo necessario a fare un certo movimento. m Vogliamo ora realizzare un programma in cui il robot compie un percorso quadrato, ovvero procedere in avanti, svoltare di 90 gradi, avanti di nuovo, svoltare di 90 gradi, ecc. In pratica dovremo far ripetere una parte della programmazione per quattro volte, ovvero dobbiamo realizzare un ciclo (in inglese “loop”).. Per realizzare un ciclo in NBC si fa ripetere una sezione del codice di programmazione più volte, così: - 19 - Programmare Lego Robots con NBC di Ross Crawford traduzione e adattamento di G. Marcianò versione 0.1 - 30 novembre 2006 #include "NXTDefs.h" #define MOVE_TIME #define TURN_TIME 800 200 dseg segment SquareCount byte 4 dseg ends thread main .it SquareLoop: OnFwd(OUT_BC,100) wait MOVE_TIME OnRev(OUT_C,100) wait TURN_TIME sub SquareCount, SquareCount, 1 brtst GT, SquareLoop, SquareCount Off(OUT_BC) endt bm m Questo programma dichiara una variabile SquareCount, e gli assegna il valore di 4. Dopo di che si esegue la stessa programmazione che abbiamo visto prima nell’esempio, muoversi in avanti e svoltare di 90 gradi. Fatto questo, si sottrae 1 da SquareCount, si confronta il suo nuovo valore con zero. Se SquareCount è maggiore di zero, si ritorna all’etichetta SquareLoop, e quindi si ripete l’avanzamento e la svolta, si toglie 1 e si confronta con zero. Ovviamente dopo 4 ripetizioni SquareCount varrà zero, e il programma eseguirà ll’ultima riga (spegnimento motori) concludendo il programma. A questo punto eseguendo il programma lo vedremo percorrere un quadrato (approssimativamente) e tornare al punto di partenza. Come esempio finale vediamo come far percorrere al robot un quadrato per dieci volte: #include "NXTDefs.h" 800 200 m ar gi @ #define MOVE_TIME #define TURN_TIME dseg segment SquareCount byte 4 RepeatCount byte 10 dseg ends thread main RepeatLoop: set SquareCount, 4 SquareLoop: OnFwd(OUT_BC,100) wait MOVE_TIME OnRev(OUT_C,100) wait TURN_TIME sub SquareCount, SquareCount, 1 brtst GT, SquareLoop, SquareCount sub RepeatCount, RepeatCount, 1 brtst GT, RepeatLoop, RepeatCount Off(OUT_BC) endt - 20 - Programmare Lego Robots con NBC di Ross Crawford traduzione e adattamento di G. Marcianò versione 0.1 - 30 novembre 2006 Abbiamo ora un ciclo dentro un altro ciclo, ovvero due cicli “nidificati” uno entro l’altro. Si possono nidificare cicli senza limiti, secondo quanto volete. Notate che ogni ciclo o rientrato rispetto al margine sinistro, cosa che facilita la lettura ma non obbligatorio. Notate anche che sebbene SquareCount sia inizializzata come variabile all’inizio del programma, si debba riportare il suo valore a 4 prima di riavviare SquareLoop. Capite come questo sia necesario in quanto il precedente ciclo l’ha azzerata. Riepilogo .it In questo capitolo avete appreso come fare controlli tra i valori del vostro programma e conservare il risultato, usando le funzioni tst e cmp. Avete anche imparato a realizzare salti condizionati all’interno del programma usando etichette e le funzioni brtst e brcmp, come pure salti incondizionati nel programma usando la funzione jmp. Infine , l’uso di brtst, brcmp e jmp per scrivere processi if-then-else clauses e cicli. NBCjunior – secondo step – cicli di comandi da ripetere più volte /* m Il file “NBC_itajunior2-QUADRATO.nbc” riporta una semplice procedura che :permette di far percorrere al Tribot una traiettoria quadrata.. AVANTIINDIETRO.nbc di Giovanni Marcianò bm novembre 2006 */ ar gi @ #include "NXTDefs.h" /* FOGLIO BIANCO NBC-ITAjunior2 - rel 30/11/06 in questo foglio si possono usare i comandi in italiano che vedete qui sopra non cambiate nulla in queste righe ... scrivete da qui in poi! */ ………… Robby ripeti(4) ciclo: destra(70,450) avanti(100,1000) conta ciao ripeti(n) Questo macrocomando semplifica la realizzazione di un ciclo di comandi. Avvia il ciclo programmato ciclo: Questo macrocomando in realtà è un’etichetta obbligatoria da assegnare alla lista dei comandi da ripetere più volte. Non dimenticate i due punti! conta m Macrocomando che decrementa il contatore, e controlla che non sia giunto a zero. Se diventa zero, il flusso del programma prosegue all’istruzione successiva (in questo caso il programma termina con ciao), in caso contrario salta a ciclo: che – ripeto – è l’etichetta obbligata che introduce la sequenza di azioni da compiere ciclicamente. - 21 - Programmare Lego Robots con NBC di Ross Crawford traduzione e adattamento di G. Marcianò versione 0.1 - 30 novembre 2006 IV. Sensori bm m .it Uno degli aspetti più interessanti dei robot Lego è la possibilità di usare dei sensori in modo da poter far reagire il vostro robot a quanto I sensori percepiscono. Prima di vedere come è possibile fare questo dobbiamo aggiungere al nostro robot un sensore. Per esempio, seguendo le istruzioni che giungono con il kit NXT, aggiungendo un sensore di contatto come qui illustrato, realizzando la versione “bumper” di Tribot: ar gi @ Collegate il sensore alla porta di input 1 dell’NXT. Come avviare un sensore Partiamo con un semplice programma in cui il robot procede sino a che non urta un ostacolo. Eccolo: #include "NXTDefs.h" dseg segment Switch sword 0 dseg ends thread main SetSensorTouch(IN_1) OnFwd(OUT_BC,100) m CheckSensor: ReadSensor(IN_1,Switch) brtst EQ, CheckSensor, Switch Off(OUT_BC) endt Vediamo in dettaglio alcuni importanti nuovi comandi: SetSensorTouch(IN_1) Informa l’NXT che il sensore connesso alla porta di input IN_1 è un sensore di contatto. ReadSensor(IN_1,Switch) - 22 - Programmare Lego Robots con NBC di Ross Crawford traduzione e adattamento di G. Marcianò versione 0.1 - 30 novembre 2006 Questo comando legge il valore corrente del sensore , e lo trasforma in un valore coerente con il tipo di sensore, restituendolo come 2° parametro Nel nostro caso Switch assumerà il valore di 1 o 0 (vero/falso) dopo questa istruzione, in base al fatto che il sensore di contatto sia premuto o no. brtst EQ, CheckSensor, Switch Questa linea di programma provoca un ciclo continuo sino a che il valore di Switch non sarà zero. Quindi l’NXT controllerà continuamente il sensore di contatto sino a che non succederà qualcosa: non appena accade che il sensore venga attivato (ad esempio il robot ha urtato un ostacolo) il programma uscirà dal ciclo e il robot si fermerà. Azioni controllate dal sensore di contatto .it Vediamo ora come far evitare un ostacolo al nostro robot. Ogni volta che urta un ostacolo, dobbiamo farlo retrocedere un po’, voltarsi e quindi procedure. Ecco il programma: dseg segment Switch sword 0 dseg ends thread main SetSensorTouch(IN_1 OnFwd(OUT_BC,100) ar gi @ endt bm CheckSensor: ReadSensor(IN_1,Switch) brtst EQ, CheckSensor, Switch OnRev(OUT_BC,100) wait 300 OnFwd(OUT_B,100) wait 300 OnFwd(OUT_BC,100) jmp CheckSensor m #include "NXTDefs.h" Come nell’esempio precedente dobbiamo per prima cosa indicare il tipo di sensore. Poi far avanzare il robot. Quindi avere un ciclo continuo che costantemente controlla il sensore e – nel caso sia attivato da un ostacolo – faccia arretrare il robot per 1/3 di secondo, svoltare a destra per 1/3 di secondo, e poi riprendere a avanzare. Sensore di luce m Oltre il sensore di contatto il kit comprende anche un sensore di luce, che misura la quantità di luce che giunge da una certa direzione. Questo sensore ha anche un LED che emette luce rossa, così è possibile puntare il sensore in na certa direzione e controllare la percentuale di luce riflessa che giunge da quella direzione. Ciò è molto utile per esempio per far seguire al nostro robot una linea tracciata a terra. È quello che vediamo nel prossimo esempio. Ma prima di tutto collegate il sensore di luce al robot, come indicato nella documentazione dell’NXT, prestando attenzione a collegare il sensore alla porta di input 3. Il robot avrà questo aspetto: - 23 - traduzione e adattamento di G. Marcianò versione 0.1 - 30 novembre 2006 m .it Programmare Lego Robots con NBC di Ross Crawford #include "NXTDefs.h" #define THRESHOLD 60 ar gi @ dseg segment Level sword 0 dseg ends bm Ci può anche essere utile la pista di prova compreso nel kit NXT (Si tratta di un grande foglio ripiegato, con un pista circolare nera.). Vogliamo che il robot proceda seguendo la traccia, controllando che la luce del sensore resti puntata sulla pista. Ogni volta che l’intensità della luce riflessa crescerà, vorrà dire che il sensore è uscito dalla traccia, e allora il robot dovrà cambiare direzione. Questo che segue è un semplice programma, che funziona con il robot impegnato a percorrere la pista in senso orario: thread main SetSensorLight(IN_3) OnFwd(OUT_BC,100) CheckSensor: ReadSensor(IN_3,Level) brcmp LT, CheckSensor, Level, THRESHOLD OnRev(OUT_B,50) FindLine: ReadSensor(IN_3,Level) brcmp GTEQ, FindLine, Level, THRESHOLD OnFwd(OUT_BC,100) jmp CheckSensor m endt Per prima cosa si indica che il sensore connesso alla porta 3 è del tipo “luce”. Quindi si avvia il robot in avanti e si attiva un ciclo continuo in cui per controllare se il valore del sensore di luce è maggiore di 60 (nel programma si usa una costante per poter comodamente variare questo valore, che è in relazione alla luce ambientale presente); in tal caso si cambia senso di rotazione a un motore e saltiamo a un’altra procedura ciclica per controllare quando il robot torna sulla traccia nera. Come potrete vedere, il movimento del robot non sarà molto fluido. Potete aggiungere un comando di attesa (wait 100) dopo OnRev e vedrete il robot muoversi con più scioltezza. Prestate attenzione al fatto che il - 24 - Programmare Lego Robots con NBC di Ross Crawford traduzione e adattamento di G. Marcianò versione 0.1 - 30 novembre 2006 programma non funziona nel caso di movimento antiorario. Per far procedere il robot lungo percorsi casuali serve un programma più complicato. Riepilogo In questo capitolo avete visto come si procede con i sensori di contatto e di luce. A questo punto ritengo siate in grado di provare a scrivere un primo vostro programma originale. Avete tutti gli ingredienti per iniziare a dare al vostro robot un comportamento già alquanto complesso. Per esempio, provate a programmare un robot in modo che non esca da un’area irregolare bordata di nero. NBCjunior – terzo step – sensore di contatto /* .it Il file “NBC_itajunior3-RIMBALZA.nbc” riporta una semplice procedura che grazie al sensore di contatto fa evitare gli ostacoli al Tribot Robby. . RIMBALZA.nbc m di Giovanni Marcianò novembre 2006 */ ar gi @ bm #include "NXTDefs.h" /* FOGLIO BIANCO NBC-ITAjunior3 - rel 30/11/06 in questo foglio si possono usare i comandi in italiano che vedete qui sopra non cambiate nulla in queste righe ... scrivete da qui in poi! */ ………… Robby sensore_contatto1 apripinza(30,400) parti: avanti(60,100) setocca indietro(40,1000) sinistra(40,400) fai parti ciao sensore_contatto1 Questo macrocomando semplifica la inizializzazione del sensore di contatto collegato alla porta 1 dell’NXT. Dopo di che si potranno usare i macrocomandi che seguono parti: Questa è solo un’etichetta e non un NBCita. setocca Verifica lo stato del sensore di contatto. Attende la condizione di “vero” (contatto premuto = 1 = vero) e solo in quel momento procede a eseguire le istruzioni successive fai m Un macrocomando che semplicemente traduce l’istruzione jmp (vedi) NBCjunior – quarto step – sensore di luce Il file “NBC_itajunior4-CERCASCURO.nbc” riporta una semplice procedura che utilizzando il sensore di luce aiuta Tribot Robby. a non uscire da una zona con un bordo scuro, e comunque a evitare le aree nere (o il vuoto, se sta muovendosi su una scrivania) del suolo su cui si muove. . - 25 - Programmare Lego Robots con NBC di Ross Crawford /* traduzione e adattamento di G. Marcianò versione 0.1 - 30 novembre 2006 CERCASCURO.nbc di Giovanni Marcianò novembre 2006 */ #include "NXTDefs.h" /* FOGLIO BIANCO NBC-ITAjunior4 - rel 30/11/06 in questo foglio si possono usare i comandi in italiano che vedete qui sopra non cambiate nulla in queste righe ... scrivete da qui in poi! */ ………… Robby sensore_luce3 avanti(30,1000) parti: .it sechiaro destra(30,1000) avanti(30,1000) fai parti m ciao sensore_luce3 Questo macrocomando semplifica la inizializzazione del sensore di luce collegato alla porta 3 dell’NXT. Dopo di che si potranno usare i macrocomandi che seguono sechiaro m ar gi @ bm Verifica lo stato del sensore di luce e se la luce riflessa registrata è superiore al valore soglia fissato (questo valore può essere regolate nel #define) . Il programma giunto a questo macrocomando attende la condizione di “vero” (luce riflessa > soglia fissata) e solo in quel momento procede a eseguire le istruzioni successive - 26 - Programmare Lego Robots con NBC di Ross Crawford traduzione e adattamento di G. Marcianò versione 0.1 - 30 novembre 2006 V. Fare musica L’NXT ha un altoparlante incorporato con cui può eseguire semplici musiche e suoni.. Questo è particolarmente utile quando volete che l’NXT vi informi di quando succede un evento. Ma può anche essere una risorsa per rallegrare le azioni del robot, ad esempio suoni da fargli eseguire mentre procede. Note musicali Per le note NBC ha il comando PlayTone(). Vi sono due argomenti. Il primo è la frequenza, e il secondo la durata (in frazioni di 1/1000th di secondo, come nel comando wait). NXT può produrre 5 ottave di note definite in NXTDefs.h, da C3 a B7, ma non tutti i valori producono una nota udibile. #include "NXTDefs.h" bm m .it thread main PlayTone(TONE_C5,500) wait 500 PlayTone(TONE_D5,500) wait 500 PlayTone(TONE_E5,500) wait 500 PlayTone(TONE_D5,500) wait 500 PlayTone(TONE_C5,1000) wait 1000 endt Forse vi state chiedendo come mai si trova il commando wait tra una chiamata e l’altra al comando PlayTone; il motivo di ciò è che il comando che avvia il suono non attende che esso sia terminato prima di eseguire l’istruzione successiva. NXT ha un piccolo buffer in cui memorizza alcuni suoni, ma dopo u n po’ questo buffer si riempe e si rischia di perdere delle note. Ciò non influisce sugli effetti sonori, quanto sui brani musicali, come vedremo dopo. ar gi @ Notate che gli argomenti di PlayTone() possono essere sia costanti che variabili. Potete così scrivere una routine che aumenta o decrementa una variabile usata poi per definire la frequenza (o la durata) del suono da eseguire (v. le funzioni matematiche descritte al Capitolo II). #include "NXTDefs.h" dseg segment freq word TONE_C3 loopCount byte 4 dseg ends m #define DURATION 500 thread main DoLoop: PlayTone(freq, DURATION) wait DURATION mul freq, freq, 2 sub loopCount, loopCount, 1 brtst GT, DoLoop, loopCount // the loop is finished, so play our last tone PlayTone(TONE_C5, DURATION*2) wait DURATION*2 exit endt Potete comunque realizzare piccolo brani musicali usando lo strumento “pianoforte” di BCC e salvando poi il brano in linguaggio NBC, da incollare nel vostro listato - 27 - Programmare Lego Robots con NBC di Ross Crawford traduzione e adattamento di G. Marcianò versione 0.1 - 30 novembre 2006 Eseguire files musicali m .it Allo stesso modo con cui NBC esegue delle note il comando PlayFile() esegue suoni o brani salvati nell’NXT. Questo comando ha un solo argomento, ovvero il nome esatto del file da eseguire.. Potete controllare quali files musicali sono presenti nel vostro NXT usando lo strumento NXT Explorer compreso in BCC-Bricx Command Center. Selezionate NXT Explorer dal menu Tools e appare una finestra come questa: #include "NXTDefs.h" bm Scegliendo “NXT Sound files” dal menu a discesa, vedrete solo I files musicali presenti nell’NXT e sul vostro PC. I 4 files mostrati nell’illustrazione sono già nell’NXT, installati assieme al firmware standard. Possiamo quindi scrivere un semplice per eseguire il file Woops.rso: dseg segment MyFile byte[] 'Woops.rso' dseg ends ar gi @ thread main PlayFile(MyFile) wait 1000 endt Anche qui potrebbe essere necessario porre un commando wait dopo PlayFile(per gli stessi motivi prima illustrati). PlayFile() non attende la fine del brano per ridare il controllo al programma. Inoltre notate che è necessario indicare il nome completo del file da eseguire, e che è indifferente usare lettere maiuscole o minuscole. Se il file richiamato non fosse disponibile, semplicemente non sarà eseguito. Potete anche passare il nome del file direttamente al comando PlayFile() senza bisogno i ricorrere a variabili. Per eseguire un file musicale si può usare un file con la stessa denominazione dei programmi, a eccezione dell’estensione che è ".rmd" invece che ".rso". L’NXT non ha alcun file musicale di default, ma potete facilmente crearlo da voi stessi usando il Brick Piano in BricxCC o procedendo alla conversione di file MIDI con l’apposito tool presente in BricxCC. Creare i propri effetti sonori m Gli effetti compresi nel kit NXT permettono già molte applicazioni, ma come fare se ne volete realizzare di nuovi? BricxCC comprende anche un tool per la conversione di file Windows WAV nel formato RSO usato dall’NXT. Scegliendo “Sound Conversion…” dl menu Tools si apre una finestra come questa: - 28 - traduzione e adattamento di G. Marcianò versione 0.1 - 30 novembre 2006 m .it Programmare Lego Robots con NBC di Ross Crawford bm Potete usare il bottone Select Files per caricare un normale file WAV presente sul vostro PC, dopo di che usando il bottone Directory potete scegliere in quale posizione salvare il file convertito. Con un clic su “Convert” si avvia quindi la conversione – che finirà salvata nella directory da voi scelta, con lo stesso nome del file originale WAV, ma con l’estensione RSO invece che WAV. L’opzione “Resample” permette di ridurre la dimensione del file finale, ma anche riduce la qualità del suono. La memoria sull’NXT è limitata, dovete procedure per tentativi per trovare il miglior compromesso. ar gi @ Dopo aver creato il vostro file, dovete trasferirlo sull’NXT con il tool NXT Explorer, e a quel punto il vostro programma potrà impiegarlo come voi avete pensato, in esecuzione di routine come quelle viste prima all’opera coi file native dell’NXT. Per spostare un file audio dal vostro computer all’NXT usando il tool NXT Explorer potete semplicemente trascinare il file dalla finestra coi file del PC a quella coi file presenti nell’NXT. Un’altra risorsa di file sonori è il software standard NXT, che comprende molti effetti sonori. Usando NXT Explorer di BricxCC potete trovarli sul PC nella cartella Program Files\LEGO Software\LEGO MINDSTORMS NXT\engine\Sounds, e da qui trascinarli nell’NXT. Ricordate che i files sonori occupano molto spazio nella memoria dell’NXT, per cui prestate attenzione nel loro uso. I files musicali di solito sono più leggeri di quelli sonori, e possono essere un’alternativa interessante e efficace. Riepilogo In questo capitolo avete appreso come realizzare e usare nell’NXT effetti musicali, e suonare musiche o riprodurre effetti sonori. Infine avete imparato a realizzare file musicali o effetti sonori a vostro piacimento, pronti da scaricare nell’NXT. m NBCjunior – quinto step – eseguire file sonori Il file “NBC_itajunior5-SONORO.nbc” riporta una variante della procedura precedente, in cui alla rilevazione di un’area scura il robot non solo cambia direzione, ma anche annuncia il fatto con un “opps” sonoro, eseguendo il file di sistema (presente nel firmware dell’NXT) Woops.rso - 29 - Programmare Lego Robots con NBC di Ross Crawford /* traduzione e adattamento di G. Marcianò versione 0.1 - 30 novembre 2006 SONORO.nbc di Giovanni Marcianò dicembre 2006 */ .it #include "NXTDefs.h" /* FOGLIO BIANCO NBC-ITAjunior5 - rel 01/12/06 in questo foglio si possono usare i comandi in italiano che vedete qui sopra non cambiate nulla in queste righe ... scrivete da qui in poi! */ ………… Robby sensore_luce3 parti: avanti(50,1000) sechiaro destra(30,500) suona('Woops.rso') fai parti ciao m suona(f) m ar gi @ bm Questo macrocomando avvia l’esecuzione del file ‘f’, che va indicato correttamente tra parentesi e apici, rispettando l’esatta ortografia del nome e con la desinenza .rso Se l’effetto sonoro non venisse eseguito, bisogna controllare: • che la riga col comando venga eseguita dal programma (nel nostro caso ciò avverrà solamente quando il sensore rivelerà un’area scura), • che l’audio dell’NXT sia attivo, con volume alto (consiglio almeno 3, ma meglio 5) • che il nome del file chiamato sia esatto, controllando con lo strumento “NXT explore” (v. sopra) che sia presente nella memoria del robot - 30 - Programmare Lego Robots con NBC di Ross Crawford traduzione e adattamento di G. Marcianò versione 0.1 - 30 novembre 2006 VI. Note finali Questa prima parte del tutorial permette di avvicinarsi alla programmazione del nuovo kit LEGO NXT con un vero linguaggio di programmazione in modo semplice e immediato. Vi segnalo comunque che: 1 – il tutorial del linguaggio NBC è ancora in progress, essendo il linguaggio stesso e BCC- Bricx Command Center in beta-release, per ora. 2 – quanto qui riportato è stato provato con successo su un modello NXT versione 01.1240/01.01 3 – potreste avere alcuni problemi nella connessione Bluetooth tra PC e NXT. La connessone USB risulta al momento più veloce e stabile, almeno per il monitoraggio dell’NXT e il download di file .it Tutto ciò consiglia di attendere il rilascio della versione 1.0 per comandi avanzati (in parte presenti sul tutorial inglese) e quanto più oltre segnalo come sviluppi a breve. m Comunque, in attesa della versione 1.0, è possibile mettere alla prova l’NXT e NBC sia nella versione nativa come in quella “junior_ita”, realizzando le prime prove e così iniziando a padroneggiare i comandi e le azioni di base del robot. A chi non ha mai usato BCC- Bricx Command Center si raccomanda di leggere la documentazione relativa. bm I prossimi sviluppi prevedono: • il controllo dei sensori di suono e di prossimità a ultrasuoni, • un più sofisticato controllo dei motori (nell’NXT il motore è molto più sofisticato che nell’RCX, e può anche svolgere funzione di sensore di rotazione, tra l’altro) • concetti più evoluti di programmazione robotica, sino all’implementazione di alcuni aspetti connessi all’intelligenza artificiale e a comportamenti di apprendimento che questo robot può realizzare. Potete trovare maggiori informazioni e aggiornamenti sul kit NXT nel sito Lego MindStorms. http://mindstorms.lego.com/ ar gi @ Sono gradite segnalazioni di uso a scuola della robotica da parte di alunni e insegnanti italiani: scrivetemi a [email protected] oppure a [email protected] m - 31 - traduzione e adattamento di G. Marcianò versione 0.1 - 30 novembre 2006 m ar gi @ bm m .it Programmare Lego Robots con NBC di Ross Crawford Ministero della Pubblica Istruzione IRRE Piemonte – Istituto Regionale Ricerca Educativa “Uso didattico della robotica” progetto N. 1280/05 delibera n. 106 del 22/12/05 sito web: http://robotica.irrepiemonte.it Responsabile: prof. Giovanni Marcianò per contatti: [email protected] - tel. 011 5606400 - cell. 338 5901442 - 32 -