fredag den 14. december 2007

Vejfinder 6

Blog6:

Varighed: 6 timer, Deltagere: Rolf og Janus

Målet idag er at få LineFollower til at virke og evt. få yderligere funktioner - f.eks. i GridBuilderen - skrevet og testet.

Vi vil opnå vores mål idag ved at:

  • Færdiggøre LineFollower-koden fra igår
  • Rette koden og sensorerne således at robotten så vidt muligt følger linierne i højre side af vejen.
  • Undersøge hvor præcist vi kan få robotten til at følge en linie (dette vil have inflydelse på hvor nemt det bliver at opdage sideveje i både højre og venstre side af vejen

LineFollowerBehaviour

LineFollowerBehaviour er lavet til at følge kanten imellem græsset og vejen rundt langs højrekanten på en vejplade. Algoritmen er 2-delt: en del der kører lidt frem, og en del som drejer i forhold til vejen.

(Bemærk venligst at den følgende kode er fra den nyeste version af LineFollowBehavior og altså ikke den kode, som giver de lidt "hakkende" bevægleser, der ses på videoen længere nede)

while (!core.isDone()) {
    findAndGotoEdge();
    driveForwardABit();
    Thread.yield();
}

Ovenfor ses hovedløkken i vores line follow behaviour. For hvert gennemløb udføres to opgaver: Først drejer robotten sig efter kanten af vejen, derefter kører den en smule frem. I de følgende afsnit gennemgår vi de to funktioner i detaljer.

findAndGotoEdge()

core.getNavigator().rotateLeft();
while(getRightSensor() == RoadSensorValue.ONGRASS) {
    try {
        Thread.sleep(10);
    }
    catch(Exception e) {
    }
}
core.getNavigator().stop();

float angleBefore = core.getNavigator().getAngle();

Først roterer vi robotten mod venstre, indtil den højre sensor ikke længere ser græs. Vi gemmer så den vinkel, som robotten står i.

core.getNavigator().rotateRight();
while(getLeftSensor() == RoadSensorValue.ONROAD) {
    try {
        Thread.sleep(10);
    }
    catch(Exception e) {

    }
}
core.getNavigator().stop();

angleBefore = leastAngleBetween(angleBefore, core.getNavigator().getAngle());

Så roterer vi nu robotten mod højre, indtil den venstre sensor ikke længere er på vejen. Herefter udregner vi den mindste vinkel imellem den forrige gemte vinkel, og den nye målte vinkel.

float rotation = angleBefore / 2.0f;

// We now know the approximate direction of "straight forward"
core.getNavigator().rotate(rotation);

Nu kan vi tage halvdelen af den udregnede vinkel, og dette er den vinkel vi skal dreje for at køre "langs" med kanten af vejen. Derfor drejer vi robotten den udregnede vinkel.


På billedet er skitseret hvordan findAndGotoEdge() fungerer. Pilene angiver den vej robotten er drejet, når man bevæger sig fra billede (1) til (2), og fra (2) til (3). Vinklerne v og w, bruges til at udregne den afvigelse, som robotten i øjeblikket har fra at køre ligeud langs vejen.

driveForwardABit()

boolean first = true;
core.getNavigator().forward();
do {
    try {
        if( first ) {
            Thread.sleep(500);
            first = false;
        }else {
            Thread.sleep(10);
        }
        core.getNavigator().updatePosition();
    }
    catch(Exception e) {

    }
} while (getLeftSensor() == RoadSensorValue.ONROAD && getRightSensor() == RoadSensorValue.ONGRASS);
core.getNavigator().stop();

Her kører vi for hvert løkkegennemløb fremad i 10msec. Bortset fra første gang løkken udføres hvor der køres frem i 0.5sec. Vi stopper med at køre frem når den højre sensor enten ikke længere ser græs, eller den venstre sensor ikke længere ser vej. Grunden til at vi i første gennemløb kører frem i 0.5sec istedet for de 10msec er at robotten ellers ikke nødvendighvis får flyttet sig nok. Hvis den er kommet til at holde et dumt sted kan den "låse sig fast". Ved først at køre i 0.5sec er vi sikre på at robotten ihvertfald bliver flyttet en smule, derfor kan vi altid komme videre.

Test af LineFollowBehaviour

Vi byggede en bane med de forskellige vejelementer vi havde tilgængelige og kiggede efter hvordan robotten bar sig ad med at følge højre kant rundt langs banen. Resultatet kan ses i videoen herunder.

LightSensorer

Generelt er det svært at bruge lyssensorer[light] , fordi vi som mennesker er vænnet til at opfatte objekter næsten uanset hvilken lyssætning de er i, og vi ingen problemer har med at genkende endda ganske mange forskellige farvevariationer. Det forholder sig anderledes for robotter, som har enddog særdeles svært ved at "abstrahere" imellem forskellige lyssætninger, de opfatter verden i absolutte værdier.

Lyssensorerne på vores robot skal kunne kende forskel på grøn og grå. Det viste sig at den mest simple metode til denne type genkendelse var den der virkede bedst, men for god ordens skyld gennemgår vi lige nogle af de ander metoder, som vi også forsøgte.

Det største problem var at lyset i vores testlokale var delvist retningsbestemt. Det vil sige at når robotten vendte mod nord modtog den mere lys end når den vendte mod syd. Af denne grund valgte vi at afprøve et system, hvor vi tillod at skillepunktet imellem grøn og grå farve kunne "flytte sig" iløbet af en gennemkørsel. Det viste sig dog at det gjorde robotten særdeles følsom over for mørkere slidmærker på vejen.

Vi forsøgte os også med en alternativ løsning: se på forskellen i lys, hvis det pludseligt er blevet meget lysere for en sensor er det fordi den er gået fra grøn til grå (grå er lysere end grøn). I samme stil må man være gået fra grå til grøn hvis det pludseligt bliver meget mørkere.
Denne tilgang virkede til dels, det eneste problem var at forskellen imellem grøn og grå tilnærmelsesvis var den samme forskel som imellem hvid og grå, og kortet indeholder hvide fodgængerfelter.
Vi prøvede derfor med en 3-farvet udgave af algoritmen, som skulle kunne kende forskel på grå, grøn og hvid. Det viste sig dog at være næsten umuligt at holde styr på de tre farver på denne måde, når man samtidigt skal tage højde for at lyset kan ændre sig (ie. der kan komme en forskel som svarrer til et spring fra hvid til grå hvis robotten drejer sig så den skygger for sig selv).

Ander forsøg inkluderede udskårne pap-plader til blokering af lyset, prøver med forskellige typer af lys (der er forskel på lysstofrør, sollys, spotlamper osv.).[lyssammenligning]

Den endelige løsning blev at kalibrere lyssensorerne før selve kørslen. Hvis der er mere lys end en givet tærskel betyder det at en sensor ser grå, hvis der er mindre betyder det at den ser grøn.

Vi havde i starten lavet den forkerte antagelse, at begge lyssensorer ville returnere den samme værdi hvis de blev holdt over det samme sted, dette resulterede i at vores robot ikke fulgte vejen eftersom værdierne for vej/græs var forkerte for den ene af lyssensorerne. Dette rettede vi ved at have særskilte grænseværdier for hver lyssensor.

Videomateriale


På film-sekvensen ses LineFollower i aktion. Den følger den højre side af vejen.

Konklusion

Vores LineFollowBehavior virkede bedre end vi havde håbet på. Den følger kanten rundt på alle vejstykkerne, også hvis det er meget skarpe sving. Det burde give et godt fundament at bygge GridBuilder på, da vi nu er sikre på at vi kan følge vejen - endda uden alt for store afvigelser fra den "bedste" linje. Som det tydeligt ses på videoen virker LineFollowBehavior med de seperate sensor grænseværdier som den skal!

Noter

  • [Light] Tom Dean skriver i sine noter omkring sensorer netop et afsnit omkring nogle af de problemer, som vi har observeret i forbindelse med dette projekt. Yderligere nævner TD at overfladens teksturelle komposition og egenskaber spiller en stor rolle for hvordan lyset tilbagekastes. Vi har ikke lavet forsøg med andre overflader end de overflader der findes på legopladerne. Det er dog klart at hvis pladerne var mindre reflektive, ville målingerne kunne have været mere præcise og i mindre grad være påvirket af reflektioner af f.eks. loftslamper. Mere information på http://www.cs.brown.edu/people/tld/courses/cs148/02/sensors.html.
  • [LightComparison] En beskrivelse af nogle af egenskaberne for de gammeldags RCX sensorer er udført af Timo Paukku Dinnesen, Århus Universitet. Selv om denne undersøgelse beskæftiger sig med de gamle sensorer er mange af konklusionerne omkring farvegenkendelse relevante for de nye NXT-sensorer også. Undersøgelsen kan findes her: http://legolab.daimi.au.dk/DigitalControl.dir/RCX/PropertiesOfTwoLightSensors.pdf.

Ingen kommentarer: