torsdag den 28. juni 2012

Slutprojekt, konklusion


Status for projektet

Hvad var planen

Vores projekt gik ud på at lave flere robotter, der samarbejdede om at tømme en mine for guld. Minen skulle bestå af en række tiles med forskellige typer. Et tile kunne således være et vejkryds (intersection), en hule med guld (hule) eller en garage (feltet hvor robotterne starter). For at gøre projektet interaktivt planlagde vi, at det skulle være muligt for publikum at placere forhindringer i form af mure rundt omkring i minen. Disse skulle simulere uforudsete begivenheder i form af stenskred, og det samlede system skulle håndtere dette dynamiske element. Vi planlagde at lave tre robotter.
  1. En ‘seeker’ hvis job det var at køre ud i minen og kortlægge, hvordan minen ser ud. Seekeren er den første robot der agerer og det er udfra den viden den indsamler, at de andre robotter udfører deres opgaver.
  2. En ‘miner’ der skulle køre ud til de huler seekeren fandt og hente guldet i dem. Planen var at lave en fysisk repræsentation af guldet som Mineren kunne finde og samle op med en klo.
  3. En ‘demolisher’ hvis job det var at fjerne de mure publikum placerede i minen, således at de andre robotter uhindret kunne udføre deres jobs.
De tre robotter skulle styres af en central computer (Hivemind), der sørgede for at holde styr på repræsentationen af minen samt de tre robotters placering. Hivemind’en skulle uddelegere opgaver til robotterne, gennem specialiserede klasser på computeren (Minds), der hver repræsenterede deres egen robot (f.eks Seeker-mind). 



Den første ide til hvordan en bane kunne se ud.



Hvad der mangler

Selvom vi nåede langt i forhold til den oprindelige plan, er der en række funktionaliteter, vi ikke nåede at implementere. Der findes således ikke nogen Demolisher, og det er ikke muligt for publikum at placere mure i banen. Der findes heller ikke nogen fysisk repræsentation af guldet og Mineren samler således ikke noget op, når den kører ind i en hule.
Derudover mangler vi mulighed for, at mere end én robot kan bevæge sig rundt i banen på samme tid.

Hvad har vi nu

Vi har pt. to robotter samt et PC-program (Hivemind), der opretholder en repræsentation af banen robotterne kører rundt i og give instruktioner til de to robotter, gennem deres Mind klasser. Robotterne registrerer farver foran sig og sender signaler tilbage der tolkes på computer siden. Derefter modtager den simple instruktioner fra sin Mind klasse (kør frem, drej til højre, drej rundt etc.). Som udgangspunkt følger robotterne sorte kanter rundt i minen. Vejkryds, miner, samt enden på en sort kant repræsenteres af hhv. rød, blå og grøn. Ved hjælp af en rød/blå/grøn sensor kan robotten se hvad den er kommet til og sende signaler om dette til computeren. 

Minen som den kom til at se ud (i den sidste implementation er der også en type af   tiles der repræsenterer en garage - det fik vi desværre ikke foto-dokumenteret).
De to robotter vi har udviklet er hhv. ‘seeker’ robotten og ‘miner’ robotten som beskrevet ovenfor. For at undgå concurrency problemer er der kun én af de to robotter i banen ad gangen. Seekeren kører rundt i hele banen og registrerer hvad den ser. På baggrund af dette kortlægger computeren hvordan den ser ud. Derefter kører Mineren ind i banen og besøger alle huler.
For at gøre det muligt for tilskuere at se, hvad der foregår, valgte vi at opbygge en visuel repræsentation af banen, der vises på computeren mens robotterne arbejder. Dette var ikke en del af den oprindelige plan, men uden denne GUI, havde det været nærmest umuligt for tilskuerne at forstå hvad der foregik. Yderligere viste det sig at være en god resurse til debugging. Vores GUI optegner løbende det Seekeren opdager og når Mineren bagefter kører rundt markeres de besøgte huler med en lysere blå farve, for at illustrere at disse nu er ‘udminet’. 
Vores GUI efter seekeren har kortlagt minen. Mørkegrå felter er garager og blå felter er miner. Den lyserøde ‘pil’ repræsenterer robottens position og retning. De grønne streger der fører væk fra kortet betyder at minen slutter her. Vejene er lyseblå når de ikke er blevet undersøgt endnu.
  
Vores Hivemind opbygger repræsentationer af alle felter i minen (deres type og koordinater) samt alle veje til og fra felterne og disse vejes status (uopdaget, fri, fører til enden af minen). Vi benytter en dybde først søgning og en simpel brute-force korteste vej algoritme til at guide seeker-robotten rundt og opdage minen. Samme korteste-vej algoritme benyttes efterfølgende til at lede mine-robotten den hurtigste vej fra hule til hule.

Herunder kan ses en video af, hvordan det endelige system kører.


Videre arbejde

Herunder beskrives en række interessante muligheder for hvordan der kan arbejdes videre med projektet.

Mure og demolisher-robot

En interessant opgave ville være, at tilføje dynamik i banen. Dette kunne gøres ved at lade tilskuere placere mure i banen som robotterne skal reagere på. Dette vil give den interessante udfordring, at Hivemind’en skal kunne håndtere en dynamisk verden. Samtidig ville det give projektet bruger interaktion, ved at give brugerne mulighed for at placere mure i verdenen.
For at håndtere disse mure ville vi implementere en robot hvis eneste funktion ville være, at fjerne disse mure fra banen.
For at dette kunne lade sig gøre, skal alle robotterne udstyres med en ultralydssensor, så de kan “se” murene og de skal opdateres med muligheden for at melde tilbage at de har fundet en mur.
På Hivemind siden har vi allerede mulighed for at blokere edges, derfor skal vi kun have implementeret at Hivemind’en kan tage imod meldingen fra robotten og oprette muren.
Sidste problem er håndteringen af mure, når de først er blevet opdaget. Som det er nu kører vi kun med én robot ad gangen og hvis den lukkes inde af murer, vil der ikke være noget at gøre. For at de dynamiske mure skal fungere ordentligt vil det derfor være nødvendigt, at udvide vores projekt så flere robotter kan køre på samme tid. Dette bliver beskrevet nedenfor.

Flere robotter på en gang

Som vores projekt fungerer nu, kører robotterne en ad gangen. Først afsøger Seekeren hele kortet og dernæst kører Mineren ud og henter guld. Det ville være mere effektivt hvis Mineren kørte ud og minede så snart Seekeren fandt en hule. Samtidig ville det også være nødvendigt at have flere robotter til at køre samtidig, hvis man skal håndtere mure på en ordentlig måde.
For at vores system kan håndtere concurrent (samtidige) robotter, skal det implementeres at de ikke støder ind i hinanden og ikke får lukket hinanden inde. Systemet kan allerede låse kanter og tiles, som er en del af en anden robots sti, så det er muligt for os at holde robotterne fra hinanden. Hvis vi begynder at benytte denne funktionalitet opstår der dog en åbenlys risiko for deadlocks robotterne imellem. Den største opgave i forhold til flere robotter på en gang er således at håndtere allokering af stier og kunne løse deadlocks der måtte opstå.

Rescue-robot

Vores nuværende udgave af projektet har meget lav tolerance overfor fejl. Hvis en robot læser forkert eller drejer forkert i forhold til, hvad computeren tror, er der ikke noget at gøre.
Dette kunne muligvis håndteres ved at lave en “rescue-robot”, der kan køre ud og finde den forliste robot. Dette ville foregå ved, at når vi fandt ud af at en robot var faret vild, ville vi bede robotten om at vente på at blive reddet. Vi ville så sende rescue-robotten ud til vores sidst kendte “sunde” position, herfra ville man så kunne bede rescue-robotten om at lede efter den forliste robot. Når den så fandt den ville den melde tilbage, hvor den var fundet og Hivemind’en kan derfra få den på ret kurs igen.

Hastighed og effektivitet: hvor hurtigt kan det gøres?

For at forøge vores hastighed og effektivitet, vil det være nødvendigt at udskifte nogle af de mere naive løsninger. Det vil være nødvendigt, at kunne køre med flere robotter ad gangen og gøre dette på den mest effektivte måde. Samtidig vil det være nødvendigt at få en bedre udforskningsalgoritme til Seekeren og få lavet en implementation af en traveling-salesman algoritme til Mineren.
En anden måde at gøre det hurtigere, ville være at sætte flere Seekers og flere Miners ind, men igen, for at dette vil være mere effektivt, skal der laves concurrency der fungerer.

Flere indgange i verdenen

Dette er lidt en pendant til at køre mere effektivt. Hvis der var flere indgange til vores verden ville det være nødvendigt at vedligeholde et kort for hver indgang. Disse kort kunne man man så sammenligne løbende og hvis man så nok ligheder mellem to kort, ville man kunne sætte dem sammen, samtidig ville det også være muligt at sammesætte to kort, hvis to seekers mødte hinanden.

Refleksion over forløbet

Vores forløb var delvist præget af, at vi ikke fra starten lavede en tidsplan. Vi var også for dårlige til at holde ‘status’-møder løbende, hvor vi kunne have snakket om, hvad vi havde nået, hvilke problemer vi havde, og hvad vi manglede. Det betød bl.a. at vi i en uge arbejdede i to grupper af to på henholdsvis robotterne og Hivemind’en. Efterfølgende havde vi nogle problemer med at få “samlet sporene” igen. Vi var ikke helt enige om, hvad der forventedes af computeren og robotterne og dette gav os noget ekstra arbejde.

Den største tekniske udfordring i projektet har været håndtering af fejllæsninger for farvesensoren. Vi har i løbet af projektet haft en del problemer med farvesensoren men synes, at vi nu er nået frem til en fornuftig implementation (beskrevet i blog post 7, se http://robotteddy.blogspot.dk/2012/06/slutprojekt-del-7.html, punkt 7). Vi havde således ikke fejl på farvesensoren de sidste  5 gennemkøringer.
Hvis Seekeren alligevel skulle læse en forkert farve på første gennemkørsel, er der ingen fejlhåndtering. F.eks. skete det tidligere, at den læste blå mens den kørte på en sort kant. Ville dette ske i vores endelige implementation, vil Hivemind’en registrere en hule på dette tile og banen ville derefter uopretteligt være fejl-repræsenteret. I afsnittet “Videre arbejde” ovenfor beskriver vi en mulig løsning på dette problem, i form af en ‘rescue’ robot.

Til trods for disse problemer er vi overordnede tilfredse med forløbet for projektet. Vi brugte de første to møder på, at blive enige om en fornuftig arkitektur for Hivemind’en og det hjalp os gevaldigt i arbejdet med den. Det betyder også, at det vil være nemt at udvide den med flere robotter og andre typer af robotter. Vi har haft mange gode arbejdsdage og vi har været gode til at føre journal, i form af blog posts, over vores arbejde. De udfordringer vi har mødt undervejs har vi fået løst og det er således kun tiden der har været den begrænsende faktor for hvor langt vi er nået.

onsdag den 20. juni 2012

Slutprojekt, del 8

Deltagere: Bjarke, Mikkel, Troels, Jesper
Tid: 4 timer

Mål

Målet med dagen er at få Seekeren til at afsøge hele den bane vi har lavet. Derudover vil vi gerne introducere endnu en robot, der kører rundt til hulerne efter at banen er blevet fuldt udforsket.

Plan

1. Juster farvesensoren så den bliver pålidelig.
2. Test hele systemet, og ret bugs.
3. Udvid Seekeren så den kan returnere til sin garage efter endt arbejde.
4. Udvid hele systemet til også at indeholde en miner robot.
5. Lav ekstra felt til mine-repræsentationen på computeren, der kan vise at en hule er udminet.

Resultater

1.
Vi har fået vores farvesensor til at virke som den skal. Vi gjorde dette ved at justere hastigheden for hvornår farver er set nok. Blå bliver, pga af lyset i lokalet, ofte set selvom sensoren ikke er over blå, hvorfor den tælles langsomt op. Rød er betydeligt mere pålidelig, så den tælles op hurtigere. Vi tilpassede hvor mange gange hver farve skal ses individuelt, så den ikke kører for langt frem på blå eller grøn. Resultatet er, at den ser alle farve yderst pålideligt og at systemet tillader os, at redigere på følsomheden for hver farve individuelt eller for alle farver simultant [1].

2.
Med farvesensoren på plads, blev den sidste udvikling og tilpasning af det samlede system betydeligt lettere. Uden større ændringer i koden afsøgte Seekeren hele banen, hvilket var en pludselig og kraftig forbedring over de tidligere forsøg vi havde udført. Dette ledte til næste funktionalitet, hvilket beskrives i næste punkt.

3.
Efter at have afsøgt alle ukendte edges i banen, skal Seekeren returnere til sit start tile. Serveren gemmer tilet i en variabel, for at gøre det tilgængeligt på dette tidspunkt, men alligevel gav punktet en mængde problemer der skulle løses. 

 
Det første problem opstod som følge af et valg vi tog, på baggrund af den pludselige positive udvikling. Vi besluttede at tilføje endnu en robot, der skulle besøge alle hulerne som Seekeren havde opdaget. Hulerne genkendes ved deres blå farve. Da farvesensoren havde givet problemer tidligere, havde vi besluttet også at gøre garage felterne blå, for at reducere mængden af forskellige farver den skulle genkende. Resultatet var derfor, at når Seekeren ville returnere til garagen, ville den genkende garagen som en hule, hvilket ville resultere i, at Mineren ville blive sendt derhen senere i processen. For at undgå dette, omskrev vi måden vores Seeker-mind, håndterede robottens indrapporteringer. 

Normalt ville ethvert felt blive opdateret med de nyeste informationer Seekeren leverede, men dette ændrede vi, således at felterne kun fik opdateret deres type, såfremt de var undiscovered, når Seekeren kørte over dem. Derved ordnede vi også et andet og lidt sjældnere problem, hvilket var at Seekeren kunne risikere at se blå, uden at den var på et blåt felt. Dette betød at et andet felt pludselig kunne omdefineres.
Desværre introducerede vi også det krav, at det Seekeren rapporterede i første omgang, ville være bindende.

Det andet problem opstod i algoritmen der beregnede stien fra robottens nuværende position til et vilkårligt andet punkt i banen. Denne var lavet meget specifikt til Seekeren og egnede sig derfor ikke til at finde en sti mellem to allerede kendte punkter. Dette krævede en større omskrivning af funktionen, men resultatet blev en mere generel funktion der egnede sig til at finde alle stier [2].



Den forbedrede algoritme til at finde den hurtigste vej mellem to tiles.
 

4.
Som beskrevet besluttede vi at introducere endnu en robot, da vi fandt relativt få problemer, efter at farvesensoren var blevet pålidelige. Ved projektets start havde vi ønsket en robot der skulle hente genstande i hver hule, men dette havde vi ikke arbejdet videre på, da vi først skulle have Seekeren til at være pålidelig. Derfor måtte vi opgive ønsket om at samle genstande op, da tiden ikke tillod denne funktionalitet. Opgaven for robotten blev derfor at opsøge samtlige huler i banen, når Seekeren var færdig med at udforske.

/**

    * Only called by SeekerMind - When a new tile is discovered it

    * is created by the seeker and saved in the Tiles map.
* if it's a tile, it'll be storred for later use by the Miner robot.

    * @param t

    *     Newly found tile

    */
   public void createNewTile(Tile t) {
   if(t.getType()==TileType.CAVE)
   miningStrategy.addCave(t);
   tiles[t.getxCoordinate()][t.getyCoordinate()] = t;
   }

På baggrund af de valg vi havde taget tidligt i projektet, var det let at udvide funktionaliteten af serveren til at håndtere endnu en robot. Yderligere kunne selve styringen af robotten nedarves fra klassen Overmind, der var skrevet med netop dette mål for øje. På selve robotten kunne den klare sig med den eksisterende software skrevet til Seekeren.
Vi udvidede Hivemind'en med et system, der gemte alle miner der blev fundet i en klasse for sig [3]. Denne klasse kunne derefter give stier ud til hver mine, når dette var nødvendigt.
Vi var nødsagede til at kræve, at Seekeren havde forladt banen, før Mineren kunne rykke ind, idet vi ikke havde funktionaliteten der kunne håndtere to robotter simultant.

5.
For at gøre vores visuelle repræsentation af banen mest brugervenlig og oplysende, udvidede vi denne med endnu et felt. Feltet repræsenterede en mine der var blevet “udtømt” af Miner robotten. Dette krævede en ny type felt på server-siden, men var let implementeret.

Konklusion

Det viste sig, at vi ved dagens start havde solid kode, der blot manglede fungerende farvesensorer. Da disse blev introduceret virkede det samlede system overraskende hurtigt. Derfor kunne vi sætte tid af, til at introducere endnu en robot, for at udvide opgaven og målet for systemet. Her viste det sig, at vores tidligere overvejelser om kodens opbygning, havde gjort denne udvidelse både hurtig og let. Da dette er sidste møde inden præsentationen af projektet vil hverken kode eller funktionalitet blive udvidet yderligere herefter.

Referencer

1. https://dl.dropbox.com/u/357278/Lego/TeddyMiners/miner/main/AbstractMiner.java

2. https://dl.dropbox.com/u/357278/Lego/TeddyHivemind/hivemind/mind/ExhaustiveSearchShortestPath.java
3. https://dl.dropbox.com/u/357278/Lego/TeddyHivemind/hivemind/mind/SimpleMiningStrategy.java

tirsdag den 12. juni 2012

Slutprojekt, del 7

Deltagere: Bjarke, Mikkel, Troels, Jesper
Tid: 9 timer



NB: Denne blog er resultatet af to dages arbejde. Der taget ikke højde for dette i beskrivelsen af det udførste arbejde.

Mål

Vores mål for dagen er at få Seekeren til at køre rundt i banen, baseret på instruktioner fra Hivemind'en. Disse instruktioner skal være baseret på den bane robotten opdager, mens den kører.

Plan

1. Rej fejl i kortet der tegnes på computeren. 
2. Ændre måden kortet tegnes på computeren, således at det vender korrekt i forhold til robotternes fysiske placering. 
3. Implementer en test-stub der skal gøre debugging af server softwaren lettere.  
4. Få robotten til at følge anvisninger fra computeren.

5. Udvis test-stub for at håndtere problemer fundet i punkt 4. 
6.Tilføj PID-kontrol som beskrevet i [1], dog kun med P.
7. Få farvesensoren til pålideligt at reagere på rød, blå og grøn.

Resultater

1.
Der var et problem med nogle tiles der ikke blev lagt ind i tiles[ ][ ] double arrayet. Det gjorde at de ikke blev repræsenteret i kortet da det kun tegnede kanter imellem to tiles der eksisterer i arrayet. Dette blev fikset, således at hver gang en edge oprettes, oprettes begge tiles den spænder imellem også. 

Udover dette oplevede vi også, at der blev markeret edges på kortet, der ikke passede med Seekerens placering. Da en edge repræsenteres som en hash værdi, der skabes vha. koordinater for de to tiles denne spænder mellem, mistænkte vi vores hash funktion for ikke at lave en unik mapping mellem koordinater og de tilhørende hash værdier. Et sådant problem kunne skabe kollisions, hvilket kunne give de problemer vi oplevede.
Derfor omskrev vi hash funktionen til at være baseret på primtal. Ved at lave en liste med de første 400 primtal (400 da den maksimale størrelse på banen var 20x20) kan hvert tile bindes til et unikt primtal og kanter mellem to tiles kan gemmes som produktet af de to primtal. Derved undgås enhver form for kollision.


Bemærk: Følgende er tilføjet d. 20/06/2012


Den anvendte hash funktionen så således ud: 


( (tile1.x + tile2.x) ^ 37) * (tile1.y + tile2.y) 


Det essentielle ved funktionen er, at der ikke må opstå kollisioner mellem hash værdier for forskellige tiles, der ligger op ad hinanden (Enten x eller y værdierne for de to tiles varierer med plus eller minus én). Dette kan ikke give kollisioner i hash værdien, så længe vi holder os inden for disse restriktioner. 
Dette var desværre ikke blevet kommunikeret klart ud, da kortet skulle laves, hvorfor måden den indtegner kendte kanter på, er baseret på at gennemløb af alle tiles i banen, for hvert eksisterende tile. Derved blev vores krav om, kun at hashe umiddelbare naboer ikke overholdt, og der opstod kollisioner. Dette resulterede i indtegninger af kanter på mere eller mindre tilfældige positioner. Vi antog, som beskrevet i punkt 1 ovenfor, at dette problem var resultatet af dårlig hash funktion, men dette har nu vist sig ikke udelukkende at være tilfældet. Dog er den nye implementation mere robust og med sikkerhed pænere end den tidligere.

2. 

Vores kort fungerede efter rettelsen fra punkt 1. Desværre var repræsentationen af verden ikke let at overskue for tilskuere, idet vores nord-syd akse vendte forkert. Dette skyldes at kortet vises i et canvas. Dette har, i modsætning til et almindeligt koordinatsystem, punktet (0,0) i øverste venstre hjørne. Udgangspunktet, da vi programmerede Hivemind'en, var at (0,0) lå i nederste venstre hjørne.
Problemet blev løst ved at ændre placeringen af alle objekter på det tegnede kort. Da vores maksimale størrelse af banen var 20x20, kunne vi tilføje denne ændring ved hjælp af følgende funktion, beskrevet i pseudo kode:


y-coordinate = (y-coordinate * (-1)) + 19;


Dette tilføjede en fejl, der betød at tiles der havde et y-koordinat mindre end vores garager (der ligger i (10,10) og (11,10)) ikke blev indtegnet, men grundet den måde den fysiske bane var konstrueret på, ville dette ikke give problemer og derfor blev denne nedprioriteret. 


Det computer-tegnede kort, efter ændringen.




3. 
Som beskrevet i forrige blog post, besluttede vi at implementere en test-stub der skulle erstatte robotten i robot-server kommunikationen. Dette fandt vi nødvendigt, idet vi havde problemer med softwaren på både robotten og serveren. Derfor ville vi fjerne den ene af disse variable, for at udføre en mere målrettet debugging. Løsningen blev, at vi implementerede en stub udgave af sender og modtager klasserne og lod dem implementere hhv. ISender og IReceiver interfacene. 
Implementationen af sender-stubben kaldte metoder direkte i receiver-stubben, hvorved vi efterlignede kommunikation med robotton, uden at vores resterende implementationer blev påvirket af dette. På den måde kunne vi i højere grad styre kommunikationen og få mere målrettet debugging. Derved fangede vi flere mindre logik fejl der plagede vores system. Selve implementationen var simpel og sparede os meget tid.

4. 

Efter at have rettet flere fejl, hvoraf enkelte var kritiske for en korrekt gennemsøgning af banen, fik vi robotten til at søge som forventet. Den finder vejkryds og fortsætter ud af kanter, på en måde der tilsvarer det resultat vi havde planlagt. Desværre er der stadig enkelte problemer der viser sig når robotten finder enden på en kant eller en hule. Disse blev ikke testet af vores test-stub, hvilket dog ville være muligt ved simple tilføjelser. Udover dette gav farvesensorerne fortsat problemer. De læser grønt og blåt korrekt når underlaget har disse farver, men genkender desværre også farverne når robotten blot følger en sort sti. 
Udvidelsen af test-stubben samt håndteringen af huler og blinde veje beskrives i næste punkt. Forbedringerne af farvesensoren beskrives i punkt 7.

5. 

Udvidelsen af test-stubben var simpel. Vi lavede en begrænsning på den bane vores test-stub efterlignede, hvorved vi kunne teste blinde edges. Derudover lagde vi en hule ind, så denne også kunne testes. 
Problemerne noteret i punkt 4 var, at vi under programmeringen af Hivemind'en havde antaget, at robotten ville køre baglæns tilbage til forrige tile, når den fandt enten en blind edge eller en hule. Dette vidste sig desværre ikke at være muligt i praksis, hvorfor vi måtte tage en anden tilgang. Vi havde en eksisterende funktion til rådighed, der tillod robotten at lave en u-vending og ved at anvende denne, kunne vi samtidig løse enkelte andre problemer der havde generet os.
Indførelsen af blinde veje i test-stubben gav også mulighed for at teste, hvorledes robotten ville afsøge en hel verden og derved om logikken omkring dette holdte vand. Som resultat af dette rettede vi enkelte logik fejl i vores algoritme for korteste vej mellem to tiles. Derudover blev det åbenlyst, at når banen blev tilstrækkelig stor, ville tiden for at finde den korteste vej blive forøget markant. Dette løste vi ved løbende at opdatere længden på den korteste sti vi havde fundet, mens algoritmen rekursivt afsøgte alle mulige veje. Dette tillod tidlig terminering af mange grene.

6. 

Det lykkedes os at implementere en PID kontrol, med kun P. Robotten sporede pænere ind på linjen efter noget tid, men hvis den tabte linjen havde den svært ved at spore ind igen. Grundet banens opbygning vil robotterne kun køre meget korte stykker ad gangen og skal være ret gode til at spore ind på stregen igen, især når der drejes i et kryds. Derfor valgte vi at gå tilbage til den helt simple on-off kontrol. Denne metode oscillerer mere, men er effektiv til at spore ind på stregen.
Vi kunne have valgt at at udvide vores PID kontrol med både I og D, men dette vil være en kæmpe arbejdsbyrde at få tunet og tilpasset så det kører lige så godt som den simple løsning og vores fokus var fortsat på farvesensoren, hvilket beskrives i næste punkt.

P kode:  
lightValue = bw.getLightValue();
error = lightValue - offset;
turn = kP * error;
turn = turn / 100;
powerA = Math.abs(minPower + turn);
powerB = Math.abs(minPower - turn);
Car.forward(powerA, powerB);  


7. 
Der har været en del iterationer af dette punkt. Først prøvede vi at anvende forskellige farver, men det viste sig at alle farverne kan blive opdaget når de ikke er der. Rød er her en undtagelse, men desværre opdager robotten ikke et rødt underlag helt pålideligt. Herefter prøvede vi at skærme sensoren af, så det kun var dens eget floodlight der oplyste dens synsfelt. Dette hjalp lidt, men den så stadig blå og grøn tilfældigt.
Vores endelige løsning blev, at man skal lave mere end én måling af farverne før robotten reagerer på det. Det viste sig dog, at det stadig ikke var helt nok for at undgå blå, da denne farve ofte blev læst mens robotten fulgte en sort streg. Så vi tilpassede den således at rød og grøn blev opdaget hurtigere end blå. Dette hjalp, mens den stadigt opdagede blå pålideligt.


Vores colorsensor kode fungerer nu på en sådan måde, at vi har tre color counters. Disse tæller op hvor meget rød, grøn og blå vi har set. Hver farve bliver talt op mindst to hver gang vi ser farven, samtidig bliver alle farver, inklusiv farven selv, talt ned. Samtidig tæller vi alle farverne to ned når vi ikke ser nogen af de tre farver. Denne metode sikrer, at vi ikke husker "gamle opdagelser" og at vi samtidig reagere på farverne når vi ser disse i et længere stykke tid. Denne løsning kan samtidig justeres så hver farve bliver talt forskelligt op, alt efter hvor tit vi læser fejl på farven. Rød læser vi stort set aldrig fejl på, derfor bliver den talt hurtigere op end blå, som vi tit læser fejl på.
Alle farverne har i den nuværende implementation den samme grænse, men dette kan ændres for an nuancere sensorerne endnu mere [2].
 


Konklusion
Efter dagens mange rettelser i Hivemind'en er vi klar til igen at teste på robotten. Hivemind'en opfører sig som forventet når den anvender test-stubbene og farvesensoren er nu mere pålidelig end ved sidste test.
Flere af problemerne har været et direkte resultat af dårlig kommunikation internt i gruppen, delvist fordi vi har arbejdet meget separat på robotten og Hivemind'en.
Målet for næste møde bliver at teste systemet på den fysiske robot og forhåbentlig få en fuld gennemkørsel.

Referencer

1. http://www.inpharmix.com/jps/PID_Controller_For_Lego_Mindstorms_Robots.html
2. https://dl.dropbox.com/u/357278/Lego/TeddyMiners/miner/main/AbstractMiner.java

fredag den 8. juni 2012

Slutprojekt, del 6

Deltagere: Bjarke, Mikkel, Troels, Jesper
Tid: 5 timer



Mål

Teste kommunikation mellem robot og computer.
Grafisk repræsentation af hulen, som robotterne bevæger sig rundt i.
P komponent af PID-kontrol til robotterne.



Plan

1. Udvid overmind, så den kan håndtere de forskellige signaler som robotten kan sende til den.
2. Test om kommunikationen virker som forventet på robotterne.
3. Få lavet en grafisk repræsentation af hulen.



Resultater

1. Vi har udvidet overminden så den nu kan håndtere alle kontrolsignaler den modtager fra robotten. En implementation af Receiver interfacet på PC'en identificerer kontrol-signalet og kalder så den korrekte metode på Overmind (f.eks. foundIntersection() eller foundCave()). Overmind klassen sørger så for at bestemme den næste besked robotten skal have. Hvis robotten er igang med at navigere af en path vil Overmind-klassen fjerne det tile vi er nået til fra path’en og køre videre. Når vi er nået til enden af path’en vil Overmind kalde ‘performTask()’ metoden på robotten. Det resulterer i at robotten finder guld i en mine eller fjerner en mur alt efter hvilken type robot det er. 
SeekerMind, der extender den abstrakte overmind-klasse, overskriver en række metoder fra Overmind-klassen. SeekerMind'en har nemlig den specielle opgave at opbygge kortet. Derfor skal vi via SeekerMind klassen sørge for at vi registrerer hvad vi opdager og gemmer informationen om dette i Hivemind'en.Der er således også indført kode i seekermind for det specialtilfælde hvor den møder enden af kortet. Pt. mangler der at blive indført kode for det tilfælde hvor en robot opdager en mur. Vi har bevidst udskudt denne implementation idet vi i første omgang fokuserer på at få en seeker robot til at opdage en verden uden mure og andre robotter i.

2. Vi har etableret kommunikation mellem robotten og computeren. Robotten kan tage imod beskeder fra computeren og rapportere tilbage hvad den ser. For at teste robottens opførsel når den modtager de enkelte beskeder, har vi implementeret en UI på computeren, der har knapper for hver funktion. 


UI der kan oprette forbindelse til en robot og sende beskeder, som markeret på knapperne.




UI'en kan oprette forbindelse til en robot og sende beskeder. Modtagne signaler, fra robotten, udskrives desuden i det store 'text area'. Den automatiske kommunikation mellem computeren og robotten kan testes ved at trykke på knappen markeret med "Start".
Selve kommunikationen fungerer fint, men vi har dog stadig nogle problemer med farvesensoren, hvilket giver nogle 'forkerte' signaler tilbage til PC'en. Farvesensoren registrerer således ikke altid rød som den skal og den ser blå steder hvor der ikke er blå. Vi skal have undersøgt om det er belysningen i rummet eller om det er farvesensoren der er problemet. Hvis det er farvesensoren der er skyld i det, skal vi konstruere en klasse der håndterer de rå værdier for os, lige som vi prøvede sidst.

Ting vi skal have testet med farvesensoren:

  1. Slukke floodlight på lyssensoren.
  2. Prøve et sted med simplere belysning, så som i køkkenet i Zuse.
  3. Prøve at afskærme sensoren, så ambient lys ikke påvirker den så meget.
  4. Prøve Rå-værdier hvis intet andet virker.







Yderligere måtte vi konkludere at Hivemind implementationen heller ikke var uden fejl. Vi forsøgte at starte den automatiske udforskning af verden, men dette virkede ikke efter hensigten, idet seekeren fik ukorrekte beskeder fra computeren. Da det til tider var svært at identificere om problemerne vi mødte lå på robot eller server siden af vores system, besluttede vi at implementere en test-stub til videre debugging, ved næste møde. Test-stub'en skal være en implementation af Hivemind'ens Receiver interface hvor vi kan styre præcis hvilke beskeder der sendes til PC'en. På den måde vil det være lettere for os at undersøge om det er på PC-siden der er problemer.


3.
For at gøre det muligt for tilskuere at se hvad der foregår og lettere for os selv at have et overblik over Hivemind'ens repræsentation af verden, besluttede vi at lave en GUI med et kort over hulen. Vi tager udgangspunkt i at vi har et 20x20 grid som vi kan tegne. Vi bruger swing til at tegne med [1]. 
Der er oprettet en java klasse (MapCanvas) der extender JComponent, som tegner kortet ud fra den information den kan læse i hiveMind. Derudover er der lavet en JFrame (MapUI) der indholder MapCanvas. Denne bliver startet som en under-Frame af UI. Så det nuværende setup er en JFrame til at styre robotten med, og en JFrame der viser et view af banen.
Indtil videre er det lykkedes at hente tile data ud, men edge dataen virker ikke endnu. Dette skyldes måske et problem med hvordan vi gemmer edges. Vi arbejder videre med GUI'en næste gang.


Konklusion

Vi har nået det vi satte os for idag, men vi stødte på nogle nye problemmer i processen. Næste gang skal vi have testet farvesensoren som beskrevet i slutningen af punkt 2 i resultater. Samtidig skal vi have set mere på kommunikationen mellem Robot og computer, samt implementationen af Hivemind på computeren. Til dette vil vi oprette en test-stub på computeren der kan efterligne signaler fra robotten. Kortet er næsten færdigt, men der mangler lige lidt arbejde med at få vejene tegnet.

onsdag den 6. juni 2012

Slutprojekt, del 5



Deltagere: Bjarke, Mikkel, Troels, Jesper
Tid: 5 timer



Mål

Test kommunikation mellem robot og PC.
Få indført en simpel korteste-vej algoritme der kan bruges af alle robotter.



Plan

1. Få udvidet seeker robotten, så den kan opdage blå huler, hvor man kan finde guld.
2. Lave en implementation af interfacet IShortestPathStrategy
3. Sætte robotterne op til at kunne modtage signaler fra PC’en og køre efter dem.
4. Test kommunikation



Resultater

1. Vi har prøvet at udvide robotten med en mulighed for at se den blå hule. Dette har dog givet nogle problemer. Det tape vi bruger registrerer farvesensoren til tider som blåt. Farvesensoren er desuden begyndt at overse den røde midte i kryds oftere og oftere. Vi prøvede at skifte farven på hulen til gul, men det viser sig at selvom robotten ser den gule farve bedre end blå, så registrerer den også bordet under,der er brunt, som gult.
Vi er blevet enige om at vi nok bliver nødt til at arbejde med rå værdier, da dette vil give os større præcision.

Vi laver vores håndtering af rå værdier, lidt som vi lavede kalibrering af lyssensoren tidligere i kurset. Vi måler hver farve med sensoren i starten og disse værdier gemmes så i robotten. Med farvesensoren er det dog 3 værdier vi skal holde styr på og ikke kun 1. Vi gik i gang med dette og det gav en del problemer. Vi havde for langsom kode, som var skyld i at robotten reagerede for langsomt. Det endte også med at den så rød alle vejne og til sidst gik vi tilbage til vores løsning der virkede tidligere idag. VI har dog ændret hule farven til gul, da robotten har tendens til at se blå steder hvor den ikke burde.

Robotten kan nu se intersections og huler.

Vi har stadig problemer med at farvesensoren nogle gange ikke opdager intersections. Dette er et meget kritisk problem da vi skal være sikre på hvor robotterne er i grid'et. Derudover ser farvesensoren nogle gange gul hvor der ikke er gult.
Det er muligvis pga. lyset fra LED’en på farvesensoren. Vi vil derfor teste uden lys i LED'en næste gang.


2. Vi har lavet en simpel rekursiv struktur der benytter exhaustive search til at finde den korteste vej. Koden ses nedenfor. I en lille bane, som den vi bygger, er det ikke et problem at algoritmen ikke er effektiv idet den kommer til at køre på en hurtig PC. Vi har lavet et interface til at finde korteste vej og den simple rekursive algoritme er en implementation af dette. Det vil gøre det nemt for os at implementere en smartere algoritme senere hen (f.eks. Dijkstra’s).

Fuld kode med javadoc til kernen i algoritmen, der finder en sti fra robottens placering til et Tile, her kaldet endTile.
 
 

3.
Robotterne skal modtage et signal i Receiver og udføre den opgave den får (f.eks. kør lige ud), og melde tilbage i Sender. På nuværende tidspunkt har vi lavet kode der, via Sender, sender et signal hvis den møder en hule (gul) eller en skillevej (rød).

4.
Næste skridt var at få kommunikationen mellem robot og PC til at virke. På PC-siden lavede vi en GUI hvor vi kunne teste simple kommandoer sendt til robotten. Til selve bluetooth kommunikationen benyttede vi produktionskoden der findes i Overmind-klassen. Dette virkede efter hensigten og ved dagens udgang kunne computeren oprette forbindelse via bluetooth til en robot. 



UI der kan oprette forbindelse til en robot og sende beskeder, som markeret på knapperne.


Koden til kommunikation mellem PC og robotterne er også implementeret på test-niveau, men vi nåede ikke at gennemteste kommunikationen. Planen for næste gang er at teste de forskellige metoder der senere skal anvendes til kommunikation. 

Konklusion

Vi har stadig en del problemer med farvesensoren, som vi skal arbejde videre med næste gang. Vi har  tilføjet kode der kan finde den korteste vej fra et tile til et andet. Vi mangler dog at teste denne, samt at teste om kommunikationen mellem robot og PC fungerer korrekt.


mandag den 4. juni 2012

Slutprojekt, del 4


Deltagere: Bjarke, Mikkel, Troels, Jesper
Tid: 6 timer

Mål

Målet er, at få robotterne til at virke, og at bygge videre på hiveminden.


Plan

1. Robotterne skal ombygges, så de fylder mindre og kan dreje skarpere.
2. Vi skal diskutere, hvordan vores tiles skal laves, så det er muligt at lave et korrekt sving til både højre og venstre, samt at fortsætte lige frem.
3. Vi skal også diskutere, hvordan vi bruger vores interne repræsentation af edges og tiles, til at lave stier, som robotterne kan følge. Denne diskussion skal også nå frem til en løsning på, hvordan og i hvilken rækkefølge banen skal udforskes af vores seeker.
4. Udvid softwaren på robotterne, så den passer til det nye design. Derudover skal dens evne til at bevæge sig i banen forbedres. Den skal begynde at anvende bluetooth kommunikation så dette kan testes.
5. Serveren skal udvides, så den kan lave stier rundt i banen baseret på forskellige mål. Disse stier skal kommunikeres med hvert mind og disse skal videre kunne tolke dem og give ordre videre til robotterne. Også på denne side skal bluetooth kommunikation implementeres yderligere.
6. Test kommunikationen mellem robotterne og serverne. 



Resultater

1.
Vi har bygget dem efter anvisningerne i Lego manualen. Derudover har vi en special tilbygning for at holde vores lys og farvesensorer (se billede længere nede på bloggen).

2.
Vi har haft en stor diskussion omkring design af tiles. Vi havde sidste gang nogle problemer med det design af tiles vi havde lavet. Problemene bundede i at vores lysforskellene imellem grøn og sort ikke var store nok til at vi kunne styre om robotten kørte ligeud eller drejede. Dette ledte til en større brainstorm over hvordan de skulle opbygges. Resultatet kan se på nedstående tavle:







Vi er nåede frem til et nyt design, hvor vi har helt lige sorte veje og grønt i midten af kryds. Her er planen så at robotten følger stregen indtil den læser grønt. Så kører den lidt frem og roterer på stedet indtil farvesensoren læser sort igen, hvilket betyder at den har ramt stregen.
Det gav et sensorsetup, hvor vi har en farvesensor i midten foran robotten og en lyssensor der står lidt forskudt til højre, som skal følge stregen. Tiles ser nu således ud:






Efter test fandt vi ud af, at problemet ligger i at farvesensoren mange gange læser grænsen imellem hvid og sort som grøn. Derfor gik vi over til et rødt midterfelt.
Efter et par test havde vi stadig lidt problemer, nu med at farvesensoren overser det røde område. Vi prøvede at få placeret sensorerne bedre i forhold til hinanden.
Efter en del test lykkedes det at få robotten til at køre som vi ønskede. Vi endte med følgende opsætning af sensorer (hvor farvesensoren er forrest og lyssensoren er bagerst, nærmest hjulene):




Det resulterede i følgende video.





 

3. Indledningsvist diskuterede vi igen, hvilke krav vi kunne sætte til start tilstanden for banen. De tre robotter starter i hver deres garage. Her diskuterede vi, om dette krav skulle udvides til også at inkludere hvert tile foran garagen, således at vi med sikkerhed kan forvente et intersection-tile der. Dette vil gøre det muligt for robotterne at køre ud uden at disse tiles først skulle opdages af seekeren. Denne diskussion startede, idet vi endnu ikke havde gennemtænkt systemet for udforskningen af banen. Overvejelserne om dette system vil blive specificeret herefter, men først vil vi præcisere de krav til starttilstanden vi endeligt fastlagde:

De tre garage-tiles skal ligge ved siden af hinanden. Der er kun én vej ud fra en garage og denne skal pege i samme retning for alle tre tiles. Grundet vores interne styring af robotterne skal vi altid vide, på hvilket tile de befinder sig. Derfor er det et krav, at seekeren altid starter på tilet yderst til venstre, således at når den forlader garagen kan den passere de andre robotters garager ved at dreje til højre. Internt giver vi de tre tiles x, y koordinaterne (10, 10) - seekerens garage, (11, 10), (12, 10), da det således giver mulighed for at disse tiles kan placeres et arbitrært sted i banen. Koordinatsystemet for banen defineres dernæst ud fra garagernes placering, således at første tile seekeren kører ud på har koordinat (10, 11). Der stilles ingen krav til de tiles, der ligger umiddelbart udenfor garagerne, men hvis de ikke er intersections bliver det en kedelig bane.


Diskussionen om, hvordan banen skulle udforskes af seekeren, blev lang og endte med at inkludere mange omskrivninger af og tilføjelser til koden. Problematikken består i den måde vi håndterer tiles og edges på internt. Som tidligere beskrevet her på bloggen, har hvert tile sin egen repræsentation bestående af et x, y koordinat og en type. En edge beskrives af en hash værdi mellem de to tiles den forbinder. Internt har vi hashmaps der forbinder de forskellige hashværdier sammen med en status for hver edge (undiscovered, free, locked, wall, map-end) og et andet map, der binder hashet sammen med de to tiles edgen ligger imellem. Dette er nødvendigt, da vi ikke kan gå fra en hashværdi til de oprindelige x, y koordinater den er lavet af.
Seekerens job er at besøge alle uudforskede tiles og edges. Dvs. vi skal konstant opretholde en oversigt over de edges og tiles, der endnu ikke er blevet undersøgt. Hver gang seekeren finder en ny intersection ved den, at der går fire edges ud fra denne, hvoraf én er den, den er kommet ind ad. Den skal derfor oprette tre nye kanter, hvilket let kan gøres da vi kender x, y koordinatet for tilet. Det er dog muligt, at et nabo-tile allerede er blevet opdaget tidligere, hvorfor edgen muligvis findes i systemet. Hvis dette er tilfældet, kan vi derfor ændre status for den edge til free i stedet for undiscovered. Der er en mængde af lignende tilfælde, der skal håndteres, men disse vil ikke blive specificeret her. 
Hver gang en edge oprettes opretter vi også de nye tiles denne edge leder over til. Dette gør vi uanset om den tile eksisterer i banen eller ej (også hvis edgen leder ud af banen). Når seekeren så forsøger, at bevæge sig ud af en edge, der ikke leder over til et nabo tile (som der sker i kanten af banen) vil den opdage, at edgen ender blindt og returnere dette. Således vil vi ende med tiles i vores system, der ikke findes rent fysisk, men som er nødvendige for systemet.
Årsagen til at de er nødvendige er, at vores robotter altid bevæger sig mellem tiles. En robot kan ikke sendes til en edge. Dette er et resultat af banens fysiske opbygning. Vi kan ikke opdage, hvor langt inde på en edge vi er, og derfor risikerer vi at blokere for andre robotter, hvis vi kører for langt eller for kort ud af edgen. For at en edge kan blive opdaget, skal vi derfor sende robotten fra det ene tile til det andet.
Da vores implementation kan indeholde ikke-eksisterende tiles, der er uopdagede, blev vi nød til at ændre vores krav til seeker robotten. Det eneste den skal undersøge, er uopdagede kanter. Derved ved vi, at hvis der ikke er nogen uopdagede kanter tilbage, findes der heller ingen uopdagede tiles, der er inden for rækkevidden af robotterne.
Alle disse overvejelser, beslutninger og tilhørende kode-ændring og skrivning betød, at vi ikke fik lavet funktionen, der genererer en sti. Målet for næste gang er derfor, at få implementeret denne.


4. Det var rimelig simpelt at få sat robottens funktioner sammen med Sender og Receiver klasserne, så den var klar til bluetooth kommunikation, da stort set al koden var på plads allerede. Som det kan ses på videoen under punkt 2, fik vi robotten til at køre og reagere på de røde midterfelter i krydsene.


5. Dette nåede vi desværre ikke, idet punkt 3 tog længere tid end beregnet.

6. Dette punkt nåede vi heller ikke.

Konklusion

Vi er kommet i mål med at få robotten til at følge et grid. Dette gør, at vi nu kan komme videre med de andre dele af projektet, da vi nu har de basale funktioner på plads, så vi kan bruge det til at teste de andre funktioner med. Af de grundlæggende robot funktioner mangler der kode til at rotere 180 grader, hvis robotten skal vende om. Derudover mangler vi at håndtere hulerne (som nu skal have en anden farve end rød).

Yderligere fik vi gennemarbejdet vores måde at udforske banen på og dette betød også, at vi fik tilføjet nye funktioner og fjernet bugs i koden. Generelt har vi nu et bedre system, omend det tog lang tid at nå dertil.
Næste gang vil vi forsøge at nå punkt 5. og 6. fra planen.