fredag den 15. oktober 2010

Week 6 in LEGO lab

Date: 7. October
Duration of activity: 8 hours
Groups members participating: Michael Vilhelmsen, Heine Stokholm og Mads Møller Jensen


Robot race


I dag er målet at bygge en robot, der kan konkurrere i LEGOLABs officielle ROBOT RACE.
Robot kapløbet går ud på at bygge en robot, som kan gennemføre "The Alishan Train Track" på hurtigst mulig tid.


Robotten tager udgangspunkt i PID system vi lavede sidste uge. Koden kan ses her.
Svingene i denne bane er ret specielle og meget svære for en robot, der kun kan følge en sort linje.
Derfor har vi modificeret programmet som følger:


Istedet for kun at have vores pid system til at styre robotten har vi nu også nogle forskellige states robotten kan være i repræsenteret ved følgende booleans:



         boolean rightTurn = false;
boolean leftTurn = false;
boolean direction = true;
boolean rightTurnAllowed = true;
boolean leftTurnAllowed = false;
boolean rightFinished = false;
boolean rightFinished2 = false;
boolean leftFinished = false;
boolean up = true;



Når rightTurnAllowed er true tjekker vi hele tiden den venstre sensor for om den ser sort, og hvis den gør laver vi følgende ændring på motorkraften:


         if(rightTurn) powerC = (powerA * 100 ) / 175;


Det vil sige at vi giver mere kraft til den inderste motor i svinget så robotten svingere blødere. Derefter registrerer vi så om den forreste sensor registrer sort så vi har færdiggjort svinget. 



I starten kunne robotten godt køre op ad banen:


 


Men som det ses havde vi allerede her lidt problemer med lys sensoren, som var spændt helt fast. Dette viste sig også at være et problem, når vi skulle ned af banen, fordi sensoren ikke kunne se den sorte streg, når robotten kørte ud over kanten, fordi sensoren blev løftet og fik andre værdier. Derfor valgte vi at modificere lidt i robotdesignet, så sensoren kunne få mulighed for at have en konstant afstand til banen.
Desværre gjorde det, at sensoren kom for langt frem i forhold til hjulene, så robotten blev umulig at styre. Sensoren fik robotten til at køre af sporet fordi den kom til svingene før selve robotten, og sendte den dermed på afveje. 
Vi skiftede derfor tilbage til det tidligere design og arbejdede videre med koden, for at undgå de fejllæsninger som sensoren laver, når vi kører ned af banen. 

Ved første forsøg på at køre ned, prøvede vi til dels at hardcode svingene, så robotten fulgte nogle bestemte instruktioner, når den (ved første sving) venstre lysmåler så en sort streg. Det gav dog nogle problemer, da robotten ikke var konsistent i kørslen, pga. PID systemet, som gjorde at vi ramte plateauet forskelligt hver gang.
Vi brugte mange forsøg og tweakede konstanterne, men udslaget var forskelligt hver gang, så robotten nogle gange kun kunne klare første sving og andre gange kun kunne klare sving nummer 2. 

Pga. de mange komplikationer gik vi tilbage til vores oprindelige PID system, og i vores næste forsøg forsøgte vi at ændre PID systemet, når robotten var i gang med at svinge, i håb om at den så kunne finde tilbage på banen. Dette lykkedes til dels, men robotten var stadig for inkonsistent til at dette virkede hver gang. Ved et perfekt gennemløb kunne robotten godt klare nedturen, men der var for langt mellem disse.


Selvom systemet ikke var perfekt, prøvede vi alligevel at implementere rotationen på toppen og stoppet i bunden. Det gjorde vi ved at hardcode en lille fremdrift efterfulgt af en 180 grader rotation når vi var færdige med venstresvinget og både venstre og højre lyssensor så en sort streg på samme tid. Dette fungerede udemærket efter en del tweaking af de forskellige variable. Stoppet i bunden fungerede ved at hvis begge sensorer målte sort og vores boolean up fortalte vi var på vej ned, så stoppede vi. 


Vi stod altså med en robot, som nogle gange kunne køre op ad banen og nogle gange kunne køre ned. Desværre måtte vi se i øjnene at vores styring var for inkonsistent, så det lykkedes os aldrig at få robotten til at køre både op og ned. Det tætteste vi kom, var at robotten kørte op og vende og kørte igennem første sving på vej ned og derefter kørte den af sporet. 
Koden og robotdesignet var altså desværre ikke tilstrækkeligt til at gennemføre banen!





torsdag den 7. oktober 2010

Week 5 in LEGO lab

Date: 30. September
Duration of activity: 3 hours
Groups members participating: Heine Stokholm, Michael Vilhelmsen and Mads Møller Jensen

Dagens opgaver:
  • Opbyg LEGO-robotten og lav et program, der benytter og tester klassen BlackAndWhiteSensor.java
  • Prøv programmet LineFollowerCal.java, der benytter BlackAndWhiteSensor klassen. (Optimér programmet så robotten følger linjen blødere og hurtigere
  • Lav et program ColorSensor.java ved at ændre i BlackAndWhiteSensor.java. Test ColorSensor og se om et sådant program er brugbart
  • Implementer ColorSensor i LineFollower så robotten stopper i en grøn målzone.
BlackAndWhiteSensor
Efter en ombygning fra sidste uge har LEGO-robotten Thor skiftet udseende og ser nu således ud:


BlackAndWhiteSensor programmet går ud på, at man kalibrerer lyssensoren til en hvid farve og en sort farve. Programmet beregner så en median (thershold). Hvis målinger herefter er over threshold-værdien sige robotten: "White", og hvis en måling er under værdien siger robotten: "Black".
Vi har ændret lidt i programmet, så vi bruger LightSensor'ens readNormalizedValue() i stedet for den i forvejen brugte readValue(). readNormalizedValue() læser nemlig raw value (0-1032), hvorimod readValue() læser en procentvis værdi (0-100). Derved får vi mere præcision i målingerne.


LineFollower
Vi har uploaded LineFollowerCal.java med følgende resultat:

Videoen lyver lidt da Thor har problemer med at følge linjen den anden vej rundt og ryger ud i svinget.

ColorSensor
Color sensoren er en udvidelse af den tidligere omtalte b/w sensor. Den fungerer ved at man udover sort og hvid også måler en tredje værdi som ligger mellem sort og hvid som vi har kaldt grøn. Så kan man spørge sensoren om man er over hvid, grøn eller sort. Det giver dog problemer da lyssensoren registrerer den grønne værdi hver gang man er på vej væk fra stregen. 

Three level lineFollower
Vores næste forsøg var at lave en three level lineFollower. Det vil sige at når vi registrede grøn ved vores lightsensor fik vi robotten til at køre ligeud. Det fik gjort den lidt mere flydende, men slet ikke optimalt. Derfor prøver vi nu en pid LineFollower.

Pid LineFollower
Vi har lavet et PID system jvf. artiklen A PID Controller for Lego Mindstorm Robots. Vi startede med at sætte værdierne Ki og Kd til 0. Robotten var altså nu kun afhængig af Kp. Vi fandt så en passende værdi, som gjorde at robotten kunne følge en linje uden at miste sporet, og uden at oscillere alt for meget. Denne værdi valgte vi så at kalde Kc. Herefter målte vi frekvensen af de oscillationer robotten foretog. Denne værdi kaldte vi for Pc. Til sidst fandt vi ud af at vores while-loop tog cirka 0.01 sekund at gennemløbe. Med disse tal kunne vi bruge Ziegler–Nichols metoden vha. følgende skema:


I koden kom det til at se således ud:

  //critical value (Vi har fundet den vha forsøg)
  int Kc = 60;
  double Kp = Kc * 0.6;

  //2*Kp*dT/Pc, (Pc og dT målt ved forsøg) 
  double Ki = (2*Kp*0.01) / 0.5;


  //(Kp*Pc)/8dT
  double Kd = (Kp*0.5)/(0.08);

Dette betyder at vi kan optimere robotten ved at tweake Tp og Kc, hvorefter de andre værdier vil tilpasse sig.


Robotten kom til at følge linjen fornuftigt ved brug af PID kontrollen:



Hele koden kan ses her: LineFollowerCS.java


STOP!
Vi skulle herefter forsøge at få robotten til at stoppe i den grønne målzone. Ved brug af kun en sensor var dette umuligt, da robotten hele tiden læste en grå værdi, svarende til den grønne. Vi valgte derfor at tilføje en ekstra sensor, som kunne måle en grøn værdi som ikke var i forbindelse med den sorte linje.
Vores robotdesign ser nu sådan ud:


Den ekstra kode vi har tilføjet til LineFollowerCS.java er følgende:


RCXLightSensor sensorLeft = new RCXLightSensor(SensorPort.S3);
...
sensorLeft.setFloodlight(true);
...

if(sensorLeft.getNormalizedLightValue()  < 340 &&  sensorLeft.getNormalizedLightValue()  > 290)
{
stop++;
} else {
stop = 0;
}
 
if(stop > 30){
System.exit(0);
}
}



Dette gav følgende resultat:




I næste uge skal vi bruge disse egenskaber og modificerer dem til at bygge en robot, som kan deltage i en konkurrence kapløb mod andre robotter.