ESEA - labnotes

fredag den 30. november 2007

ESEA - Labnotes

NXT Programming - Lektion 11
Varighed: 3.5 timer - kl. 9:00-12:30
Gruppemedlemmer: Aslak, Ruben og Lars

Gruppens mål for dagens lektion:
  • lave en beskrivelse af vores projekt
  • opbygge en blokopdelt oversigt over komponenter i projektet
  • diskutere mulige løsninger på de enkelte blokke
  • diskutere mulige krav til hardware (hvilke sensorer, antal osv.)

Idet vi har snakket om hvilket projekt vi gerne ville give os i kast med i forbindelse med afslutningen af dette fag (ESEA - embedded systems, embodied agents) var vi ved lektionens opstart ret afklarede omkring projektets afgrænsning.

Projektet omhandler navigation af en gaffeltruck (eller andet transportkøretøj), eksempleficeret ved en Lego NXT robot, i et afgrænset miljø (lagerbygning/fabrikshal). Robotten skal kunne tage hensyn til andre i området, herunder andre transportkøretøjer (hermed sagt at vi gerne vil have adgang til 2 NXT'er ialt). Der skal laves en undvige-funktionalitet, som ikke forstyrrer den overordnede navigation. En overordnet styrende computer (big-brother) giver ordre til transport-robotten, og herefter udffører robotten opgaven på egen hånd. Hvilke informationer som denne "ordre" skal indeholde er ikke fastlagt endnu.

Den blokopdelte oversigt over projektet ser pt ud som følger (se linket):

http://userportal.iha.dk/~20060651/dokumenter/projektbeskrivelse.pdf

Mulige krav til hardware:

Vi forventer at kunne bruge de medfølgende motore og sensore fra NXT-kittet. Dog håber vi på at have 2 NXT'er at arbejde med, og hermed også ekstra motore og sensore. Det udarbejdede dokument, som kan ses via ovenstående link, beskriver hvilke ting vi forventer at skulle bruge, og hvor mange.

Med hensyn til mulige løsninger på de enkelte blokke på projektoversigten har vi i gruppen diskuteret forskellige tilgange til bl.a. robottens kørselsmønster. Det skal besluttes om robotten skal køre midt på en midterstribe, eller om den skal køre på højre side af en midterstribe. Yderligere skal det besluttes, hvordan robotten tackler sving. Om den skal køre ind på midten, rotere om sig selv, for at have størst mulig viden om sin egen placering, eller om den skal svinge på en mere "normal" måde. Det blev besluttet at vi først vil træffe valg omkring den endelige løsning af de forskellige blokke, når vi går i gang med blokkene. Altså har vi på denne måde mulighed for at afprøve en eller flere mulige løsninger inden vi træffer beslutningen. Også på området omkring kommunikation mellem styrecomputer og robot skal der træffes valg omkring hvilke informationer som skal kommunikeres frem og tilbage. Skal robotten modtage en "kørselsvejledning" eller blot en kendt destination. Disse valg og overvejelser vil blive beskrevet nærmere, når vi påbegynder løsning af selve opgaven.

fredag den 23. november 2007

ESEA - Labnotes

NXT programming - Lesson 10
Varighed: 4.5 timer - kl. 09.00-13.30
Gruppemedlemmer: Aslak, Ruben og Lars

Gruppens mål for dagens lesson:
  • At undersøge hvorledes en behaviour-baseret arkitektur er implementeret i subsumption API'en.
  • At følge dagens lektion og først implementere og observere "BumperCar" robotten
  • At udvide "BumperCar" robotten med en ny behaviour
  • At forsøge med en ny "Arbitrator", som er den kode som styrer hvilke behaviours som skal "køres"

Det første der blev gjort, var at montere en tryksensor på køretøjet. Dernæst hentes klassen 'BumperCar.java' og downloades til NXT'en. Programmet startes og køretøjets opførsel o
bserveres. Da vores design af køretøj fra sidste gang ikke svarer helt overens med, det der var tiltænkt i dag, er der "byttet rundt på" forward og backward. Derfor ændrede vi dette i koden, for at rette op på dette. Programmet downloades igen og bilens opførsel observeres. Det ses at bilen kører fremad. Når tryksensoren bliver aktiveret, bakker bilen
lidt og korrigerer herefter en anelse til højre.

Køretøjets tryksensor bliver til tider ikke trykket ordentligt ind, som ønsket,
hvilket resulterede i at køretøjet fortsatte ind i "væggen". For at afhjælpe dette, påmonterede vi endnu en tryksensor og anordninger, der hjælper med bedre at trykke sensorerne ordentligt ind. Denne sensor tilføjes også i "HitWall.java", således at et tryk på en af tryksensorerne returnerer TRUE fra takeControl().
Den omtalte kodeændring kan ses i følgende uddrag:


public class HitWall implements Behavior{
TouchSensor touch1 = new TouchSensor(SensorPort.S2);
TouchSensor touch2 = new TouchSensor(SensorPort.S3);
public boolean takeControl() {
boolean t1 = touch1.isPressed();
boolean t2 = touch2.isPressed();

return (t1 t2);
}
.
.
.
}


Køretøjet kan ses på følgende billede.


Ovenstående billede viser robottens "stødtænder" som opfanger , når robotten kører ind i noget.


Ovenstående billede viser robottens opbygning, set fra siden.


Ovenstående billede viser robotten tæt på en væg, dvs. tæt på at få aktiveret den venstre tryksensor.


Dette billede viser et "close-up" af tryk-sensor systemet. Selve tryksensoren har den indbyggede svaghed, at kontakten skal trykkes ind vinkelret, for at sensoren virker. Derfor skal der bygges tilbygning på, foran tryk-sensoren, for at robotten registrere at den kører ind i ting fra forskellige vinkler.

Det undersøges herefter hvad der sker, hvis en af tryksensorerne trykkes ind og holdes inde.
Når sensoren trykkes ind, bakker køretøjet et stykke tid og korrigerer herefter til højre (pga HitWall.java). Herefter holder køretøjet helt stille. Dette fortsætter indtil sensoren slippes igen. Denne opførsel sker fordi takeControl() holdes til TRUE fra den tidligere behaviour. Dette resulterer i at action() ikke køres igen. En behaviour kan ikke køre flere gange i træk. Der skal ske noget andet inden den samme behaviour kan køre igen. I afsnittet "Coding Solid action() and suppress() Methods" fra " The leJOS Tutorial" under afsnittet "Behaviour" af Brian Bagnall, er netop denne problemstilling beskrevet.
Denne tutorial kan findes via følgende link:

http://lejos.sourceforge.net/p_technologies/rcx/tutorial/behavior/index.html


Der implementeres endnu en behaviour, 'TuneBehave.java', der spiller en meget kort melodi.
Klassen så ud, som følger, ved timens afslutning:
(det skal nævnes at vi har eksperimenteret en del, bl.a. med at bruge tryk-sensorene også, hvilket koden bærer en del præg af)

public class TuneBehave implements Behavior{
private static final short [] note = {
2349,115, 0,5, };
TouchSensor touch1 = new TouchSensor(SensorPort.S2);
TouchSensor touch2 = new TouchSensor(SensorPort.S3);
public boolean takeControl() {
boolean i = true;
while(i) {
i = false;
try{Thread.sleep(3000);}catch(Exception e){}
return false;
}
return true;
}
public void suppress() {
}
public void action() {
for(int i=0;i


Denne tredje behaviour kom aldrig til at virke, som vi gerne ville have den til, så vi kom aldrig til at se at HitWall styrede motorerne, selvom den er undertrykt. Dette gør det meget svært for os at svare på, hvorfor dette er tilfældet. I den ovennævnte tutorial "Behaviour" nævner Brian Bagnall, at der specielt mht. tråde kan opstå problemer med at undertrykke dem med "suppress" funktionaliteten. Om det kan være her at svaret skal findes kan vi ved lektionens afslutning ikke svare på. Vi må spørge en "Teaching Assistant"', eller Ole C. ved nærmeste lejlighed.

Den nye behaviour tilføjes i klassen 'BumperCarAb2.java', med højeste prioritet:

public class BumperCarAb2 {
public static void main(String[] args) {
Behavior b1 = new DriveForwardAb2();
Behavior b2 = new HitWallAb2();
Behavior b3 = new TuneBehave();
Behavior [] bArray = {b1, b2, b3};
Arbitrator2 arby = new Arbitrator2(bArray);
Motor.A.setSpeed(400);
Motor.C.setSpeed(400);
arby.start();
}
}

Det blev forsøgt at køre med den nye Arbitrator (vi kaldte den Arbitrator2). Når denne blev benyttet, kunne det observeres, at en behaviour godt kunne køres flere gange i træk. Bilen kunne bakke og korrigere
flere gange i træk, når sensoren holdes inde.

Her er en lille film, hvor robottens opførsel kan ses:


fredag den 16. november 2007

ESEA - Labnotes

NXT Programmering - Lektion 9
Varighed: 3.5 timer - kl. 09:00-12:30
Gruppemedlemmer: Aslak, Ruben og Lars


Gruppens mål for dagens lesson:
  • Undersøge hvordan NXT'en navigerer vha. tachocounterne
Det første der blev gjort var at bygge robotten efter vejledningen på side 292 i Chapter 12 af Brian Bagnall. (Udleveret kopi).Robotten kom dermed til at se således ud (se Billede 1 og Billede 2).

Billede 1


Billede 2

Testprogrammet der er givet på side 298 i Chapter 12 af Brian Bagnall, blev lagt ned på XT'en.Testprogrammet fører køretøjet rundt til forskellige destinationer i et koordinatsystem. Dette blev forsøgt flere gange, og afvigelsen fra startpunktet til slutpunktet, der burde være det samme sted, blev målt. Målingerne blev foretaget ved at lægge en mønt under det højre hjul, ved start og slut og måle afstanden imellem disse mønter.Da køretøjet efter endt kørsel næsten havde den modsatte retning af startretningen, tillader vi os at trække 16 cm fra, der er afstanden imellem hjulene.Dette er dog ikke en helt pålidelig måling, da retningen ikke er 100 % modsat, men der er en vinkelforskel. Der er altså en vis usikkerhed ved metoden. Det giver dog en indikation af afstanden mellem start og slut, og de enkelte målinger i serien er sammenlignelige.

Med hjulet: Måling 1: Måling 2: Måling 3: Måling 4: Måling 5: Måling 6: Måling 7:
Vi blev gjort opmærksomme på at det kunne give lidt problemer med forhjulet, der kunne være med til at bringe køretøjet ud af kurs, både under ligeud-kørsel og i svingene. Derfor blev der også foretaget en udskiftning af forhjulet med et "støtteben" med en "glide-klods" i bunden. Dette ses på Billede 3:

Billede 3

Med støttebenet:

Måling 1:
Måling 2:
Måling 3:
Måling 4:
Måling 5:
Måling 6:
Måling 7:


Ud fra vores målinger var tendensen dog at køretøjet blev mere upræcist med støtte benet, så vi valgte at gå tilbage til hjulet.
Efterfølgende førsøgte vi at montere en sprittusch på køretøjet, så vi kunne følge køretøjets bane på en tavle der var opstillet horisontalt.

Billede 4

Billede 5


Det blev forsøgt at skifte hjulene til forskellige typer (og huske at ændre dette i koden) for at se om der kunne opnås et bedre resultat. Det blev dog ikke på noget tidspunkt bedre end det originale køretøj.

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.

onsdag den 7. november 2007

ESEA - Labnotes

NXT Programming - Lektion7 - fortsat onsdag d. 7. nov. 2007
Varighed: 4.0 timer - kl. 17:00 - 21:00
Gruppemedlemmer: Aslak, Ruben og Lars

Gruppens mål for dagen:

  • At få løst de problemer vi havde i fredags, se Lektion 7. Problemerne bestod i, at robotten stoppede af sig selv efter ganske kort til og udskrev en exception i displayet, samt, at vi ikke kunne udskrive fra vores 2 tråde i displayet. Når vi forsøgte at skrive i displayet fra de 2 tråde, så fik vi en anden exception og koden blev aldrig startet op på NXT'en.
  • At, når det første punkt er løst, observere Braitenberg-robottens opførsel i begge konfigurationer (2a og 2b i lektionensbeskrivelsen fra Lektion 7). Disse Braitenberg-robotter, som vi forsøger at implementere vha. NXT'en, kan ses på følgende side: http://www.legolab.daimi.au.dk/DigitalControl.dir/NXT/Lesson7.dir/Lesson.html
Den Første Del
Vi startede eftermiddagen med at addressere det første problem fra sidste gang, nemlig at robotten stopper efter et kort stykke tid med en fejlmeddelse på skærmen. Ved at ændre på måden vi skriver ud på displayet lykkedes det at få robotten til at fortsætte "uendeligt". Denne ændring kan ses af det følgende kode:


String str1 = "Left read: ";
while(true) {
try {
light = ls.readValue(); // 2. step
LCD.clearDisplay(); // 1. step
LCD.drawString(str1, 0, 1); // 1. step
LCD.drawInt(light, 14, 1); // 2. step
LCD.refresh(); // 1. step

}
}

Linierne i den ovenstående kode efterfølges af kommentare, som henviser til i hvilket trin vi skrev linierne. Først brugte vi de linier mærket "1. step" og da det fungerede tilføjede vi linierne mærket "2. step".

Efterfølgende var vi interesserede i, at få de to tråde til at skrive ud på skærmen med en opdateringsfrekvens, som gør det muligt at se hvad der står. Hvis trådene opdaterer hver gang de læser en sensor-værdi, så bliver displayet opdateret så ofte, og hermed også slettet så ofte, at det som effekt blinker alt for hurtigt. Displayet blinker så hurtigt, at det ikke er muligt af aflæse. Dette løser vi ved at lade de 2 tråde sove i et stykke tid (laver en løkke, som laver ingenting:

int i = 10000;
while (i > 0) {
i--;
}


Denne fremgangsmåde gør reaktionstiden for robotten længere, idet der ikke bliver reageret på lysændringer sålænge den ovenstående while-løkke eksekveres. Dog er det nu lykkedes os, at løse de 2 problemer, som var dagens første mål. Nu kan vi observere hvordan robotten opfører sig, når den udsættes for lys.

Koden, som den ser ud under de følgende observationer:
http://userportal.iha.dk/~20060651/JavaFiles_ESEA/Lektion7/fortsat/MotorLightLeft.java

http://userportal.iha.dk/~20060651/JavaFiles_ESEA/Lektion7/fortsat/MotorLightRight.java

http://userportal.iha.dk/~20060651/JavaFiles_ESEA/Lektion7/fortsat/RobotA.java

Den Anden Del

Når robotten er i den ene konfiguration, hvor højre lyssensor styrer højre motor, og venstre sensor styrer venstre motor, opfører robotten sig nogenlunde som forventet. Med det samme skal det siges, at de monterede RCX-lyssensorer har en meget lille 'range' indenfor hvilken de måler lyset. Den laveste måling vi kunne opnå er på omkring 16-20 og den højeste måling er omkring de 40-45. Dette er ikke en 'range' som tydeligt stiger, når vi bringer lyskilden tættere og tættere på sensorene. Derfor opfører robotten sig heller ikke helt som forventet/håbet.

Nok fordi vi, som forklaret ovenfor, har indsat en "tom" while-løkke, at robotten reagerer forsinket på lysintensitetsændringer. Altså reagerer robotten relativt pludseligt på højere lysintensitet og drejer kraftigt imod/væk fra lyskilden, alt efter om robotten er i 2A, eller 2B opsætning (se linket under det andet punkt i målsætningen for denne lektion). Vi har altså, med andre ord, gjort robotten relativt langsomtopfattende, idet den ikke reagerer når koden står i tomgang i de "tomme" while løkker. Udover dette, så har lyssensorene (RCX-generation lyssensorer) ikke så stor 'range', dvs. der er ikke så stor forskel på den laveste måling (16-20) til den højeste måling (40-50). Denne sidste måling er med en lygte direkte ind i sensor, dvs. relativt uopnåeligt i en virkelig situation. Indfaldsvinklen på det lys om sensorene skal måle intensiteten på, skal også være stort set lig 0 grader (direkte frontalt ind i sensoren) for at det bliver opfattet.

Alt i alt gør dette, at robotten reagerer for kraftigt, når den endelig reagerer. Holdes et lys til højre for robotten, når den er sat til at køre mod lys, så drejer den alt for kraftigt imod lyset, og den modsatte sensor når ikke at reagere, fordi robotten er i en tilstand af "køre mod lyset til højre". Der er flere årsager til denne opførsel, bl.a. reagerer robotten for kraftigt, og de tråde, som robotten kører i kan ikke afbryde hinanden.
En løsning på dette ville være hvis en tråd aflyttede begge sensorer, og kunne sige ( i ovenstående tilfælde) at robotten skulle dreje mod højre SÅLÆNGE at lysintensiteten målt ved højre sensor var højere end ved den venstre. Vi forsøgte ikke at indbygge denne funktionalitet, idet opgaven for i dag lagde op til, at der skulle implementeres 2 tråde som hver især styrede en sensor og en motor.

Dette var hvad vi nåede på denne lektion.

fredag den 2. november 2007

ESEA - Labnotes

NXT programming - Lektion 7
Varighed: 4.0 timer - kl. 9:00-13:00
Gruppemedlemmer: Aslak, Ruben og Lars

Gruppens mål for dagens lektion:
  • Bygge en robot, som kan benyttes til at undersøge opførslen på Braitenbergs køretøjer 2a og 2b. Disse køretøjer kan ses på lektionsplanen: http://www.legolab.daimi.au.dk/DigitalControl.dir/NXT/Lesson7.dir/Lesson.html
  • På baggrund af Tom Deans noter at implementere disse to køretøjer i java-kode. Til forskel for Tom Deans noter, er det meningen, at der skal implementeres 2 tråde, som hver især tager sig af kontrollen mellem samplingen af en lysføler og styringen af en motor. Hvilken databehandling som indgår i denne "kontrol" omtales i detalje, når vi når så langt. Først vil vi blot omregne imellem det tilgængelige lysintensitets-interval og det mulige interval for "power" til motorene.

Fabrikation af Braitenberg-robot

"First things first", som det hedder. Dette indebærer, at bygge en robot, som ligner de skitser på dagens lektion. Et køretøj, som har 2 lysfølere foran, og som drejer udelukkende på baggrund af hvilken af baghjulene, som kører hurtigst. Der er to Braitenberg-variationer. Den første har en kobling mellem den lysføler til højre og den motor, som driver højre baghjul og mellem den lysføler til venstre og den motor, som driver venstre baghjul. Den anden variation bytter om på koblingerne, således at venstre lysføler kobles til højre baghjul og højre lysføler kobles til venstre baghjul.

I dag startede vi med at bruge lidt tid på at modtage kritik af vores labnotes frem til nu. Dette gav os gode tilbagemeldinger, både ros og gode råd til forbedringer. Der var også lidt tid til at diskutere muligheder for emner til det afsluttende arbejde.

Robotten tog lang tid at bygge. Problemet var faktisk at udarbejde en forhjulskonstruktion, som virkede stabil nok, idet robotten skubber bagfra. Tidligere har vi arbejdet med den "default" robot, som kan ses i manualen, som følger med de lånte legoklodser. Denne "default" robot trækker på forhjulene og trækker et baghjul, som blot følger efter og kan rotere frit (dreje frit om en vertikal akse). Vores ønske er at bygge en robot som ligner Braitenbergs skitser så meget som muligt. Problemet med det første udkast til en forhjulskonstruktion var, at rotationspunktet for aksen ned til forhjulet var lavet lige over hjulet. Dette gør det vanskeligt at få hjulet til at dreje, når baghjulene skubber bagfra. Løsningen blev at bygge et simpelt forhjul, som har rotationspunkt forskudt i forhold til centrum af selve hjulet. Dette svarer til princippet for baghjulet på den førnævnte "default" robot. Følgende billeder viser lidt tydligere hvordan den færdige forhjulskonstruktion ser ud. Billederne viser yderligere hvordan vores Braitenberg-robot ser ud.

(indsæt billeder..)

Implementering af koden

Vi påbegyndte arbejdet med koden ved at danne 2 tråde i java. Disse tråde skal hver især aftaste en lysføler (vi bruger de "gamle" fra RCX-tiden) og styre en motor af NXT-typen.
Den første version af koden skrev intet ud på displayet (noget vi bøvlede en del med under arbejdet med "Robot Race" robotten) og gav bare et niveau til begge hjul. Denne kode fik en exception efter at have kørt et ganske kort stykke tid. Forsøgte vi at udskrive noget i displayet fik vi en exception med det samme, og koden kom aldrig i gang. Altså er der 2 ting, som skal rettes: Koden skal ændres, således at den ikke stopper af sig selv, og det skal være muligt at udskrive i displayet. Disse 2 opgaver skal løses inden vi kan komme i gang med den egentlige opgave, nemlig at realisere Braitenberg-robot 2a og/eller 2b. Den ene java-fil 'RobotA.java' starter de to tråde, og de to andre (som er ens i koden) tager sig af at læse hhv. den højre og venstre lyssensor og styre hhv. den højre og venstre motor. Disse to sidstnævnte filer hedder 'MotorLightRight.java' og 'MotorLightLeft.java'.

Vi aftalte at mødes igen inden næste uges forelæsning.

Koden, som den så ud ved afslutningen:

http://userportal.iha.dk/~20060651/JavaFiles_ESEA/Lektion7/RobotA.java

http://userportal.iha.dk/~20060651/JavaFiles_ESEA/Lektion7/MotorLightRight.java

søndag den 21. oktober 2007

ESEA - Labnotes

NXT programming - Lektion 6 - fortsat (igen)
Varighed: mange timer
Gruppemedlemmer: Aslak, (Ruben og Lars)

Fejlen med motoren (se blog fra lektion 6 - lørdag) blev rettet relativt hurtigt da dette var pga. at vores initialisering af motoren ikke var rigtig. Herefter kørte begge motorer lige hurtigt.

Herefter begyndte vi at skrue på parametrene for KP, KI og KD.Vi lavede kopier af programmet, hvor vi ændrede KP i positiv og negativ retning med 2 for hver test altså KP = (20, 22, 24, 26, 28 (standard), 30, 32, 34, 34). Vi kunne ikke konstatere nogen umiddelbar forbedring, men jo lavere KP blev desto svagere blev selvreguleringen. Og det modsatte skete hvis KP blev højere, men dette hjalp ikke på balancen.

KI ændringen kunne ikke mærkes på robotten.Det samme oplevede vi for KD. Derudover opdagede vi en klassisk fejl, som også omtales i den læste litteratur; Batteriniveauet har stor betydning for, hvordan robotten reagerer. Vores bedste resultat, som vi desværre ikke fik filmet, hvor vi var oppe på et minuts ballance, var med et batteri niveau på 7.0 (så vidt der huskes). Men da Aslak, som arbejdede individuelt i ferien, dagen efter havde kameraet klar og havde opladet batteriet, gik robotten fuldstændig amok med sin regulering. Dette skal man nok tage højde for en anden gang og skrive en regulerings algoritme i forhold til batteriet.

Efter en snak med Ole, prøvede vi at fjerne KI konstanten fra algoritmen. Og dette hjalp faktiskt på balancen.Dette skyldes, at Integral fejlen stiger og stiger. Denne stigende Integral fejl resulterer i, at robotten fint holder balancen i starten. Herefter bliver reguleringen kraftigere og kraftigere, hvilket resulterer i, at robotten kommer i ossilationer og får besvær med balancen.

den endelige kode (som den ser ud nu) kan ses her:
http://userportal.iha.dk/~20060651/JavaFiles_ESEA/Lektion6/Balancer.java