LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3):...

61
Faculteit Toegepaste Wetenschappen Vakgroep Zuivere Wiskunde en Computeralgebra Voorzitter: prof. dr. J. A. Thas LL(1)-sturing van de Lego Mindstorms robot door Sam Lerouge Promotor: prof. dr. A. Hoogewijs SCRIPTIE ingediend tot het behalen van de academische graad van licentiaat in de informatica, optie software-ontwikkeling Academiejaar 2000-2001

Transcript of LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3):...

Page 1: LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3): elke herschrijfregel van P is van de vorm A ! aB of A ! a met A;B 2 N en a 2 T ;

Faculteit Toegepaste Wetenschappen

Vakgroep Zuivere Wiskunde en Computeralgebra

Voorzitter: prof. dr. J. A. Thas

LL(1)-sturing van de Lego

Mindstorms robot

door Sam Lerouge

Promotor: prof. dr. A. Hoogewijs

SCRIPTIE ingediend tot het behalen van de academische

graad van licentiaat in de informatica, optie

software-ontwikkeling

Academiejaar 2000-2001

Page 2: LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3): elke herschrijfregel van P is van de vorm A ! aB of A ! a met A;B 2 N en a 2 T ;

Dankwoord

Graag zou ik iedereen willen bedanken die heeft bijgedragen tot het tot stand komen

van dit eindwerk; in het bijzonder wil ik volgende personen bedanken:

• mijn promotor, prof. Albert Hoogewijs om mij de kans te geven op een nuttige

manier met legoblokken te werken, en om mij van in het begin op het juiste

spoor te zetten;

• mijn ouders, omdat ze mij altijd gesteund hebben tijdens mijn studies;

• Geert Vernaeve, om altijd te antwoorden op mijn vele lastige vragen;

• mijn voorganger Hans Gruyaert, omdat er zonder zijn werk wellicht geen

sprake zou geweest zijn van deze scriptie.

Toelating tot bruikleen

De auteur geeft de toelating deze SCRIPTIE voor consultatie beschikbaar te stellen

en delen van de SCRIPTIE te kopieren voor persoonlijk gebruik.

Elk ander gebruik valt onder de beperkingen van het auteursrecht, in het bijzon-

der met betrekking tot de verplichting de bron uitdrukkelijk te vermelden bij het

aanhalen van resultaten uit deze SCRIPTIE.

Sam Lerouge 30 mei 2001

i

Page 3: LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3): elke herschrijfregel van P is van de vorm A ! aB of A ! a met A;B 2 N en a 2 T ;

LL(1)-sturing van de Lego Mindstorms robot

door

Sam Lerouge

SCRIPTIE ingediend tot het behalen van de academische graad van licentiaat in de

informatica, optie software-ontwikkeling

Academiejaar 2000–2001

Universiteit Gent

Faculteit Toegepaste Wetenschappen

Vakgroep Zuivere Wiskunde en Computeralgebra

Voorzitter: prof. dr. J. A. Thas

Promotor: prof. dr. A. Hoogewijs

Samenvatting

Drie jaar geleden toonde Hans Gruyaert in zijn thesis “LL(1)-specificaties in robo-

tica” [2] aan dat LL(1)-talen bijzonder geschikt zijn voor het aansturen van robots.

Deze stelling werd eerder al door prof. Hoogewijs naar voor gebracht. In [3] stelde

hij dat LL(1)-beschrijvingen gebruikt kunnen worden voor de automatische ont-

wikkeling van software voor bewegingscontrole, objectherkenners en mens-machine

interfaces.

De ontwikkeling van de Lego Mindstorms robot, die als commercieel pakket op

grote schaal verkocht wordt, gaf de gelegenheid in de praktijk na te gaan hoe LL(1)-

specificaties kunnen gebruikt worden om een robot op een interactieve manier te

besturen.

Trefwoorden: LL(1)-specificaties, syntax-gerichte software-ontwikkeling, ro-

botsturing, Lego Mindstorms.

ii

Page 4: LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3): elke herschrijfregel van P is van de vorm A ! aB of A ! a met A;B 2 N en a 2 T ;

Inhoudsopgave

1 LL(1) voor robots 1

1.1 LL(1)-talen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1

1.1.1 Talen en grammatica’s . . . . . . . . . . . . . . . . . . . . . . 1

1.1.2 Reguliere grammatica’s . . . . . . . . . . . . . . . . . . . . . . 3

1.1.3 Contextvrije grammatica’s . . . . . . . . . . . . . . . . . . . . 5

1.1.4 LL(1)-grammatica’s . . . . . . . . . . . . . . . . . . . . . . . . 6

1.1.5 Betekenis van een taal . . . . . . . . . . . . . . . . . . . . . . 7

1.1.6 Visual MIRA . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

1.2 CDL en RCL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

1.2.1 Configuration Description Language . . . . . . . . . . . . . . . 10

1.2.2 Robot Control Language . . . . . . . . . . . . . . . . . . . . . 11

1.3 Doel van deze thesis . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

1.4 LL(1)-talen voor robotsturing . . . . . . . . . . . . . . . . . . . . . . 15

2 Lego Mindstorms 18

2.1 Het Mindstorms pakket . . . . . . . . . . . . . . . . . . . . . . . . . . 18

2.2 Programmeeromgevingen voor de RCX . . . . . . . . . . . . . . . . . 19

2.2.1 RCX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

2.2.2 NQC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

2.2.3 LegOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

2.2.4 TinyVM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

2.2.5 LeJOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

iii

Page 5: LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3): elke herschrijfregel van P is van de vorm A ! aB of A ! a met A;B 2 N en a 2 T ;

2.2.6 Andere . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

2.2.7 De keuze . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

2.3 Lego Mindstorms als educatief hulpmiddel . . . . . . . . . . . . . . . 23

2.4 Bouw van de gebruikte robot . . . . . . . . . . . . . . . . . . . . . . 23

3 Realistatie van de RCL 24

3.1 Bereik van de IR zender . . . . . . . . . . . . . . . . . . . . . . . . . 24

3.2 Implementatie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

3.2.1 Origineel voorstel . . . . . . . . . . . . . . . . . . . . . . . . . 27

3.2.2 Aanpassing van de Robot klasse . . . . . . . . . . . . . . . . . 28

3.2.3 Integratie in de scanner/parser . . . . . . . . . . . . . . . . . 30

3.3 Evaluatie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

3.3.1 Eenvoud . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

3.3.2 Traagheid . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32

3.3.3 Vreemde effecten . . . . . . . . . . . . . . . . . . . . . . . . . 32

3.3.4 Onzuivere richting . . . . . . . . . . . . . . . . . . . . . . . . 33

4 Verbeteringen 35

4.1 Aanpassing van de taal . . . . . . . . . . . . . . . . . . . . . . . . . . 36

4.1.1 Richtingen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36

4.1.2 Overbodige instructies . . . . . . . . . . . . . . . . . . . . . . 37

4.1.3 Semantische wijziging . . . . . . . . . . . . . . . . . . . . . . . 38

4.2 Bepalen van de positie . . . . . . . . . . . . . . . . . . . . . . . . . . 38

4.3 Realisatie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40

4.3.1 Bewegen in het rooster . . . . . . . . . . . . . . . . . . . . . . 41

4.3.2 Het gebruik vanuit de parser . . . . . . . . . . . . . . . . . . . 44

5 Conclusie 45

5.1 Suggesties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45

5.1.1 Peer-to-peer . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47

5.1.2 De robot als interpreter . . . . . . . . . . . . . . . . . . . . . 48

iv

Page 6: LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3): elke herschrijfregel van P is van de vorm A ! aB of A ! a met A;B 2 N en a 2 T ;

5.1.3 MIRA als vertaalmechanisme . . . . . . . . . . . . . . . . . . 50

5.2 Besluit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51

v

Page 7: LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3): elke herschrijfregel van P is van de vorm A ! aB of A ! a met A;B 2 N en a 2 T ;

Hoofdstuk 1

LL(1) voor robots

1.1 LL(1)-talen

1.1.1 Talen en grammatica’s

Een taal kunnen we beschouwen als een verzameling van zinnen. Elke zin bestaat uit

een eindig aantal symbolen of bouwstenen. De eindige verzameling van bouwstenen

noemen we het woordenboek of het alfabet. Vermits de meeste talen een oneindig

aantal zinnen bevatten, is er nood aan een formalisme dat toelaat dergelijke talen

op een eindige manier te beschrijven. Een taal zal vastgelegd worden door een

grammatica en een herkenner.

We vertrekken van een eindig woordenboek W en definieren daarmee W +, de

(oneindig aftelbare) verzameling van alle eindige rijen van woorden uit W , d.i. alle

zinnen over W . De lege zin noteren we als & en we noteren W + ∪ {&} als W ∗. Een

taal L over W is een eindige deelverzameling van W ∗.

De kern van een grammatica wordt gevormd door een eindige verzameling P

van herschrijfregels. Een herschrijfregel is een geordend paar (z1, z2) van zinnen met

z1 ∈ W+ en z2 ∈ W ∗. We gebruiken de notatie z1 → z2 wanneer (z1, z2) ∈ P .

Intuıtief kan z1 → z2 gezien worden als “z1 kan vervangen worden door z2” of “z1

kan herschreven worden als z2”. We noemen → de herschrijfrelatie. Ze geeft aan

dat de herschrijving van links naar rechts moet worden toegepast.

1

Page 8: LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3): elke herschrijfregel van P is van de vorm A ! aB of A ! a met A;B 2 N en a 2 T ;

Definitie 1.1 We zeggen nu dat z′ ∈ W ∗ op directe wijze voortgebracht wordt door

z ∈ W+ wanneer er zinnen u, v, z1, z2 ∈ W ∗ bestaan zodanig dat

z = uz1v, z′ = uz2v, z1 → z2 ∈ P (1.1)

en we noteren dit als z ⇒ z′.

Definitie 1.2 We zeggen dat z′ ∈ W ∗ voortgebracht wordt door z ∈ W + wanneer

er zinnen z0, . . . , zn(n ≥ 0) bestaan zodanig dat

z = z0, z′ = zn, ∀i ∈ [0, n − 1] : zi ⇒ zi+1 (1.2)

en we noteren dit als z ⇒∗ z′.

We zijn nu in staat om een grammatica op een formele manier te definieren. We

spreken van voortbrengende of generatieve grammatica’s aangezien ze een taal op

een generatieve manier beschrijven.

Definitie 1.3 Een generatieve grammatica G is een geordend viertal (N, T, S, P )

waarbij:

N een eindige verzameling van woorden is die we de niet-terminalen zullen

noemen;

T een eindige verzameling is van woorden die we terminalen zullen noemen,

zo dat N ∩ T = ∅; merk op dat W = N ∪ T ;

S ∈ N het startsymbool genoemd wordt;

P een verzameling is van herschrijfregels zodanig dat het linkerlid van de her-

schrijfregels minstens een niet-terminaal bevat, d.w.z. P ∈ W ∗NW ∗ × W ∗.

Definitie 1.4 We zeggen nu dat een zin z voortgebracht wordt door de grammatica

G als z ∈ T ∗ en S ⇒∗ z.

Definitie 1.5 De verzameling van alle zinnen voortgebracht door G noteren we

L(G) = {z ∈ T ∗ : S ⇒∗ z}, en noemen we de taal voortgebracht door G.

2

Page 9: LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3): elke herschrijfregel van P is van de vorm A ! aB of A ! a met A;B 2 N en a 2 T ;

Chomsky heeft de grammatica’s ingedeeld in een aantal klassen naargelang de

eigenschappen van de herschrijfregels.

Definitie 1.6 Een generatieve grammatica G = (N, T, S, P ) wordt van het type k

of een (type k)-grammatica (k = 0, 1, 2, 3) genoemd als de volgende restrictie voor

de herschrijf-regels vervuld is:

(0): geen restricties;

(1): elke herschrijfregel van P is van de vorm z1 → z2 met z1, z2 ∈ (N ∩ T )+,

zodanig dat |z1| ≤ |z2|, d.w.z. elke herschrijfregel is niet-verkortend (zin z1 bevat

minder of evenveel woorden dan zin z2); ( contextgevoelig)

(2): elke herschrijfregel van P is van de vorm A → z, met A ∈ N en z ∈

(N ∪ T )∗; ( contextvrij)

(3): elke herschrijfregel van P is van de vorm A → aB of A → a met A, B ∈ N

en a ∈ T ; ( regulier)

Gegeven een grammatica G en een zin z, dan kunnen we nagaan of deze zin

kan voortgebracht worden door G, m.a.w. of S ⇒∗ z. Daartoe wordt vertrokken

van S en worden er herschrijvingen toegepast tot de zin z is bekomen. We noemen

dit een afleiding. De afleiding van een zin kunnen we grafisch voorstellen door een

boom, die we de afleidingsboom zullen noemen. In zo een boom is de wortel het

startsymbool, de bladeren zijn terminalen, en de andere knopen zijn niet-terminalen

uit het alfabet.

Een meest-linkse afleiding wordt gedefinieerd als een afleiding waarbij steeds de

meest-linkse niet-terminaal eerst wordt herschreven. Voortaan zullen we met ⇒ en

⇒∗ steeds de meest-linkse afleidingen bedoelen.

1.1.2 Reguliere grammatica’s

Reguliere grammatica’s werden gedefinieerd in de vorige paragraaf. We geven hier

echter een alternatieve definitie die een meer gestructureerde en beknopte beschrij-

ving van de reguliere grammatica’s toelaat.

3

Page 10: LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3): elke herschrijfregel van P is van de vorm A ! aB of A ! a met A;B 2 N en a 2 T ;

Definitie 1.7 Een reguliere grammatica G wordt gedefinieerd als een koppel (T, e)

waarbij

1. T een eindige verzameling van terminale symbolen is; T = {a1, . . . , an} met

n ≥ 0;

2. e een reguliere expressie is; e kan gezien worden als een regel die aangeeft hoe

strings van terminale symbolen die behoren tot L(G) kunnen afgeleid worden in G.

We geven nu een formele definitie voor reguliere expressies.

Definitie 1.8 Als T een eindige verzameling van terminale symbolen is, dan wordt

een reguliere expressie recursief gedefinieerd door de volgende twee atomaire en drie

samengestelde regels:

(A1) & is de reguliere expressie die de lege string voorstelt;

(A2) ai is een reguliere expressie met ai ∈ T een terminaal symbool;

Stel nu dat e, e1, . . . , en reguliere expressies zijn, dan geldt:

(S1) (e1| . . . |en) is een reguliere expressie (n > 1) waarbij het symbool | de unie-

operator wordt genoemd; intuıtief geeft deze operator aan dat ofwel e1 ofwel e2 ofwel

. . . ofwel en moet gekozen worden;

(S2) e1.e2. . . . .en is een reguliere expressie (n > 1), waarbij het symbool . de

concatenatie- of product-operator wordt genoemd en meestal niet expliciet geschre-

ven wordt;

(S3) (e)∗ is een reguliere expressie waarbij het symbool ∗ de closure-operator

wordt genoemd; intuıtief geeft de closure-operator aan dat e nul of meer keer kan

voorkomen;

Applicaties die als input zinnen uit een bepaalde taal verwachten, krijgen initieel

eigenlijk rijen van karakters aangeboden. Het is de taak van de lexicale analyse om

deze strings te partitioneren in groepjes van karakters die we tokens zullen noemen.

De tokens zijn de elementaire bouwstenen of woorden waarmee de zinnen uit de taal

worden opgebouwd. De tokens hebben dus een betekenis binnen de taal, terwijl

de karakters waaruit de tokens worden opgebouwd, op zich geen betekenis hebben.

4

Page 11: LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3): elke herschrijfregel van P is van de vorm A ! aB of A ! a met A;B 2 N en a 2 T ;

Voorbeelden van tokens zijn cijfers, operatoren, sleutelwoorden en identifiers. We

kunnen reguliere grammatica’s gebruiken om de lexicale structuur van een taal,

i.e. de manier waarop een rij van karakters moet verdeeld worden in tokens, vast

te leggen. De tokens zullen gebruikt worden in de volgende fase van de compiler,

namelijk de syntax-analyse, die de tokens een hierarchische structuur geeft.

In het zogenaamde Dragon Book [1] worden enkele redenen opgesomd om de

opsplitsing tussen een scanner voor de lexicale analyse en een parser voor de syntax-

analyse te maken:

• het ontwerp van de compiler wordt eenvoudiger en overzichtelijker

• de compiler kan efficienter geschreven worden

• de overdraagbaarheid over verschillende platformen wordt groter omdat pro-

blemen door machine-afhankelijkheden opgevangen kunnen worden in de scan-

ner, zodat enkel daar aanpassingen nodig zullen zijn

1.1.3 Contextvrije grammatica’s

De reguliere grammatica’s zullen meestal gebruikt worden om de lexicale structuur

van een taal vast te leggen. Om de syntactische structuur van een taal te be-

schrijven zijn deze grammatica’s te beperkt. Het is bijvoorbeeld niet mogelijk om

met reguliere grammatica’s geneste structuren te beschrijven, zoals conditionele- en

iteratie-statements, expressies met haken en begin-end blokken. De context-vrije

grammatica’s bieden hiervoor een oplossing.

We vertrekken van een generatieve grammatica G = (N, T, S, P ) waarbij

N = {A0, . . . , An} en T = {a0, . . . , an}. Opnieuw zijn N de niet-terminalen, T de

terminalen, S het startsymbool, en P de verzameling herschrijfregels.

Bij een context-vrije grammatica (CVG) zijn alle herschrijfregels uit P van de

vorm Ai → ei waarbij Ai ∈ N en ei een context-vrije expressie (CVE) is. Er is

precies een herschrijfregel voor elke niet-terminaal uit N . Merk op dat we in de

context van CVG’s zullen spreken van syntax-regels i.p.v. herschrijfregels.

5

Page 12: LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3): elke herschrijfregel van P is van de vorm A ! aB of A ! a met A;B 2 N en a 2 T ;

De CVE’s worden recursief gedefinieerd door drie atomaire en drie samengestelde

regels. Het verschil met de reguliere grammatica’s zit in de derde atomaire regel: in

een reguliere expressie kunnen enkel niet-terminalen voorkomen.

(A1) & is een CVE;

(A2) ai ∈ T is een CVE;

(A3) Aj ∈ N is een CVE;

Stel nu dat e, e1, . . . , en CVE’s zijn, dan geldt:

(S1) (e1| . . . |en) is een CVE (n > 1);

(S2) e1. . . . .en is een CVE (n > 1);

(S3) (e)∗ is een CVE;

1.1.4 LL(1)-grammatica’s

We beschouwen een CVG G en een zin z = a1 . . . an ∈ L(G), m.a.w. S ⇒∗ z (de

meest-linkse afleiding). We zullen nu nagaan op welke manier de afleiding van z tot

stand komt. Daarvoor gaan we gebruik maken van de top-down methode. Hierbij

wordt vertrokken van de startknoop, en wordt de afleidingsboom van boven naar

beneden opgebouwd zodanig dat de boom uiteindelijk als bladeren a1, . . . , an bevat.

Algemeen gesproken kunnen we parsers schrijven voor om het even welke CVG.

Door onze grammatica goed te schrijven kunnen we er echter voor zorgen dat er

nooit backtracking zal nodig zijn, waardoor de parser een stuk efficienter wordt. We

moeten dan wel op elk ogenblik genoeg informatie uit de configuratie van de parser

kunnen halen om een juiste beslissing te nemen, meer bepaald het volgen van de

juiste productieregel. In dit geval spreken we van predictieve parsers [1].

Uitgaande van een inputzin maken we gebruik van een inputhead, die zich telkens

boven een bepaald inputwoord bevindt. We vertrekken van het startsymbool, en

herschrijven telkens de meest-linkse niet-terminaal. Voor predictieve parsers moet

het inputwoord voldoende informatie geven om de juiste regel te selecteren. Telkens

wanneer we in de afleiding een terminaal bereiken, wordt de inputhead met een

plaats opgeschoven.

6

Page 13: LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3): elke herschrijfregel van P is van de vorm A ! aB of A ! a met A;B 2 N en a 2 T ;

Een grammatica G wordt een LL(1)-grammatica genoemd wanneer er telkens ten

hoogste 1 woord moet verder gekeken worden vanaf de inputhead om uit te maken

welke herschrijfregel moet toegepast worden. De eerste L staat voor het lezen van

de inputzin van links naar rechts, de tweede L staat voor de meest-linkse afleiding.

Definitie 1.9 Een LL(1)-grammatica is een grammatica waar voor elke zin van de

vorm wAv, w ∈ T ∗, A ∈ N, v ∈ (N∪T )∗, afgeleid door een meest-linkse afleiding, ten

hoogste 1 woord verder moet gekeken worden om op unieke manier te beslissen welke

van de regels met aan de linkerkant de niet-terminaal A, moet toegepast worden.

1.1.5 Betekenis van een taal

Tot nu toe hebben we beschreven hoe de lexicale en de syntactische structuur van

een taal kan vastgelegd worden. De beschrijving van terminalen en syntax-regels uit

een CVG noemen we een syntax-beschrijving of syntax-specificatie. In het bijzonder

kunnen we dus een LL(1)-specificatie opstellen voor een bepaalde LL(1)-grammatica.

Vertrekkend van een dergelijke LL(1)-specificatie kan mechanisch (bv. met Visual

MIRA) een herkenner voor de taal gegenereerd worden. Dit is een programma dat

voor een gegeven inputzin kan uitmaken of de zin al dan niet tot de taal behoort.

We zullen dit programma voortaan de parser noemen.

Met wat we tot nu toe gezien hebben, zijn we in staat om voor een bepaalde

zin na te gaan of deze grammaticaal correct is onder een gegeven grammatica. We

willen echter de gedefinieerde taal ook een betekenis kunnen geven.

De syntax-beschrijving vormt een kader waarop een aantal zaken kunnen gehecht

worden. Die aanvullingen zorgen ervoor dat aan de beschreven taal een betekenis

kan gegeven worden. We geven een kort overzicht:

• Attributen laten toe om zowel aan terminale als aan niet-terminale symbolen

een waarde van een bepaald type te hechten. De terminale en niet-terminale

symbolen met attribuut kunnen dan in semantische acties gebruikt worden als

gewone variabelen.

7

Page 14: LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3): elke herschrijfregel van P is van de vorm A ! aB of A ! a met A;B 2 N en a 2 T ;

• Een semantische actie kan beschouwd worden als een stukje code met een

naam. De naam wordt gebruikt om de bijhorende code op te roepen en komt

voor binnen de syntax-regels. De code wordt uitgevoerd op het moment dat de

semantische actie geparst wordt. Semantische acties kunnen gebruikt worden

om bepaalde code te hechten aan bepaalde woorden of zinnen uit de taal.

• Lokale en globale variabelen: het is mogelijk om variabelen te declareren die

als scope een bepaalde syntax-regel of alle syntax-regels hebben.

• Op dezelfde manier waarop we een verzameling van inputsymbolen opstellen

kunnen we nu een verzameling van outputsymbolen declareren. De input-

symbolen zijn de symbolen die door de parser kunnen ingelezen worden; de

outputsymbolen zijn de symbolen die door de parser gegenereerd worden. De

outputsymbolen komen ook voor in de syntax-regels. Outputsymbolen worden

vooral gebruikt bij lexicale analyse: de input symbolen zijn dan bv. letters,

de output symbolen de sleutelwoorden uit de taal.

1.1.6 Visual MIRA

Visual MIRA is een CASE-tool (Computer Aided Software Engeneering) dat uit-

gaande van de LL(1)-specificatie voor een softwaresysteem de broncode voor de

parser genereert in een traditionele programmeertaal zoals C++. Het is ontworpen

door de MIRA-Development Group van Expert Software Systems N.V. en toegepast

in de ontwikkeling van industriele systemen.

Naast de beschrijving van de grammatica, weergegeven in Backus-Naur Form

(BNF), kunnen semantische acties opgegeven worden, waarvan de code in C++ is ge-

schreven. BNF is een sterk gestructureerde, hierarchische metataal. Niet-terminalen

in een expressie kunnen opeenvolgend worden vervangen door andere niet-terminalen

alvorens uiteindelijk een terminaal symbool bereikt wordt. Deze boomstructuur van

verschillende niveau’s kan voor mensen moeilijk te volgen zijn omdat tegen de tijd

dat men de terminalen bereikt, men de uitdrukking van het hoogste niveau al lang

8

Page 15: LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3): elke herschrijfregel van P is van de vorm A ! aB of A ! a met A;B 2 N en a 2 T ;

kan vergeten zijn. Visual MIRA laat toe om de BNF-beschrijvingen te visualiseren

in corresponderende transitiediagrammen. Figuur 1.1 geeft een voorbeeld van zo

een transitiediagram.

Figuur 1.1: Een transitiediagram in Visual MIRA

De MIRA input kunnen we formeel beschrijven als een syntax-regel:

<MIRA Input> = "Comment"*

(<Option Part> | &)

(<Attribute Part> | &)

(<InputPrimitive Part> | &)

(<OutputPrimitive Part> | &)

<Rule Part>*

(<Parser Part> | &)

(<FollowSet Part> | &)

• Option Part: Dit deel laat toe de generatie van de applicatie af te stellen door

bepaalde opties op te geven.

• Attribute Part: Hier worden de types van de attributen gedefinieerd. Attri-

buten kunnen geassocieerd worden aan regels, input- en outputprimitieven.

• InputPrimitive Part: In dit deel worden de symbolen gedefinieerd die de ge-

genereerde applicatie als input zal aanvaarden (de terminalen).

• OutputPrimitive Part: Dit deel bevat de definitie van de symbolen die de

applicatie zal produceren in zijn output.

9

Page 16: LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3): elke herschrijfregel van P is van de vorm A ! aB of A ! a met A;B 2 N en a 2 T ;

• Rule Part: Dit deel bevat de syntax-regels die de structuur van de input van

de applicatie vastleggen. De syntax-regels kunnen in de context van MIRA

gezien worden als kleine modules die elk hun eigen lokale informatie kunnen

hebben. De attributen worden gebruikt als communicatiemechanisme tussen

regels en ook tussen de stukken C++ code die regels kunnen bevatten (de

semantische acties).

• Parser Part: In dit deel staan de globale code en de data definities. Deze

definities kunnen gebruikt worden in elke regel. Bovendien kunnen de de-

fault routines om inputprimitieven te lezen of outputprimitieven te schrijven

herdefinieerd worden.

1.2 CDL en RCL

Gruyaert [2] ontwikkelde twee domein-afhankelijke specificatie-talen, de ene om de

omgeving van de robot te beschrijven, de andere om de robot aan te sturen.

1.2.1 Configuration Description Language

De omgeving van de robot wordt beschreven door CDL, de Configuration Description

Language. Een CDL-specificatie beschrijft een omgeving. Deze specificatie wordt

omgezet in een configuratie die gebruikt wordt door de controle-eenheid van de

robot. [2]

Zo’n beschrijving geeft minimaal de afmetingen van de werkruimte en de begin-

positie van de robot op. Verder kunnen de posities van obstakels en de doelpositie

van de robot vastgelegd worden.

Wij hebben geen CDL nodig, omdat het niet de bedoeling is dat de gebruiker

de omgeving beschrijft. Het is de robot die zelf door middel van zijn sensoren zijn

omgeving, meer bepaald de plaats van aanwezige obstakels, moet gaan ontdekken.

10

Page 17: LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3): elke herschrijfregel van P is van de vorm A ! aB of A ! a met A;B 2 N en a 2 T ;

1.2.2 Robot Control Language

Gruyaert haalde zijn inspiratie voor de RCL taal bij Logo, een simpel maar krachtig

interactief systeem voor het uitvoeren van zogenaamde Turtle Graphics. Een turtle

is een kleine driehoekige wijzer die reageert op een aantal eenvoudige commando’s

zoals go, line en left. Logo is net als RCL een geınterpreteerde taal. De commando’s

worden ingelezen aan een prompt en direct uitgevoerd. Een dergelijke omgeving

waarin instructies onmiddellijk een actie van de turtle tot gevolg hebben, leent zich

uitstekend tot het op een speelse en directe manier aanleren van enkele basisprincipes

van het programmeren. [2]

De Robot Control Language is een erg intuıtieve taal voor de besturing van de

robot. Er zijn zogenaamde motion commands of bewegingscommando’s, controle-

statements (if-testen en voorwaardelijke en onvoorwaardelijke lussen), en elemen-

taire operaties op de drie datatypes int (gehele getallen), bool (booleaanse waarden)

en dir (richtingen). Een syntaxbeschrijving moet voldoende zijn om weer te geven

hoe de robot precies bestuurd kon worden.

<RCL input> = (<variable declaration> |

<statement> | <procedure declaration>) ";"

<variable declaration> = ("int" | "bool" | "dir")

(& | "[" "number" "]") "identifier"

<statement> = <simple statement>

| <conditional>

| <iteration>

| <procedure call - assignment>

<simple statement> = "go" (& | <expression>)

| "test" (& | <expression>)

| "turn"

11

Page 18: LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3): elke herschrijfregel van P is van de vorm A ! aB of A ! a met A;B 2 N en a 2 T ;

| "flip"

<conditional> = "if" <expression> "then" <statement list>

<iteration> = "loop" <expression> "times" <statement list>

| "while" <expression> "repeat" <statement list>

<procedure call - assignment> = "identifier"

(<actual arguments> |

(& | "[" <expression> "]") "=" <expression>)

<statement list> = "[" <statement> (";" <statement>)* "]"

<actual arguments> = & | "("<expression> ("," <expression>)* ")"

<expression> = <comparison> (("and" | "or") <comparison>)*

<comparison> = <integer>

(("<" | "<=" | "==" | ">=" | ">" | "!=") <integer>)*

<integer> = <term> (( "+" | "-") <term>)*

<term> = <factor> (("*" | "/") <factor>)*

<factor> = "not" <factor>

| "-" <factor>

| "abs" <factor>

| "number"

| "true"

12

Page 19: LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3): elke herschrijfregel van P is van de vorm A ! aB of A ! a met A;B 2 N en a 2 T ;

| "false"

| "left"

| "up"

| "right"

| "down"

| "("<expression>")"

| "identifier" ("[" <expression> "]" | &)

<procedure declaration> = "procedure" "identifier"

<formal arguments> <local variables> <body definition>

<formal arguments> = & | "("<variable declaration>

("," <variable declaration>)* ")"

<local variables> = & | "var" <variable declaration>

("," <variable declaration>)* ";"

<body definition> = "begin"

<statement> (";" <statement>)*

"end"

Bemerk de op het eerste zicht nogal merkwaardige definitie van <statement>:

procedure-calls en assignaties zijn gegroepeerd. Dit is nodig omdat beide soorten

statements met een identifier beginnen. We willen dat onze taal LL(1) is (voor het

gebruik van Visual MIRA), wat betekent dat het volgende inputsymbool voldoende

informatie bevat om te weten welke grammaticaregel(s) we moeten toepassen.

RCL kent drie verschillende datatypes: gehele getallen (int), booleaanse waarden

(bool) en richtingen (dir). Richtingen zijn left, up, right en down, en hebben dezelfde

betekenis als respectievelijk 0, 1, 2, 3 modulo 4. De richtingen worden absoluut

geınterpreteerd, dus niet ten opzichte van de richting van de robot. Om die reden

13

Page 20: LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3): elke herschrijfregel van P is van de vorm A ! aB of A ! a met A;B 2 N en a 2 T ;

zou het misschien logischer geweest zijn windrichtingen (noord, oost, zuid, west) te

gebruiken om de richtingen aan te duiden, in plaats van de huidige benamingen up,

right, left en down.

De gebruiker kan zelf variabelen van een bepaald type declareren, maar kan ook

gebruik maken van een beperkt aantal systeemvariabelen. Deze geven toegang tot de

informatie omtrent de robot en zijn werkruimte. Ze kunnen niet door de gebruiker

gewijzigd worden en worden bij elke actie van de robot aangepast. In Gruyaert’s

Robot Control Language komen volgende gegevens voor als systeemvariabelen: de

afmetingen van de werkruimte (XW en YW), de positie van de robot (XR en YR),

de coordinaten van het doel (XT en YT), de orientatie van de robot (DIRECTION)

en het resultaat van de test-instructie (CONDITION), indien dit de vorige instructie

was.

Door deze syntaxbeschrijving samen met de gepaste semantische acties als input

aan Visual MIRA te geven, wordt een parser gegenereerd voor RCL. Dit is voor

de auteur van de user interface een C++ functie die als argument een string heeft

die een (al dan niet correcte) RCL instructie voorstelt, een object van de klasse

Robot en de ProgramState, die informatie over de toestand van het programma

bijhoudt. Die twee objecten zijn nodig omdat nogal wat informatie over verschillende

RCL instructies heen bewaard moet worden, zoals gebruikers- en systeemvariabelen.

Figuur 1.2 geeft weer hoe de twee onderdelen in [2] met elkaar samenwerkten in een

geheel.

1.3 Doel van deze thesis

Het is de bedoeling om de Robot Control Language te gebruiken voor de besturing

van een Lego Mindstorms robot in plaats van een virtuele ’turtle’ op het compu-

terscherm. Indien dit nodig blijkt, kan de taal uiteraard ook (in beperkte mate)

aangepast worden aan de nieuwe situatie.

We konden vooraf al voorspellen dat de grootste problemen zouden ontstaan uit

de belangrijkste beperkingen van de Lego robot: infrarood communicatie tussen host

14

Page 21: LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3): elke herschrijfregel van P is van de vorm A ! aB of A ! a met A;B 2 N en a 2 T ;

Figuur 1.2: De interactie tussen CDL en RCL

en robot vereist visueel contact, de motoren kunnen niet nauwkeurig genoeg afgesteld

worden, en er kunnen slechts drie motoren en drie sensoren gebruikt worden.

1.4 LL(1)-talen voor robotsturing

In Teach your Robot an LL(1)-Jargon [4] wordt beschreven hoe we een domein-

specifieke taal kunnen ontwerpen voor een robot. Met het aanleren van een LL(1)-

Jargon aan een robot bedoelt men het specifieren van een taalprocessor die instruc-

ties voor de robot omzet in machinecode voor die robot. Daarbij kunnen we gebruik

maken van syntaxgestuurde ontwikkeling. Hieronder verstaat men een methode voor

software-ontwikkeling waarbij de syntax van de invoer van de applicatie een centrale

rol speelt: de syntax vormt een kader waaraan semantische acties, attributen en lo-

kale en globale informatie kan opgehangen worden. We kunnen voor de beschrijving

van de taal het ELL(1) formaat gebruiken, in combinatie met Visual MIRA.

Met een jargon bedoelt men een gemakkelijk te ontwikkelen domein-specifieke

15

Page 22: LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3): elke herschrijfregel van P is van de vorm A ! aB of A ! a met A;B 2 N en a 2 T ;

taal, die kan aangemaakt worden door domein-ingenieurs die zelf geen taalexperten

zijn. De praktijk heeft aangetoond dat voor hen LL(1)-specificaties gemakkelijk te

hanteren zijn. Het jargon dat we willen beschrijven hangt af van de omgeving van

de robot en van de opdrachten die hij zal moeten uitvoeren. We moeten het jargon

definieren alvorens we overgaan tot het schrijven van de taalprocessor, zo stelt [4].

De tekst somt een aantal voordelen op van het syntaxgestuurd ontwikkelen van

een LL(1)-jargon met de hulp van een tool als Visual MIRA:

• De implementatie van het jargon hangt vooral af van de syntaxbeschrijving,

wat aanpassingen aan structurele veranderingen in de omgeving vergemakke-

lijkt.

• Er is een hoog niveau van abstractie, wat zorgt voor een overzichtelijke en

goed leesbare code.

• Het automatisch genereren van de parser verkleint de kans op fouten.

• Het aanbrengen van wijzigingen aan de syntax is erg eenvoudig, en de taal is

gemakkelijk uitbreidbaar.

• Overschakelen naar een ander platform is eenvoudig.

Tijdens mijn realisaties heb ik kunnen vaststellen dat deze voordelen stuk voor

stuk aanwezig zijn. Ik kon inderdaad gemakkelijk reageren op de veranderde omge-

ving, de code die ik overnam uit [2] had ik snel onder de knie, ik had zelden met

bugs te kampen, een kleine toevoeging aan de syntax was in een oogwenk geklaard,

en de overschakeling van een Windows- naar een Linux-platform gaf geen noemens-

waardige problemen. Op elk van deze punten ga ik in de volgende hoofdstukken

dieper in.

De semantische acties die in [4] gebruikt worden bij de syntax-gestuurde ont-

wikkeling van de domein-specifieke RCL taal, zijn objectgeorienteerde C++ functie-

aanroepen, die een parserboom opbouwen. Bij de evaluatie van die boom worden

methodes uit de klasse Robot aangeroepen, waarvan de implementatie specifiek is

16

Page 23: LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3): elke herschrijfregel van P is van de vorm A ! aB of A ! a met A;B 2 N en a 2 T ;

voor de robot die we ons jargon willen leren. Het gebruik van dit interface-paradigma

vergemakkelijkt de overstap van de ene robot naar de andere: het volstaat de im-

plementatie van de methodes uit die klasse aan te passen aan de nieuwe robot. Dit

paradigma heb ik zelf ook nog eens doorgetrokken op een ander niveau, door in de

eigenlijke code een bestand op te roepen waarin dan precies vastgelegd wordt hoe de

robot zijn bewegingen uitvoert. Het uitgangspunt van mijn werk was een voorstel

in de tekst voor een aanpassing van de RCL omgeving voor de Lego Mindstorms

robot. Binnen de klasse Robot moet hierbij in de eerste plaats een nieuwe methode

moveto(dir) geımplementeerd worden. Deze functie zou dan NQC code genereren,

afhankelijk van de opgegeven richting, en deze dan op de robot laten uitvoeren. De

andere functies in de klasse moeten dan indien nodig ook aangepast worden door

gebruik te maken van deze moveto functie. Voor elke beweging die de robot moet

doen, wordt dus een klein programma naar de robot gestuurd, die dat dan uitvoert.

Om het probleem van visueel contact voor de infrarood verbinding op te lossen,

werd er voor gezorgd dat na elke beweging de robot terug in dezelfde richting keek.

Dit kan door in het begin in de juiste richting te draaien, vooruit te rijden, en tot

slot in de omgekeerde richting te draaien. Figuur 1.3 geeft schematisch weer hoe het

geheel dan zou moeten werken.

inputstring tokenstringScanner Parser

PC Robot

Communicatie

Figuur 1.3: RCL voor Lego Mindstorms

17

Page 24: LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3): elke herschrijfregel van P is van de vorm A ! aB of A ! a met A;B 2 N en a 2 T ;

Hoofdstuk 2

Lego Mindstorms

2.1 Het Mindstorms pakket

De essentiele onderdelen van de Mindstorms omgeving kunnen we opsplitsen in drie

delen: de zogenaamde RCX programmable brick, een infrarood zender en ontvanger

en een PC.

De kern van de robot is de RCX programmable brick (vanaf nu spreken we van

het RCX blok of kortweg de RCX). Dit is een blok waarop bovenaan en onder-

aan legoblokken kunnen bevestigd worden om zo een robot te kunnen bouwen uit

legoblokken. Binnenin zit de kern van de robot: een Hitachi H8 processor, die

32kB extern RAM-geheugen heeft. Daarnaast bevat de RCX een infrarood zender-

ontvanger, een LCD scherm om informatie te tonen en elektronica voor de invoer-

signalen (3 sensoren) en uitvoersignalen (3 motoren). Verder vinden we nog een

16kB ROM-geheugen dat als driver gebruikt wordt bij het opstarten van de robot.

Samen met de firmware, die zich in het RAM-geheugen bevindt, voert dit geheu-

gen instructies uit die verstuurd worden vanaf de PC. Bij de standaardomgeving die

Lego bij het RIS-pakket (Robot Invention System) levert, is de firmware 16kB groot.

Gebruikersprogramma’s kunnen in een deel van het geheugen dat 6 kB groot is als

bytecode bewaard worden en uitgevoerd worden wanneer daarom wordt gevraagd.

De infrarood zender-ontvanger, ook wel de toren genoemd, heeft twee modes

18

Page 25: LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3): elke herschrijfregel van P is van de vorm A ! aB of A ! a met A;B 2 N en a 2 T ;

voor het zenden: short range en long range. Het onderscheid is zeer belangrijk,

zoals we later zullen merken. De gebruiker kan kiezen tussen de twee modes met

behulp van een schakelaar op de toren. De infrarood component van de RCX kent

hetzelfde onderscheid, maar daar is geen schakelaar. Wel kan in de meeste program-

meeromgevingen via een instructie bepaald worden in welke mode we werken. De

toren wordt met de PC verbonden via een kabel die op de seriele poort aangesloten

wordt.

In november 1998 slaagde Kekoa Proudfoot [7] erin het seriele protocol tussen de

PC en de RCX te ontcijferen. Daarmee ging een nieuwe wereld open voor de Mind-

storms wereld: verschillende groepen slaagden erin alternatieven te creeren voor de

bestaande firmware die Lego leverde en uiteindelijk toch nogal wat beperkingen had

voor mensen met een minimum aan programmeerervaring.

2.2 Programmeeromgevingen voor de RCX

We kunnen nu een kort overzicht geven van de verschillende mogelijkheden om pro-

gramma’s te schrijven voor de RCX.

2.2.1 RCX

De standaardtaal die Lego zelf levert bij het Mindstorms pakket, en wordt geınter-

preteerd door een door Lego ontwikkelde interpreter die loopt op de RCX processor,

wordt zelf ook RCX genoemd.

Deze taal is vooral gericht naar kinderen van een jaar of twaalf die de wereld

van robots willen leren kennen. Lego levert voor hen een visuele programmeer-

omgeving bij het RIS-pakket. Sterke punten zijn de eenvoud, de mogelijkheid om

visueel te programmeren en de voorzieningen voor multithreading. Zwakheden zijn

het beperkt aantal variabelen en de afwezigheid van procedures.

19

Page 26: LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3): elke herschrijfregel van P is van de vorm A ! aB of A ! a met A;B 2 N en a 2 T ;

2.2.2 NQC

Dave Baum [8] ontwikkelde een eenvoudige programmeertaal die de mogelijkheden

overhoudt van de vorige taal, maar toch wat meer lijkt op een klassieke program-

meertaal als C, vandaar de naam Not Quite C. Procedures zijn hier wel toegelaten.

De code wordt vertaald naar RCX commando’s, zodat de instellingen van de RCX

niet moeten veranderd worden. Programma’s zijn meestal kort en eenvoudig. NQC

is vrij beschikbaar onder de Mozilla Public License, en wordt gebruikt onder Win32,

Macintosh, Mac OS X en Linux.

De grote zwakte van NQC is dat het slechts een beperkt aantal variabelen toe-

laat (32 om precies te zijn). Daardoor wordt het moeilijker bruikbaar voor grote,

complexere toepassingen. Men kan wel gebruik maken van een veel grotere datalog,

een geheugenruimte waar een NQC-programma gegevens kan naar wegschrijven, en

die later door de host computer kan opgevraagd worden. Jammer genoeg kan de

RCX zelf de datalog niet raadplegen.

Het is nodig om het ook even te hebben over de communicatie van de host compu-

ter met de robot onder NQC. We moeten dit zien als een client-server architectuur,

niet als een peer-to-peer communicatie. We hebben dus niet met twee ’gelijken’ te

maken, die om het even wanneer het initiatief kunnen nemen om een communicatie

op te starten. In het NQC model, opgedrongen door de firmware die Lego levert,

kan enkel de host computer (in dit geval de client) het initiatief nemen om de com-

municatie te beginnen. Dit is bijvoorbeeld het doorsturen van een programma dat

moet uitgevoerd worden, of het opvragen van de datalog. Het is dan aan de RCX,

de server dus, om het verzoek van de client te beantwoorden. Indien de opdracht

een programma was, moet de robot dit uitvoeren maar geen antwoord terugsturen;

indien het het opvragen van de datalog was, wordt er wel een echt antwoord terug-

gestuurd naar de PC. Doordat de infra-rood toren automatisch uitgeschakeld wordt

na enkele seconden inactief zijn, kan de robot niet zelf het initiatief nemen om een

of ander bericht naar de PC te sturen.

20

Page 27: LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3): elke herschrijfregel van P is van de vorm A ! aB of A ! a met A;B 2 N en a 2 T ;

2.2.3 LegOS

LegOS [9] is een open source besturingssysteem voor de RCX. De kernel vervangt de

oorspronkelijke firmware die Lego zelf voorziet. In LegOS is er wel toegang tot het

beschikbare RAM-geheugen mogelijk en die wordt enkel beperkt door de grootte van

het geheugen. Enkele bibliotheken implementeren de instructies voor de aansturing

van de motoren en het lezen van de gegevens van de sensoren. Programma’s worden

geschreven in C of C++ en gecompileerd met de GNU C compiler, die eerst moet

geconfigureerd worden als cross-compiler1 voor de Hitachi H8 processor. Ook het

besturingssysteem zelf is in C geschreven, en gecompileerd met de GNU C compiler.

De ontwikkeling gebeurde onder Linux, maar legOS zou ook bruikbaar moeten zijn

op alle platformen waarvoor de GNU C compiler beschikbaar is, dus de meeste

Unix-varianten en de Windows-omgeving.

Naast het feit dat de programmeur nu gebruik kan maken van al het beschikbare

geheugen, en in een vertrouwde taal kan programmeren, biedt LegOS nog enkele

voordelen. Zo is multithreading met al zijn aspecten geımplementeerd, en kan de

hardware, bijvoorbeeld het LCD scherm, rechtstreeks aangesproken worden. Er is

het LegOS Network Protocol, dat communicatie mogelijk maakt tussen de RCX en

de host-computer, of zelfs tussen verschillende robots en host-computers. Nadelig

is dat het besturingssysteem ongeveer de helft van het geheugen inneemt, weliswaar

afhankelijk van welke functionaliteiten aanwezig moeten zijn (de voorzieningen voor

geluid kunnen bijvoorbeeld gemakkelijk weggelaten worden bij de installatie). Bo-

vendien is het project op dit ogenblik nog in beta-fase, wat betekent dat het nog

een aantal bugs kan bevatten.

2.2.4 TinyVM

TinyVM [10] is een open source project dat een (beperkte) virtuele Java-machine

bovenop de Hitachi processor implementeert. Het sterke punt is zijn kleine om-

1Een cross-compiler is een compiler die code genereert voor een andere machine dan die waar

de compiler zelf op draait.

21

Page 28: LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3): elke herschrijfregel van P is van de vorm A ! aB of A ! a met A;B 2 N en a 2 T ;

vang: minder dan 10kB! Bovendien worden de class-files die de programmeur aan-

maakt, nog eens sterk gecomprimeerd. De meeste functionaliteiten van Java worden

geımplementeerd, behalve garbage collection, het gebruik van floating point getallen,

en het gebruik van switch statements. Constante strings worden bovendien gene-

geerd. Ook is slechts een beperkt deel van de standaard Java API geımplementeerd.

Dit alles is natuurlijk een serieuze beperking.

2.2.5 LeJOS

LeJOS [11] is een oplossing voor de beperkingen van TinyVM: het is een meer

volledige virtuele Java-machine, die bijvoorbeeld wel floating point getallen toelaat.

Resultaat is wel dat de grootte onmiddellijk enorm toeneemt. De huidige versie

heeft 17k nodig van de 28k die effectief voor de gebruiker beschikbaar zijn. LeJOS

is op dit ogenblik nog in volle ontwikkeling; zo moet in de nabije toekomst onder

andere nog garbage collection geımplementeerd worden.

2.2.6 Andere

Verder zijn er nog een aantal alternatieve programmeertalen in gebruik of in ontwik-

keling, waaronder pbFORTH en SmallTalk, maar daar ben ik niet diep op ingegaan.

Aangezien er maar weinig over te vinden is, veronderstel ik dat rond deze omge-

vingen niet echt veel gebeurt.

2.2.7 De keuze

Mijn keuze viel uiteindelijk op NQC, in de eerste plaats omwille van zijn eenvoud.

Wie enkele van de talloze voorbeelden op het net bekijkt, zal vaststellen dat op-

drachten die in vele gevallen erg ingewikkeld lijken, dikwijls in bijzonder compacte

en toch nog leesbare code kan gerealiseerd worden. Bovendien was NQC in het be-

gin van het academiejaar het enige platform dat kon gevonden worden dat al een

volledig werkbare, (zo goed als) foutvrije versie kon bieden.

22

Page 29: LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3): elke herschrijfregel van P is van de vorm A ! aB of A ! a met A;B 2 N en a 2 T ;

2.3 Lego Mindstorms als educatief hulpmiddel

De RCX is al meermaals gebruikt voor educatieve doeleinden, vooral in informatica-

klassen. Zo wordt in [6] beschreven hoe men de robot kan gebruiken om studen-

ten aan te leren meer vooraf te plannen en te ontwerpen, dit in plaats van in het

wilde weg iets uit te proberen en te verbeteren, zoals veel beginnende informatica-

studenten gemakkelijk geneigd zijn te doen.

Indien het lukt de Lego Mindstorms robot op een handige manier te laten be-

sturen via de RCL taal, kan hij ook voor jongere studenten als educatief project

gebruikt worden. Een eenvoudige domein-specifieke taal als RCL is wellicht zeer

goed geschikt om studenten uit het secundair onderwijs te laten kennismaken met

de basisprincipes van programmeren en met de wereld van de robotica.

2.4 Bouw van de gebruikte robot

In de handleiding die bij het Mindstorms pakket zit, wordt een robuuste robot

beschreven, die goed geschikt is om rond te rijden in een omgeving zonder al te

moeilijke hindernissen. Hij wordt aangestuurd door twee motoren, die elk twee wie-

len aandrijven. De robot is zodanig gebouwd dat er makkelijk een of twee bumpers

en een lichtsensor op kunnen aangesloten worden. In de eerste versie was er enkel

een bumper nodig.

23

Page 30: LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3): elke herschrijfregel van P is van de vorm A ! aB of A ! a met A;B 2 N en a 2 T ;

Hoofdstuk 3

Realistatie van de RCL

3.1 Bereik van de IR zender

Alvorens de methode te volgen die A.Hoogewijs, H.Gruyaert en G.Vernaeve voorstel-

len in het artikel Teach your robot an LL(1)-jargon, dienen we ons er van te gewissen

dat de robot op om het even welke plaats in de te gebruiken ruimte de infra-rood

signalen (meer bepaald mini-programma’s die een atomaire beweging uitvoeren) kan

ontvangen indien de robot voldoende goed gericht staat. Indien dit niet het geval

is, zal een totaal andere aanpak gevolgd moeten worden. Lego zelf beweert in de

Users Guide dat er visueel contact nodig is, en dat de afstand tot zo’n 30 meter mag

oplopen, hoewel de ideale afstand voor het laden van programma’s 10 tot 12 cm is.

Om een beeld te krijgen van de posities waar signalen ontvangen worden, schreef

ik een programma dat zelf zo een beeld uittekent. Het is zodanig geschreven dat

de afmetingen van het rooster gemakkelijk kunnen aangepast worden. Eerst creeert

het programma (geschreven in C) een NQC-programma dat op de robot zal lopen.

De robot gaat op alle plaatsen van het rooster staan, en op elke plaats wacht hij

twee seconden om te zien of hij signalen ontvangt van de IR toren. Als dat zo is,

dan onthoudt hij deze plaats. Op het einde keert hij terug naar de oorspronkelijke

plaats (verondersteld wordt dat dit recht tegenover de toren is) waar hij uiteindelijk

zijn datalog met succesvolle plaatsen doorstuurt naar de host computer. Het C-

24

Page 31: LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3): elke herschrijfregel van P is van de vorm A ! aB of A ! a met A;B 2 N en a 2 T ;

programma zelf is ondertussen verder gegaan. Het schat de tijd die de robot zal

doen over de hele cyclus, en gedurende die tijd zendt het elke seconde een signaal

naar de robot, die zelf moet kijken of hij dit ontvangt. Wanneer de tijd is afgelopen,

downloadt het programma de daarnet vermelde datalog en gebruikt deze informatie

om de resultaten visueel voor te stellen.

De eerste tests vielen zwaar tegen. Figuur 3.1 toont bijvoorbeeld een situatie

van een 12x10 rooster, met een onderlinge afstand van een tiental centimeter tussen

de meetpunten.

Figuur 3.1: De ontvangst in short range mode

Merk vooral op dat het beeld helemaal niet symmetrisch is. Verder is ook de

afstand teleurstellend, en vooral de hoek waaronder de robot niets meer ontvangt.

Een eerste zware ontgoocheling dus, maar kort nadien las ik in de NQC handlei-

ding dat er een optie -far was die er voor moet zorgen dat er in long range mode

gewerkt wordt. Toen wist ik wel al dat de IR unit van de RCX brick onderscheid

maakte tussen short range en long range, maar blijkbaar gold dit ook voor de to-

ren. Hoopvol probeerde ik hetzelfde, maar dan met de -far optie voor het continu

sturen van boodschappen. De resultaten vielen opnieuw zwaar tegen: bijna identiek

25

Page 32: LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3): elke herschrijfregel van P is van de vorm A ! aB of A ! a met A;B 2 N en a 2 T ;

hetzelfde resultaat! Figuur 3.2 toont bijvoorbeeld het beeld van een 8x8 rooster met

onderlinge afstand van ongeveer vijftien centimeter.

Figuur 3.2: De ontvangst met de -far optie

Gelukkig had ik de dag voordien op een website [12] gelezen dat er op de IR

toren een schakelaar moest zijn die er voor zorgt dat je kan kiezen tussen short en

long range. Links is short, rechts is long. Deze informatie staat uiteraard ook in de

Users Guide, maar die had ik toen nog niet grondig bekeken. Toen ik de schakelaar

naar rechts had geplaatst en precies hetzelfde programma had uitgevoerd, kreeg ik

de resultaten die weergegeven zijn in figuur 3.3. Ze zijn niet te vergelijken: op elke

plaats is er nu ontvangst! Een uitstekend resultaat, vooral omdat er blijkbaar ook

geen enkel probleem is wat de hoek betreft. Bovenaan in het midden kijkt de robot

naar de toren, maar links en rechts bovenaan kijkt de robot eigenlijk naast de toren;

de hoek tussen de IR transmitters bedraagt net geen 180 graden.

Ik begon mij hierdoor af te vragen wat er zou gebeuren als ik de robot net buiten

het visueel bereik van de toren zou plaatsen (erachter dus). Tot mijn grote verbazing

bleek de robot ook daar alles te ontvangen! Toch ga ik er van uit dat enkel bij visueel

contact de communicatie betrouwbaar genoeg is om te mogen veronderstellen dat

instructies met zekerheid ontvangen zullen worden. Daarom kies ik er voor om de

aanpak uit [4] te blijven volgen. Concreet betekent dit dat elke beweging er voor zal

26

Page 33: LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3): elke herschrijfregel van P is van de vorm A ! aB of A ! a met A;B 2 N en a 2 T ;

Figuur 3.3: De ontvangst met de zender in long range mode

zorgen dat de robot op het einde toch in de oorspronkelijke richting staat. Een turn

of een flip instructie zal dan geen zichtbaar effect hebben, enkel de ProgramState

wordt aangepast.

3.2 Implementatie

3.2.1 Origineel voorstel

In [4] wordt, zoals eerder al vermeld, voorgesteld om de robot telkens in dezelfde

richting te laten kijken om zo het IR probleem aan te pakken. Wanneer de robot

een vakje naar links wil, zal hij dus niet enkel naar links draaien en vooruit gaan,

maar ook terug naar rechts draaien om de richting te behouden.

Bij dit voorstel worden volgens mij twee belangrijke dingen over het hoofd gezien:

• Het is niet de bedoeling dat de robot achter de IR toren terechtkomt. Daarom

maakt mijn implementatie gebruik van een soort virtuele muur. Bij de initi-

alisatie krijgt de robot de coordinaten (0, 0) mee, wat betekent dat de robot

vlak voor de toren staat (we veronderstellen dus dat de gebruiker de robot

daar gezet heeft). Wanneer de Y-coordinaat positief wordt, kunnen we er dus

27

Page 34: LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3): elke herschrijfregel van P is van de vorm A ! aB of A ! a met A;B 2 N en a 2 T ;

vanuit gaan dat de robot zich niet meer in het gezichtsveld van de toren zal

bevinden. De oplossing is dus erg eenvoudig: als moveto wordt aangeroepen,

en de robot bevindt zich op een positie met Y-coordinaat 0 en wil vooruit

gaan, dan zullen we dit verhinderen door te doen alsof de robot op een muur

gebotst is.

• Er werd ook geen rekening gehouden met mogelijke obstakels. Kennelijk was

het de bedoeling een tweede functie te implementeren die de testopdrachten

zou realiseren. Toch blijft er dan een probleem: wanneer de robot een obstakel

tegenkomt, blijft hij een zekere tijd verder rijden, waardoor hij gedesorienteerd

kan raken. Een betere oplossing is daarom de twee functies te integreren:

moveto doet de robot naar de opgegeven richting rijden totdat de tijd die

met een vakje overeenkomt overschreden is of tot de bumper een obstakel

detecteert. In dat geval keert hij naar zijn oorspronkelijke plaats terug, en

rapporteert via de datalog de faling aan de PC. De moveto heeft dus altijd

een booleaans resultaat, die in een go opdracht genegeerd wordt, maar waar

in een test opdracht wel rekening mee gehouden wordt. Hierdoor is nog een

aanpassing nodig: bij een go down (achteruit dus), kan de robot niet achteruit

rijden omdat hij daar geen bumper heeft. Hij moet dus 180 graden draaien,

vooruit gaan, en opnieuw 180 graden draaien.

3.2.2 Aanpassing van de Robot klasse

Omdat er niet langer gebruik gemaakt wordt van CDL om de configuratie van de we-

reld van de robot op te geven, maar de robot zelf zijn omgeving gaat aftasten, is het

gebruik van een Workspace, die aanwezig was in de implementatie van [2] overbodig

geworden. Alle verwijzingen ernaar kunnen dus verwijderd worden, waardoor enkele

functies uit de klasse Robot totaal overbodig zijn geworden en dus ook verwijderd

mogen worden.

Om eventuele aanpassingen te vergemakkelijken stopte ik de code die recht-

streeks voor de interactie met de robot zorgt, in een private functie moveto(dir).

28

Page 35: LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3): elke herschrijfregel van P is van de vorm A ! aB of A ! a met A;B 2 N en a 2 T ;

Die genereert een klein NQC programma dat een atomaire instructie uitvoert: de

robot verplaatst zichzelf hoogstens een coordinaat naar voor, achter, links of rechts,

afhankelijk van de parameter van de functie. Indien de bumper tijdens deze be-

weging ingedrukt raakt, zal de robot naar zijn oorspronkelijke plaats terugkeren.

In de datalog wordt opgeslagen of de beweging al dan niet gelukt is. Aan de kant

van de gebruiker wordt ondertussen voldoende lang gewacht, tot het programma

zeker beeindigd is. Vervolgens wordt de datalog opgevraagd om het resultaat van

de beweging te kennen. De moveto functie wordt aangeroepen vanuit de go en test

functies.

Voor de geınteresseerden geven we nu de inhoud van de moveto functie.

bool Robot::moveto(int dir) {

FILE *program, *datalog;

char line[80];

bool res;

program = fopen("gridmove.nqc", "w");

fprintf(program, "#include \"roverbot.h\"\n\n");

fprintf(program, "task main() {\n int afstand;\n initmotors();\n"

" SetSensor(SENSOR_1,SENSOR_TOUCH);\n afstand = 0;\n");

switch(dir) {

case R: fprintf(program, " right(90);\n"); break;

case D: fprintf(program, " right(180);\n"); break;

case L: fprintf(program, " left(90);\n"); break;

default: break;

}

fprintf(program, " Wait(%d);\n", RELAXTIME);

fprintf(program, " CreateDatalog(1);\n"

29

Page 36: LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3): elke herschrijfregel van P is van de vorm A ! aB of A ! a met A;B 2 N en a 2 T ;

" if (afstand < %d) AddToDatalog(0);\n"

" else AddToDatalog(1);\n}\n", GRIDTIME);

fclose(program);

system("nqc -d gridmove.nqc -run");

sleep(4);

datalog = popen("nqc -datalog", "r");

if (fgets(line,sizeof(line),datalog)) {

if (strstr(line, "No reply")) res = false;

else

if (atoi(line) == 0) res = false;

else res = true;

}

else res = false;

pclose(datalog);

return res;

}

3.2.3 Integratie in de scanner/parser

Omdat ik mijn pogingen op een Linux-machine uitvoerde, bestond het risico dat

de door Visual MIRA gegenereerde C++ code niet helemaal compatibel zou zijn.

Inderdaad, enkele kleine wijzigingen waren nodig. Eerst en vooral bleek Gruyaerts

implementatie van een geschakelde lijst met templates niet helemaal ANSI C++

compatibel. Een kleine aanpassing volstond om dit euvel weg te werken. Het grote

gevaar zat hem natuurlijk in de code die door Visual MIRA werd gegenereerd.

Groot was mijn opluchting wanneer ik zag dat de fouten die bovenkwamen allemaal

30

Page 37: LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3): elke herschrijfregel van P is van de vorm A ! aB of A ! a met A;B 2 N en a 2 T ;

afkomstig waren uit de broncode voor Visual MIRA en dus niet uit wat MIRA zelf

genereerde.

Ten eerste gebruikte Gruyaert een functie strupr die een string kon converteren

naar uppercase; dit is echter geen standaard ANSI functie, maar blijkbaar een functie

die door de gebruikte compiler (Borland) aan een van de standaardbibliotheken is

toegevoegd. Dit veranderen was uiteraard heel eenvoudig.

Een tweede probleem was dat Gruyaert een globale veranderlijke _init ge-

bruikte. Dit zorgde voor enkele onduidelijke linker errors. Kort opzoekingswerk

leerde me dat het gebruik van variabelen die beginnen met underscore sterk afge-

raden wordt, omdat veel compilers zelf dit soort variabelen gaan definieren. En

inderdaad, _init vervangen door my_init volstond om dit probleem op te lossen.

Hiermee waren alle errors verdwenen, en de overgebleven warnings gaven ook

geen problemen meer. Het enige wat er nu nog moest gedaan worden was een test-

programma schrijven om te kijken of er inderdaad instructies konden doorgestuurd

worden. Het volstaat hierbij om de functie RCLParser aan te roepen met de gepaste

argumenten. Alles bleek te werken zoals ik het wou, waarmee een eerste belangrijke

stap gezet was. Uiteraard waren er nog flink wat tekortkomingen waar een oplossing

voor moest gezocht worden.

3.3 Evaluatie

3.3.1 Eenvoud

Het sterke punt van deze implementatie is de eenvoud: de aanpassingen die nodig

waren om tot deze implementatie te komen, vertrekkende van het RCL gedeelte van

Gruyaert, waren zeer beperkt. Latere uitbreidingen van de taal zouden ook geen al

te grote veranderingen in de code mogen teweeg brengen.

Merk ook op dat er slechts een functie is in de hele klasse Robot die de ro-

bot rechtsteeks aanstuurt en bovendien nog private is. Ook dit zorgt er voor dat

toekomstige aanpassingen beperkt zullen blijven in omvang.

31

Page 38: LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3): elke herschrijfregel van P is van de vorm A ! aB of A ! a met A;B 2 N en a 2 T ;

De oorzaak van deze eenvoud ligt in het gebruik van objectgeorienteerd ontwerp,

gecombineerd met de geschiktheid van LL(1)-talen in een CASE-tool als Visual

MIRA.

3.3.2 Traagheid

Een nadeel van deze implementatie, waarbij elke atomaire beweging volledig afzon-

derlijk wordt uitgevoerd, is de traagheid. Elke beweging moet immers doorgestuurd

worden, vervolgens moet het programma wachten tot de beweging beeindigd is, en

tot slot moet het het resultaat opvragen en interpreteren.

3.3.3 Vreemde effecten

Enkele voorbeelden illustreren het bestaan van een tweetal vervelende neveneffecten.

Het eerste kunnen we omschrijven als het ’Echternach-effect’: wanneer we bijvoor-

beeld vooruit willen gaan, zullen we gewoonlijk eerst testen of die plaats wel vrij

is, en pas als dat zo is kunnen we ook effectief naar voor gaan. Stel dat de plaats

inderdaad vrij is. In dat geval zal de robot eerst vooruit bewegen om te kijken of die

plaats vrij is en vervolgens terugkeren naar zijn oorspronkelijke positie. Dan wordt

het resultaat doorgestuurd en op basis daarvan wordt er beslist om terug vooruit te

gaan. Er zijn dus drie bewegingen nodig om op een betrouwbare manier een plaats

vooruit te gaan.

Een tweede neveneffect is het probleem van de richtingen. De klasse Robot houdt

de richting bij naar waar hij gedraaid is. Dit is een overblijfsel van de originele code,

waarin de robot in om het even welke richting gedraaid kan staan. In ons geval staat

de robot echter telkens in dezelfde richting gekeerd. Het resultaat is dat de robot

kan denken dat hij naar rechts gedraaid staat, terwijl de gebruiker hem vooruit ziet

kijken. Het resultaat is natuurlijk een grote verwarring.

Beide fenomenen zijn het gevolg van enkele essentiele verschillen tussen de vir-

tuele robot van Gruyaert en onze Mindstorms robot, die nogal wat beperkingen

heeft.

32

Page 39: LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3): elke herschrijfregel van P is van de vorm A ! aB of A ! a met A;B 2 N en a 2 T ;

Wat het eerste geval betreft, is het zo dat de virtuele robot zonder te bewegen

langs alle vier de zijden kon detecteren of hij naast een obstakel stond. De omgeving

werd immers gewoon voorgesteld door een matrix, waarvan elk element weergaf of er

al dan niet een obstakel aanwezig was. Het aftasten betekende dus het controleren

van een element binnen die matrix. De Mindstorms robot werkt op een volkomen

andere manier. Ik heb er voor gekozen om zijn leefwereld niet te beperken tot een

statische omgeving, wat wel het geval was bij de virtuele robot. Indien ik dit wel

had gedaan, kon ik de robot laten onthouden op welke plaatsen er een obstakel

aanwezig is. In mijn model daarentegen gaat de robot er van uit dat de omgeving

door externe factoren kan veranderen. Hierdoor is hij verplicht bij elke beweging

te kijken of zijn bumper al dan niet ingedrukt wordt. Daardoor is voor elke test-

instructie ook effectief een beweging nodig.

Zoals ik daarnet al vermeld heb, is het tweede probleem het gevolg van het feit

dat de robot nu omwille van de IR beperking telkens naar dezelfde richting gedraaid

staat bij het beeindigen van een instructie, terwijl de virtuele robot naar om het

even waar gedraaid kon staan.

3.3.4 Onzuivere richting

Na een aantal draaibewegingen zal het duidelijk worden dat de robot ernstige afwij-

kingen begint te vertonen. Een eerste oorzaak is het feit dat ’rechtdoor’ niet altijd

perfect rechtdoor is, omdat de kracht van de twee motoren niet mooi gelijk blijkt te

zijn, en omdat een ondergrond die niet perfect egaal is ook voor afwijkingen zorgt.

Bovendien is het moeilijk om een draaibeweging mooi over 90 graden te doen ver-

lopen. Dit gebeurt gewoon op basis van een experimenteel vastgelegde tijd, terwijl

de hoek in de praktijk niet enkel afhankelijk blijkt te zijn van een tijdsduur, maar

ook van de grip die de wielen ondervinden op het oppervlak en zelfs van de kracht

die de batterijen nog hebben.

Bernd Frassek verwoordt het als volgt in een discussie op LUGnet1: ”Het grote

1www.LUGnet.com is de website van de Lego Users Group, die onder andere tientallen discus-

33

Page 40: LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3): elke herschrijfregel van P is van de vorm A ! aB of A ! a met A;B 2 N en a 2 T ;

probleem is nauwkeurigheid. Om dit te begrijpen moet men met enkele basisprinci-

pes rekening houden: laat de robot voor ongeveer 2 meter RECHT vooruit rijden;

laat hem terug achteruit rijden tot precies op het startpunt; laat de robot 360 graden

draaien, en als dat lukt, laat hem acht keer 90 graden draaien. Dit lijken triviale

en domme opdrachten, maar probeer ze! Ik heb het geprobeerd, en dit is het re-

sultaat: de bovenstaande opdrachten zijn niet op te lossen, althans niet nauwkeurig

genoeg. Er is te veel speling op de motoren. Ook het contact met de ondergrond is

belangrijk.”

Het is duidelijk dat we op zoek zullen moeten gaan naar een meer intelligente

oplossing om dit moeilijke, maar erg belangrijke probleem op te lossen. Wanneer we

niet kunnen garanderen dat de robot na een vijftal bewegingen staat op de plaats

waar we hem willen, kunnen we moeilijk van een bruikbare robot spreken.

siegroepen bevat over allerlei Lego-onderwerpen, zoals de treinen, piraten, en dus ook de robots

die Lego verkoopt

34

Page 41: LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3): elke herschrijfregel van P is van de vorm A ! aB of A ! a met A;B 2 N en a 2 T ;

Hoofdstuk 4

Verbeteringen

Het is uiteraard de bedoeling om de vastgestelde problemen aan te pakken en uitein-

delijk tot een goed werkende robot te komen, die ook voor praktische, bijvoorbeeld

educatieve, doeleinden kan gebruikt worden.

Het probleem van de trage bewegingen zou kunnen opgelost worden door niet

elke beweging afzonderlijk door te sturen, maar door een volledige RCL-instructie

in zijn geheel door te sturen. Dit zou kunnen neerkomen op een poging om zo een

instructie te vertalen naar een NQC programma. Hierbij komen echter een aantal

nieuwe problemen kijken. Aangezien de uitvoeringssnelheid niet prioritair is, heb

ik ervoor gekozen hier niet verder op in te gaan. In 5.1 kom ik nog terug op dit

probleem: ik zal er enkele voorstellen doen die voor een aanzienlijke verhoging van

de uitvoeringssnelheid moeten kunnen zorgen.

Het tweede probleem is het verschil tussen de virtuele robot en onze robot. De

enige manier om dit op te lossen, is de RCL taal aan te passen aan de nieuwe

omgeving door een aantal instructies te verwijderen, eventueel enkele andere toe

te voegen, en indien nodig de semantiek van bestaande instructies te wijzigen. Zo

zijn de TURN en FLIP instructies overbodig geworden omdat onze robot altijd in

dezelfde richting zal staan. Een GO instructie moet volgens mij ook de systeemva-

riabele CONDITION kunnen aanpassen zodat de instructie kan gevolgd worden door

een voorwaardelijke instructie. Verder ben ik het niet eens met de keuze van de

35

Page 42: LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3): elke herschrijfregel van P is van de vorm A ! aB of A ! a met A;B 2 N en a 2 T ;

benaming van de richtingen: waar Gruyaert spreekt van UP, RIGHT, DOWN, LEFT be-

doelt hij eigenlijk NORTH, EAST, SOUTH en WEST. Doordat de robot altijd in dezelfde

richting (NORTH) kijkt, kunnen LEFT en RIGHT behouden blijven, maar UP en DOWN

kunnen volgens mij beter vervangen worden door FORWARD en BACK. Toch lijkt het

mij geen slecht idee om ook de windrichtingen toe te voegen aan de taal.

Het probleem van de onzuiverheid van de richting moet ook aangepakt worden.

Het is duidelijk dat we extra sensoren zullen moeten toevoegen, om zo de robot toe

te laten op een of andere manier een zicht te geven op zijn wereld. Wanneer we een

persoon zouden blinddoeken en er voor zorgen dat hij geen enkel omgevingsgeluid

meer hoort, en hem dan vragen om 2 meter vooruit te stappen en 90 graden naar

links te draaien, en dat vier keer te herhalen, is het twijfelachtig dat hij op zijn

startpunt zal uitkomen. Iemand met zicht op de omgeving heeft meer kans op

slagen omdat hij zijn zintuigen ten volle kan gebruiken. Zo is het ook met onze

robot: hij zal bijkomende zintuigen nodig hebben die hem toelaten zijn omgeving

op een zinnige manier te interpreteren.

4.1 Aanpassing van de taal

Gruyaert merkte in zijn thesis op dat het gebruik van LL(1)-talen met een CASE-tool

als Visual MIRA aanpassingen aan de taal een stuk gemakkelijker maakt. Dit kon ik

aan den lijve ondervinden: het denk- en zoekwerk over welke de juiste syntactische

en semantische wijzigingen waren, was veel moeilijker en duurde veel langer dan de

realisatie van die wijzigingen in de broncode (de code van scanner en parser voor

Visual MIRA en de C++ code die erbij hoort).

4.1.1 Richtingen

De voorgestelde aanpassingen aan de verschillende richtingen (toevoegen van de

windrichtingen en wijziging van UP in FORWARD en DOWN in BACK) was bijzonder

eenvoudig. Het volstaat immers om in de scanner een soort van vertaling in te

36

Page 43: LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3): elke herschrijfregel van P is van de vorm A ! aB of A ! a met A;B 2 N en a 2 T ;

bouwen, wat in Visual MIRA bijzonder eenvoudig blijkt: de string NORTH in de

broncode wordt vertaald naar het token UP in de parser, waardoor die op geen enkele

plaats meer moet aangepast worden. De enige wijziging zit dus in de MIRA-code

van de scanner.

Deze techniek kan ook gebruikt worden om dezelfde parser te gebruiken voor

een gelijkaardige taal met andere sleutelwoorden. Het zou bijvoorbeeld kunnen dat

we een gelijkaardige RCL willen hebben, maar dan met Nederlandse woorden in

plaats van Engelse, bijvoorbeeld omdat we nederlandstalige kinderen willen laten

kennismaken met de mogelijkheden van de robot. In dat geval kunnen we de string

NOORD bijvoorbeeld in de scanner vertalen naar het token UP en de parser ongewijzigd

laten.

4.1.2 Overbodige instructies

De instructies TURN en FLIP zijn overbodig geworden omdat de robot steeds in

dezelfde richting blijft kijken. Het volstaat in principe om de gepaste stukken code

uit de MIRA-definities van de scanner en de parser te verwijderen.

De wijziging gaat deze keer echter verder: de klasse Robot heeft een attribuut

direction, dat de richting van de robot weergeeft. Aangezien dit niet langer re-

levant is, kan het maar beter verwijderd worden, samen met alle verwijzingen er-

naar in de code van de klasse Robot. Dit is nodig om er voor te zorgen dat pro-

grammeerfouten vermeden worden. Merk op dat dit verwijderen ook in de bron-

code duidelijk maakt waarom TURN en FLIP overbodig zijn geworden: de functies

Robot::Turn() en Robot::Flip() zijn leeg geworden. Daarnaast is ook de sys-

teemvariabele DIRECTION overbodig geworden, zodat ook alle verwijzingen hiernaar

verwijderd moeten worden.

Meteen werden ook enkele andere systeemvariabelen verwijderd, namelijk XW, YW,

XT en YT. Deze systeemvariabelen waren aanwezig voor het opvragen van informatie

over de omgeving, die gedefinieerd werd in de CDL, de Configuration Description

Language, maar zijn niet langer relevant.

37

Page 44: LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3): elke herschrijfregel van P is van de vorm A ! aB of A ! a met A;B 2 N en a 2 T ;

4.1.3 Semantische wijziging

Het was de bedoeling er voor te zorgen dat een GO instructie ook de systeemvariable

CONDITION aanpast, zodanig dat het al dan niet slagen van een dergelijke instructie

meteen kan beslissen wat de volgende instructie wordt. Het is belangrijk in te zien

dat het verschil met een TEST nu enkel nog het feit is dat bij een TEST de robot altijd

naar zijn oorspronkelijke plaats terugkeert, terwijl een GO op een nieuwe plaats staat

indien die plaats vrij was. Daarom heb ik het stuk code van de TEST gekopieerd, en

de aanpassing van de systeemvariabelen XR en YR toegevoegd.

4.2 Bepalen van de positie

Een van de moeilijkste problemen om op te lossen was dat van de onzuivere rich-

tingen. Het is de bedoeling dat we trachten rekening te houden met een (niet

noodzakelijk zichtbaar) coordinatenstelsel. Tal van voorstellen om de precieze po-

sitie van de robot te bepalen ben ik op discussiegroepen tegengekomen, werden mij

in de late uurtjes op cafe voorgesteld door vrienden, of heb ik zelf bedacht.

Een van de opvallendste ideeen was wellicht het idee van een kleinschalig GPS-

systeem1. Hierbij was het de bedoeling in een kamer drie lichtjes te plaatsen, die elk

aan een andere frequentie flikkerden om zo het onderscheid tussen de verschillende

lichtbronnen te vinden. De robot heeft een soort oog, een lichtsensor dus, waarmee

hij de kamer afspeurt op zoek naar de precieze richting van elk van de drie licht-

bronnen. We kunnen ons echter enkele vragen stellen bij dit idee. Ten eerste lijkt

het mij twijfelachtig of het detecteren van de lichtbronnen wel nauwkeurig genoeg

kan gebeuren. Bovendien is er een groot probleem wanneer we dit in NQC willen

gerealiseerd krijgen: deze taal kent geen floating point getallen, wat we eigenlijk

wel nodig hebben aangezien we aan driehoeksmeetkunde willen doen. Het is ook zo

dat over dit idee al meer dan een jaar op LUGnet gepraat wordt en er ondertussen

1Het Global Positioning System laat toe zeer naukeurig de coordinaten van een plaats op aarde

te bepalen op basis van de positie van minstens drie satellieten.

38

Page 45: LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3): elke herschrijfregel van P is van de vorm A ! aB of A ! a met A;B 2 N en a 2 T ;

nog niemand iets werkbaar gerealiseerd heeft. Kennelijk is het inderdaad erg moei-

lijk, misschien zelfs onmogelijk om een GPS-achtig systeem te ontwikkelen voor de

Mindstorms robot, tenzij met extra hardware. Het is overigens ook zo dat sommigen

van plan zijn om een echt GPS-systeem te ontwikkelen, dat als sensor op de RCX

moet kunnen aangesloten worden. Dit is voor ons hoe dan ook niet bruikbaar: GPS

is bedoeld voor in open lucht, en de nauwkeurigheid gaat slechts tot een vijftigtal

centimeter, wat in onze situatie veel te weinig is.

Nog een voorstel was gebruik te maken van de afstandsdetectie waar sommigen

al in geslaagd zijn. Het idee achter deze afstandsdetectie is de volgende: de infra-

rood zender/ontvanger op de robot is in staat om licht uit te zenden, dat weliswaar

niet zichtbaar is voor de mens, maar kennelijk wel voor de lichtsensoren. Bovendien

wordt licht weerkaatst door voorwerpen, tenzij ze veel te donker zijn. Deze vast-

stellingen brachten Simen Svale Skogsrud [13] ertoe om de traditionele bumper van

een standaard type robot te vervangen door een lichtsensor die kijkt hoeveel licht

er terugkomt van wat de infra-rood component van de robot elke seconde uitzendt.

Wanneer er erg veel licht ontvangen wordt, kunnen we vermoeden dat we ons vlak

voor een obstakel bevinden, dat we moeten ontwijken. Een andere toepassing is een

soort scanner: een oog tast het blad af dat we willen inscannen, terwijl de RCX

systematisch infra-rood licht op het blad stuurt. Beide projecten behaalden aan-

vaardbare resultaten. Een mogelijk idee was om de afstandsbepaling te gebruiken

om de precieze positie binnen een kamer te bepalen. We moeten ons opnieuw een

aantal vragen stellen. Zo is het twijfelachtig dat de afstand voldoende nauwkeurig

kan bebaald worden. Bovendien moet de RCX precies 90 graden kunnen draaien om

de andere muur te bekijken, en zoals reeds vermeld is dat niet zo vanzelfsprekend.

Tot slot kan nog opgemerkt worden dat dit idee er van uitgaat dat we werken in een

eerder kleine rechthoekige ruimte, waarbij de muren niet al te donker mogen zijn, en

er geen obstakels in het gezichtsveld van de robot mogen staan. Vooral dit laatste

is een probleem aangezien het juist de bedoeling is dat onze robot kan navigeren

in een wereld vol obstakels. De meest eenvoudige oplossing voor het probleem van

39

Page 46: LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3): elke herschrijfregel van P is van de vorm A ! aB of A ! a met A;B 2 N en a 2 T ;

de positiebepaling werd mij ingefluisterd door Geert Vernaeve, en werd ook al in de

praktijk gerealiseerd met de GridBot van Bernd Frassek [14]. Eerst moet ik opmer-

ken dat het in onze situatie niet nodig is om op elke plaats de precieze coordinaten

te kennen. Het volstaat om voldoende nauwkeurig te kunnen bewegen tussen de

verschillende coordinaten met discrete waarden. Het volgen van een zwarte lijn op

een witte ondergrond is een van de allereenvoudigste oefeningen die Lego aan be-

ginners, in de eerste plaats kinderen dus, vraagt om op te lossen. Het zou dus vrij

goed mogelijk moeten zijn om dit ook in onze robot te gebruiken.

4.3 Realisatie

Het tekenen van een rooster was uiteraard geen groot probleem. De vloer waar wij

gebruik van maakten, is erg licht van kleur, wat noodzakelijk is om genoeg contrast

te hebben. De zwarte lijnen zijn gemaakt van 15 mm brede tape die gebruikt wordt

om elektrische draden te beschermen. De vakjes hebben een breedte van ongeveer

20 cm maar zijn niet altijd even groot. Omdat onze robot hier hoegenaamd geen

rekening mee houdt, kan dit geen enkel probleem opleveren. De lijnen moeten zelfs

niet perfect recht zijn, maar wanneer men ze te dicht bij elkaar zou plaatsen, riskeert

men wel dat de robot onverwachte dingen zal doen. De kans bestaat dan immers

dat hij verschillende lijnen met elkaar gaat verwarren of soms eens een dwarslijn zal

overslaan omdat hij ze nog niet verwacht.

Geert Vernaeve heeft enkele ideeen uitgewerkt om er voor te zorgen dat de robot

maar een lichtsensor zou nodig hebben om door het rooster te navigeren. Naar

mijn mening waren deze voorstellen in de praktijk moeilijk of niet te realiseren. We

moeten immers onderscheid maken tussen drie onafhankelijke problemen die met de

lichtsensoren opgelost dienen te worden:

• Het voorwaarts en achterwaarts volgen van een lijn gedurende onbepaalde tijd.

De lijn dient als een soort rail, die de robot verplicht is te volgen. De robot

moet kunnen detecteren wanneer hij de lijn kwijt is en zo snel mogelijk terug

40

Page 47: LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3): elke herschrijfregel van P is van de vorm A ! aB of A ! a met A;B 2 N en a 2 T ;

op het goede spoor zien te geraken wanneer dit gebeurt, en dit liefst zodanig

dat hij nog wel even verder kan rijden zonder de lijn opnieuw kwijt te raken.

• Het stoppen bij de eerstvolgende dwarslijn. De robot moet kunnen detecteren

wanneer hij precies moet stoppen, meer bepaald aan het eerstvolgende kruis-

punt, maar hij moet ook opletten dat hij niet te vroeg stopt. Dit kan immers

gebeuren wanneer hij moest manoeuvreren nadat hij zijn rail is kwijtgeraakt.

• Draaien over een hoek van 90 graden, in wijzerzin of tegenwijzerzin. Het is

de bedoeling dat de robot dit zodanig doet, dat hij na deze beweging recht

staat ten opzichte van de dwarslijn, die hij in de volgende beweging wellicht

zal moeten volgen.

Merk op dat de eerste twee problemen tegelijkertijd moeten gebeuren, waardoor het

bijna onmogelijk wordt om hiervoor slechts een lichtsensor te gaan gebruiken. We

hebben dus minimaal twee lichtsensoren nodig om een praktische oplossing uit te

werken. Het derde probleem gebeurt altijd op een ander tijdstip, zodat we daarvoor

geen derde sensor meer nodig hebben, maar een van de eerste twee kunnen gebruiken,

of beide.

Aan de robot die we al hadden werd achteraan een lichtsensor toegevoegd op

de manier die in de handleiding van Lego beschreven wordt. Het was ook niet zo

moeilijk om aan de zijkant van de robot een lichtsensor te hangen.

4.3.1 Bewegen in het rooster

Het volgen van een lijn

• Wanneer de robot zijn lijn kwijt is, draait hij kort om de lijn terug te vinden.

Indien dit niet meteen lukt, zal hij gedurende een iets langere tijd in de andere

richting draaien, enzovoort. Hij onthoudt ook in welke richting hij uiteindelijk

als laatste gedraaid heeft.

41

Page 48: LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3): elke herschrijfregel van P is van de vorm A ! aB of A ! a met A;B 2 N en a 2 T ;

(a) (c) (d)(b)

Figuur 4.1: Het volgen van een lijn

• Van zodra de robot zijn lijn heeft teruggevonden rijdt hij gedurende een vaste,

experimenteel vastgelegde tijd recht achteruit.

• Vervolgens draait de robot in de tegengestelde richting van die waarin hij moest

draaien om de lijn terug te vinden, en dat tot hij de lijn opnieuw tegenkomt.

• De robot gaat er van uit dat hij nu terug voldoende recht staat en rijdt opnieuw

gewoon vooruit.

In theorie kunnen bij dit algoritme complicaties optreden wanneer de robot zich

in de buurt bevindt van een kruispunt, omdat de dwarslijnen verkeerdelijk zouden

kunnen verward worden met de te volgen lijn. In de praktijk heb ik hier tot nu toe

echter geen problemen mee ondervonden.

Een lijn achterwaarts volgen

Doordat de sensor nu eigenlijk vooraan de robot zit, worden afwijkingen veel sneller

opgemerkt en volstaat het om in dat geval al draaiende de lijn terug te zoeken zoals

in de eerste fase van Figuur 4.1, en dan gewoon de weg verder te zetten zonder nog

verder te manoeuvreren.

42

Page 49: LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3): elke herschrijfregel van P is van de vorm A ! aB of A ! a met A;B 2 N en a 2 T ;

Stoppen bij de volgende dwarslijn

Omdat deze opdracht in principe onafhankelijk is van het volgen van een lijn, koos

ik er voor om deze twee opdrachten als twee aparte taken te laten lopen, wat in

NQC geen enkel probleem is. De ene taak volgt een lijn op de manier die daarnet

beschreven werd, terwijl de andere de zijdelingse sensor observeert. Het blijkt echter

niet correct te zijn om gewoon te stoppen wanneer een lijn gedetecteerd wordt, en

dit bij twee situaties:

• Tijdens het manoeuvreren kan de zijdelingse sensor de lijn detecteren die de

robot moet volgen; deze geeft uiteraard niet aan dat hij mag stoppen. Tijdens

het manoeuvreren moet de sensor dus genegeerd worden.

• Indien de robot zijn lijn erg snel kwijt is, kan hij tijdens het manoeuvreren

achter de dwarslijn terechtkomen waar hij gestart was. Daarom moet de sensor

dus niet enkel tijdens het manoeuvreren genegeerd worden maar ook gedurende

een korte tijd erna.

Draaien naar links of rechts

(a) (b) (c) (d)

Figuur 4.2: Naar links of naar rechts draaien

De robot rijdt eerst heel even, gedurende een experimenteel vastgelegde tijd

achteruit, en draait dan naar de gevraagde richting tot zijn achterste sensor een lijn

tegenkomt. Vervolgens rijdt hij nog even vooruit tot hij bovenop de dwarslijn staat.

43

Page 50: LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3): elke herschrijfregel van P is van de vorm A ! aB of A ! a met A;B 2 N en a 2 T ;

4.3.2 Het gebruik vanuit de parser

Nogal wat gegevens die nodig zijn voor de bewegingen die hierboven beschreven

werden, blijken erg afhankelijk te zijn van het ontwerp van de robot. Niet enkel

de experimenteel bepaalde tijden spelen een rol, maar blijkbaar ook de lichtinval;

en wanneer we de lichtsensoren op een andere plaats zouden hangen, zouden de

algoritmes misschien moeten veranderd worden.

Daarom heb ik er voor gekozen om hier een extra niveau van abstractie in te

bouwen. Dit kan door alles wat afhankelijk is van de specifieke bouw van de robot

vast te leggen in een NQC header file. Vanuit de klasse Robot wordt dan dit bestand

geıncludeerd, en er worden enkel nog functies en macro’s aangeroepen die in dat

bestand geımplementeerd zijn. Wanneer we dus om het even welke andere robot

willen gebruiken die ook NQC begrijpt, volstaat het om die functies en macro’s te

herdefinieren. Het is zelfs niet nodig om de parser opnieuw te compileren, aangezien

de header at run-time aangeroepen wordt.

Volgende functies worden verondersteld geımplementeerd te zijn in het bestand

grid.h:

• init() laat de nodige initialisaties toe, bijvoorbeeld om het type van de sen-

soren vast te leggen.

• left() en right() doen de robot 90 graden draaien naar de gepaste richting.

• forward() doet de robot vooruit rijden tot hij ergens op botst of het volgende

punt bereikt; reverse() doet het tegenovergestelde.

• BUMPER is een macro die teruggeeft of de bumper al dan niet is ingedrukt.

44

Page 51: LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3): elke herschrijfregel van P is van de vorm A ! aB of A ! a met A;B 2 N en a 2 T ;

Hoofdstuk 5

Conclusie

5.1 Suggesties

De aandachtige lezer zal wellicht opgemerkt hebben dat een zwak punt uit de eerste

versie nog niet is aangepakt. De lange wachttijd tussen de instructies is gebleven, en

in de huidige architectuur lijkt het weinig waarschijnlijk dat we daar iets aan gaan

kunnen doen. In de beschrijving van de NQC omgeving in sectie 2.2.2 vermelde ik

al dat de communicatie tussen de PC en de robot het client-server principe volgt.

Bovendien bestaat elke atomaire instructie uit twee fases: in de eerste fase stuurt de

parser een NQC programma door naar de robot, die dit programma uitvoert maar

niets antwoordt, en in de tweede fase vraagt de PC het resultaat van de actie op

via de datalog. Dit zorgt voor een vervelende situatie. Enkel de robot weet immers

wanneer de actie, opgestart vanop de PC, voltooid is. Het is echter het programma

dat op de PC loopt, dat het initiatief moet nemen om naar het resultaat te vragen

van de actie die kort voordien is opgestart. De enige oplossing hiervoor is de PC

voldoende lang te laten wachten, in de hoop dat de actie dan zeker beeindigd is. Het

is dus nodig een voldoende grote marge te nemen. In sommige gevallen, wanneer de

robot slecht geplaatst staat, en dus nogal veel moet manoeuvreren om tot bij zijn

bestemming te geraken, kan een enkele instructie erg lang duren. In onze huidige

architectuur hebben we geen andere keuze dan voor elke instructie zo lang als nodig

45

Page 52: LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3): elke herschrijfregel van P is van de vorm A ! aB of A ! a met A;B 2 N en a 2 T ;

te wachten, hoewel in de meeste gevallen de beweging snel voltooid is.

inputstring tokenstringScanner Parser

PC RCX

Resultaat?

NQC code

Datalog

Figuur 5.1: De huidige situatie met NQC

Een eerste mogelijke oplossing is om niet op het resultaat van een instructie te

wachten. Dit lijkt mogelijk, omdat we er van kunnen uitgaan dat de systeemvari-

abele CONDITION slechts af en toe door de gebruiker zal opgevraagd worden. We

zouden er dus voor kunnen kiezen om de datalog, die het resultaat van de laatste

beweging bevat, enkel op te vragen wanneer de gebruiker naar die systeemvariabele

vraagt. De klasse Robot houdt echter intern ook de coordinaten van de robot bij,

en als we het principe van de virtuele muur willen blijven gebruiken, kunnen we de

huidige werkwijze niet overboord gooien: we moeten op elk ogenblik de positie van

de robot kennen ten opzichte van de infra-rood toren en daarom moeten we van elke

moveto(dir) weten of de beweging al dan niet gelukt is. Stel dat we er voor zou-

den kiezen dit toch te doen, moeten we met nog enkele andere problemen rekening

houden. Zo kan de gebruiker te vroeg een nieuwe instructie doorgeven. Ook in een

lus of procedure kan de volgende instructie gemakkelijk te vroeg opgestart worden,

voordat de vorige echt voltooid is. En hier zitten we terug met ons oorspronkelijk

probleem: de parser, die op de PC loopt, weet niet wanneer de robot zijn actie heeft

voltooid, terwijl de robot zelf niet het initiatief kan nemen om dit te laten weten.

We moeten ook durven toegeven dat de code een stuk minder elegant wordt. Op

dit ogenblik worden alle systeemvariabelen in een lijst bijgehouden, en tijdens de

uitvoering op de gepaste ogenblikken aangepast. Wanneer de gebruiker er een van

wil opvragen, wordt de lijst doorlopen tot de juiste naam gevonden is, en het bijho-

rende resultaat teruggegeven. In het voorstel dat ik zopas gedaan heb, zou dus een

46

Page 53: LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3): elke herschrijfregel van P is van de vorm A ! aB of A ! a met A;B 2 N en a 2 T ;

uitzondering moeten gemaakt worden voor een bepaalde systeemvariabele, namelijk

CONDITION, waarbij een totaal ander stuk code moet uitgevoerd worden. Hoewel dit

technisch geen enkel probleem is, gaat de uniformiteit van het gebruik van de sys-

teemvariabelen verloren, waardoor de code toch weer iets moeilijker onderhoudbaar

wordt.

De enige echte oplossing is uiteraard af te stappen van datgene wat de problemen

veroorzaakt: de client-server architectuur die eigen is aan NQC, en eigenlijk afstamt

van de grafische RCX-omgeving. Zelf zie ik drie grote categorieen van oplossingen.

Een eerste behoudt een erg gelijkaardige structuur, maar maakt gebruik van een

architectuur met een peer-to-peer communicatie. De tweede volgt een verschillende

aanpak: we kunnen de parser laten lopen op de RCX zelf. De derde oplossing gaat

het in een nog andere richting zoeken: we zouden Visual MIRA kunnen gebruiken

om RCL commando’s te vertalen naar een andere taal, die we wel rechtstreeks in de

robot kunnen gebruiken.

5.1.1 Peer-to-peer

Zoals reeds vermeld in 2.2.3, gebruikt LegOS een eigen protocol, het LegOS Network

Protocol, om communicatie toe te laten tussen verschillende RCX blokken en PC’s.

Kennelijk is het hier niet nodig dat de communicatie opgestart wordt door de PC,

maar kan om het even welke partij het initiatief nemen. Dit is dus een voorbeeld van

een architectuur die peer-to-peer mogelijkheden heeft. Het moet dus mogelijk zijn

om, wanneer LegOS op de RCX draait, C programma’s te laten genereren, in plaats

van NQC programma’s. Deze moeten dan zelf signaleren wanneer ze beeindigd zijn.

Ondertussen blijft de PC wachten op dit signaal, pas dan kan hij verder gaan. Het

grote voordeel van deze aanpak is dat de huidige code niet al te veel aanpassingen

zal vragen, omdat in de ganse code slechts een functie zal moeten gewijzigd worden.

47

Page 54: LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3): elke herschrijfregel van P is van de vorm A ! aB of A ! a met A;B 2 N en a 2 T ;

inputstring tokenstringScanner Parser

PC RCX

LNP

Figuur 5.2: Peer-to-peer met LegOS

5.1.2 De robot als interpreter

Wat naar mijn gevoel de boeiendste oplossing is om uit te proberen, is de tweede.

Hierin loopt de interpreter, de scanner en de parser dus, niet langer op een PC, maar

op de robot zelf, die op die manier veel zelfstandiger wordt. Het grote probleem van

deze aanpak is echter de beperking van het geheugen dat op de RCX beschikbaar is.

LegOS is in principe de enige omgeving waarin deze mogelijkheid kan gerealiseerd

worden. Ik heb LegOS nooit geınstalleerd op de RCX, maar ik heb wel de door MIRA

gegenereerde C++ code gecompileerd voor uitvoering op LegOS, en de uitvoerbare

code bleek inderdaad te groot te zijn. Mogelijk wordt deze grootte negatief beınvloed

door het gebruik van de objectgeorienteerde aspecten van C++ en kunnen we dit

wegwerken door de constructie van de parserboom te herschrijven naar C, waardoor

wellicht veel compactere code zal gegenereerd worden. Toch blijft het risico bestaan

dat het opbouwen van parserbomen voor grotere RCL-commando’s te veel geheugen

gaat opslorpen.

tokenstringScanner Parser Instructies

PC RCX

inputstring

Figuur 5.3: De interpreter op de RCX

48

Page 55: LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3): elke herschrijfregel van P is van de vorm A ! aB of A ! a met A;B 2 N en a 2 T ;

Dit jaar werd bij een andere scriptie op de vakgroep Zuivere Wiskunde en Com-

puteralgebra een nieuwe versie van Visual MIRA ontwikkeld, die het mogelijk moet

maken om Java-code te genereren in plaats van C of C++ [5]. Dit biedt ons de

optie om na te gaan of we de scanner en parser voor RCL niet kunnen herschrijven

naar Java, om dan de zojuist beschreven architectuur met Java te realiseren onder

bijvoorbeeld TinyVM, waarvan we in 2.2.4 al vermeldden dat deze omgeving erg

zuinig is op het geheugengebruik.

Het grote voordeel van deze aanpak is dat de robot veel autonomer wordt: er is

enkel communicatie nodig bij het doorsturen van een RCL instructie en eventueel

bij het beeindigen van een dergelijke instructie. Hierdoor zal de robot wellicht een

stuk efficienter kunnen werken. Doordat de robot op die manier een grote mate

van zelfstandigheid heeft, wordt het wellicht mogelijk om ook andere infra-rood

apparaten te gaan gebruiken om RCL instructies door te sturen. Het enige wat er

immers moet overgedragen worden, is een string van karakters die een commando

vormen. Het enige probleem zou de compatibiliteit van de verschillende infra-rood

apparaten kunnen zijn, maar aangezien men er al is in geslaagd om de RCX te laten

communiceren met een Palm Pilot [15] en met een HP 100lx palmtop computer [16],

lijkt dit me geen onoverkomelijk probleem.

Indien er toch te veel tijd zou nodig zijn voor het doorsturen van de strings,

of er blijft een probleem met de geheugengrootte van de interpreter, kan men nog

altijd een andere mogelijkheid uitproberen. We kunnen in principe de scanner op

de PC en de parser op de robot laten lopen, zodat er enkel nog tokens moeten

overgedragen worden. De tokenstring moet normaal gezien compacter zijn, omdat

de sleutelwoorden van de taal voorgesteld worden door identifiers, gehele getallen

dus. Doordat de scanner niet op de RCX loopt, is er meer geheugen beschikbaar

voor de parser, die wel nog op de RCX loopt. Zoals gezegd werd in 1.1.6, laat Visual

MIRA toe om de zogenaamde read routine en write routine door de gebruiker te

herdefinieren, zodat deze oplossing binnen het kader van Visual MIRA kan blijven.

Een nadeel van deze oplossing is dat de zelfstandigheid van de robot voor een stuk

49

Page 56: LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3): elke herschrijfregel van P is van de vorm A ! aB of A ! a met A;B 2 N en a 2 T ;

terug verloren gaat en we dus moeilijker andere apparaten kunnen gebruiken voor

de aansturing van de robot.

inputstring Scanner Parser Instructies

PC RCX

tokenstring

Figuur 5.4: Zuiniger zijn op de communicatie

5.1.3 MIRA als vertaalmechanisme

Een compiler wordt in [1] gedefinieerd als een programma dat een programma ge-

schreven in een bepaalde taal vertaalt naar een equivalent programma in een andere

taal. Merk op dat het huidige programma geen echte compiler is, maar een in-

terpreter. Een interpreter produceert geen programma in de doeltaal, maar voert

operaties uit die opgelegd worden door het bronprogramma.

We mogen dus concluderen dat we Visual MIRA ook kunnen gebruiken om een

vertaling te doen van RCL naar bijvoorbeeld NQC. Dit lijkt echter gedoemd om

te mislukken: in RCL kunnen we gebruik maken van variabelen en arrays, denk

maar aan de GOTO2 procedure, terwijl NQC een beperking oplegt aan het aantal

variabelen. Wanneer we RCL vertalen naar C en we laten LegOS op de robot lopen,

moet het wel mogelijk zijn om deze techniek te volgen. Het enige probleem dat ik

op dit ogenblik zie opduiken, is dat procedures op een gegeven moment gedefinieerd

worden en op een later ogenblik worden aangeroepen. In de tussentijd moet de

procedure dus op een of andere manier ergens bewaard worden. En wat er precies

met systeemvariabelen moet gebeuren, is mij ook nog niet helemaal duidelijk.

Stof genoeg dus om in de toekomst nog een of meerdere van deze alternatieven

uit te proberen.

50

Page 57: LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3): elke herschrijfregel van P is van de vorm A ! aB of A ! a met A;B 2 N en a 2 T ;

inputstring tokenstringScanner Parser

PC RCX

C−programma

Figuur 5.5: Scanner en parser vertalen RCL-instructies naar C-programma’s

5.2 Besluit

Het uitgangspunt voor deze thesis was het eindwerk van Hans Gruyaert [2]. Hierin

wordt onder andere nagegaan of LL(1)-specificaties gebruikt kunnen worden voor de

realisatie van een mens-machine interface voor de bewegingscontrole van een robot.

Om dit in de praktijk aan te tonen ontwikkelde hij een interactietaal: de Robot

Control Language (RCL).

Het was mijn bedoeling te onderzoeken of de Lego Mindstorms robot voldoende

mogelijkheden in zich heeft om een rondzwervende robot te realiseren, die bestuurd

wordt aan de hand van een interactietaal gelijkend op de RCL uit [2].

De Mindstorms robot heeft erg veel beperkingen, hij is immers bedoeld om kin-

deren vanaf 12 jaar spelenderwijs met de wereld van de robots te laten kennismaken,

niet om volwassenen volwaardige robots te laten bouwen. Toch kunnen elk van deze

beperkingen met een beetje creativiteit omzeild worden:

• De communicatie tussen robot en PC gebeurt via infra-rood signalen waardoor

visueel contact nodig is. Door er voor te zorgen dat de robot bij het beeindigen

van elke beweging (min of meer) in de juiste richting kijkt, kunnen we ver-

mijden dat dit problemen geeft. Een gevolg hiervan is dat de robot altijd in

dezelfde richting kijkt waardoor enkele instructies overbodig geworden zijn.

• De robot kan niet zien of er een obstakel is, hij kan het enkel voelen door te

bewegen. Dit is niet echt een groot probleem, maar het gaf wel aanleiding tot

een kleine wijziging in de semantiek van een instructie.

51

Page 58: LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3): elke herschrijfregel van P is van de vorm A ! aB of A ! a met A;B 2 N en a 2 T ;

• De robot kan zich niet blindelings orienteren in zijn wereld. Om dit probleem

op te lossen kunnen we een rooster tekenen dat de robot moet volgen, gebruik

makend van twee lichtsensoren.

• De robot heeft slechts plaats voor drie sensoren. In mijn ontwerp was dit

voldoende, maar mochten er later toch meer nodig zijn, dan kan men verschil-

lende sensoren op een aansluiting plaatsen. Aan de hand van de zogenaamde

’raw value’, het precieze spanningsverschil aan de aansluiting van de sensoren,

kan men dan toch een vermoeden krijgen van wat de sensoren willen zeggen.

Let wel: niet alle combinaties van sensoren blijken goed te werken.

• De gebrekkige communicatie tussen robot en PC kan op verschillende manieren

aangepakt worden, zoals ik suggereerde in 5.1.

Tijdens de realisatie van het geheel heb ik bovendien kunnen vaststellen dat de

voordelen die in [2] en [4] aangehaald worden over het gebruik van LL(1)-talen met

behulp van een tool als Visual MIRA, in combinatie met objectgeorienteerd ontwerp,

ook in mijn ontwerp blijken te kloppen:

• Het omschakelen tussen verschillende platformen vergt weinig aanpassingen.

Om tot een eerste werkbare versie te komen, bleven de aanpassingen in de

broncode quasi beperkt tot een C++ klasse, waarbinnen ook maar weinig

aanpassingen nodig waren.

• Aanpassingen aan de omgeving kunnen gemakkelijk gebeuren omdat de im-

plementatie sterk gekoppeld is aan de syntaxbeschrijving. In 3.3.3 beschrijf

ik de verschillen tussen de robot uit [2] en onze Lego-robot. Deze verschillen

dwingen ons het jargon van de robot te wijzigen. De nodige aanpassingen

bleken verassend eenvoudig realiseerbaar.

• Het automatisch genereren van scanner en parser vermindert de kans op fou-

ten. De enige bugs die ik gedurende de realisatie van de robotsturing ben

tegengekomen, waren fouten in de NQC programma’s die ik geschreven had.

De fouten lagen dus eigenlijk buiten het domein van de parser.

52

Page 59: LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3): elke herschrijfregel van P is van de vorm A ! aB of A ! a met A;B 2 N en a 2 T ;

We kunnen dus besluiten dat het mogelijk is om de Lego Mindstorms robot aan

te sturen aan de hand van een LL(1) interactietaal. Wanneer we de robot uiteindelijk

ook voor meer praktische doeleinden willen gaan gebruiken, is het volgens mij wel

aangewezen een andere aanpak te volgen dan mijn methode.

53

Page 60: LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3): elke herschrijfregel van P is van de vorm A ! aB of A ! a met A;B 2 N en a 2 T ;

Bibliografie

[1] Aho Alfred, Sethi Ravi en Ullman Jeffrey, Compilers, Addison-Wesley

Publishing Company, 1986

[2] Gruyaert Hans, LL(1)-specificaties in robotica, 1998

[3] Hoogewijs Albert, LL(1) descriptions for robots, Robotica volume 15, pp

105-110, Cambridge University Press 1997

[4] Hoogewijs Albert, Gruyaert Hans en Vernaeve Geert, Teach your Robot

an LL(1)-Jargon, 2000

[5] Impens Freya, Visual MIRA voor JAVA, 2001

[6] Wolz Ursula, Teaching Design and Project Management with Lego RCX

Robots, SIGCSE Bulletin, Volume 33, Nr 1, Maart 2001, pp 95-99

[7] RCX, internals, een uitgebreide beschrijving van de in-

terne werking van de RCX, opgesteld door Kekoa Proudfoot:

http://graphics.stanford.edu/ kekoa/rcx/

[8] De homepagina van Dave Baum, de ontwerper van NQC:

http://www.enteract.com/ dbaum/nqc/

[9] De legOS homepagina: http://legos.sourceforge.net/

[10] De TinyVM homepagina: http://tinyvm.sourceforge.net/

[11] De LeJOS homepagina: http://lejos.sourceforge.net/

54

Page 61: LL(1)-sturing van de Lego Mindstorms robotlib.ugent.be/fulltxt/RUG01/000/686/003/RUG01... · (3): elke herschrijfregel van P is van de vorm A ! aB of A ! a met A;B 2 N en a 2 T ;

[12] Analysis of the RCX: http://www.rcx.ic24.net/analysis.htm

[13] Proximity detection http://www.mop.no/ simen/legoproxi.htm

[14] De persoonlijke pagina van Bernd Frassek op de Mindstorms

website: http://mindstorms.lego.com/bookmarks/users.asp?

2C41D51DB4D7F2BBA1F71A6F7B0C90A5

[15] RCX and Palm: http://members.rotfl.com/vadim/rcx/

[16] Controlling the LEGO MindStorms robot from a HP100lx palmtop com-

puter: http://www.magicnet.net/ twdow/mindstorms.html

55