søndag den 18. oktober 2009

Robot Race

Dato

9. Oktober 2009

Tidsforbrug

3 timer

Deltagende gruppemedlemmer

Martin Aksel Jensen, Kim Munk Petersen

Mål

  1. At bygge en robot der gennemfører banen hurtigst muligt.

Resultater

Initielle design

Opgaven gik ud på at lave en robot der hurtigst muligt gennemførte banen som beskrevet her. Som det ses er det ikke nok at lave en robot der følger banens sorte sti, den skal også være i stand til at følge den rigtige når stien deler sig eller den møder en tværgående sort stribe. Derudover skal den også være i stand til at opfange hvornår den har nået banens top og bund og reagere derudfra. Vi vurderede at den nemmeste løsning var at montere tre tætsiddende lyssensorer på robottens front således at den midterste generelt ville se den sorte streg mens de to yderste ville se banens hvide overflade. På den måde ville robotten slippe for at dreje fra side til side og "tælle" hvor mange streger lyssensoren passerede. Idet vi blot havde en enkelt NXT-lyssensor til rådighed, blev vi i stedet nødt til at anvende RXC-lyssensorerne. Efter nogle tests fandt vi ud af at de ikke var ligeså gode som NXT-lyssensoren idet de har en svagere LED (floodlight) og er meget forskellige mht. værdierne de måler. Vi prøvede at kompencere herfor ved at kalibrere dem enkeltvis, men måtte desværre opgive idet de ikke var i stand til at måle den rigtige farve stabilt nok. Der var ganske enkelt for lille margin mellem de målte værdier til at måle forskel på farverne. I stedet for at prøve at løse dette problem, besluttede vi os for at lave et alternativt design der ville øge chancen for at vi fik en virkende robot.


Alternativt design

Det alternative design gik ud på at lave robotten fjernstyret fra en computer via Bluetooth. Det kan diskuteres om denne løsning er "lovlig", men vi synes det var mere spændende at undersøge Bluetooth og de funktioner Lejos giver mht. afvikling af programmer på en computer i modsætning til på NXT-brick'en. I samme ombæring noterer vi at andre grupper hardcodede banen ind i deres robot, hvilket vi mener er mindst ligeså usportsligt. Efter vi havde fået programmet på computeren til at oprette forbindelse til NXT-brick'en og fik robotten til at reagere på tryk på computerens piltaster, testede vi robotten på gulvet i legolab. Det viste sig at den kunne styres i en afstand op til 20 meter hvilket var rigeligt til vores formål. Robotten var nem at fjernstyre på det flade gulv, men idet banen indeholder stejle ramper og har en glat overflade, var det næsten umuligt for os at styre robotten igennem banen. Fordi robotten lavede hjulspin når den kørte op ad bakke og til tider fik greb på et af hjulene på skift, kørte den ikke ligeud selvom hjulene roterede lige hurtigt. Vi måtte desværre sande at vi var for langsomme til at reagere når den pludseligt var på vej væk fra stien og at en automatiseret robot nok ville have klaret opgaven bedre. Efter nogle timers træning blev n´vi dog så øvede i at styre robotten så vi var i stand til at give robotten nok tilløb til at komme op af skråningerne at det lykkedes os at lave nogle gode omgangstider. For at forbedre tiden, implementerede vi en funktion således at vi ved at trykke på "space" på computeren fik robotten til at dreje 180 grader rundt så hurtigt som muligt, hvilket gjorde at den var i stand til at vende hurtigt når den nåede toppen af banen. Vores omgangstider lå til sidst stabilt på 22-24 sekunder, mens den hurtigste tid vi målte var 21.5 sek. Vi har desværre ikke nogen video der demonstrerer dette, men der er mange vidner idet de andre hold var meget fascinerede over vores løsning idet vores robot, i modsætning til de fleste andre, var i stand til at klare banen, men også pga. de vanskeligheder vi havde med at styre robotten præcist.

Konklusion

Konklusionen er at det lykkedes os at lave en robot der kunne gennemføre banen. I stedet for at bruge en masse tid på lyssensorer, som vi har gjort ved andre øvelser med stor succes, brugte vi i stedet tiden på at udforske de muligheder Bluetooth giver. Den hurtigste tid vores robot klarede banen på var 21.5 sek. hvilket vi er ganske tilfredse med.

torsdag den 8. oktober 2009

Øvelse 5: Light Sensor Calibration

Dato

2. Oktober 2009

Tidsforbrug

3 timer

Deltagende gruppemedlemmer

Martin Aksel Jensen, Kim Munk Petersen

Mål

  1. Kalibrere lyssensoren så den kan detektere 3 forskellige farver: sort, grøn og hvid.
  2. Bruge lyssensoren til at bygge en line-follower som standser i et grønt felt.

Resultater

Black-White sensor

Vi startede med at genskabe vores line-follower-robot fra øvelse 1. Herefter testede vi BlackWhiteSensor.java som er givet i opgavebeskrivelsen. Vores testprogram skrev på NXT-brick'ens LCD hvilken farve lyssensoren registrerede. Herunder ses den vigtige del af vores test-program:

         while (! Button.ESCAPE.isPressed()) {

             LCD.drawInt(bwSensor.light(),4,10,2);
             LCD.refresh();
             
             if ( bwSensor.black() )
                 LCD.drawString("Black",4,3);  
             else
                 LCD.drawString("White",4,3);
             
             Thread.sleep(10);
         }

Efter at have konkluderet at BlackWhiteSensor.java fungerede efter hensigten, testede vi en version af line-followeren, også givet i opgaven, der brugte denne sort-hvid sensor. Resultatet var at robotten fint var i stand til at følge den sorte streg på det hvide underlag.

Sort-hvid sensoren virker ved at man kaliberer sensoren, eller nærmere programmet, til en værdi for sort og en værdi for hvid. Programmet laver herefter en threshold værdi som er medianen af de to målinger. Lysværdier under denne grænse tolkes som sorte og værdier over denne grænse tolkes som hvide.

Black-White-Green sensor

Svarende til Black-White sensoren, lavede vi en klasse som skal kaliberes med 3 målinger, en for sort, en for grøn og en for hvid. Herefter opdeler vi lyssensorens måleområde i 3 intervaller, et for hver farve. Denne gøres ved at opstille to tresholds, ét mellem sort og grønt og ét mellem grønt og hvidt. Grunden til denne fordeling er at lysmålinger for grøn klart nok ligger mellem lysmålinger for sort og hvid. De to tresholds blev beregnet på følgende måde:

// The threshold is calculated as a weighted average
blackGreenThreshold = (int)((blackLightValue+greenLightValue*weight)/3f);
greenWhiteThreshold = (int)((greenLightValue+whiteLightValue*weight)/3f);

Vi testede denne black-white-green lyssensor ved at lave et testprogram der på NXT-brick'ens LCD udskrev den aktuelt registrerede farve. Herefter udvidede vi Line-follower-programmet således at robotten stoppede når lyssensoren registrerede farven grøn.

LEGO model


søndag den 27. september 2009

Øvelse 4: Balancer

Dato

25. September 2009

Tidsforbrug

3 timer

Deltagende gruppemedlemmer

Martin Aksel Jensen, Kim Munk Petersen

Mål

  1. Bygge en robot der kan balancere på to hjul så den ikke vælter
  2. Få erfaring med PID-controllere og justering heraf

Resultater

Vi startede med at bygge vores robot magen til Philippe Hurbain's NXTway[1]. Herefter hentede vi source-koden til en lignende NXT-robot, via et link givet i opgavebeskrivelsen. Efter at have flashet vores robot med denne dette program, testede vi hvor godt den virkede. Programmet virker sådan at robottens setpoint sættes når man trykker på Enter-knappen efter opstart. Det medfører at robotten skal stå i balance-punktet når man trykker Enter. Efter store vanskeligheder med at ramme balancepunktet præcist, ændrede vi programmet således at vi vha. Right- og Left-tasterne på NXT-brick'en, kunne justere setpoint'et mens programmet kørte. Herefter lykkedes det os at få robotten til at stå i 2-3 sekunder inden den væltede. Den virkede meget urolig, som om den ikke ville holde stille selvom den var i balance. Årsagen hertil var at programmet som minimum gav 55% kraft på de to motorer. Ifølge en test vi lavede, skulle der 35% til før robotten var på grænsen til at bevæge sig. Vi ændrede derfor i programmet således at det som minimum gav 35% kraft i stedet for 55%. Dette gjorde robotten mere rolig, men desværre lidt for rolig idet dens PID-controller var justeret efter et minimum på 55%. Vi rettede derfor PID-controllerens skalering således at den gav 100% kraft til motorerne når robotten var så tæt på at vælte at vi mente det var nødvendigt med 100% for at undgå at vælte. Herefter var robotten i stand til at stå oprejst i 4 sekunder uden hjælp.


Ved at analysere robottens reaktion mht. overshoot, oscillation, offset osv. prøvede vi at lave justeringer på PID-controlleren så dens balanceevne burde forbedres. Det lykkedes til dels, men efter omkring 6 sekunder væltede robotten fordi den ikke kunne nå at reagere på et udsving. Lige meget hvordan vi ændrede PID-controlleren lykkedes det os ikke at rette denne fejl. Vi besluttede derfor at ændre robottens fysiske design en smule for at gøre den mere stabil. Ved at flytte NXT-brick'en længere ned gav vi robotten et lavere tyngdepunkt der i teorien skulle gøre det nemmere for den at korrigere udsving. Det havde desværre ikke den store effekt i praksis.


Efter at have prøvet forskellige justeringer af PID-controlleren, blev vi nødt til at sande at det ikke var muligt for os at få den til at holde balancen på egen hånd i længere tid. Vi mistænker lyssensoren for at være hovedårsagen til at robotten vælter. Vi har nogle idéer til forbedringer af robotten. På software-siden har vi bl.a. overvejet at gøre den proportionelle del af controlleren eksponentiel mens vi på hardware-siden har overvejet at prøve LEGO's UltraSonic Sensor til at måle afstanden til underlaget. Disse forslag har vi ikke prøvet at realisere endnu, men vil måske gøre det på et senere tidspunkt.

LEGO model

Her ses Philippe Hurbain's NXTway som er magen til vores robot.

Referencer

  • [1], Philippe Hurbain, NXTway

torsdag den 24. september 2009

Øvelse 3: Sound Sensor, Sound Controlled Car og Clap Controlled Car

Dato

18. September 2009

Tidsforbrug

3 timer

Deltagende gruppemedlemmer

Martin Aksel Jensen, Kim Munk Petersen

Mål

  1. Undersøge NXT Sound sensor (mikrofon)
  2. Bruge DataLogger-klassen til at gemme målinger til fil som overføres og analyseres på PC
  3. Bygge en robot der reagerer kinematisk på lyde
  4. Modificere robotten så den kun reagerer på klap-lyde

Resultater

Indledende test af lyd-sensoren

Efter at have monteret lyd-sensoren på vores LEGO 9797 robot, lavede vi et simpelt program til at teste lyd-sensoren. Programmet måler hele tiden det aktuelle lydniveau og skriver dette på LCD-displayet. Derudover skriver det den højst målte amplitude siden programmet blev startet, samt en "lokal" højst målt amplitude der nulstilles efter et bestemt stykke tid (1 sek. pr. default). Begge amplituder skrives på LCD-skærmen og idet lyde som fx klap er meget korte, brugte vi sidstnævnte til at se den maksimale amplitude for den foregående lyd.
Koden til programmet er vist herunder:

import lejos.nxt.*;
/**
 * Simple test program for the NXT Sound Sensor (microphone)
 * @author  Martin Aksel Jensen & Kim Munk Petersen
 */
public class SoundSensorTest 
{
    public static void main(String [] args)    throws Exception 
    {
        SoundSensor soundSensor = new SoundSensor(SensorPort.S1);
        long timeSet = 0;
        int soundValue = 0;
        int globalMax = 0;
        int localMax = 0;
        final int localHoldTime = 1000; // Time before local max is reset to 0

        LCD.drawString("Sound (%)  ", 0, 0);
        LCD.drawString("Local Max  ",0,1);
        LCD.drawString("Global Max ",0,2);

        while (! Button.ESCAPE.isPressed())
        {
            soundValue = soundSensor.readValue();
            LCD.drawInt(soundValue, 3, 13, 0);
            
            // Hold time elapsed, reset local max sound value
            if(System.currentTimeMillis() - timeSet > localHoldTime) {
                localMax = 0;
                LCD.drawInt(localMax, 3, 13, 1);
                timeSet = Long.MAX_VALUE;
            }
            // Set new local max sound value
            if(soundValue > localMax) {
                localMax = soundValue;
                LCD.drawInt(localMax, 3, 13, 1);
                timeSet = System.currentTimeMillis();
            }
            // Set new global max sound value
            if(soundValue > globalMax) {
                globalMax = soundValue;
                LCD.drawInt(globalMax, 3, 13, 2);
            }
        }
        LCD.clear();
        LCD.drawString("Program stopped", 0, 0);
        Thread.sleep(1000);
    }
}

I skemaet herunder er resultatet af vores målinger med ovenstående program.
Lyd
Afstand (cm)
Lyd (%)
Almen støj
N/A
3-10
Tale
10
85-95
Tale
50
20-35
Tale
100
10-20
Tale
200
4-16
Klap
10
93
Klap
50
70.90
Klap
100
50-75
Klap
200
20-45


Robot-test 1: "Sound Controlled Car"

Vi lage programmet SoundCtrCar.java (givet i opgavebeskrivelsen) over på robotten.Programmet giver robotten 5 tilstande: forward, right, left og stop som angiver om den skal køre, og i givet fald i hvilken retning. Når lyd-sensoren opfanger en høj lyd - amplitude over 50% - skifer robotten til næste tilstand. Det er således en sequential strategy[1].

Som forklaret i opgavebeskrivelsen er der et problem mht. registrering af tryk på Escape-knappen. Vi forsøgte at løse dette problem på en elegant måde vha. flere tråde. Først lavede vi en ButtonListener som asynkront lytter efter tastetryk. Når der registeres et tryk på Escape-knappen sættes en delt boolean ved navn terminate der indikerer at programmet skal lukkes. terminate bliver sat til true i buttonListener'en. Når tråden der kører selve programmet registrerer dette, lukker programmet. Noget der snød os var at tråd-metoden join() ifølge lejos dokumentationen ikke er implementeret, men det er den! Vi har testet og konkluderet at den virker efter hensigten.

Robot-test 2: "Clap Controlled Car"

For at kunne skelne klap-lyde fra andre lyde, brugte vi DataLoggeren givet i opgaven til at logge en lydmålinge ved klap-lyde. Grafen herunder viser denne lydmåling.


Det første lyd-udsving skyldes "bib"-lyden der kom fra NXT-brick'en da vi trykkede på Enter-knapper for at starte programmet og de 3 næste er klap-lyde. Det ses at de tre klap-lyde er meget ens, både i amplitude og varighed.

På grafen herunder har vi zoomet ind på det midterste klap for at kunne analysere det nærmere.


Ifølge Sivan Toledo [2], kan et klap genkendes vha. følgende "mønster":
A clap is a pattern that starts with a low-amplitude sample (say below 50), followed by a very-high amplitude sample (say above 85) within 25 milliseconds, and then returns back to low (below 50) within another 250 milliseconds.
Dette mønster passer fint med vores målinger. Det er dog noget mere restriktivt hvilket tillader mere omgivende støj og gør at klap kan registreres på længere afstand end ved vores målinger.
Vores implementering af ovenstående mønster til at detektere klap-lyde ses herunder:
private static  void waitForClap() throws Exception
    {
        Thread.sleep(500);

        int state = 0;
        int soundValue;
        long starttime = System.currentTimeMillis();
        long timestamp;

        while(true) {
            if(terminate) // break out if terminate flag is set
                break;
            
            soundValue = sound.readValue(); // read current sound value from sensor
            timestamp = System.currentTimeMillis() - starttime;
            
            if(state == 0 && soundValue < 50) // in start state, wait until sound < 50%
                state = 1;
            else if(state == 1) { // if sound > 85 within 25ms, go to next state, else reset (go to state 0)
                if(timestamp > 25) {
                    state = 0;
                    starttime = System.currentTimeMillis();
                }
                else if(soundValue > 85)
                    state = 2;
            }
            else if(state == 2) { // if sound < 50 within 250ms, break out to indicate clap, else reset
                if(timestamp > 275) { // 25 + 250
                    state = 0;
                    starttime = System.currentTimeMillis();
                }
                else if(soundValue < 50)
                    break;
            }
        }
    }

LEGO model

Herunder er et billede af vores LEGO-model (Clap detector).


Referencer

torsdag den 17. september 2009

Øvelse 2: Afstandsmåler og WallFollower

Dato

11. September 2009

Tidsforbrug

3 timer

Deltagende gruppemedlemmer

Martin Aksel Jensen, Kim Munk Petersen

Mål

  1. Undersøge NXT UltraSonic sensor (afstandsmåler)
  2. Bygge en "Wall Follower" der gør brug af afstandsmåleren


Resultater

Indledende test af afstandsmåleren

Efter at have sluttet afstandsmåleren til NXT-brick'en, afviklede vi programmet "SonicSensorTest.java" (givet i opgavebeskrivelsen). Afstandsmåleren var i stand til at nøjagtigt måle afstanden til både små og store objekter, uanset materiale.
Ifølge dokumentationen udbredes ultralyden med en vinkel på ca. 30 grader hvilket vi verificerede passer med virkeligheden.
Den mindste afstand vi kunne måle vha. afstandsmåleren var 4cm. Dette gjorde vi ved at placere afstandsmåleren 0,5cm fra en vinkelret, plan overflade. Det tyder altså på at afstandsmåleren ikke er korrekt kalibreret ved små afstande. Ifølge lejos-dokumentationen virker setCalibrationData-metoden ikke, så det er ikke muligt for os at kalibrere den.


Idet lyd udbredes med hastigheden 340.29m/s, tilbagelægger det 255cm på ca. 0,0075sek = 7,5ms. Idet lyden både skal sendes ud og reflekteres tilbage igen, tager det ca. 15ms (2 x 7,5ms) fra lyden sendes til ekkoet opfanges. Vores målinger viste at det var nødvendigt at vente ca. 20ms mellem hver måling for at målingen altid var korrekt. Ved lavere ventetider kunne afstandsmåleren maksimalt måle en afstand på 188cm. Denne opførsel gentog sig selv uden nogen ventetid overhovedet.
Afstandsmåleren kører som default i Continous mode hvilket betyder at den med et bestemt (dog ukendt) interval, sender et såkaldt "ping", altså en kort lyd. Hvis der kommer et ekko tilbage inden 15ms, sættes afstandsmålerens register til den tilsvarende afstand, ellers 255. Noget kunne tyde på at dette register bliver clearet når man læser fra det, idet vi ellers ikke kan forklare hvorfor man skal vente de føromtalte ca. 20ms. Ventetiden medfører klart nok at man højst kan sample 50 gange pr. sekund, men dette burde også være nok i de fleste tilfælde, så vi mener ikke har nogen betydning i praksis.

Robot-test 1: "Tracker"

For at teste afstandsmåleren på en robot, installerede vi afstandsmåleren på vores LineFollower-robot fra forrige uges øvelse. Efter at have uploaded "Tracker.java" og hjælpeklassen "Car.java" (begge givet i opgavebeskrivelsen) til robotten, betragtede vi dens opførsel. Programmet får robotten til at holde en bestemt frontal afstand, 35cm, til det nærmeste detekterede objekt. Robotten sammenligner hele tiden den aktuelle afstand med den ønskede afstand. Jo tættere den kommer på den ønskede afstand, jo langsommere bevæger den sig derhen imod. Denne form for control kaldes proportional-only Idet motorerne kræver en vis mængde "power" for at kunne køre, er der en grænse for hvor lidt power de må få. Denne grænse gør at robotten aldrig holder stille, men bevæger sig så dens afstandsmåling oscillerer omkring den ønskede værdi.

Robot-test 2: "Wall Follower"

Vi oversatte Philippe Hurbain's program fra NQC til Java og rettede det til således at det kunne bruges på NXT'en. Ved at placere afstandsmåleren på samme måde som på Philippe Hurbain's robot, lykkedes det os at få vores robot til at følge en væg.

Idet vi blot har oversat NCQ-algoritmen til Java, "wiggler" vores robot meget idet den ene motor slukkes helt når den drejer. Det er nødvendigt at vores robotter drejer meget til hver side for at undgå at køre frontalt ind i en mur ved højresving. Dette skyldes at afstandsmåleren sidder så langt tilbage at den ikke kan se fronten af robotten.

LEGO model

Herunder er et billede af vores LEGO-model (Wall Follower).

torsdag den 10. september 2009

Øvelse 1: LineFollower

Dato

4. September 2009

Tidsforbrug

3 timer

Deltagende gruppemedlemmer

Martin Aksel Jensen, Kim Munk Petersen

Mål

  1. Bygge en LEGO bil der følger en sort sti på en hvid overflade.
  2. Flashe NXT'en via USB eller Bluetooth
  3. Eksperimentere med lys-sensoren
  4. Eksperimentere med forskellige sample-intervaller
  5. Undersøge leJOS' garbage collector


Resultater

Lyssensor

Farve Med floodlight Uden floodlight
Hvid 62 53
Sort 38 34
Rød 59 52
Orange 60 53
Gul 60 53
Grøn 56 51
Blå 49 48
Lilla 53 51

Sample-interval

Vi prøvede at ændre sample intervallet og undersøgte hvordan det påvirkede robottens evne til at følge linjen. Herunder er en tabel der viser tiden det tog robotten at følge banen.
Interval (ms) Brugt tid (min)
10 1:52
100 1:50
200 1:52
500 Fejlede


Ved 500ms og derover kunne robotten ikke følge linjen fordi den "forbindelsen" til stien. Det ses at der ikke var den store forskel på tiderne 10, 100 og 200ms. Det var tydeligt at den lavede større udsving ved de høje intervaller, men til gengæld kørte den længere inden den drejede.


Garbage collection

Vi prøvede at allokere nye strenge hver gang vi skrev til displayet. For at undersøge hvordan garbage collectoren virker, brugte vi Datalogger-klassen til at opsamle målinger. Begge grafer viser et tidsinterval på ca. 5 sek. På første graf herunder ses det at garbage collectoren til syneladende først kører når der ikke er mere ledig hukommelse, og altså ikke med et bestemt tidsinterval.



Anden graf viser mindre hyppige allokeringer af tekststrenge, og at garbage collectoren ikke træder til i tidsrummet. Det viser at det ikke blot var et tilfælde at garbage collectoren blev kørt når der ikke var mere ledig hukommelse i første test.



Ud fra vores test kan man se at det er en dårlig idé at unødigt allokere nye strenge da hukommelsen herved fyldes op med forældede strenge. I og med at garbage collectoren først træder til når der er brug for den, kan det give problemer når man foretager allokeringer eller procedurekald på baggrund af den ledige hukommelse (defensive programming).

LEGO model

Manglende brikker foresagede at det var nødvendigt med nogle ændringer til det originale lego-robot design. Baghjulet som skulle kunne rotere om sig selv for at robotten skulle kunne vrikke sig afsted, kunne ikke side som oprindeligt tiltænk. Vi lavede en modificering på robotten så hjulet kunne dreje om sig igen, men gjorde den muligvis lidt mere ustabil og mere modtagelig for fejl ved større sving. Den kørte dog testbanen med tape-striben fint igennem.


Herunder er et billede af vores LEGO-model.