torsdag den 23. februar 2012

NXT Programmering, Lesson 4


NXT Programmering, Lesson 4
Varighed: 3,5 timer
Deltagere: Mikkel, Troels, Jesper, Bjarke


Formål

I denne lektion vil vi lave en robot der kan følge en sort linje og stoppe ved en mållinje for enden, markeret med en tredje farve. Ideen er at benytte lyssensoren til at måle tre forskellige farver.
Slutteligt vil vi ændre i programmet så en PID regulator benyttes til at sørge for at bilen følger den sorte linje hurtigere og mindre slingrende.


Plan


  1. Udvid robotten fra de tidligere lab lektioner med en lyssensor.
  2. Lav et program der benytter BlackAndWhiteSensoren[1] til at skelne mellem sort og hvid. Placer den over forskellige områder og se hvilke værdier den registrerer.
  3. Afprøv LineFollowerCar.java[2] og se hvordan den fungerer.
  4. Med udgangspunkt i BlackAndWhiteSensoren: Lav et program der kan skelne mellem sort, grøn og hvid. Test programmet.
  5. Tilpas LineFollowerCal programmet så bilen stopper når den kommer ind i et grønt målfelt.
  6. Modificer programmet så det benytter en PID regulater til at styre bilen mindre slingrende, og hurtigere, langs den sorte linje, hen til målzonen.


Resultater

1. Vi har aldrig fjernet lyssensoren fra første første lektion[3], så den sidder endnu på robotten. Vi har derudover tilføjet en lyssensor mere til brug i opgave 5. 

2. Vi lavede et program[4] der benyttede BlackAndWhiteSensor klassen til at aflæse en værdi vha. lyssensoren og overførte dette til vores NXT-brick.  Alt efter hvad vi rettede lyssensoren imod viste den forskellige værdier på display’et. Hvis den blev rettet mod en blank hvid overflade viste den ~60 og mod en blank sort overflade ~30

3. Vi overførte LineFolllowerCar til NXT-brick’en og testede bilen. Den fulgte den sorte linje præcis som forventet


4. Vi tilføjede en lyssensor mere til vores ‘bil’. Med udgangspunkt i BlackWhiteSensor lavede vi et ColorSensor[5] program. Programmet kalibrerede først begge lyssensorer med værdier for sort, hvid og en tredje farve (som vi har kaldt blue i koden). Herefter viste den hvilken farve sensor nr.  1 målte. Hvis der blev trykket ‘escape’ viste den hvilken farve sensor nr. 2 registrerede. Programmet virkede som det skulle. 

5. Vi modificerede ColorSensor programmet så bilen fulgte den sorte linje vha. sensor nr. 1. Når begge sensorer målte den 3. farve (i vores tilfælde blå) stoppede vi bilen. Vi vekslede mellem forskellige delrutiner i programmet via ‘escape’ knappen. Da vores første implementation ikke havde en Thread.sleep() kommando efter den første del-rutine, der blev afbrudt ved tryk på escape, ville programmet springe den næste del-rutine over da denne også var afhængig af et tryk på escape knappen. Vi snakkede i øvrigt om at vi måske skulle holde det så escape knappen altid lukker programmet ned og for fremtiden benytte andre knapper til at springe imellem del-rutiner.


6. Vi lavede en grov omskrivning af pseudokoden præsenteret i [6]. Desværre havde vi ikke tid til at tilpasse de variable der påvirkede robotten (proportional, integral og derivitive konstant). Grundet mangel på tid kunne vi ikke forbedre resultaterne her. Koden findes her [6].



NXT Programmering, Søndag d. 26.02.2012
Varighed: 2 timer
Deltagere: Mikkel, Jesper, Bjarke



Formål
Formålet med dagen er at implementere en PID styret bil, således at den kan følge en sort linie med høj fart og minimal oscilering. Dette er en fortsættelse af punkt 6 fra lesson 4.

Plan
1. Implementer en PID styret bil som beskrevet i [7], men programmeret fra bunden.
2. Tilpas de variable i programmet fra 1. punkt således at bilen kan følge en sort linie med højest mulige hastighed mens den eliminerer oscilering.

Resultater

1. Vi lavede en step-by-step implementation af vores PID styrede bil, som beskrevet i [7]. Opgaven kan deles op i tre trin. Den proportionelle kontrol, den integrelle kontrol og den afledte kontrol. Hvert trin blev løbende debugget og tilpasset således at robotten kunne følge linien, uden at "fare vild".
Koden anvender en modificeret BlackWhiteSensor og en ny klasse kaldet PIDCar [8].

2. Vores implementation blev aldrig tilstrækkeligt tilpasset. Initielt havde vi mange problemer med tilpasningen af integralet, da der blev så ofte, at når robotten skiftede retning ville den skyde over målet og krydse den sorte streg, hvorved den mistede orienteringen. Vi fandt to forskellige løsninger på dette problem. Første var kun at tage en procentsats af integrale værdien, således at påvirkningen på robottens drejning blev mindre. Den anden var at sætte en max værdi for integralet, således at den aldrig ville kunne påvirke drejningen med mere end denne værdi. Begge løste problemet med "overskydning".
Desværre var vi fortsat plaget af oscilering selv efter at vi havde implementeret 'the derivitive term'. Det var tydeligt at dette reducerede oscilering ganske betydeligt, men robotten fandt aldrig et sted hvor den kunne køre lige frem.

Status
Vores robot kan følge en linie og den anvender alle tre termer som er beskrevet i [7]. Desværrer undgår den ikke oscilering og vi har generelt haft problemer med at fintune de variable der kunne være årsag hertil.
Derudover opdagede vi af og til fejl i vores implementation, der påvirkede resultaterne. Vi konkluderede da vi var færdige søndag at vi fremover vil forsøge at være mere metodiske når vi skal implementere rutiner for robotten. Vi brugte for megen tid på 'trial & error' hvor en metodisk fejlgennemgang af koden nok havde været bedre.



__________________________________________
Referencer


torsdag den 16. februar 2012

NXT Programmering, Lesson 3

NXT Programmering, Lesson 3
Varighed: 4 timer
Deltagere: Mikkel, Troels, Jesper, Bjarke

Formål
I denne lab-session vil vi udvide vores robot med to lyd sensorer og undersøge hvordan disse kan bruges til at styre robotten på forskellige måder. Derudover vil vi lære at bruge en datalogger Java-klasse til at indsamle data, der kan eksporteres til en computer til videre behandling.

Plan
Følgende plan er baseret på [1].
1. Udvid robotten fra uge 2 med NXT lydsensoren, som beskrevet i bygningsmanualen [3].
2. Skriv et program der tester lydsensorerne og udfør en række tests, som beskrevet i [1].
3. Udvid programmet fra punkt 2 med en datalogger og eksporter den samlede data til computeren. Herefter plottes den indsamlede data i en graf. 
4. Implementer "sound controlled car" [7] og eksperimenter med dennes opførelse.
5. Undersøg hvordan et klap kan genkendes og anvendes til styring af robotten, baseret på [2]
6. Udvid robotten med endnu en NXT lydsensor.
7. Implementer et program der vha. input fra de to lydsensorer kan styre imod en lydkilde.

Resultater
1. Vi har udvidet robotten efter anvisningerne i [3]. Ved samme lejlighed har vi udvidet robotten som planlagt i punkt 6, for at samle mere data og lære om hvordan sensorerne opfanger lyd.

2. For at hente værdien ud af sensorerne har vi anvendt readValue() og skrevet dem på display'et.
public int readValue() 
Read the current sensor value. 
Returns: 
value as a percentage.

Beskrivelsen af readValue() kan ses ovenfor og programmet kan findes her [4].
Værdien er klart sammenhængende med amplituden og afstanden til mikrofonen. Derimod ser frekvensen ikke ud til at påvirke den målte værdi. Dette nåede vi frem til ved at måle en tone med konstant amplitude med varierende frekvens. Dette gav ingen nævneværdige udslag.

3. Vi har anvendt en let modificeret udgave af DataLogger.java til at samle lyd-data fra robotten [5]. 

Den indsamlede data hentede via programmet nxjbrowse. Det er et javaprogram der tilgår hukommelsen på robotten og kan eksportere den indsamlede data til et tekst dokument. Programmet startes med kommandoen nxjbrowse i commandopromten i windows, forudsat at softwaren er opsat som beskrevet i uge 1. 

Vi har lavet to indsamlinger der kan ses plottet på en graf herunder. Dataen kan findes her [6]:
Første graf er tilfældige lyde og anden er klap udført tæt på sensoren. 


4. Vi implementerede indledningsvist "sound controlled car" [7]. Denne implementation starter begge robottens motorer på 100, ved første lyd på over 90. Anden lyd på over 90 får bilen til at dreje mod højre, derefter venstre og fjerde lyd stopper den. 


Dog kan man ikke kan stoppe robotten før den er nået igennem hele dette loop. Dette ændrede vi ved at tilføje en boolean variabel kaldet run. Variablen starter som true og bliver ændret til false når et tryk på escape knappen registreres. Dette gjorde vi ved at tilføje en ButtonListener til escape knappen:

Button.ESCAPE.addButtonListener(new ButtonListener() {
@Override
public void buttonReleased(Button arg0) {
}
@Override
public void buttonPressed(Button arg0) {
run = false;
}
});
Derudover sørgede vi for, at while loopet inde i metoden waitForLoudSound også var afhængig af at run er true. Koden kan findes her [8].

5. For at lave en robot der kan startes og stoppes vha klap, skrev vi et program fra bunden. Indledningsvist baserede vi koden på [2].

Programmet består af et ydre while loop, der forsøger at genkende en klap lyd. Hvis lyden registreret af sensoren er under et 'lower threshold' starter et indre while loop der varer i 25 ms. Dette 'lytter' efter en lyd på over et 'upper threshold', hvilket et klap gerne skulle ligge over.
Hvis en lyd der er højere end 'upper threshold' registreres startes endnu et loop der over 250 ms poller om lyden falder til under 'lower threshold' igen. Hvis dette sker vil robotten genkende det som et klap.
Et klap skifter mellem robottens to tilstande: Stå stille og kør fremad. Koden findes her [9].



For at finpudse vores variable og lave bedre data indsamling, har vi udvidet DataLogger.java, således at vi også kan sende en streng med. Dette gør det muligt at tilføje beskeder til de målinger vi sender til dataloggeren, hvilket gør det lettere at tolke dataen.
public void writeSample(String message, int sample)
Tilføjer en linie data på formen: message + ": " + sample
Desværre fanger koden ikke udelukkende klap og nogle klap bliver umiddelbart ignoreret. Vi mistænker at baggrundsstøj fra bl.a. robottens egne motorer, samt at variablerne ikke er tweaket tilstrækkeligt kan være årsagen. Dette vil kræve en nærmere undersøgelse af målinger foretaget under kørsel.


6. Som beskrevet lavede vi tidligere denne udvidelse.


7. Koden til at vores Party Finder Robot, fungerede indledningsvist ved at de læste værdier fra hver sensor blev sammenlignet, hvorefter robotten ville køre fremad med forskellig power på hvert hjul. Denne power blev bestemt ud fra hvilken sensor der målte den højeste værdi, således at robotten ville dreje i den retning der målte den højeste lyd.


Desværre opførte robotten sig aldrig konsistent. 
Baseret på output fra robotten konkluderede vi, at hver enkelt måling ikke var konsistent nok, da almindelige lyde (musik, snak, klap, mm) generelt ikke ikke opfanges ens af hver sensor. Vi ændrede derfor programmet til at kigge på gennemsnittet over de seneste fem målinger og tilføjede et interval der tillod målinger fra sensorerne at varierer uden at det påvirkede robottens retning.


Dette virkede heller ikke som forventet. Målingerne fra sensorerne gav fortsat målinger med så store forskelle at robotten i højere grad roterer omkring sig selv, istedet for at søge imod en lydkilde. 


Vi mistænkte de to sensorer for ikke at måle lyd ens, hvilket vi testede ved at lade en computer afspille en konstant sinus-tone. Desværre viste dette, at de begge optog samme lyd, hvorfor der måtte være andre fejlkilder. 
Med denne konklusion indstillede vi arbejdet med robotten. Koden kan findes her [10].

Status
Vi fik udvidet robotten med to lyd sensorer og testet at begge kunne registrerer lyde. Vi lavede en række tests hvor vi optog lyde og eksporterede dem til computeren, hvor vi kunne lave grafer over lyden. Desværre måtte vi senere erkende at vores tilgang til de tests vi lavede ikke havde været tilstrækkelig striks. Vi manglede indsigt i hvordan lyden blev opfanget helt tæt på og hvor hurtig de målte værdier falder når afstanden til lydkilden forøges. At vi ikke gjorde os disse erfaringer her, blev et problem da vi i senere opgaver skulle finde fejlkilder og sætte variabelværdier.


Vores ClapCar implementation er ikke tilstrækkelig robust. Den ignorerer nogle klap og reagerer også på lyde, der ikke er klap. Vores vurdering er, at dette må skyldes variable der ikke er tweaket korrekt nærmere end fejl i koden. 


Slutteligt blev vores Party Finder Robot aldrig egnet til at finde fester. Som beskrevet bevæger den sig ikke konsistent mod en lydkilde, da vi ikke får konsistente målinger ind fra de to sensorer. Umiddelbart virker begge sensorer dog ens, så der må være andre fejlkilder der påvirker vores resultater.

Referencer
3. LEGO Mindstorms Education NXT Base Set 9797 building instruction, side 24-26.
4. http://dl.dropbox.com/u/357278/Lego/SoundSensorTest/SoundSensorTest.java
5. http://dl.dropbox.com/u/357278/Lego/DataLogger/DataLogger.java
     http://dl.dropbox.com/u/357278/Lego/DataLogger/SoundSampling.java
6. http://dl.dropbox.com/u/357278/Lego/DataLogger/FirstSample.txt
    http://dl.dropbox.com/u/357278/Lego/DataLogger/FourClapsSample.txt
7. http://legolab.cs.au.dk/DigitalControl.dir/NXT/Lesson3.dir/SoundCtrCar.java
8. http://dl.dropbox.com/u/357278/Lego/SoundCtrCar/SoundCtrCar.java
9. http://dl.dropbox.com/u/357278/Lego/ClapControlledCar/ClapCar.java
10. http://dl.dropbox.com/u/357278/Lego/PartyTeddy/PartyTeddy.java

torsdag den 9. februar 2012

NXT Programmering, Lessen 2


Torsdag 9. februar 2012

NXT Programmering, Lesson 2

Varighed: 4 timer
Deltagere: Mikkel, Troels, Jesper, Bjarke

Formål
Formålet med denne lab-session er at undersøge, hvordan ultralydsensoren fungerer og anvende sensoren til forskellige bevægelsesprogrammer til robotten, som beskrevet i lab-materialet [1].

Plan
1. Tilføj sensor til robot fra uge 1.
2. Udføre tests på sensoren, som beskrevet i [1].
3. Installere TrackerBeam [1], og modificere koden så den bruger proportional control med et derivative term, som beskrevet i [2].
4. Lave en Wall Follower, som i [3].

Resultater
1. Tilføj sensor til robotten
Vi har fulgt anvisningerne i Lego byggeinstruktionerne [4], side 28-30.

2. Udføre tests på sensoren
Vi har placeret robotten med forskellige afstande fra objekter og undersøgt hvilke afstande ultralydsensoren aflæser. Det er muligt for robotten at måle helt ud til sit maximum på 255, værdien for "Out of Range". Altså den kan måle til 254, den bliver dog mere upræcis på de længere afstande.

Vi har konstateret at robotten måler i en kegle foran sig. Se billede:
På billedet fanger robotten stolpen til højre for den. Hvis man går ud i en bredere vinkel fanger sensoren ikke stolpen.

Vi har fjernet Thread.sleep, da getDistance selv er sat til at vente et stykke tid, så den kan få svar tilbage, jf. API [5]:
public int getDistance()
Return distance to an object. To ensure that the data returned is valid this method may have to wait a short while for the distance data to become available.
Det giver dog stadig mening at have et delay i loopet hvis man ikke har brug for en masse målinger, da hver måling bruger batteri.


Hvis der er mange overflader kan man få meget varierende resultater. Dette skyldes at overfladerne kan være på forskellig afstand og ekkoerne derfor kommer tilbage på forskellige tidspunkter.

Ekkoet kan tage op til 15 milisekunder om at tage tilbage, når vores maximale afstand er 254, udregnet således:

2 * 254 cm
-------------------  =~ 15 millisekunder pr. måling
34,029 cm/millisec


Lydens hastighed sætter derfor en begrænsning på vores "sample-rate", man skal derfor overveje hvilke afstande vi har med at gøre. 


3. Installere TrackerBeam og modificere koden
Vi startede med at uploade programmet fra lab-materialet [1]. Her observerede vi at robotten oscillerede omkring desiredDistance [6]. Vi har valgt at bruge power som derivative term [2], så vores hastighed faldt jo nærmere vi kom desiredDistance.
Her er der et problem med at bruge power som derivative term, da den afhænger af hvilke faktorer der påvirker hastigheden. Det er f.eks. hårdere for motoren at køre på en overflade med mere friktion. Her ville det være bedre at bruge velocity (som vi selv skulle regne ud, udfra omdrejninger pr sekund, hjulstørrelse osv). Det resulterede i koden som kan ses i [7].
Dette resulterede i en robot der bevægede sig som i nedenstående video:




4. Lave en Wall Follower
Vi har tilpasset robotten så vi kan dreje ultralydsensoren. Vi har låst den i en 45 graders vinkel:


Vi oversatte derefter koden fra [3] fra NQC til java. Koden kan ses i [8]. Vi har været nød til at modificere Car.java[9] fra [1]. Resultatet kan ses i nedenstående video:




Robotten oscillerer meget da energien på motorerne er for høj. Der er ikke taget højde for noget derivative term, i stedet der 7 predefinerede intervaller som angiver afstandene robotten kan befinde sig i. 


Status
Vi er nået igennem alle punkterne.


Referencer
1. http://www.legolab.daimi.au.dk/DigitalControl.dir/NXT/Lesson2.dir/Lesson.html

torsdag den 2. februar 2012

NXT Programmering, Lesson 1

Torsdag 2. februar 2012

NXT Programmering, Lesson 1

Varighed: 3 timer
Deltagere: Mikkel, Troels, Jesper

Formålet med øvelsen er at få LineFollower til at virke. Vi har samlet robotten efter anvisningerne i lego-folderen, det tog knap 30min.
Robotten (Teddy):

Vi har nu forsøgt at installere LeJOS og få hele mindstorm-frameworket til at virke på vores laptops. Det viser sig at den ene 32bit maskine vi har ikke vil lade os installere det, pga. manglende rettigheder og vi har gjort den fejl at installere 64 java og eclipse på de to andre maskiner. Vi arbejder derfor stadig på at få det til at virke, efter knap to timer. Løsningen lige nu er at fjerne alt hvad der har med 64bit java at gøre og installere 32bits version i stedet.

Efter at have fjernet alt 64bit og installeret 32bit software, har det endelig lykkedes os at få kontakt til robotten. Et andet problem vi oplevede var at den bluetooth dongle der medfulgte ikke har drivere til et 64bit system. Det var derudover også et problem at finde passwordet i robotten til bluetooth-pairing.

Vi fik uploaded programmet "Linefollower.java" og det virkede præcis som det skulle, den fulgte den sorte linie. Video af kørsel:



For at få programmet til komme over på NXT:
1. Compile java-fil:
> nxjc <filename.java>
2. Connect via bluetooth:
- connect fra computer
- find pin på device (vi har sat den til 1234)
3. Upload til device
> nxj -r <filename>

En tabel over farveværdier:
Hvid - 57
Mat hvid - 56
Bord brun (blank overflade) - 52
Bordeaux rød - 40
Tavle blå - 38
Sort - 32

Når threshold er over 45 kører robotten på venstre hjul i stedet for højre. Det stemmer overens med koden. For at finde threshold fra en sort og en hvid læsning kan vi tage gennemsnittet af de to værdier (57 + 32 = 89 / 2 ~= 45 ).

Så slog vi den røde led fra og aflæste følgende værdier:
Hvid - 27
Mat hvid - 28
Bord brun - 26
Bordeaux rød - 18
Tavle blå - 25
Sort - 16

Her kan vi se at værdierne ligger meget mere tæt, hvilket gør det svære at skelne mellem sort og hvid.

Vi har så ændret sampling intervallet til 1, 10, 100, 1000 millisekunder. Jo højere intervallet var jo længere er der imellem samplings. Dette resulterer i større bevægelser fra robotten. Med 1000 millisekunder kører robotten i cirkler, hvilket giver mening da den kun får lavet målinger på det hvide område og derfor ikke får tændt for den anden motor.

Når vi bruger nye strings i hvert loop gennemløb går freememory imellem 45000 og 55000. Med de string variablerne går den imellem 40000 og 56000 og memory bliver fyldt langsommere. Det tyder på at man kan spare noget hukommelse på at gemme string i variable, i stedet for at allokere nye string for hvert gennemløb af loopet.
Det betyder at strings bliver allokeret i memory hver gang vi introducerer en ny string. Derudover er der en garbage collector der rydder op.