Informaticasite van het Lauwers College te Buitenpost                 © R.J. van der Beek
 

Het programmeren van lego-robots

  1.1. Inleiding

Robots spreken sterk tot de verbeelding van mensen. Daarbij wordt vaak gedacht aan wat je ziet bij science fiction films: enigszins mensachtige apparaten die regelmatig op hol slaan.
De werkelijkheid is minder spectaculair.
Robots worden al vele jaren in de industrie gebruikt. Ze lijken echter in de verste verte niet op mensen. In de auto-industrie doen bijvoorbeeld robotarmen een aanzienlijk deel van het werk. In sommige ziekenhuizen rijden robots die medicijnen rondbrengen.
Sinds enige tijd worden ook robots gemaakt als speelgoed. Eén ervan is het Lego Mindstorms Robotic Invention System.
In de VS is dit 'speelgoed' al een groot succes geworden.
Met Mindstorms kun je robots maken die een bepaald gedrag hebben. Ze kunnen rondrijden, obstakels vermijden, objecten oppakken en ergens anders weer neerzetten en, als er meerdere robots zijn, met elkaar communiceren.
Om een robot een bepaalde taak te laten uitvoeren, moet deze geprogrammeerd worden.
De programmeertaal die hoort bij de Lego Mindstorms Robotics Invention System heet NXT. Als je een lego-robot koopt krijg je het programma LEGO MINDSTORMS NXT erbij. Hiermee kun je programma's voor de robot maken en ze ook direkt verzenden naar de robot.
Dat gaat heel eenvoudig, je kunt gewoon opdrachtblokjes achter elkaar zetten.
En dan kun je de robot starten en stoppen.
Er bestaan ook alternatieve programmeeromgevingen voor het programmeren van Lego robots. Daarover later.
We gaan er bij de volgende programma's van uit dat je met de volgende robot werkt: (in de handleiding bij de robot staat beschreven hoe je dit apparaat in elkaar zet)

  1.2. Het eerste programma met NXT

Bij het schrijven van de programma's voor de robot gaan we uit van het model zoals dat hierboven is afgebeeld.
We beginnen met een eenvoudig programma.
Dit programma start de robot, laat hem een eindje vooruit rijden, daarna wacht de robot drie seconden en daarna rijdt de robot weer terug naar de startpositie met een hogere snelheid dan in het begin.
Vervolgens stopt de robot.

Als je LEGO MINDSTORMS NXT start zie je het volgende op het scherm:



Onderaan zie je Start new program en daaronder kun je de naam van het te maken programma invoeren.
Noem het programma test, klik achter het tekstvenster met de naam op Go >>
(Je kunt ook op File → New klikken als je met een nieuw programma wilt beginnen)
Dan verschijnt het programmeervenster, dat ziet er als volgt uit:



Klik in de gereedschapsbalk (links) op het move-blok
Dan verschijnt er een kopie van het move-blok, versleep dat naar de startpositie. Als je op die startpositie klikt wordt het daar geplaatst.
Tegelijk verschijnt onderaan het configuratie-paneel voor het move-blok.


  1. Port
    Achter Port kun je aangeven welke motoren in beweging gezet moeten worden. We kiezen de twee motoren B en C, die zullen dan tegelijk vooruit of achteruit draaien met dezelfde snelheid (behalve als je dat bij 3=Steering verandert). Dat moet natuurlijk ook als je wilt dat de robot recht vooruit rijdt, de twee wielen moeten dan dezelfde snelheid hebben en in dezelfde richting gaan.
    Zet dus een vinkje voor B en voor C
  2. Direction
    Achter Direction kun je aangeven in welke richting er gereden moet worden. Klik op het eerste rondje, dan geef je aan dat de robot vooruit moet bewegen.
    (Het tweede betekent achteruit, en het derde betekent dat de wielen stil staan.)
  3. Steering
    Achter Steering kun je aangeven of er rechtuit moet worden gereden of met een bocht.
    Als je de schuifbalk in het midden tussen B en C laat staan dan zullen de motoren B en C dezelfde snelheid hebben, en dan gaat de robot recht vooruit.
    Beweeg je de schuifbalk helemaal naar C toe, dan zal motor B stil staan en dan wordt er dus een bocht gemaakt.
    Beweeg je de schuifbalk helemaal naar B toe, dan wordt er een bocht naar de andere kant gemaakt.
    Zet je de schuifmaat niet in het midden en niet helemaal aan de kant van B of C dan zal er een rondje worden gereden.
    Het is de bedoeling dat er rechtuit wordt gereden, dus je hoeft de schuifbalk achter Steering niet te verschuiven.
  4. Power
    Met de schuifbalk achter Power kun je de snelheid bepalen (van 0 tot 100), zet die op 50.
  5. Duration
    Achter Duration kun je aangeven hoe lang de robot in de aangegeven richting moet rijden.
    Je kunt dat aangeven in seconden, in rondjes, in graden, en unlimited. Als je op het pijltje achter Rotations klikt krijg je een pull-down menu waarbij je uit die vier mogelijkheden kunt kiezen.



    Kies voor Rotations, en tik achter Duration 5 in, dan zullen de motoren 5 rondjes draaien.
  6. Next Action
    Achter Next Action kun je aangeven wat er aan het eind van het move-blok moet gebeuren: brake, dus remmen, of coast, d.w.z. dat de motoren worden uitgezet maar verder niet. Als de robot op een helling staat betekent het dat de robot blijft stilstaan als je voor break kiest, en als je kiest voor coast zal de robot langzaam naar beneden zakken.
    Als het nog niet het einde van het robot-programma is kun je het beste voor coast kiezen, omdat er waarschijnlijk toch een andere beweging op volgt.
    Klik dus op het rondje voor Coast.
  7. Feedback-venster
    In de feedback-tekstvenstertjes aan de linkerkant van het paneel zal worden aangegeven, als de robot in beweging is, hoeveel rondjes de motoren op elk moment gedraaid hebben. Klik op de reset-knop om die waarden op 0 te zetten.
Zo, dat was de eerste programmeeropdracht.
Nu gaan we naar de tweede: de robot moet, na het eerste stukje gereden te hebben, drie seconden blijven staan.
Om dat te kunnen programmeren klik je in de gereedschapsbalk op het wacht-blok:
Dan verschijnt er een venstertje naast met vijf icoontjes:



Klik op het eerste (er staat time bij), dan verschijnt er een kopie van het wacht-blok. Versleep dat naar de plaats achter het move-blok en klik daar.
Dan wordt het daar geplaatst en tegelijk verschijnt onderaan het configuratie-paneel voor het wacht-blok.



Daar hoef je alleen maar in te voeren hoe lang er gewacht moet worden. Vul 3 in (achter seconds).

Dan nu de derde opdracht: de robot moet weer naar de startpositie terugrijden.
Klik in de gereedschapsbalk op het move-blok en plak het nieuwe move-blok achter het wacht-blok.
In het configuratie-paneel voor het move-blok voer je het volgende in:
  1. Port
    Bij Port kies je weer voor de twee motoren B en C
  2. Direction
    Bij Direction klik je nu op het eerste rondje, dan geef je aan dat de robot achteruit moet bewegen.
  3. Steering
    Bij Steering hoef je de schuifbalk niet te verschuiven.
  4. Power
    Met de schuifbalk achter Power zet je de snelheid op 70 (de robot moest sneller terugrijden).
  5. Duration
    Bij Duration kies je weer voor Rotations, en weer 5 rondjes.
  6. Next Action
    Bij Next Action klik je nu op het rondje voor Break.


Dan is het programma klaar. Klik op het icoontje in de rechter benedenhoek, op de pijl naar beneden (er staat Download bij, zie zwarte pijl).
Dan wordt het programma naar de robot gestuurd, en dan kan de robot het programma uitvoeren.

  1.3. Het eerste programma met NBC

De programmeertaal die hoort bij de Lego Mindstorms Robotics Invention System heet NXT.
Dat programmeren gaat heel eenvoudig, je kunt gewoon opdrachtblokjes achter elkaar zetten.
Het is echter nogal beperkt in zijn mogelijkheden, maar er zijn alternatieve programmeeromgevingen.
Bijvoorbeeld de programmeertaal NBC dat komt van 'Next Byte Code'), een taal die ontworpen is door John Hansen.
En er is een programma waarmee je de commando's van deze taal handig kunt invoeren, en waarmee je de programma's ook naar de robot kunt zenden, en de robot kunt starten en laten stoppen: Bricx Command Center. Je kunt dat programma downloaden van http://bricxcc.sourceforge.net/
De programmeertaal NBC kan van diezelfde site worden gedownload: van http://bricxcc.sourceforge.net/nbc/
Het starten van Bricx commando centrum Bij het starten van Bricx verschijnt eerst een scherm dat controleert of de robot op de computer is aangesloten. Aangezien we voorlopig eerst programma's gaan maken zonder daarbij de robot te gebruiken, kun je deze schermpjes negeren door op Cancel te klikken.
Wil je alles direkt m.b.v. de robot uitproberen, doe de robot dan aan en klik op OK.
Het programma zal de robot waarschijnlijk herkennen, en je kunt verder met het programma.

Klik op Bestand, en dan op Nieuw, dan kun je een programma invoeren.
We beginnen met hetzelfde programma als hierboven. Dit programma start de robot, laat hem een eindje vooruit rijden, daarna wacht de robot drie seconden en daarna rijdt de robot weer terug naar de startpositie met een hogere snelheid dan in het begin.
Vervolgens stopt de robot.

Voer het volgende in:

#include "NXTDefs.h"

thread main
OnFwd(OUT_B,50)
OnFwd(OUT_C,50)
wait 4000
Off(OUT_BC)
wait 3000
OnRev(OUT_BC,70)
wait 4000
Off(OUT_BC)
exit
endt


Programma's in NBC bestaan uit taken (threads). Dit eerste programma heeft maar één taak, genaamd main.
Ieder programma moet een thread 'main' hebben, want die wordt uitgevoerd door de robot.
Een thread bestaat uit een aantal commando's, ook wel opdrachten of statements genoemd.
De thread eindigt met de opdracht endt

De eerste regel van het programma is #include NXTDefs.h
Dat heeft tot gevolg dat de computer het bestand NXTDefs.h inleest. Dat bestand bevat een aantal belangrijke constanten, typen, en macros, zodat de computer weet wat hij bij de opdrachten OnFwd, OUT_B, enz. moet doen.

OnFwd(OUT_B,50)
Dit statement vertelt de robot om output B te starten, dat wil zeggen dat de motor die via output B is aangesloten start, en naar voren te gaan rijden. Hij rijdt op 50% van de maximale snelheid.

OnFwd(OUT_C,50)
Hetzelfde statement, maar nu voor het starten van motor C. Na deze twee statements draaien beide motoren en rijdt de robot naar voren.

Wait 4000
Dit statement laat het programma vier seconden wachten. Het argument (ook wel parameter of variabele genoemd), dat is het getal tussen haakjes, geeft het aantal 'tikken'. Elke tik duurt 1/1000 seconde.
Het programma doet vier seconden lang niets, terwijl de robot vooruit rijdt.
Een argument (of parameter/variabele) is dus een middel om informatie aan een statement door te geven.

Off(OUT_BC)
Dit heeft tot gevolg dat beide motoren worden uitgeschakeld, en dat de robot dus stopt.
Let er op dat beide motoren tegelijk in de opdracht kunnen worden aangeroepen (OUT_BC)

Wait 3000
Het programma doet drie seconden lang niets, de robot blijft dus drie seconden stilstaan.

OnRev(OUT_BC,100)
De motoren B en C gaan in tegengestelde richting draaien, de robot gaat nu dus achteruit.
Ze draaien nu op 100 % van de maximale snelheid, de robot rijdt nu dus sneller dan in het begin.
Let er op dat beide motoren ook hier tegelijk in de opdracht kunnen worden aangeroepen (OUT_BC); dat had bij de opdrachten met OnFwd ook gekund.

Wait(4000);
Weer wordt er vier seconden niets aan de situatie van de robot veranderd, hij rijdt dus vier seconden op dezelfde manier door.

Off(OUT_BC)
Dit heeft tot gevolg dat beide motoren worden uitgeschakeld, en dat de robot dus stopt.

  1.4. Save, download en run

Als je het programma hebt ingevoerd moet je het eerst op schijf vastleggen.
Klik op File, en dan op Save as, en dan moet je het programma een naam geven waaronder het wordt vastgelegd.
De extensie wordt automatisch ".nbc"
Daarna klik je op de download-button.
Dan wordt het programma gecompileerd (dat betekent dat de code wordt vertaald in machinetaal, dat is de code die de robot begrijpt) en naar de robot gezonden m.b.v. een USB-kabel of via Bluetooth.
Als er fouten in het programma zitten dan wordt dat aangegeven en dan moet je die eerst verbeteren.
Anders kun je het programma laten lopen. Klik daarvoor op "Software Files" op je NXT-robot, zoek naar "1-simple", klik dan op de oranje NXT-button om het te laten lopen.
Je kunt het ook runnen door in het Bricx Command Center te klikken op het groene run-driehoekje.

Doet de robot niet precies wat je verwacht, verander het programma dan zo, dat het beter werkt. Stuur het opnieuw naar de robot en laat het weer lopen.

  1.5. Variabelen, constanten en commentaar

We gaan het programma nog een beetje wijzigen.
We gaan ten eerste commentaarregels toevoegen.
Die regels slaat de robot, als het programma loopt, over. Ze dienen er alleen voor om het programma te verduidelijken.
Als je commentaar hebt dat niet meer dan een regel beslaat laat je het vooraf gaan door //
Alles wat achter // staat wordt dus als commentaar opgevat.

Als je commentaar hebt dat uit meer dan een regel beslaat dan laat je het vooraf gaan door /* en aan het eind zet je */
Alles wat tussen /* en */ staat wordt dus als commentaar opgevat.

Je kunt in NBC gebruik maken van constanten.
Er staat op twee plaatsen in het programma de opdracht wait 4000
Als je de wachttijd 4000 wilt wijzigen dan moet je op beide plaatsen 4000 veranderen in een ander getal.
Je kunt het ook op een nadere manier programmeren.
We voegen als tweede regel toe de opdracht #define RIJTIJD 4000, RIJTIJD wordt een konstante genoemd.
En de beide opdrachten wait 4000 wijzigen we in wait RIJTIJD
Als je de wachttijd nu wilt veranderen hoef je het getal maar één keer te wijzigen, op de tweede regel.

Je gebruikt konstanten voor dingen, die tijdens de werking van het programma niet wijzigen.
Je kunt ook zogenaamde variabelen gebruiken, daarmee kun je gegevens vastleggen die tijdens de werking van het programma wel kunnen veranderen.

We gebruiken in dit programma de variabele snelheid, die is op de heenweg 50 en op de terugweg 70.
Een variabele moet je eerst declareren: je moet het programma vertellen dat er een geheugenplaats voor de variabele gereserveerd moet worden.
Dat doe je m.b.v. de volgende opdrachten:

dseg segment
      snelheid byte
dseg ends

Een declaratie begint dus met de opdracht dseg en dan een naam, waarmee het declaratiegedeelte wordt aangegeven.
Dan de regel snelheid byte, daarmee geef je aan dat de variabele snelheid van het type byte is, en byte betekent dat het een geheel getal is dat m.b.v. één byte wordt vastgelegd. De maximale waarde is dus 255
De declaratie eindigt met de opdracht dseg ends

M.b.v. de opdracht set snelheid, 50 krijgt de variabele snelheid de waarde 50.

Het programma ziet er na deze wijzigingen als volgt uit:

/*
Vooruit, silstaan en achteruit
Dit programma laat de robot vier sec. vooruit rijden en daarna vier sec. achteruit.
*/

#include "NXTDefs.h"
#define RIJTIJD 4000

dseg segment
      snelheid byte
dseg ends

thread main
      set snelheid, 50
      OnFwd(OUT_BC, snelheid) // vooruit
      wait RIJTIJD // rijd 4 seconden
      Off(OUT_BC)
      wait 3000 // blijf 3 sec. stilstaan
      set snelheid, 70
      OnRev(OUT_BC, snelheid) // achteruit
      wait RIJTIJD // Wacht 4 seconden
      Off(OUT_BC) // Stop
      exit
endt

Dit programma doet precies hetzelfde als het vorige.