fredag den 9. november 2007

ESEA - Labnotes

NXT Programming - Lektion 8
Varighed: 5.0 timer - kl. 9:00 - 14:00
Gruppemedlemmer: Aslak, Ruben og Lars

Dagen i dag startede lidt rodet op, og der gik et godt stykke tid inden vi påbegyndte dagens dont.
Inden vi påbegyndte arbejdet med dagens lektion gik vi Oles kode for det flertrådede projekt igennem, for at gennemskue det og se, hvordan det adskiller sig fra vores tidligere kode. Vi har i tidligere lektioner oplevet uventede exceptions, når vi har forsøgt at skrive ud på NXT'ens display fra forskellige tråde. Dette lykkes meget smart med Oles kode og vi har nu, med denne kode, et godt udgangspunkt, både for denne lektion, og fremtidige opgaver.

Dagens mål:

  • Opnå en bedre forståelse for håndteringen af tråde. Dette punkt er et gennemgående punkt, både for den første og anden halvdel af lektionen.
  • Første del af dagens lektion; Prøve 'BehaviourTest1.java' og de tilhørende filer, samt at undersøge robottens opførsel med hhv. den første 'behaviour' tråd, de første 2 'behaviour tråd' og alle 3 tråde.
  • Tilføje en "behaviour" fra Lektion 7. Denne opførsel er at køre mod lys. Det skal overvejes hvordan denne tråd skal implemeteres og hvilke andre 'behaviours' den kan undertrykke. Er det vigtigere at spille en melodi, som tråden 'PlaySounds.java' gør, eller at køre imod lyset ?

Det var til denne lesson ikke muligt at benytte den computer vi hidtil havde benyttet i forbindelse med øvelserne. Eftersom vi tidligere ikke havde kunnet få kommunikationen imellem NXT'en og de andre computere til at virke, stod vi over for lidt af et problem. Efter en vis eksperimenteren, viste det sig, at den ene computer alligevel kunne bruges. Det var dog ikke helt problemfrit. Flere gange var det nødvendigt at lukke og genstarte Eclipse for at downloade klasserne til NXT'en.

Det første punkt på dagsordenen, at få større forståelse for tråde, blev både dækket af det indledende arbejde, hvor vi gennemgik Oles kode, samt da vi skulle skrive vores egen tråd 'DriveTowardsLight.java'.

Den første del - 'BehaviourTest1.java'

'BehaviourTest1.java' starter de 3 tråde, kodet i 'RandomDrive.java', 'AvoidFront.java' og 'PlaySounds.java' og lader dem efterfølgende køre indtil 'escape'-knappen trykkes ned.
Som det første downloades programmet 'BehaviourTest1.java', efter at de 3 nye klasser er blevet oprettet i Eclipse, og køretøjets opførsel samt udskriften på LCD displayet observeres. I displayet er de tre behaviours/tråde repræsenteret på hver sin linie. Efter navnet på hver behaviour/tråd står der 0 eller 1, hvor '1' indikerer, at den enkelte behaviour/tråd bliver undertrykt/supressed og '0' indikerer at den ikke bliver undertrykt. Som nævnt i indledningen har vi tidligere haft problemer med at få tråde til at udskrive i displayet, hvilket Oles kode klarer fint. Til forskel fra det vi tidligere har forsøgt, tildeles trådene en linie i displayet, som den pågældende tråd herefter opdaterer, uden at ændre på det som ellers udskrives i displayet.

Ved at starte 'RandomDrive'-tråden alene, ses det tydeligt, hvordan tråden styrer robotten. Koden for tråden ses her:

reportState();
Locomotion.forward((int)(50+50*Math.random()),(int)(50+50*Math.random()));
delay((int)(500+1000*Math.random()));
reportState();
Locomotion.stop();
delay((int)(1500+1000*Math.random()));

Robotten kører fremad på begge hjul, med 'tilfældig' hastighed på hhv. højre og venstre hjul, herefter kører den i perioden (500+1000*Math.random()), udskriver sin tilstand i displayet og venter (laver ingenting) i perioden (1500+1000*Math.random()). Denne opførsel virker meget tilfældig, når robotten observeres. Robotten opleves som 'vægelsindet', altså ubeslutsom og med skiftende forkærlighed for den retning den sidst bevægede sig i.

Ved at starte 'AvoidFront'-tråden sammen med 'RandomDrive'-tråden, ses det, hvordan de styrer robotten. 'AvoidFront' foretager sig intet, sålænge der ikke 'ses' noget med den påmonterede ultralydssensor. Mere præcist fortalt måles konstant den afstand som aflæses med ultralydssensoren, og kun når den målte afstand når ned under en givet tærskel reagerer tråden og griper ind i robottens opførsel. Tråden starter med at undertrykke 'RandomDrive', noget som er gjort muligt vha. Oles kode, hvor alle trådene egentlig er baseret på klassen 'Behaviour'. Efter at undertrykke 'RandomDrive' sørger 'AvoidFront' for at robotten først bakker lige bagud i et sekund (Delay(1000)) for derefter at dreje til venstre, ved at køre fremad på højre hjul i 800 ms. Afslutningsvis holder robotten stille i et halvt sekund. Yderligere udskriver tråden i displayet når den hhv. bakker (skriver 'b'), drejer til venstre (skriver 'l') og holder stille (skriver 's'). Helt til slut frigives tråden 'RandomDrive' igen.


Ved at starte 'PlaySounds'-tråden tilføjes den sidste behaviour. Denne tråd starter med at sove i 10 sekunder, hvor de andre tråde får frit spil. Herefter undertrykker den de to andre tråde, tilføjer et 's' i sin display-linie, samt afspiller en lydsekvens, venter i 200 ms og afspiller en anden lydsekvens. Afslutningsvis frigiver tråden de andre tråde.


Den anden del - 'DriveTowardsLight.java'
Efterfølgende blev klassen 'DriveTowardsLight.java' oprettet, der extender klasssen 'Behaviour.java'. Denne klasse går overordnet set, ud og læser hvilke værdier, der er på begge RCX-lyssensorerne. Såfremt værdierne ligger under en fastsat tærskelværdi, køres en while-løkke, der udelukkende udskriver værdierne for de to sensorer i hver deres linie af displayet.
Komme værdien for en af lyssensorerne over tærsklværdien, springes der ud af while-løkken og 'RandomDrive'-løkken undertrykkes. Vi har valgt at 'DriveTowardsLight' i øjeblikket kun undertrykker 'RandomDrive', således at den stadig kan undgå at køre frontalt ind i noget, og at den stadigvæk kan blive afbrudt og bryde ud i festlige toner. Det kan nemt ændres på et andet tidspunkt. Efter at have undertrykt 'RandomDrive'-tråden forsøger vi at omsætte de to aflæste værdier på lyssensorene til en hastighed/power til hjulene. Denne omregning kan forbedres, men ser i pt. ud som følger:

leftSpeed = 50+ 800-(60-rightlight)*800/(40);
rightSpeed = 50+ 800-(60-leftlight)*800/(40);

Motorene modtager herved 'hastigheder' imellem 50 og 850, når lyssensorene måler hhv. 20 og 60. Tråden udskriver stadigvæk de målte lysintensiteter og udskriver herudover teksten 'li' i den øverste af sine 2 tilgængelige linier. Den kører i en tilfældig tidsperiode, noget vi har taget fra en af de andre tråde. Til slut stopper tråden de to motore og venter i en tilfældig periode. Årsagen til at det blev denne opbygning, med tilfældige periode-længder var fordi vi kopierede en af de andre tråde. I teorien bør dette ændres på baggrund af ekperimentiel data, således at robotten kører mest optimalt hen imod en lyskilde.


Denne nye klasse/tråd, 'DriveTowardsLight.java' ses i sin fulde kode her:
http://userportal.iha.dk/~20060651/JavaFiles_ESEA/Lektion8/DriveTowardsLight.java

Den førnævnte kode for 'DriveTowardsLight'-tråden tilføjes i 'BehaviourTest1.java', således at den ('DriveTowardsLight') kan undertrykke 'RandomDrive' og robotten tilføjes de to RCX-lyssensorer. Det følgende billede viser robottens udseende.




Idet vores nye tråd udelukkende har mulighed for at undertrykke 'RandomDrive'-tråden sker der ofte det, at lysfølger-funktionaliteten afbrydes af de to andre tråde, enten fordi hånden, som holder lyskilden aktiverer 'AvoidFront' eller fordi den fantastiske melodi pludselig afspilles. Reelt set burde vi teste 'DriveTowardsLight'-tråden, enten alene, eller med mulighed for, at den undertrykker de andre tråde, og ingen af de andre tråde undertrykker den. Desværre nåede vi ikke mere i denne lektion.

Af denne lektion, sammenlignet med vores tidligere oplevelser, ses det hvor vigtigt det er at have en ordentlig struktur på sin kode. Vi har i tidligere lektioner brugt meget tid på at få udskrift i display til at fungere med multitråd-projekter, uden at have fundet en langtidsholdbar løsning. Med den, til dagens lektion udleverede kode, under armen kan vi forhåbentlig spare meget tid i fremtidige lektioner, i hvert fald når det drejer sig om udskrift i displayet og flere tråde. Yderligere nævnes, at vi startede med at teste hver enkelt 'behaviour' hver for sig, og sluttede alligevel af med at teste vores 'DriveTowardsLight' sammen med de andre tråde uden at teste den for sig selv. Her kunne vi jo godt have tænkt os lidt mere om. Ja, ja. Vi er her jo for at lære.

Ingen kommentarer: