Saturday, April 13, 2013

Week 8

Dato:

11-04-2013

Varighed:

Fælles lab: 40-45 timer
Blog: 5 timer

Deltagere:

Steffen Høi
Nikolaj Mols Hansen
Martin Vang
Ulrik Sahl Lystbæk

Status

Vi har bygget en LEGO-bil, der kan gennemføre "Alishan Train Track" på 23,386 sekunder ved en delvis sekventiel løsning med lyssensorer samt PID-Controller, hvor vi har fulgt reglerne fra "Week 8 - Robot Race"1.

Mål

Målet for denne laboratoriesession er at bygge en LEGO-bil, der gennemfører "Alishan Train Track" i den hurtigst mulige tid samt at følge reglerne fra "Week 8 - Robot Race"1.

Plan

  • Konstruere en LEGO-bil med formålet, at den skal kunne køre hurtigt.
  • Programmering af LEGO-bilen, så den kan gennemføre banen i den bedst mulige tid, og udnytte bilens fysiske konstruktion bedst muligt.
  • Udarbejdelse af blogindlæg for denne laboratoriesession.

Konstruktionen af robotten

Da vi skulle til at konstruere robotten var vores udgangspunkt, at vi gerne ville lave en konstruktion, der udnyttede motorernes kraft bedst muligt. Vi valgte derfor at lave et gearingssystem bestående af et lille og et stort tandhjul, hvilket fik hjulet til at dreje 3:1 ratio af normal hastighed grundet tandhjulenes størrelse i forhold til hinanden. For at gøre LEGO-bilen mere stabil, besluttede vi os for at lægge NXT Bricken ned, og vi monterede desuden to hjul på hver sin motor for at sikre, at bilen havde et bedre greb på banen samt, at den ikke ville skride så meget i svingene. Endvidere satte vi et fleksibelt hjul bagpå for at LEGO-bilen kunne holde balancen og bedre klare svingene. For at gøre motorerne mere kraftfulde skaffede vi os desuden nogle almindelige AA-batterier, hvilket gav en mærkbar forskel i forhold til at bruge det almindelige Lithium-ion-batteri.

Vi eksperimenterede kortvarigt med flere forskellige kombinationer af tandhjul for at finde en god ratio2 til banens hældning og bilens motor. En af de kombinationer der holdt længst i vores test-kørsler, var 5:1 som kan ses nedenfor. Den blev dog fravalgt, da vi ikke kunne få robotten til at følge linjen ordenligt ved meget over 3:1, og den ekstra gearing gjorde derfor blot vores robot mindre præcis i svingene.
Den endelige konstruktion af vores robot, som den ser ud ved "Sekventiel løsning med lyssensorer samt PID-Controller", ses på nedenstående billeder:


Løsningsforslag


Sekventiel løsning

Den umiddelbare måde vi tænkte at programmere vores LEGO-bil på var, så den kunne klare banen sekventielt. Ideen var at bruge klassen TachoMotor og tælle TachoCount. Her fik vi dog et problem allerede ved den første strækning på banen, da LEGO-bilen ikke ville køre lige, men hele tiden kørte skævt og dermed af banen. Dette fandt vi ud af skyldtes, at de to motorer ikke havde samme kraft, og vi blev derfor nødt til at finde en løsning, der kunne tage højde for dette, og rette bilen op, når denne kørte skævt.

Fjernstyret løsning

Efter forrige forsøg med den sekventielle løsning overvejede vi, hvad vi kunne gøre for at sikre, at bilen ikke kørte skævt. Dette førte os til en fjernstyret løsning af problemet. Vi lavede en GUI, hvor vi kunne indtaste værdierne til de to motorer, og dermed ændre bilens retning på kørselstid. Problemet ved denne løsning var, at kaldene nogle gange blev forsinket en del, formentlig pga. Bluetooth-forbindelsen. Af denne årsag kunne vi derfor ikke få LEGO-bilen til at reagere hurtigt nok.
Kommandoerne vi uploadede til robotten blev også gemt og udført sekventielt, hvilket betød at det var meget besværligt at reagere på pludselige udsving fra robottens side - den skulle først køre en ordre færdig før den ville tage imod en anden. Dette var det endelige argument for ikke at fjernstyre hele vejen, men vi overvejede, om det ville give mening at kunne lave små "tilpasninger" af kørslen vha. vores GUI, hvilket vi dog ikke fik afprøvet.

Sekventiel løsning med lyssensorer

Den næste løsning vi kom frem til var at montere 4 lyssensorer på robotten, så vi kunne korrigere vores bil efter den sorte linje. Dette gjorde, at vi kunne få robotten til at holde sig inden for banen og køre nogenlunde lige. For at lyssensorerne kunne være på bilen, så de sad langt fremme, blev vi nødt til at sætte det lille drejehjul forrest. Vi forsøgte derefter at lave et sving på det første plateau, fange den sorte linje på den modsatte side og dernæst køre ligeud opad den næste bakke. Grunden til at vi ville lave et sving, og ikke bare prøve at følge den sort linje rundt var, at vi mente, at det ville tage kortere tid at lave et sving, samt at det ville være svært at følge den sorte linje hele vejen, da den delte sig i to stier ved et sving. Da vi prøvede på at implementere svinget, opstod der dog et nyt problem, hvilket var, at bilen kom meget forskelligt ind i svinget. Derfor, var det næsten umuligt at forudsige nogenlunde præcist hvorhenne, bilen ville ramme linjen. For at sikre at bilen kom nogenlunde ensartet ind i svinget, blev vi altså nødt til at finde en måde hvorpå, vi kunne mindske oscilleringen af bilen. Denne løsning kan ses i det efterfølgende afsnit.
Vi arbejdede nu med lyssensorer, hvilket skabte en ny udfordring, der skulle tages højde for. Den måde banen stod på gjorde, at der kom sidelys ind, så der i løbet af dagen var meget forskellig lys på banen. Dette betød, at vi fik problemer med, at lyssensorerne opfattede LEGO-bilens egen skygge som sort, hvilket gjorde, at selvom vi kalibrerede ofte, havde vi stadig problemer med at hvid plus skygge blev opfattet som sort af robotten.
Vores løsning til skygge-problemet var at kalibrere én gang, for så at tilpasse sort/hvid værdierne manuelt for at se hvilke værdier, der fungerede bedst (typisk lige omkring de mest ekstreme forskelle på banen).

Sekventiel løsning med lyssensorer samt PID-Controller

Problemstillingen fra forrige afsnit vedrørende bilen, der oscilerede, besluttede vi at løse ved at lave en PID-Controller. Dette medførte, at vi i stedet for at bruge 4 lyssensorer, kunne nøjes med at bruge 3. Ideen bag PID-controlleren var at benytte forskellen fra hvid for de to yderste lyssensorer til samlet set at betegne error og bruge den midterste lyssensor til at nulstille integralet, hver gang den læste sort. Til at lave selve svinget brugte vi stadig TachoMotor klassen til at rotere bilen. Dette var dog en smule upræcist, og vi fandt senere ud af, at man ved at bruge klassen DifferentialPilot, kunne lave et mere præcist sving med robotten. Dette var dog ikke så ligetil, som først antaget, da vi fik et nyt problem med at motoren blev blokeret i forbindelse med et sving, og vi derfor ikke umiddelbart efter kunne kalde funktionerne på TachoMotoren. Dette problem fik vi dog løst ved at finde kildekoden3 inde på hjemmesiden for LEJOS og ændre i Stop-metoden (sætte motorerne til float efter alle stop) inde i klassen DifferentialPilot, så vi nu havde vores egen modificerede udgave af denne klasse. Dette viste sig også senere at komme os til nytte, da vi skulle lave nummer to sving, da DifferentialPilot, når vi skulle rotere, huskede rotationen fra forrige gang og foretog den umiddelbart efter, vi havde lavet den drejning, der var relevant for at klare svinget. Dette krævede, at vi lavede om i Reset-metoden i vores modificerede udgave af DifferentialPilot, så tacho-counterne rent faktisk blev nulstillet hver gang, vi skulle i gang med et nyt sving (jf. metodens java-doc).
Nedenfor ses en pseudo-kode beskrivelse af, hvad vi gør for at få vores PID-Controller til at fungere.


Endnu en udfordring ved at lave drejningen var at hjulets diameter og omdrejningsgrader ikke passede pga. vores gearingssystem, og det var derfor nødvendigt at tilpasse den til at tage højde for dette. Her forventede vi, at vores 3:1 gearing ville betyde, at vi kunne rotere 180/3 grader for at lave et 180 graders sving, men dette var ikke tilfældet. Det kan enten være, at vi har en bug et sted i koden4, eller at DifferentialPilot ikke helt håndterer gearede hjul så godt.
For at fange den sorte linje igen efter et sving, lavede vi vores egen line-catcher, hvilken var en del lettere nu, hvor vi nogenlunde præcist vidste, hvor robotten ville lande efter et sving. Til at lave en 180-grader stillestående rotation oppe på toppen af banen, brugte vi også DifferentialPilot. Nedad turen skulle justeres en del i svingene i forhold til turen opad, da bilen skred nedad bakke. Dette prøvede vi på at løse ved at sætte et ekstra hjul på hver motor, så der på hver side af bilen nu er 3 hjul, hvilket hjalp en smule på problemet, samt gjorde at bilen blev mere konsekvent i den måde, den klarede svingene på. En stor faktor der påvirkede, hvor hurtigt vores LEGO-bil kunne klare banen og nå frem til svingene viste sig desuden at være, hvor meget strøm, der var tilbage på batteriet, og vi fandt derfor ud, at det var en fordel at have to lithium-ion-batterier at skifte imellem, så vi havde nogenlunde samme power til vores motorer.

Resultater

Vi fik optaget tre videoer af vores LEGO-bil, hvor den gennemførte banen.

Kørsel 1

Tid: 32,009 sekunder

Nedenstående video blev taget første gang, det lykkedes vores LEGO-bil at gennemføre banen. Denne tid mente vi dog godt, at vi kunne forbedre ved at lave nogle optimeringer i koden.




Kørsel 2

Tid: 23,386 sekunder

Efter at have optimeret vores kode ved b.la. at sætte tiden ned for, hvor meget LEGO-bilen skulle sove i et sving og sætte power op på de lige strækninger samt forbedre vores line-catcher, så den fangede den sorte linje bedre, kunne vi skære godt 9 sekunder af vores tid i forhold til kørsel 1.

Kørsel 3

Tid: 23,417 sekunder

Denne kørsel var en anelse langsommere end kørsel 2, der er den bedste tid vores LEGO-bil har gennemført banen på.


Konklusion

Denne uge har vi bygget en LEGO-bil og programmeret den, så den kan gennemføre "Alishan Train Track" på 23,386 sekunder, som den hurtigste tid. Vi har været en del løsningsforslag igennem, som vi teoretisk set troede ville virke, men pga. de fysiske forhold, som at motorerne ikke trækker med samme kraft samt forsinkelse i Bluetooth, praktisk set ikke virker. Vi har desuden set, hvor lidt der skal til af forandring i den fysiske verden, såsom skygger samt den måde lyset falder på for at påvirke robotten samt sensorernes evne til at læse et givet resultat, som man forventer. Desuden har vi fundet ud af, at den løsning, vi har kunnet opnå det bedste resultat på, har været ved at lave en delvis sekventiel løsning, hvor vi bruger lyssensorer til at følge den sorte linje samt en PID-Controller for at LEGO-bilen ikke skal oscilere så meget, at den vil komme skævt ind i et sving. Det har desuden været en udfordring, at der har været så mange variabler, der kan ske at skulle ændres, hvis f.eks. kraften til motorerne falder, som følge af at batteriet mister styrke. Vi har desuden lært, hvordan DifferentialPilot klassen i LEJOS fungerer, samt hvad man skal være opmærksomme på, når man bruger denne sammen med TachoMotor klassen, og hvordan man kan ændre i den, så man får den funktionalitet, man i en specifik situation skal bruge.

____________________________________________________________________________________________________________

1. http://legolab.cs.au.dk/DigitalControl.dir/NXT/Lesson7.dir/Lesson.html
2. http://sariel.pl/tools/ratios/
3. http://svn.code.sf.net/p/lejos/code/branches/lejos_nxj_0.9.1-x/pccomms/src/lejos/robotics/navigation/DifferentialPilot.java
4.
https://sites.google.com/site/digikaison/AlishanTrain.java
https://sites.google.com/site/digikaison/Car.java
https://sites.google.com/site/digikaison/DifferentialPilot2.java
https://sites.google.com/site/digikaison/BlackWhiteSensor.java
https://sites.google.com/site/digikaison/Turn.java
https://sites.google.com/site/digikaison/FollowLine.java
https://sites.google.com/site/digikaison/CatchLine.java

No comments:

Post a Comment