SAM 

af Alexander Nygreen, Miriam Krebs og Sille Pedersen

 

Indledning

SAM er en bil bygget af LEGO klodser og elektroniske komponenter bestående af en Arduino, to refleksionssensorer, to motorer og en ultralydssensor. SAM skal køre igennem en bane hvor den skal følge en sort linie med to sving og registrere en mur den skal køre udenom.

1.0 Produktbeskrivelse

SAM er en bil der er bygget til det formål at kommet igennem et forudbestemt bane. Banen består af en lang sort streg med to sving. Denne streg skal SAM følge. Den må ikke kører over de røde streger som agerer murer, da det giver strafpoint.. Den sidste sorte streg længst til venstre er mållinien og den røde streg, ved siden af mållinien, vil være bygget af LEGO Dublo klodser således at det også giver strafpoint at vælte muren. (se figur 1.1)

Figur 1.1 – banen

SAM har to motorer der styrer et hjul hver. Den har to refleksionssensorer der er placeret under bilen. Disse er på hver deres side af den sorte streg og så længe de ikke registrerer sort, skal SAM køre lige ud. Registrerer den ene sensor at SAM kommer over den sorte streg skal SAM rette op ved at få det ene hjul til at køre hurtigt baglæns og sætte hastigheden op på det andet. Registrerer begge sensorer sort, skal SAM stoppe motorerne og gøre sig klar til at komme rundt om muren. Til det bruger SAM en ultralydssensor som registrerer afstanden mellem den selv og muren. Hvis SAM kommer tættere på muren end 10 cm eller længere væk end 18 cm. skal SAM rette op. Når SAM ikke længere registrerer muren skal den dreje højre om.

2.0 Materialeliste

Arduino UNO

  • Der bliver brugt en Arduino UNO til projektet. Denne behandler input fra refleksionssensorerne og ultralydssensoren.

Refleksionssensor QRE1113

  • En refleksionssensor består af en IR-emitterende LED og en IR-følsom fototransistor. Den virker ved at fototransistoren reagere på den mængde af IR-lys LED’en reflekterer tilbage til den. Den giver høje værdier for lyse overflader. Der bliver brugt to af disse sensorer til SAM.

Ultralydssensor

  • En ultralydssensoren sender en højfrekvent lydpuls ud og måler hvor lang tid det tager for lydens ekko at reflektere tilbage. Denne sensor kan måle når den er mellem 2 til 400 cm fra et andet objekt.

To LEGO motor serienr. 43362

 

3.0 Kredsløb

Kredsløbet for SAM består af en batteripakke for strøm til bilen, en tænd/sluk knap, to motorer til at drive SAM frem, en ultralydssensor til at registrere muren og to reflektionssensorer til at følge linien. Figur 3.1 viser et andet billede på en reflektionssensor end den benyttede QRE1113 da Fritzing programmet ikke havde denne komponent.

Figur 3.1 – diagramtegning af SAM fra Fritzing

Figur 3.2 – kredsløbstegning af SAM fra Fritzing

4.0 Fysisk konstruktion (LEGO)

SAM er konstrueret således, at der er plads til både breadboard, arduino og batteripakke. De to større hjul er drivkraften til bilen og er koblet til motoren via to tandhjul, et lille på motoren, et stort på hjulet for at øge drejningsmomentet. Der var problemer med vejgrebet, som der senere vil blive nævnt og det tænktes et større drejningsmoment kunne bidrage til en løsning. Hvert hjul er koblet til egen motor, da dette giver kontrol over SAM´s bevægelsesmønstre. Under SAM er der en LEGO-udbygning, denne eksisterer af den simple årsag, for at få refleksionssensorerne så tæt på jorden som muligt. Dette giver et mere præcist resultat af målingerne fra refleksionssensorerne. Da SAM holder på alt elektronikken, er der implementeret et lille hjul på undersiden af bagenden, som er med til at stabilisere og som mindsker friktionen mellem gulv og bil. Derudover er der også fastsat nogle barrierer (de sorte byggeklodser), der sørger for at elektronikken forbliver på sin plads og ikke falder af i farten.

Figur 4.1 – SAM fra LEGO Digital Designer

 

5.0 Opførsel

(Figur 5.1) viser et flowchart over SAM, således at hans forskellige beslutninger bliver visualiseret. Dette indebærer eksempelvis hvornår den skal køre til henholdsvis højre eller venstre, hvornår den skal køre ligeud og hvornår dens decision trigger skal skifte. Flowchartet skal læses som et loop, der gentagende gange undersøge hvilket stadie bilen er i og hvilke bevægelser den skal gøre som det næste.

Figur 5.1 – flowchart af SAM

 

6.0 Kode

Da bilen styres af to decision triggers, hvilke enten er refleksionssensorerne eller en ultralydssensor, bliver der differentieret mellem hvilken af disse to triggers, den skal tage input fra. Måden hvorpå dette gøres, er ved at have forskellige stadier. SAM skifter mellem 3 stadier, hvilke er enten driveMode 0, driveMode 1 og driveMode 2. Ved driveMode 0 tager SAM input fra refleksionssensorerne og styrer bilen derigennem. Når begge sensorer registrerer en sort farve samtidig, skifter SAM stadie, hvorved driveMode 1 aktiveres. Når driveMode 1 er aktiveret, tager SAM input fra ultrasonic sensoren. Afslutningsvis skifter SAM stadie til driveMode 2, hvilket indikerer at ruten er lykkedes og bilen skal lave en sejrsdans hvor den snurrer rundt om sig selv.

driveMode 0

For at SAM ikke afviger fra den sorte linje er der som tidligere nævnt implementeret to refleksionssensorer. Kriteriet for at SAM kører ligeud er, at begge sensorer måler en værdi svarende til en hvid baggrund. Der blev testet frem til en threshold på 550, hvor under denne værdi blev betragtet som hvidt, og over blev betragtet som sort.(Figur 6.1)

if (lineAVal > THRESHOLD && lineBVal > THRESHOLD)

   {

     // Når den er når krydslinje, så skal den stoppe, køre frem, dreje, og skifte til drive mode 1

     //Serial.println("Stopping");

     driveStop();

     // kør fremad ~12cm

     driveStart();

     driveStraight();

     delay(2000);

     //stop på stedet og drej skarpt venstre

     driveStop();

     driveStart();

     hardLeft();

     driveMode = 1; //skift til væg følge mode

   }

   else if (lineAVal < THRESHOLD && lineBVal < THRESHOLD) {

     //Serial.println("drive forward");

     driveStraight();

   }

   else if (lineBVal > THRESHOLD && lineAVal < THRESHOLD) {

     //Serial.println("turn right");

     turnRight();

   }

   else if (lineAVal > THRESHOLD && lineBVal < THRESHOLD) {

     //Serial.println("turn left");

     turnLeft();

   }

Figur 6.1 – Kode til at følge linje


Måler begge sensorer en værdi svarende til et sort underlag, startes funktionen driveStop();, hvilket bremser bilen. (Figur 6.2) I samme kodeblok skifter SAM også stadie, hvor driveMode 1 påbegyndes. 

void driveStop() {

 analogWrite(pwmA, 0);

 analogWrite(pwmB, 0);

 digitalWrite(brakeA, HIGH);

 digitalWrite(brakeB, HIGH);

 delay(BREAK_TIME);//giver bremserne tid til at slå til

}

Figur 6.2 – driveStop funktion


Ligeledes vil SAM, ved registrering af et sort underlag på en af refleksionssensorerne, dreje til henholdsvis højre eller venstre. Sker registreringen af højre sensor, så bevæger bilen sig mod højre, registreres det af venstre sensor, så bevæger bilen sig til venstre. (Figur 6.3)

void turnLeft() {

 digitalWrite(dirA, HIGH);

 digitalWrite(dirB, LOW);

 analogWrite(pwmA, TURN_FORCE);

 analogWrite(pwmB, FORWARD_FORCE);

}

void turnRight() {

 digitalWrite(dirA, LOW);

 digitalWrite(dirB, HIGH);

 analogWrite(pwmA, FORWARD_FORCE);

 analogWrite(pwmB, TURN_FORCE);

}

Figur 6.3 – turnLeft & turnRight funktion

Da rotationen skal ske forholdsvis skarpt, opnås dette ved at ændre retningen på det hjul som ikke registrerer det sorte underlag. Derudover bliver bilens hastighed sat op for begge hjul, dog mere på det hjul der kører baglæns frem for det som kører forlæns. Derved bliver bilen hurtigt rettet op og kan fortsætte med at køre indtil en af sensorerne registrerer et sort underlag igen.

Registrerer begge sensorer et hvidt underlag, får begge motorer lige meget power, hvorved bilen vil fortsætte ligeud. (Figur 6.4)

void driveStraight() {

 digitalWrite(dirA, LOW);

 digitalWrite(dirB, LOW);

 analogWrite(pwmA, CRUISE_FORCE);

 analogWrite(pwmB, CRUISE_FORCE);

}

Figur 6.4 – driveStraight funktionen

driveMode 1

    //drej om hjørnet
    if (distance > EMPTY_SPACE) {
      driveStop();
      driveStart();
      hardRight();
      //-> kør forbi mur
      driveStraight();
      delay(4000);
      driveStop();
      driveStart();
      hardRight();
      //-> kør frem til mur
      driveStraight();
      delay(2000);
    }
    //juster til venstre
    else if (distance < CLOSE) {
      //Serial.println("echo");
      // her skal bilen dreje til venstre
      driveLeft();

      //juster til højre
    } else if (distance > FAR_AWAY) {
      // her skal bilen dreje til højre
      driveRight();
    } else {
      // her skal bilen fortsætte ligeud
      driveStraight();
    }

Figur 6.5 – kode for at navigere om mur


driveMode1 fungerer meget lig driveMode0, men i stedet for at skulle følge den sorte linje, prøver den at holde sig en fastsat afstand fra muren på dens højre side. Hvis den kommer for langt til den ene eller den anden side, skal den dreje tilbage mod midten. For at sikre at den vil forsøge at finde muren igen, er der blevet lavet en konstant EMPTY_SPACE, der indikerer om hvorvidt der stadigvæk befinder sig en mur på højre side af bilen. Denne har en rækkevide på 40 cm. Det vil altså sige, at hvis bilen ikke registrere en mur indenfor  40 cm, vil den skiftevis køre frem og dreje til højre til den har rundet muren.

Højresvinget styres  vha. hardRight() funktionen. Denne funktion får den til at dreje 90 grader til højre, se figur 6.6, værdierne skal tilpasses efter vægtfordeling og motorkraft. Derefter kører den en hardcoded mængde tid til den har passeret muren. Det er her nødvendigt at den hardcoded tid ikke er for kort, hvis SAM hænger for meget til venstre, eller kører over banen hvis SAM hænger til højre. Dernæst skal den tage endnu et 90 graders sving til højre. SAM skal så køre frem en hardcoded længde indtil ultralydssensoren er parallel med muren (igen er en buffer nødvendig), hvorefter den går tilbage til at følge muren som før.

//90 graders sving
void hardLeft() {
  digitalWrite(dirA, HIGH);
  digitalWrite(dirB, LOW);
  analogWrite(pwmA, HARD_TURN_FORCE);
  analogWrite(pwmB, HARD_TURN_FORCE);
  //runs for a certain amount of milliseconds
  delay(HARD_TURN_TIME);

  //pull the brakes, return to start values
  digitalWrite(dirA, LOW);
  driveStop();
  delay(10);
  driveStart();
}
void hardRight() {
  digitalWrite(dirA, LOW);
  digitalWrite(dirB, HIGH);
  analogWrite(pwmA, HARD_TURN_FORCE);
  analogWrite(pwmB, HARD_TURN_FORCE);
  delay(HARD_TURN_TIME);

  //pull the brakes, return to start values
  digitalWrite(dirB, LOW);
  driveStop();
  delay(10);
  driveStart();
}

Figur 6.6  – hardRight og hardLeft funktionerne 

 

   digitalWrite(triggerPin, LOW);

   delayMicroseconds(2);

   digitalWrite(triggerPin, HIGH);

   delayMicroseconds(10);

   digitalWrite(triggerPin, LOW);

   duration = pulseIn(echoPin, HIGH);

   distance = (duration / 2) / 29.1;

Figur 6.7 – kode der håndtere ultralydssensoren

Ultralydssensoren består af 2 dele, en transmitter og en receiver. Transmitteren er i stand til at sende 2 slags lydsignaler ud: HIGH og LOW. Når der skal foretages en måling på afstand mellem væg og ultralydssensor, sendes der først en kort LOW ultralyds bølge ud for at “rense luften” (for at reducere graden af “støj” der kan påvirke målingen), derefter sendes der en noget længere HIGH bølge ud, efterfulgt af endnu en LOW til at give HIGH bølgen en ende. Receiver modtager og måler så hvor lang tid det tog for HIGH bølgen at blive sendt tilbage og gemmer denne værdi i variablen “duration”, der gennem en  formel konverteres til afstand i cm (distance). I slutningen af dette loop er der et kort delay (250 millisekunder) for at forhindre at målingerne påvirker hinanden.

Figur 6.8 – Illustration af anden del af banen, med relevante afstande indsat

driveMode 2

Sejrsdansen fungere ved at SAM hvert 0,5 sekund drejer 90 grader til venstre vha. hardLeft funktionen (se Figur 6.7).

else if (driveMode = 2) {
   hardLeft();
   delay(500);
 }

Figur 6.9 – kode for sejrsdans

Der var ikke tid til at få sejrsdansen implementeret, men skulle det gøres, var det tiltænkt at det kunne gøres på 2 måder:

  1. Fortsæt med at aflæse på refleksionssensorer i driveMode 1 og skift til driveMode 2, når anden stoplinje er nået. Her risikeres det dog at de mange sensorer der skal køre på samme tid dræner for meget energi fra batterierne hvilket sænker motorernes ydeevne og kræver re-justering af værdier. Ydermere kan en meget snavset bane få SAM til at skifte til driveMode 2 for tidligt hvilket gør det umuligt for den at nå igennem banen.
  2. Sætte en timer der starter med at tælle ned efter SAM har rundet muren, ud fra den tid det normalt tager den at passere målet (plus en buffer), og skifter til driveMode2 når timer når 0. Dette kræver dog hardcoding, hvilket mindsker mængden af forskellige forhold den kan arbejde under, og fører til at kræver at koden skal justeres når der sker ændringer i designet.

 

Udfordringer ved SAM

Der har været en del udfordringer med at få SAM til at køre efter hensigten. Nogle af problemerne har skyldtes at banen, SAM skulle køre på, var for beskidt og refleksionssensorerne derfor gav blandede målinger. Andre problemer har været hjulene, som skøjtede rundt og ikke kunne få ordentligt vejgreb når der skulle drejes. Gruppen arbejdede med at ændre gearingen, prøvede at stabilisere hjulene med andre LEGO klodser og skifte til større hjul. Det gav bedre vejgreb, men løste ikke problemet helt. I forhold til strøm har gruppen været meget overrasket over hvor stor en forskel der er på strøm fra computeren og strøm fra batterier. Selv i forhold til almindelige batterier og genopladelige batterier. Det har gjort at gruppens konstante værdier har skulle ændres mange gange for at justere til strømstyrken. De genopladelige batterier der blev udleveret var dog af ældre dato, hvilket var til meget besvær under testfasen da de hurtigt ville blive drænet til et punkt hvor det begyndte at påvirke motorernes ydeevne.

Refleksionssensorerne skulle placeres meget tæt på jorden for at få mest pålidelige målinger (med færrest udslag påvirket af støj), dog uden at de kommer i reel berøring med den. Sensorens lille størrelse, kombineret med et opgavekrav om at LEGO’et ikke måtte beskadiges under konstruktionen resulterede i at der til sidst måtte bruges en stor mængde gaffatape til at fæstne dem som ønsket.

For at SAM bedst kunne dreje krævede det at der blev fundet nogle passende værdier for hvornår motorerne skulle dreje om hjørner og deres kurs skulle tilpasses. Ud fra samtaler med klassekammerater blev det fundet frem til at den bedste måde at dreje var at sætte en motor til at køre baglæns og den anden til at køre forlæns, men da SAM er markant lettere, og mere kompakt end andre modeller til denne opgave, var det kun i ringe grad muligt at aflæse de værdier klassekammerater brugte. At finde den rigtige dreje kraft var en balancegang. Var kraften for høj, drejede SAM for skarpt og endte med begge sensorer placeret horisontalt på linje,  var kraften for lav kunne SAM ikke dreje hurtigt nok i svingende og den ville kører over linjen og fortsætte lige ud til den nåede en mur. Derudover var robottens vægtfordeling forskellig, hvorved at bilen altid ville hælde til henholdsvis højre eller venstre, når den forsøgte at køre ligeud. Der var tre variabler der kunne justeres for at finde den rette værdi: fremadrettet kræft, bagudrettet kraft, og forskellen mellem de to. Grundet gruppens begrænsede erfaring med robot konstruktion viste samspillet mellem disse tre værdier sig for overvældende at forstå og det blev accepteret at det ikke var muligt inden for deadline at konstruere en robot der kunne dreje tilpas godt til at komme igennem banen.

Testkørsel

SAM var ikke i stand til at klare banen. Ved forudgående prøver var problemet at SAM enten drejede for hårdt, eller ikke drejede hårdt nok. Under selve testkørslen var problemet dog i stedet at SAM udelukkende kørte til venstre, det blev foreslået at der enten var kommet lim fra gaffatape’en der fæstnede sensorerne i måleinstrumenterne, eller at de på anden måde var blevet beskadiget. Der var dog ikke mulighed for at løse dette under testen, da det ville kræve større reparationsarbejde end var rimeligt indenfor tidsrummet.

Figur 7.1 – Testkørsel

Konklusion

På trods af flere forsøg at tilgå robotten og koden på, er det ikke lykkedes at få en velfungerende robot op at køre. Koden fungerer fint og teoretisk set burde robotten virke, men det gør den ikke. Der er mange faktorer der spiller ind over at SAM ikke fungerer optimalt, hvilket blandt andet er banen, konstruktionen af bilen, skiftende målinger og ændring af strømforsyning såsom batterier, opkobling til computer mm.

Ved konstruktionen var der forsøgt at tage højde for nogle problematikker som gruppen tænkte kunne hænde, det viste sig dog at det åbnede op for en langt større række problemer.

Der er forsøgt at tage højde for at alle gruppemedlemmer kunne programmere og arbejde med arduinoen, hvilket i og for sig er en god idé, da det giver et større udbytte for alle, problematikken med dette var, at forskellige processer var afhængige af hinanden og dette var med til at udskyde processen og gøre det svært at teste de forskellige funktionaliteter individuelt. Et andet problem var også at sammenkobling af de forskellige processer viste sig at være langt mere tidskrævende og kompliceret end forventet.

 

Perspektivering

Gruppen delte opgaverne op i tre dele, som blev delt ud mellem hvert medlem; konstruktion af bilen med kode til at få motorerne til at køre fremad, kode til at få refleksionssensorerne til at følge den sorte streg og kode til ultralydssensor så den køre udenom væggen. Opgaverne blev delt op for at hvert gruppemedlem kunne lege med Arduino uafhængigt af hinanden da gruppe følte man hurtigt kunne blive for mange ind over én Arduino. Hver enkelte opgave virkede som de skulle, men da det hele blev koblet sammen og SAM blev sat på banen, kørte den ikke som forventet. Der er blevet lagt mange timer i at få SAM til at køre, men den gør stadig ikke som forventet hver gang til stor frustration for gruppen.

Gruppen lånte en ultralydssensor, men ville godt have haft to. Den ene ultralydssensor skulle registrere væggen og dreje og den anden skulle følge væggen. Da gruppen kun kunne låne sig til én, blev det hardcoded i SAM  at den skulle dreje når den nåede den sorte streg.

Modsat de fleste andre grupper der arbejde på samme opgave havde SAM sine motorer placeret forrest på chassiset i stedet for bagerst. Dette var gjort i et forsøg på at give bedst mulighed for skarpe sving (fordi omdrejningspunktet var så langt fremme som muligt), men som SAM begyndte at tage form viste det sig at den ofte drejede for skarpt – En mulig forbedring kunne derfor være at placere motorerne/de kørende hjul længere tilbage på chassiset. Ydermere var refleksionssensorerne også placeret umiddelbart bag motorerne for at placere dem i skygge under chassiset, for at forhindre støj i form af lys. Dette har dog ført til at der skal drejes med stor præcision, i de værdier motorerne bliver givet, da de allerede er noget forbi det punkt hvor de optimalt set skulle dreje. Det ville derfor have været bedre, hvis  sensorerne var placeret foran motorerne. Da den opdagelse blev gjort, var det for sent i processen til at ændre, da det grundlæggende krævede at bilen blev bygget om.

Retroperspektivt har processen været meget lærerig, på trods af at bilen ikke fungerer som ønsket. Det har givet en bedre indsigt i hvor stor en betydning konstruktionen har og hvor mange faktorer der reelt spiller ind over at få en bil til at køre samt få den til at undvige nogle forhindringer. Derudover er det også blevet tydeligt hvor kompliceret en process det er, at få flere komponenter til at spille sammen og at få koblet koden og konstruktionen sammen til et velfungerende endeligt produkt.

 

ZIP fil med byggevejledning og komplet kode findes på følgende link: 

Byggevejledning:

Download (ZIP, 983KB)

Komplet kode:

Download (ZIP, 2KB)

Leave a Reply