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

Hoofdstuk 2: Lego-robots, loops

  2.1. Een vierkant rijden m.b.v. NXT

We gaan nu een programma voor de robot maken zodat hij een vierkant gaat rijden.
Hij moet dan vier keer een recht stuk rijden en vier keer een bocht maken.
Start LEGO MINDSTORMS NXT, en klik op File ® New, en geef als naam van het programma vierkant
Begin met het plaatsen van een move-blok op de startpositie. Kies voor de twee motoren B en C, laat de robot vooruit rijden, laat de schuifbalk bij Steering in het midden staan, zet Power op 75, kies voor Seconds, en tik bij Duration 4 in, en kies tenslotte bij Next Action voor Coast.
Vervolgens moet er een bocht van 90 graden worden gemaakt.
Klik in de gereedschapsbalk op het move-blok en plak het nieuwe move-blok achter het vorige move-blok.
In het configuratie-paneel voor het move-blok voer je het volgende in:
  1. Port, Direction, Power, Next Action
    Kies weer voor de twee motoren B en C, laat de robot vooruit rijden, zet Power op 75, en kies bij Next Action voor Coast.
  2. Steering
    Bij Steering verschuif je de schuifbalk helemaal naar links, dan maakt de robot een bocht naar links (tenminste als C de motor voor het linker wiel is)
  3. Duration
    Bij Duration kies je weer voor seconden. Hoe lang het rechter wiel stil moet staan om een hoek van 90 graden naar links te maken moet je even uitproberen, hier hebben we voor 0,75 seconden gekozen.


Na de bocht moet de robot weer een stukje rechtuit rijden. Plak dus een move-blok voor die beweging, en plak het achter de tweede.
Je kunt dat net zo doen als bij het eerste move-blok, maar het kan ook sneller:
Klik op het eerste blok, druk op Ctrl/C, klik dan achter het tweede blok en druk op Ctrl/V. Dan wordt een kopie van het eerste blok gemaakt en achter het tweede geplakt. Je moet het misschien nog wel even naar de juiste plaats verschuiven.
Dan weer een bocht, maak dus een kopie van het tweede move-blok en plak het achter het derde.
Ga zo door tot je in totaal acht move-blokken achter elkaar hebt, vier rechtdoor en vier bochten.
Dan is het programma voor het vierkant klaar. Download het programma, d.w.z. stuur het programma naar de robot, en laat het uitvoeren.

  2.2. Een loop m.b.v. NXT

Stel dat je de robot 8 keer achter elkaar een vierkant wilt laten rijden. Dan zou je in totaal 8 x 8 = 64 move-blokken achter elkaar kunnen plaatsen. Maar het kan veel handiger.
Je kunt de robot dingen laten herhalen m.b.v. het loop-blok
Zorg er voor dat je het programma voor het rijden van een vierkant (zie hierboven) in beeld hebt.
Klik in de gereedschapsbalk op het loop-blok
Plaats dit loop-blok voor het eerste move-blok, zodat je het volgende in beeld hebt:



Verschuif de acht move-blokken dan één voor één zo dat ze in het loop-blok zitten.
Dat ziet er dan als volgt uit:



En klik nog eens op het loop-blok, dan verschijnt het configuratiepaneel voor het loop-blok er onder.
Daar voer je het volgende in:
  1. Control
    Klik op het pijltje achter het invulvenster van Control. Dan kun je kiezen uit: Forever, Sensor, Time, Count, Logic.
    Kies voor Count, dan kun je invoeren hoe vaak de opdrachten binnen het loop-blok herhaald zullen worden.
  2. Until
    Bij Until voer je het getal 8 achter Count in. Dan zullen de opdrachten binnen het loop-blok acht keer herhaald zullen worden.
  3. Show
    Zet een vinkje voor Counter. Waar dat voor dient merk je nog wel.
Dan is het programma klaar. Stuur het programma naar de robot, en controleer of de robot inderdaad acht vierkanten gaat rijden.

  2.3. Een vierkant rijden m.b.v. NBC

We gaan nu het programma voor het rijden van een vierkant maken m.b.v. NBC.
Hij moet dan net zoals hierboven vier keer een recht stuk rijden en vier keer een bocht maken.
Je kunt de robot na een eindje rijden (dus beide motoren draaien op dezelfde kracht) een bocht laten maken door één van de motoren een poosje stil te zetten of in tegengestelde richting te laten draaien.
Hoe lang de ene motor stilgezet moet worden of in tegengestelde richting moet draaien kun je uitvinden door het uit te proberen.
Die tijd hangt o.a. af van de ondergrond waarop gereden word. Voor die tijd gebruiken we de constante rechtehoektijd, en we gaan er eerst van uit dat die tijd 200 milliseconden is.
Je krijgt dan het volgende programma voor het rijden van een vierkant:

/*
Een vierkant rijden
*/

#include "NXTDefs.h"
#define rijtijd 2000
#define rechtehoektijd 200

thread main
      OnFwd(OUT_BC,50)
      wait rijtijd //rijdt vooruit
      OnRev(OUT_C,50)
      wait rechtehoektijd // maak een bocht
      OnFwd(OUT_C,50)
      wait rijtijd //rijdt vooruit
      OnRev(OUT_C,50)
      wait rechtehoektijd // maak een bocht
      OnFwd(OUT_C,50)
      wait rijtijd //rijdt vooruit
      OnRev(OUT_C,50)
      wait rechtehoektijd // maak een bocht
      OnFwd(OUT_C,50)
      wait rijtijd //rijdt vooruit
      OnRev(OUT_C,50)
      wait rechtehoektijd // maak een bocht
      Off(OUT_BC)
endt

  2.4. Een loop m.b.v. NBC

Stel dat je de robot 8 keer achter elkaar een vierkant wilt laten rijden, en elke keer wacht de robot drie seconden voordat hij met het volgende vierkant begint. Dan zou je de opdrachten uit het vorige programma acht keer achter elkaar kunnen plaatsen, en tussen die acht opdrachtblokken steeds de opdracht wait 3000 plaatsen (om er voor te zorgen dat er steeds drie seconden wordt gewcht voordat het volgende vierkant wordt gereden)
Maar het kan veel handiger.
Je kunt de robot dingen laten herhalen m.b.v. de sprong-opdracht.

Je moet dan een variabele gebruiken, die bijhoudt hoevaak er al een vierkant is gereden. Die variabele geven we hier de naam teller
Die variabele moet gedeclareerd worden, dat gaat m.b.v. de opdrachten:
dseg segment
      teller byte 8
dseg ends
Hier wordt de variabele teller gedeclareerd, en hij krijgt tegelijk de beginwaarde 8.
Dus door achter het woord byte het getal 8 te zetten voorkomen we dat we nog een extra opdracht set teller, 8 moeten toevoegen.

Verder worden de opdrachten voor het rijden van een vierkant voorafgegaan door de opdracht vierkant_en_wacht:
Dat wordt een label genoemd. Daarmee wordt aangegeven waar de opdrachten voor het vierkant beginnen, want die moeten herhaald worden.

Na de opdrachten voor het rijden van een vierkant (en het wachten van drie seconden) komt nu de opdracht sub teller, teller, 1
sub is de afkorting van subtract, en dat betekent dat er iets van de variabele teller moet worden afgetrokken.
Het getal 1 moet van de variabele teller worden afgetrokken (dat zie je aan de laatste 1 in de opdracht), en die nieuwe waarde moet worden toegekend aan de variabele teller (de eerste variabele na sub is altijd de variabele waaraan de nieuwe waarde moet worden toegekend).

Dat heeft tot gevolg dat na het rijden van één vierkant de variabele teller de waarde 7 krijgt, dat is dus het aantal vierkanten dat daarna nog moet worden gereden.

Vervolgens komt de zogenaamde sprongopdracht, (engels: jump-statement):
brtst GT, vierkant_en_wacht, teller
Dit betekent : if teller > 0 then goto vierkant_en_wacht

GT is de afkorting van greater then, dus groter dan.
Het getal waarmee vergeleken wordt is altijd nul !
Als de eerste parameter GT is dan moet de variabele > 0 zijn.
Als de eerste parameter LT (dat is de afkorting van little then) is dan moet de variabele < 0 zijn.
Als de eerste parameter EQ (dat is de afkorting van equal, dus gelijk aan) is dan moet de variabele = 0 zijn.

En als er aan die voorwaarde voldaan is dan wordt er naar het label gesprongen dat in het midden staat.
Als er niet aan de voorwaarde is voldaan dan wordt er gewoon verdergegaan met de volgende opdracht.
In het voorbeeld van ons programma worden de opdrachten van het vierkant dus herhaald als teller > 0, en als dat niet het geval is (dus als teller = 0 of teller < 0) dan wordt er verder gegaan met de volgende opdracht van het programma, en dat heeft tot gevolg dat er dan gestopt wordt. Je krijgt dan het volgende programma voor het rijden van acht vierkanten:

/*
Acht vierkanten rijden, met drie seconden wachttijd
*/

#include "NXTDefs.h"
#define rijtijd 2000
#define rechtehoektijd 200

dseg segment
      teller byte 8
dseg ends

thread main

      vierkant_en_wacht:
            OnFwd(OUT_BC,50)
            wait rijtijd
            OnRev(OUT_C,50)
            wait rechtehoektijd
            OnFwd(OUT_C,50)
            wait rijtijd
            OnRev(OUT_C,50)
            wait rechtehoektijd
            OnFwd(OUT_C,50)
            wait rijtijd
            OnRev(OUT_C,50)
            wait rechtehoektijd
            OnFwd(OUT_C,50)
            wait rijtijd
            OnRev(OUT_C,50)
            wait rechtehoektijd
            wait 3000 //wacht drie seconden

            sub teller, teller, 1 // trek 1 van teller af
      brtst GT, vierkant_en_wacht, teller // als teller > 0 spring dan naar vierkant_en_wacht

      Off(OUT_BC)
endt

  2.5. Meer operator- en jump-opdrachten (flow-control)

Bekijk het volgende programma:

#include "NXTDefs.h"
dseg segment
a byte
b byte
c byte
d byte 57
dseg ends

thread main
set a, 10 // a wordt nu 10
mul b, 20, 5 // b wordt nu 100
mov c, b // c wordt nu 100
div c, d, a // c wordt nu 10
add c, c, 5 // c wordt nu 15
NumOut(10, 8, 1, ccc)
wait 2000 // wacht 2 sec. zodat je kunt zien wat op het display staat
exit
endt

De rest komt nog, hier ben ik nog mee bezig.