torsdag den 4. december 2008

Week 11

Projektplanlægning.

Dato: 4/12 2008
Deltagere: Asger, Michael, Peter
varighed: 3 timer.

Plan:



  • Brainstorm af projekt emner

  • Vælge et projekt

  • Beskrive det valgte projekt

  • Lav en plan for projektet


Brianstorm project


Vi brugte 10 minutter på at brainstorme projektemner der kunne være
intressante. Vi kom frem til følgende liste af projekter.


* Boids/flocking
* Spil
* Rabbit hunt
* Selvsamlende robot
* Dart spil
* Service bot
* Dyr
* Bomberman
* Tower defence
* Laser/paintball game
* Fodbold
* Pebernøds kanon

Valg af projekt.



Vi har valgt projektet Fodbold fordi det har et indhold og
kompleksitet der passer til tidsrammen og kursets indhold. Derudover
er det et projekt der indrager emner som Boids/flocking, Spil, Rabbit
hunt (jagter bolden), Dyr (man kan betragte spillerne som autonome dyr
der skal samarbejde/modarbejde).

Beskrive det valgte projekt

Vi har valgt et projekt, hvor nogle robotter på en bane skal spille
fodbold eller en dialekt heraf. Vi forestiller os at der er 4-6
robotter på en bane af passende størrelse. Robotter har en opbygning
i stil med standard robotten der er beskrevet i samlevejledningen
til legosættet 9797.

Vi vil fokusere på hvordan robotterne spiller bold og forholder sig
til hinanden, ikke hvorledes de kan se hvor de andre robotter
er. Derfor har vi tænkt os at tracke robotterne med et webcam der er
tilsluttet en komputer. Via bluetooth kan denne fortælle robotterne
hvor de er og hvor de andre robotter er placeret, samt hvordan de er
orienterede. Endvidere kan man tracke bolden hvis den fx er det
eneste røde objekt på banen. I praksis har vi tænkt, at man med tags
på toppen af robotterne kan bruge AR-toolkit til det.

For at robotterne kan skyde til bolden tillader vi kun at robotterne
bevæger sig med 50% af maksimal hastighed, hvis de så vil skyde til
bolden tillader kan de give fuld power i et kort tidsinterval.

Vi forventer at kunne præsentere en bane hvorpå der kører 4-6 robotter
og spiller noget der minder om fodbold, altså et boldspil med 2 hold
og 2 mål, hvor det gælder om at score mål.

Tidsplan for projektet.


* Uge 50, Godkendelse af projektet.
* Uge 51, Bygge robotterne og få dem tracket via AR-toolkit.
* Uge 52, Få bluetooth kommunikation til robotterne til at virke.
* Uge 1, Implementere en naiv algoritme.
* Uge 2, Teste algoritme fra udvalgte papers.
* Uge 3, Reflektere over algoritmer.
* Uge 4, Projekt fremlæggelse.

torsdag den 27. november 2008

week 10

Deltagere: Peter, Michael, Asger
Varighed: 3 timer
Mål: Undersøg Behaviour programmering med nxj klasser

Plan:
* Kør BumperCar på NXT'en
* Undersøg koden for NXJ's behaviors
* Tilføj exit behavior
* Tilføj play behavior

Bemærk, vi bruger lejos 0.7, som har en forbedret Behavior og Abritrator

BumperCar på NXT


NXT'en kører fremad til touchsensoren bliver aktiveret, når det sker
kører den lidt tilbage, og dreje en smule til venstre. Derefter
starter den forfra. Hvis man holder touchsensoren nede bliver den ved
med at bakke og dreje gentagende gange, uden at køre fremad.

Koden


I Abritrator finder man en Monitor med følgende kode.

//FIND HIGHEST PRIORITY BEHAVIOR THAT WANTS CONTROL
highestPriority = NONE;
for( int i = maxPriority; i >= 0; i--)
{
if(_behavior[i].takeControl())
{
_highestPriority = i;
break;
}
}
if(_highestPriority > _current && _current != NONE)
{
_behavior[_current].suppress();
}
Thread.yield();


Det den gør er at gennemløbe alle behaviors startende med den der har
højst priotet, når den finder en som ønsker kontrol stopper den
gennemløbet og vælger den behavior.

Dvs. at DriveForward.takeControl kun bliver kaldt når HitWall retunere
false i sin takeControl.


Exit Behavior


At implementere en exitbehavior "burde" være simpelt. Desværre ser det
ud til at de ellers gode ændringer der er kommet i version 0.7 af NXJ
har tilføjet nogle nye problemer. Fx starter Abritrator en monitor
tråd, som ikke er sat til daemon, derfor kan ens program ikke afslutte
så længe den tråd kører, hvilket den bliver ved med så længe, at der
er en Behavior der vil have kontrol. Derfor, for at lave en
exitbehavior, så skal den have kendskab til alle andre behaviors, som
have mulighed for at slå dem alle fra.

Opdatering:


Ved at Kalde Abritrator med false som andet argument, så den ikke ikke
retunere ved inaktivitet, så fungere det hele meget bedre. Dog er
semantiken for action og suppress ændret lidt, så suppress bliver kun
kaldt, hvis action ikke har retuneret før en anden Behavior skal
afvikles. Derfor lavede vi om i DriveForward, så den har en whileløkke
der bliver ved med at kalde Thread.yield() indtil suppress bliver
kaldt, på den måde er vi sikret at suppress bliver kaldt.

Play sound


Når alle behaviors er sat ind, og man aktivere hitwall og sound
samtidig, så ignorers sound da hitwall har højere priotet. Hvis man
derefter aktivere exit, så afslutter programmet.

torsdag den 20. november 2008

Legolab week 9


Legolab week9

Dato: 20/11 2008
Tidsforbrug: 3 timer
Deltagere: Michael, Asger, Peter

Plan:
* Teste præcisionen af relativ positionering.


=== Teste præcisionen af relativ positionering.
Vi bruger en standard robot lavet fra byggevejledningen i LEGO 9797
sættet s. 8-22.

-- Kalibrering.
Vi kalibrerer både omkredsen af hjulene og hjulafstanden. For at
kalibrere omkredsen lader vi robotten køre en meter frem og stoppe. Så
kan vi teste om de præcist er 56mm i diameter som der står påtrykt på
hjulene.

Kalibrering af hjul:
Vi kalibrerede robottens hjuldiameter ved at bruge programmet
CalHjul.java
.

Da vi satte robotten igang så vi straks at den drejede en smule til
den ene side, fordi hjulene ikke var præcist lige store. Vi satte en
whiteboard marker på robotten for at den kunne tegne den vej den
faktisk kørte. Det viste sig at den kørte vej, afveg 1cm fra en lige
streg over en afstand på en meter. Vi løste problemet ved at prøve
forskellige hjul, indtil vi fandt 2 ens hjul, der kun gav en afgivelse
på 2mm over afstanden på 1m.

Med en hjuldiameter på 56mm kører robotten 1cm forkort
på 1m, så den faktiske hjuldiameter for robotten er en smule mindre
nemlig 55,44mm.

Vi kørte 3 test med den nye hjuldiameter. Alle gav en afvigelse på
under 1mm, over afstanden på 1m.

--- Kalibrering af hjulafstand.

For at kunne dreje præcist med TachoNavigator klassen, skal man kende
den diameter robotten drejer om. Vi har målt den til at være 110mm,
for at eftertjekke dette har vi lavet et lille program

CalDistance.java
som drejer 2 gange rundt om sig selv i step af
45 grader.

Vi ser at robotten faktisk drejer præcist med en hjulafstand på 110mm.

--- Test af kalibrering.

Vi tester præcisionen af robotten ved at lade den køre samme rute som
i Brian Bagnall's bog, kapitel 12, men vi lader vores robot køre turen
2 gange så vi bedre kan se effekten af akkumuleret fejl. Programmet vi
har brugt er TestCal .

Resultat:

Det viser sig at robotten er omtrent 40cm fra origo når den slutter
sin anden runde. Vores første tanke var at det skyldes at
TachoNavigators goTo metode var upræcis, så vi udregnede selv de
vinkler og afstande der skulle bruges. Resultatet var det samme. Ved
at montere en whiteboard marker på robotten kunne vi se hvilken sti
den kørte på gulvet. Det viser sig at robotten slet ikke kører lige
selvom vi kalibrede den til at kunne køre ligeud. Over 2m afviger
banen robotten kørte, 2 cm fra en lige linje, dvs den har en afvigelse
på 2,26 grader pr meter den kører. Det betyder at hvis vi kører 10m
har vi en akkumuleret afvigelse af vinklen på 22,6 grader. Det passer
godt med den observerede slutafvigelse for vinklen i vores test.

Men da vi havde slet ikke så store afvigelser i den kliniske test vi
kørte. Konklusionen må hermed være at batteriniveauet eller overfladen
der køres på spiller en rolle for præcisionen af robotten. Når denne
styres vha.

Week 8 - Prioriteret opførsel

Date: 20/11-08
Duration of activity: 3hours
Group members: 20051770, 20051866 og 20052051




LEGO car that exhibits several behaviors



Goal:
Beskrive hvordan Jack opfører sig når vi kører programmet
SoundCar.java
på ham og tolke det output han giver.

Plan:
Oploade programmet og lade Jack gøre det han gør bedst. Excekverer det.

Robot:
Vi brugte samme robot som til øvelserne i uge 7.

Code:
SoundCar
er det primære program.

Hjælpeklasserne er:
AvoidFront
Behavior
Car
PlaySound
RandomDrive

Resultater:
Vi så at hvis Jack blev overladt til sig selv, kørte han glad rundt på
må og få og spillede lyde engang imellem. Hvis vi så stak en hånd ned
foran ham, så vi at han bakkede bagud og drejede mod venstre for at
kunne køre i en anden retning end der hvor noet blokerede hans vej.

Vi så også at hans opførelser kunne blokere hinanden, da vi kunne
sætte en hånd ned foran ham mens han kørte rundt og han ville straks
stoppe og bakke væk. Dog stoppede han helt op selvom der var en hånd
foran ham, hvis han skulle til at spille en melodi, da denne opførsel
blokerer for alle andre.

På LED'et havde de forskellige opførsler fået en linje hvor de kunne
printe deres opførsel. 'f' hvis de kørte fremad, 'b' hvis de kørte
bagud og 's' hvis de stoppede Jack. Her kunne man igen se hvordan de
forskellige opførsler blokerer hinanden.

Konklusion:
SoundCar ser ud til at give Jack flere forskellige opførsler, to han
kan bruge til at bevæge sig rundt i verdenen og "fløjte" og én til at
køre væk fra objekter han ellers vill være kørt ind i. Vi kan se at
implementationen virker, da Jack stopper med at køre rundt på må og få
hvis han skal fløjte eller undgå en hånd.


Class Behavior



Hvis vi kigger i SoundCar klassen kan vi se at der bliver oprettet 3
tråde, en RandomDrive tråd, en AvoidFront tråd og en
PlaySoundTråd. Hver ny tråd får de foregående givet med i sin
konstruktor, således at den kun undertrykke deres opførsel.

Formålet med at gøre de tre ovennævnte tråde til daemons er så vidt vi
kan se udelukkende at man så slipper for at "holde styr på dem". Dvs
vi behøver ikke vente på at de lukker ned før vi stopper programmet.

Opførslen i SoundCar er implementeret ud fra Subsumption Architecture idéen.

Idéen baserer sig på at opførelserne er strukturet i lag, hvor
"reflekserne" ligger i bunden og "overvejede" handlinger ligger
øverst. En opførsel kan så blokere de ovenliggende opførsler, således
at disse ikke udføres.

Et eksempel vil være en overvejet handling som at bevæge sig mod en
dør og refleksen at flytte sig fra det søm man lige har trådt på. Her
skal refleksen naturligvis blokere for at man bevæger sig videre mod
døren indtil sømmet er ude.

Implementationen af Behavior klassen virker ved at hver underliggende
handling kender til alle de ovenstående og så blokerer hver eneste af
dem når dens egen opførsel skal udføres.

Dette er en udemærket implementation så længe vi ikke har mange
forskellige behaviors. Hvis vi derimod havde mange behaviors ville en
anden implementation mæske være bedre. Vi forestiller os et array af
opførsler med et blokerings indeks, der kan fortælle hvorfra og
opefter opførsler er blokeret. Dette ville forhindre at alle
ovenliggende opførsler skulle tilføjes i konstruktoren som det gøres
nu, se bl.a PlaySound, men istedet skulle opførslen bare tilmelde sig selv til en
BehaviorController klasse og tilgå motore gennem denne klasse.

Dette ville bl.a gøre det muligt at udkommentere AvoidFront tråden
uden at ændre for meget i koden. Pt. hvis man vil af med AvoidFront,
skal man også rette i PlaySound Klassen, da denne kræver to Behavior
objekter, men nu kun skal blokerer RandomDrive. (Alternativt kunne man
give RandomDrive med to gange til PlaySound, men dette er heller ikke
synderligt kønt)


Added "Drive Towards Light" behavior



Goal:
Vi skal tilføje en opførsel til Jack, således at han sammen med de tre
tidligere opførsler nu også vil søge mod lyset. Denne nye opførsel
skal spille sammen med de tre tidligere og undertrykke dem hvor det mening.

Plan:
Planen er ganske simpel. Vi skal med udgangspunkt i
vores SensorBot
klasse fra uge 7 bygge en FollowLight klasse, som nedarver fra
Behavior klassen og bruger denne til at arbejde sammen med de andre behaviors.

Måden vi har tænkt os at gøre dette på er ved at bygge en FollowLight
klasse, der nedarver fra Behavior og i run implementerer en algoritme
til at køre mod lys.

For ikke at skulle ændre alt for meget på opførsels rækkefølgen,
behavior stakken, vælger vi at lægge FollowLight ovenpå og lade den
blokerer alt andet hvis Jack ser et lys han kan køre
mod. Dvs. prioriteringsrækkefølgen er RandomDrive, AvoidFront,
PlaySound og FollowLight. Besynerligt nok vil Jack dermed hellere
følge efter et lys end at undgå en lavthængende bro lige foran ham.

Da måden Jack "ser" lys på er ved at observerer forskelle i lyset til
venstre og lyset til højre for ham. Vi antager at disse godt kan
varierer uden at Jack faktisk har set et lys og vælger derfor at
FollowLight først skal sætte ind hvis hvis forskellen kommer over et
threshold, som vi finder ved trial and error.

Kode:
Koden for den nye main klasse kan ses i
LightSoundCar

Selve koden der får robotten til at følge efter lys er implementeret i
en do-while løkke der bliver ved med at køre indtil lysforskellen
kommer under thresholdet. Når dette sker holder klassen op med at
undertrykke de "højere" opførsler.

Den modificerede SensorBot ligger i
FollowLight

Resultater:
Robotten reagerer fint på lys og vi kan se på displayet at den
undertrykker de andre.

Desværre har vi også set PlaySound klassen afspille lyd og "låse op"
for AvoidFront og RandomDrive.

Konklusion:
Behavior implementationen har vist nogle kraftige mangler i disse
forsøg. Vi har observeret at selvom opførsler ikke selv er i stand til
at overtage styringen fordi de bør være undertrykte, kan de godt låse
op for højereliggende opførsler.

Et hotfix til dette ville være at suppress alle andre opførsler inde i
vores løkke i, så det ville se således ud.


do {

b1.setSuppress(true);
b2.setSuppress(true);
b3.setSuppress(true);
int rightSpeed = rightLight * SPEED_GAIN;
int leftSpeed = leftLight * SPEED_GAIN;
forward(rightSpeed, leftSpeed);

rightLight = rightLS.readPercent();
leftLight = leftLS.readPercent();

} while (threshold < (rightLight - leftLight));


En anden og bedre er at hver klasse i deres while-loop som det første
checker om de er suppressed og hvis de er så ikke gør noget derfra.

En helt tredje er at man som nævnt ovenfor implementerer en behavior
stack, der som et minimum ikke tillader undertrykte opførsler at
ændre på om andre opførsler er undertrykte. En lidt udvidet
implementation ville endda selv schedule opførselstrådene og ikke køre
de undertrykte.

Vores konklusion er at Behavior klassen virker, men den kræver at man
har tiltro til de klasser der extender den, da det er alt for nemt at
implementere en klasse som låser op for sig selv eller andre uden at
"have tilladelse til det".

mandag den 3. november 2008

Week 7 - Braitenberg vehicles

Deltagere: Asger, Michael og Peter
Varighed: 4 timer.
Målet er at se hvordan Braitenberg køretøjer reagerer ved påvirkninger udefra.

Plan:
  1. Se at køretøj 2a kører mod lyset, hvis den ser lys.
  2. Se at køretøj 2b vil afvige fra en lyskilde.
  3. Gøre koden adaptiv overfor ændringer i omgivelsens lysstyrke.



Robotten:
Da vi skulle bruge en robot trukket ved 2 uafhængige hjul, har vi bygget den "oprindelige" lego robot. Denne har vi udstyret med 2 lyssensorer, som peger fremad. Derudover er robotten udstyret med 2 fremadrettede lydsensorer.





Teori:
Teorien kan findes her.


Forsøg 1:
Det første forsøg vi har lavet med robotten var at forbinde sensorer til motorerne, som i køretøj 2a.
Ideen med dette køretøj er at det vil forsøge at køre mod sensorernes stimuli. Da vi har bruge lys sensorer, valgte testede vi køretøjet ved brug af lyset fra en lighter. Vores test viser at robotten kører mod flammen, hvis den er mindre end 30 cm. fra lighteren, er den længere væk er lyset fra flammen for svagt (I dagslys).

Forsøg 2:
I dette forsøg er højre/venstre sensor forbundet til venstre/højre motor, som på køretøj 2b.
Teorien er at køretøjet vil dreje væk fra den sensor der får et stimuli. Igen har vi brugt en lighter som lyskilde, robotten drejer væk fra ilden, hvilket er meget smart, så den ikke bliver brændt af :)

Forsøg 3:
Formålet med forsøget er at få robotten til at ændre opfattelsen af hvad der er gennemsnitlige lysværdi.

For at gøre det laver vi et løbende gennemsnit.
Lad A være det løbende gennemsnit, v være den nuværende lysværdi og N er antallet af målinger der udregnes over.
Formlen for det løbende gennemsnit er så:
A := v/N + (1 - 1 / N) * A

Denne formel gør at vores gennemsnit vil konvergere mod vores målinger over tid, således at vores robot vil kunne begå sig i et foranderligt miljø.

Robottens gennemsnitlige lysværdi er adaptiv overfor ændringer i lysforholdene. Med de nuværende konstanter der bliver brugt i koden tager det ca. 20 sekunder fra der sker en markant ændring i lysforholdene, til der er en ny stabil gennemsnitlig værdi.

** snip
Vores normalize funktion er ganske simpel.
Den lader kun lys og lyd værdier på over average påvirke jack, da average ses som værende baggrundsstøj.
Den returnerer så lysværdien minus lydværdien og bruger denne som power til motorene. Ideen er at jo mere lys der er jo hurtigere kører jack og jo mere lyd jo langsommere.

Tests:
Succeskriteriet for vores robot er at dens threshold værdier kan ændre sig løbende alt efter dens miljø og at den vil reagerer veldefineret når den ser stærkt lys.

Det første succeskriterie blev opfyldt da vi kunne se vores robots average værdi ændre sig alt afhængig af om vi slukkede eller tændte lyset.
** snip

fredag den 10. oktober 2008

Week 6 - Race video

Legolab week 6,7

Vi lavede en bil med firhjulstræk og firhjulsdrej, som det kan ses i videoen.
Den bedste tid den kørte banen i var på 17 sekunder. I videoen ses et tidligere forsøg hvor den brugte 20 sekunder.

Vi startede med at gøre brug af Motor klassen, men ved nærmere gennemgang af lejos koden stod det klart, at der er alt for stort delay i klassen til, at den kan bruges i kode der skal reagere i realtime. Istedet valgte vi så at bruge MotorPort klassen, hvilket gjorde at bilen blev ca. 5 sekunder hurtigere. Ved yderligere at tweake vinklen bilen drejede og hvilke hastigheder den gjorde det med, hentede vi yderligere et par sekunder og endte således med at kunne køre banen i 17 sekunder.




Youtube version



torsdag den 2. oktober 2008

week 5

Uge 5 - Segway.

Forsøg:
vi byggede vore robot på forskellig vis, men det lykkedes ikke at få den til at balancere i mere end et par sekunder med Sejway.java programmet.
Vi forsøgte, at tweake parametrene SCALE, KP, KI og KD og basis motor-power, men det hjalp ikke meget. Dernæst fik vi mistanke om, at den måde det approximerede integrale blev udregnet, ikke var den bedste, integral_error = 2/3 * (integral_error+error).
Hvis man har hurtige cycles betyder det at integralet ikke har megen information om fortiden, hvilket ikke er i overensstemmelse med definitionen af integralet.

Vi satte derfor integral_error = integral_error+error. Antager man, at cyklus tiden har længde 1 så får man det approximerede integrale, der er defineret ved:
Oversummen når error er stigende.
Undersummen når error er faldenden. For inddelingen {1,2,...,n} af error funktionens domæne.

For at integral_error bliver lille, kræves det, at der har været samme mængde positiv og negativ fejl i kørselsperioden, det kan sagtens lade sig gøre hvis robotten bliver på samme position. Hvorom alt er, så lykkedes det ikke med denne konstruktion at få et brugbart resultat ud af programmet. Vi lavede grafer over tid, error, integral_error, derivative_error, power, retning og pid_value, men selv med denne information lykkedes det ikke at konstruere fornuftige konstanter til PID controlleren.

De bedste resultater fik vi ved at placere vægt højt oppe på robotten, for at opnå samme effekt som når man balancerer med et kosteskaft i håndfladen.

//JACK

søndag den 21. september 2008

Legolab week 4.

Test af lydsensoren.

Dato: 21/9 2008

Forsøg:
Lydniveauer fra forskellige afstande og forskellige lyde.


Lydniveau målinger.
Vi har konstrueret et program der måler lyden og gemmer målingerne i en datafiler. Vi har så plottet datafilerne. Først har vi målt knips, klap og fløjten i en afstand af 30 cm., dernæst fra 1 m.




Målinger fra 1 meters afstand.


Da der er noget spændende støj på målingen af klappet, har vi lavet en ny måling fra en meter afstand hvor vi kun klapper 2 gange.

På målingen ses at der mellem klappene igen fremkommer støj med en lignende frekvens, for at finde ud af hvad baggrundsstøjen er har vi lavet en måling hvor der ikke blev larmet.



Det er tydeligt at der er en baggrundsstøj med en frekvens på ca. 3,2hz. Det er samme frekvens der er observeret i målingerne for klappene. Derfor skyldes de lydbølger, der er opfanget efter klappet ikke selve klappet, men at der er 3,2hz baggrundsstøj med maks værdi på 4-5.
Med baggrund i denne information kan man se at Jack stortset ikke kan skelne knips fra baggrundsstøjen. Derimod kan han tydeligt høre hvis man fløjter eller klapper. Selvom vi med 1 meter forsøgene var 3 gange længere væk end ved 30cm forsøgene så opfanger Jack stadig meget af lyden. Det vil derfor være svært for Jack at bruge lyden til at bedømme afstand til objekter.


Program der opfanger klap til at styre bilen.
For at vide mere om klaps natur har vi lavet en højopløst graf af et klap.

For at se hvad støjen ved tale er har vi snakket mens Jack lyttede på.

Ud fra graferne har vi valgt at implementere en klasse som kan kører i sin egen tråd og lytte efter klap, så vi kan styre Jack med klap for fremtiden.

Programmet ser således ud:

public class Clapclass extends Thread

{


private static SoundSensor ss = new SoundSensor(SensorPort.S2);

private static final int BACKGROUND_NOISE = 30;

private static final int CLAP_NOISE = 70;

private static final int CLAP_SPIKE_TIME = 25; //millisecond

private static final int CLAP_SUBSIDE_TIME = 125; //millisecond

private static final int WAITTIME = 5; //millisecond


private boolean running;

private int clapStartTime;

private boolean clapping;

private boolean newClap;


public Clapclass(){

running = true;

clapping = false;

newClap = false;

}


public void run(){

int prevSound = ss.readValue();


while(running){

int sound = ss.readValue();


if (!clapping){

clapStartTime = (int)System.currentTimeMillis();

clapping = true;

}else{

int clapTime = (int)System.currentTimeMillis();

if (clapTime <= (clapStartTime + CLAP_SPIKE_TIME) && sound >= CLAP_NOISE){

// Clap starting

clapTime += WAITTIME;

}else if ((clapStartTime + CLAP_SPIKE_TIME) <>

&& clapTime <= (clapStartTime + CLAP_SPIKE_TIME + CLAP_SUBSIDE_TIME)

&& sound <= prevSound){

// Clap subsiding

clapTime += WAITTIME;

if (sound <>

// Clap over

Sound.playTone(440, 1000);

newClap = true;

clapping = false;

}

}else{

// The clap didn't meet the criteria

clapping = false;

}

}

prevSound = sound;


try { Thread.sleep(WAITTIME); }

catch (InterruptedException _) {}

}

}


public boolean pollClap(){

if(newClap){

newClap = false;

return true;

}

return false;

}

}


Ud fra vores data har vi valgt at sige at et klap kan starte ved enhed 70, i stedet for højere. Vi har også valgt at sætte vores baggrundsstøj til 30, så vi kan tale i baggrunden, jvf tale diagrammet ovenfor. Dette har påvirket den tid det ta'r før klappet er 'ovre', dvs lydstyrken for klappet ikke kan kendes fra baggrundsstøjen, så denne er blevet reduceret.


Som noget fremtidigt skal klassen udvides til at gemme de sidste x antal klap og kunne genkende dobbeltklap, måske også huske en højeste lydstyrke, således at den kan bruges til at styre robotten. :)

torsdag den 11. september 2008

Legolab week 3

Den ultrasoniske sensor:

Egenskaber for sensoren:
Vi har lavet 2 forsøg for at finde den vinkel, sensoren kan se ud til siderne med.
De 2 forsøg er lavet med en plade der stod foran Jack, men forskudt til den venstre side, som første billede illustrerer. I andet forsøg er pladen vinklet iforhold til Jack, så ultralydsbølgerne lettere kan komme tilbage til modtageren. (Billede 2).

Forsøg 1.
Pladen er placeret så langt mod venstre, som det var muligt, således Jack stadig kunne se pladen. lyden må således forventes at være reflekteret på pladen ved det markerede sted (Lille pink streg).
Vinkel mellem Jacks ultralydssensor og pladen, blev målt til 23.5 grader.

Forsøg 2.
Dette forsøg minder om forsøg 1. Vi har her vinklet pladen så lydbølgerne får retning mod jack, når de rammer pladen. Ved dette setup, kan Jack opfange pladen når den står optil 30grader fra dens direkte synsfelt. Forklaringen på at dette hjælper , er at bølgerne, som kommer tilbage er meget svagere end dem der bliver sendt ud. Bølgernes styrke aftager ca. proportionalt med den afstand de sendes gennem luften.



Da lyd bevæger sig med ca. 340m/s i atmosfærisk luft, tager det ca 15ms for en lydbølge at bevæge sig frem og tilbage fra et objekt der er 2.5m væk. 2.5m er den afstand vi kan måle med den ultrasoniske sensor.
Antaget at man så tilføjer en sikkerhedsmargin på 5ms , så man ikke risikerer at objekter der er lidt over 2.5m væk forstyrrer ens målinger , skal man afsætte omkring 20ms til en sample. Det giver en sample frekvens på 50hz.


Trackeren:
Når Jack kører tracker programmet, forsøger han at opnå en afstand på 35 cm til det objekt han kan se. Ser han intet kører han bare ligeud indtil han ser et. Måden han forsøger at ramme de 35 cm er ved reactive control, dvs Jack bare reagerer ud fra hvor han ser væggen og hvor tæt på væggen han er. Jacks afstand fra hans mål, hans error, bruges til at beregne et gain, som multipliceret med error giver en hastigheds nedsættelse. Denne skal hvis den er kalibreret rigtig gøre at Jack ikke overskyder sit mål og ender med at oscillere omkring sit mål. Metoden er også kendt som proportional derivative (PD) control.
Vi har udvidet Jack med proportional integral derivative control, ved at bruge Motor klassen i stedet for MotorPort, da Motor bruger tachometeret til at se integrere over motorens rotation.
Som udgangspunkt oscillerer jack med ~1-2 centimeter omkring hans mål. Noget af denne oscillering skyldes at Jack er sat til at sove hver 300 msec, og noget af den skyldes at Jack faktisk ikke er programmeret til at stå stille hvis han opnår sit mål. Så noget af det første der skulle gøres ved Tracker klassen var at fjerne sleep, for at få målinger noget oftere. Dernæst satte vi Jack til at stoppe sine motore hvis hans error var 0.
Dette gjorde at vi kunne få Jack til at stoppe ved hans mål uden at pille ved gain.

tirsdag den 2. september 2008

Legolab week 2

Når Captain Jack bruger sin lyssensor med floodlight slået til, ser han hvor meget ting under ham reflekterer. Farverne sort og hvid fungere på den måde at de reflektere hhv. mindst og mest lys. Jack bruger så en tærskelværdi til at afgøre om han befinder sig på noget sort eller hvidt.

Vi har brugt standardværdien på 45, hvilket fungerede glimrende ved test. Hvis ikke den havde virket, så ville vi kunne finde det ved at tage de to ekstremer (helt hvid og helt sort) og vælge en tærskel midt mellem de to.

Farvetabel
Yellow 55%
Black 52%
Red 49%
Green 37%
Blue 32%
White 30%
Lyssensoren måler lysstyrke og ikke i farver, hvilket i tabellen kan ses da der næsten ikke kan skelnes mellem hvid, blå og grøn eller rød, sort og gul.

Hvis vi sætter lyssensoren til at måle på ambient light kan Captain Jack ikke længere følge en sort streg, da han måler baggrundslyset, så i et ekstremt case kan han dreje højre om sig selv hele dagen og venstre hele natten.

Med en linjetykkelse på cirka 2cm kunne Jack sagtens følge den rundt med sleep tid på 100 og naturligvis med en sleeptid på 10. Sætter vi Jack til at opdaterer hvert sekund havde den stakkels kaptajn nærmest ikke en chance for at opfatte linjen og der udbrød stor jubel da han en enkelt gang spottede den.
I et så simpelt program som giver det faktisk ikke mening at ha sat sleep værdien så højt da vi ikke skal bruge processortiden til andre ting, så en værdi på 100 eller 10 må siges at være bedre.

Ved at bruge de prædefinerede strenge til output, havde heapen hele tiden 52448 enheder fri. Men skiftede vi til at skrive strengene direkte til lcd displayet, kunne vi se hvordan heapen fik mindre og mindre fri plads i takt med at flere streng objekter blev oprettet pr. iteration. Til sidst måtte garbage collectoren sætte ind, så mængden af fri heap lå imellem ~52448 og ned til ~0.

It lives!

The monster has awakened...


Polly want's a cracker? Yarr... Captain Jack will bring Polly one.