torsdag den 7. oktober 2010

Lab Session 5

Black White Detection

Vi startede ud med at bygge robotten fra første lab session og montere lyssensoren som anvist i instruktionerne. Herefter satte vi os ind i funktionalitet af BlackWhiteSensor klassen og gav os derefter til at skrive en ny klasse som anvendte denne.

Vores klasse er relativt simpel og indeholder et loop, som anvender busy-wait til konstant at checke hvorvidt venstre eller højre knap på NXT enheden bliver trykket på. Hvis dette er tilfældet, så foretager vi en måling, viser værdien og hvorvidt det er en sort/mørk farve eller en hvid/lys farve.

Indmaden i control-loopet ser således ud:

boolean left = waitForLeftRight();

if (left)
{
LCD.clear();
LCD.drawString("The color is", 0, 0);
LCD.drawString("black: "+ blackWhiteSensor.black(), 0, 1);

LCD.drawString("Threshold="+blackWhiteSensor.getThreshold(), 0, 3);
LCD.drawString("Light value="+blackWhiteSensor.light(), 0, 4);
Thread.sleep(5000);
}
else
{
LCD.clear();
LCD.drawString("The color is", 0, 0);
LCD.drawString("white: "+ blackWhiteSensor.white(), 0, 1);

LCD.drawString("Threshold=" + blackWhiteSensor.getThreshold(), 0, 3);
LCD.drawString("Light value="+blackWhiteSensor.light(), 0, 4);
Thread.sleep(5000);
}



Line Follower with Calibration

I denne opgave anvendte vi de to klasser LineFollowerCal og Car sammen med BlackWhiteSensor klassen fra første opgave. Vores afprøvning af disse fungerede helt som forventet, og vores robot fik tilført power til enten venstre eller højre motor alt afhængigt af, om lyssensoren detekterede en mørk eller lys farve.



ColorSensor with Calibration

Her lod vi os inspirere af BlackWhiteSensor klassen fra de forrige to opgaver og udvidede blot denne for også at kunne detektere en blå farve, da en sådan farve var tilstede på testbanen.

Vi tilføjede følgende metode blue til vores nye ThreeColorSensor klasse og tilføjede også et par nye fields, som skulle bruges i forbindelse med black/blue og blue/white threshold. Vores test klasse implementerede vi i meget samme stil som i forrige opgave, hvor vi testede BlackWhiteSensor klassen. På denne måde var vi i stand til at detektere både hvid, sort og blå farve på NXT enheden.

public boolean blue()
{
int value = ls.readValue();
return (value > blackBlueThreshold && value <>
}

Vi valgte ikke at detektere grøn farve, som der bliver lagt op til i opgaven, da "goal" zonen på testbanen er blå :)



Line Follower that stops in a Goal Zone

I denne sidste opgave, hvor vi skulle anvende vores ThreeColorSensor, forsøgte vi først naivt blot at tilføje en case til LineFollowerCal klassen, sådan at vores robot ville stoppe, hvis lyssensoren målte en værdi, som repræsenterede en blå farve, jvf. nedenstående kode:

if (sensor.black())
Car.forward(power, 0);
else if (sensor.white())
Car.forward(0, power);
else
{
Car.stop();
Sound.beepSequenceUp();
}

Dette virkede dog ikke efter hensigten, da det gik op for os, at lyssensoren kommer ind i "else" casen, når farven skifter mellem sort og hvid, så her stoppede robotten næsten med det samme under vores test.

Vi huskede Ole's vise ord og tilføjede en ekstra lyssensor til vores robot, som kun skulle bruges til at detektere blå farve. For at dette skulle virke, måtte vi være sikre på, at den ekstra lyssensor under kørslen kun detekterer den samme farve (vi har monteret sensoren, så den kun ser hvid), for ellers ville vi havne i samme situation som før. Vi ændrede vores ThreeColorSensor klasse til at tage to sensorer i konstruktøren og ændre control-loopet til følgende:

public ThreeColorSensor(SensorPort blackWhite, SensorPort blue)
{
ls = new LightSensor(blackWhite);
blueSensor = new RCXLightSensor(blue);
// Use the light sensor as a reflection sensor
ls.setFloodlight(true);
blueSensor.setFloodlight(true);
}

while (! Button.ESCAPE.isPressed())
{
LCD.drawInt(sensor.light(),4,10,2);
LCD.refresh();
if (sensor.blue()) //Uses sensorport S1
{
Car.stop();
Sound.beepSequenceUp(); //WEEE!
Thread.sleep(1000);
break;
}
else if (sensor.black()) //Uses sensorport S4
Car.forward(power, 0);
else if (sensor.white()) //Uses sensorport S4
Car.forward(0, power);
else
{
//We should not end up here, but just to be safe!
Car.stop();
break;
}
Thread.sleep(10);
}

Desuden tilføjede vi et par threshold metoder, som vi brugte til at
detektere, hvorvidt robottens lyssensor målte en sort, hvid eller blå farve:


public boolean black()
{
return (ls.readValue() < blackWhiteThreshold);
}
public boolean white()
{
return (ls.readValue() > blackWhiteThreshold);
}
public boolean blue()
{
return (blueSensor.readValue() < blueWhiteThreshold);
}


Vi havde dog problemer med at få robotten til at opføre sig som forventet, da RCX sensoren tilsyneladende har en meget lav granularitet. Den læste 22 ved detektering af en blå farve og 28 ved hvid - ikke den store forskel! Dette havde den uheldige effekt, at de beskidte dele af banen blev fortolket som blå med RCX sensoren, og derfor stoppede robotten hurtigt. Vi er dog rimelig sikre på, at robotten ville opføre sig korrekt med to NXT sensorer, da disse havde større granularitet i målingerne. F.eks. målte denne lyssensor følgende værdier:

32 = black
40 = blue
54 = white

onsdag den 6. oktober 2010

Lab Session 4

Balancing Robot:

Vi anvendte Nathanael Wilson's samlevejledning til at bygge robotten. Derefter overførte vi i første omgang Sejway.java programmet uden at ændre på konstanterne i koden. Det virkede ikke så godt. Den kunne ikke holde balancen i meget mere en et enkelt sekund.

Vi prøvede så at ændre int konstanterne til de double værdier, som er angivet af Ole's kommentarer i noten om Sejway programmet og fjerne brugen af SCALE konstanten. Dette ændrede dog ikke noget særligt ved robottens adfærd.

Vi har forsøgt at få robotten til at balancere på gulvet (mørkeblå), et stykke hvidt papir og på bordet. Men ingen af stederne kan den holde balancen uanset hvilke små justeringer vi laver ved robottens hældning ved kalibreringen i starten af programmet.

Det virker som om, at robotten fint står og justerer sin balance i 1-2 sekunder, men herefter kører hjulene kun i én retning, enten forlæns eller baglæns afhængigt af den indledende kalibrering, og mister derfor balancen.

Vi har forsøgt at korrigere lidt ved primært den proportionelle konstant KP i programmet, men en forøgelse af denne konstant havde ikke nogen synlig effekt.

I noten står der, at en forudsætning for at robotten kan balancere er at batterierne er fuldt opladte, men resultatet var det samme med fuldt opladte batterier.

mandag den 4. oktober 2010

Lab Session 3

Test of the Sound Sensor

Til den første opgave skulle vi montere lydsensoren på vores sædvanlige robot. I første omgang læste vi ikke opgaven på ugesedlen grundigt nok, så vi antog at linket til SonicSensorTest.java var det program, som vi skulle bruge. Efter lidt forvirring indså vi dog hurtigt at programmet var det samme program som ved lab session 2, og at opgaven i stedet bad os om selv at tilrette programmet til at anvende lydsensoren. Dette var hurtigt gjort (skifte fra at bruge UltrasonicSensor klassen til SoundSensor klassen). Ved at lave forskellige lyde i form af klap og råb under kørsel af programmet, så kunne vi aflæse forskellige sample værdier på displayet som forventet.

Data logger

De to udleverede programmer, DataLogger.java og SoundSampling.java, blev benyttet til en simpel indsamling af data fra lydsensorens målte værdier. Ved at anvende "nxjbrowse" kunne vi hente de loggede data ned som en .txt fil. Nedenfor følger uddrag af denne fil:

"86,87,87,88,89,89,90,91,91,92,92,93,93,92,88,80,76,68,62,55,
52,47,44,40,36,32,30,28,26,24,22,20,19,17,17,15,13,12,12,11,
10,10,9,8,8,8,8,8,7,6,6,6,6,5,5,5,4,4,4,4,
4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, [...]"

Vi kunne ikke umiddelbart finde et program til plotning af disse data på en graf...

Sound Controlled Car

Udførslen af de to programmer, SoundCtrCar.java og Car.java, viste at vi kunne få robotten til at skifte mellem at køre fremad, til højre, til venstre og til sidst stoppe helt, hvorefter den igen kørte fremad. Skiftene mellem disse skete hver gang vi foretog en lyd (f.eks. klap), som var højt nok. Af koden kan det ses hvordan programmet virker. Den primære part af programmet er denne while løkke: 

while (! Button.ESCAPE.isPressed())
{
   waitForLoudSound();            
   LCD.drawString("Forward ",0,1);
   Car.forward(100, 100);
      
   waitForLoudSound();            
   LCD.drawString("Right ",0,1);
   Car.forward(100, 0);
      
   waitForLoudSound();            
   LCD.drawString("Left ",0,1);
   Car.forward(0, 100);
      
   waitForLoudSound();            
   LCD.drawString("Stop ",0,1); 
   Car.stop();
}

Programmet indeholder desuden en variabel, "soundThreshold", som er sat til 90. Denne bruges i waitForLoudSound, så den busy-waiter så længe lydsensoren ikke har aflæst en lyd med værdi større end 90.

En ulempe ved programmet er at den eneste måde at få programmet til at stoppe er ved at man skal holde ESCAPE knappen nede i den sidste del af while-løkken. Dette kunne vi gøre smartere ved at tilføje en ButtonListener, som lyttede på et ESCAPE.isPressed event ved at "override" buttonPressed metoden.

Clap Controlled Car

Til denne opgave modificerede vi programmet fra første delopgave, så vi i programmet anvender en liste, hvor vi ved hver sampling tilføjer den målte værdi til listen. For at listen ikke bliver enorm, så sørger vi for at kun gemme de seneste 56 sample værdier i denne liste således at vi jvf. Sivan Toledo's definition på klap-detektion har lige præcis nok målinger til at vi kan detektere et klap.
Uddrag af koden fra vores ClapDetector.java klasse:
static List<Integer> data = new ArrayList<Integer>();

private static boolean detectClap()
{
   if (data.get(0) < 50)
   {
      for (int i = 1; i < 6; i++)
      {
         if (data.get(i) > 85)
  {
            for (int j = i+1; j < i+51; j++)
     {
        if (data.get(j) < 50) return true;
     }
         }
      }
   }
   return false;
}

Algoritmen virker OK til at detektere klap, men det er dog også forholdvis let at "snyde" den ved at lave andre høje og korte lyde. Man skal desuden klappe helt tæt på sensoren før den reagerer på klappet (Men det er sandsynligvis sensorens skyld).