“Blackbird” (Vinderrobot 2014)

Designet og programmeret af:
Henning Vestergaard, Stefan Petersen, Juri Wulff og Jakob Høg

2014-03-18 12.17.23

Robottens opbygning

Robotten har været igennem mange iterationer.

pic1

Første udgave “Hellikopteren”
Arduino-boardet, batteripakkerne eller sensorene kunne desværre ikke være nogle steder på dette design, så vi måtte tilbage på tegne- og byggebordet for at lave en markant større model.

 

 

pic2

 

 

Anden udgave “Trimaran”
Designet var markant større, men også langt mere skrøbeligt end det første. Så selvom der var plads til at sætte hardware på, så ville den formentlig være brast sammen hvis vi havde nået så langt. Det der først og fremmest fik os til at ændre design var, at den alt for bred til banen: Flere steder på banen kørte den over to parallelle streger samtidig!

 

Ok, spøg til side… Vi havde faktisk lavet en seriøs førsteudkast-udgave som vi testede på helt op til 4 dage før konkurrencen (i vores travlhed har vi dog glemt at dokumentere denne med et billede). Placeringen af hjul og batterier var ikke hensigtsmæssig, og den lavede nogle mærkelige bevægelser når den kørte. Det endelig design var en klar forbedring! Her ændrede vi positionen af hardware til at være lige over hjulakserne og det løste vores bevægelse og præcisions problemer!

Både i det “rigtige” førsteforsøgs-design (som vi ikke har et billede af) og i det endelig design havde vi brugt samme størrelse hjul. Vi havde valgt at bruge nogle store hjul som ikke var for brede, for at opnå større hastighed. Men vi fandt hurtigt ud af at hastigheden blev for høj, og derfor tilførte vi gearing; først med et mellemstort tandhjul på motoren hen til et lidt større på hjulene, sidenhen en forbedring af dette med et meget lille tandhjul på motoren og det største tandhjul vi kunne finde på selve dækket.

2014-03-18 12.17.44Vi har brugt to lyssensorer og en ultralydssensor. Lyssensorerne er placeret foran robotten, næsten på linje med hjulene, dog lidt tættere på hinanden. Ultralydssensoren er placeret i midten af fronten og den står vinkelret på en klods, sådan at den fik mere præcis måling.

Derudover er både batteripakker og arduinoboardet placeret sådan på robotten at de er nemme at tilgå. USB-stikket kan sættes direkte op i bagenden og batterierne kunne hurtigt tages ud ved at fjerne det ene hjul og en stopklods. Vi fik også sat en switch på som kunne tænde og slukke robotten, så vi ikke skulle fumle med at hive batteri-spændingen fra hele tiden.

Robottens hardware

På vores lyssensor sidder en diode der kræver en modstand for at ikke at få for meget strøm. For at beregne modstandens størrelse har vi brugt Ohms lov:

U = R · I
(U = spændning, R = modstand, I = strøm)

Vi kender systemets spænding og diodens max spænding som værende 5 v og 1,25 v. Disse to trækkes fra hinanden og der fås 3,75 v (U). Diodens strøm = 50 mA(I). Lys sensorens navn er cny70 og dennes strøm og spændningsforhold er hentet via et datablad (hint google cny70)

Ohms lov omskrives og variablerne sættes ind med SI-enheder:
Screen Shot 2014-03-28 at 10.53.44På hver lyssensor har vi brugt 75Ω.

robotsnapseed

Robottens opførsel

robot.pngI den røde cirkel ses lyssensoren, som består af en diode der udsender lys og en modtager af lys! I den blå cirkel ses ultralyds sensoren, som er positioneret så lige som muligt da det giver den bedst mulige forhold for signal modtagelse. Der er således to lyssensorer positioneret med ca. otte cm imellem hinanden.

Afstanden blev fundet via “trial and error” – banens sving og forhindringer havde stor betydning for positionering af disse.

 

 

Screen Shot 2014-03-18 at 15.01.41

På dette billede ses en prioritering for hvordan vores kode afvikles.

1. Ultralyd: Checker om der er et objekt foran
2. Sensor input: hvid/hvid – kører lige ud
3. Sensor input: sort/sort – kører lige ud
4. Sensor input: hvid/sort – drejer til højre
5. Sensor input: sort/hvid – drejer til venstre

/*************************************************************
 * 
 * Sensor 1 er den til venstre set fra styrehus (port A2).
 * Sensor 2 er den til højre set fra styrehus (port A3).
 * Motor A er den til venstre set fra styrehus.
 * Motor b er den til højre set fra styrehus.
 *************************************************************/
static int maxSpeedLeft = 135;  // vaerdi imellem 0-255, 0 er stillestaaende, 255 er hurtigt muligt.
static int maxSpeedRight = 140; //Bilen drejer naturligt til hoejre pga. mekanisk sloer, dette goer lidt op for det.
static int turnSpeed = 240;     //Naar vi drejer vil vi goere det saa hurtigt som muligt, bilen staar stille naar den drejer, derfor kan vi tillade os dette
static int d = 1; // readingsdelay
int i = 0;
int x = 0;
int reading = 0;
#include <Wire.h>

void setup() {

  //Setup Channel A
  pinMode(12, OUTPUT); //Initiates Motor Channel A pin
  pinMode(9, OUTPUT); //Initiates Brake Channel A pin

  //Setup Channel B
  pinMode(13, OUTPUT); //Initiates Motor Channel B pin
  pinMode(8, OUTPUT); //Initiates Brake Channel B pin

  // initialize serial communication at 9600 bits per second:
  //IR sensors
  Serial.begin(9600);
  Wire.begin();
}

void loop(){

  x++; 

  // step 1: instruct sensor to read echoes
  Wire.beginTransmission(112); // transmit to device #112 (0x70)
  // the address specified in the datasheet is 224 (0xE0)
  // but i2c adressing uses the LOW 7 bits so it's 112
  Wire.write(byte(0x00));      // sets register pointer to the command register (0x00)  
  Wire.write(byte(0x51));      // command sensor to measure in "inches" (0x50) 
  // use 0x51 for centimeters
  // use 0x52 for ping microseconds
  Wire.endTransmission();      // stop transmitting

  // step 2: wait for readings to happen
  if(x==6){            // denne kode vil eksekvere kun hver syvende gang, hvilket giver tid til transmitting imellem ultralydsensor og arduino

    // step 3: instruct sensor to return a particular echo reading
    Wire.beginTransmission(112); // transmit to device #112
    Wire.write(byte(0x02));      // sets register pointer to echo #1 register (0x02)
    Wire.endTransmission();      // stop transmitting

    // step 4: request reading from sensor
    Wire.requestFrom(112, 2);    // request 2 bytes from slave device #112

      // step 5: receive reading from sensor
    if(2 <= Wire.available())    // if two bytes were received
    {
      reading = Wire.read();  // receive LOW byte (overwrites previous reading)
      reading = reading << 8;    // shift LOW byte to be LOW 8 bits
      reading |= Wire.read(); // receive low byte as lower 8 bits
      Serial.print("Afstand");
      Serial.println(reading);   // print the reading
      if(reading > 12 && 22 > reading  ){

    //***************************************         
    //*      HARDCODED EVASIVE MANEUVER     * 
    //*      TO GET AROUND THE BOX          *   
    //***************************************    

   //       ___  ________   
   //                    |
   //                    |xxxx 
   // 0 : OBJECT         |   x
   // x : NEW ROUTE      0   x
   // _ : ROUTE          |  x
   // | : ROUTE    ______|x   
    digitalWrite(12, HIGH);  // 
    digitalWrite(9, HIGH);   //  Stopper bilen i 500milisekunder 
    digitalWrite(13, HIGH);  //  for at undgaa hastigheden har et udslag
    digitalWrite(8, HIGH);   //  paa det foelgende sving
    delay(500);    

   // motoren drejer om sin egen akse i 360milisekunder til venstre     
   // 360milisekunder svarer ca. til 90 grader     
   //Motor A
   digitalWrite(12, LOW); 
   digitalWrite(9, LOW);      
   analogWrite(3, turnSpeed);  //Bruger turnSpeed(hurtigste) fordi vi kan bedre styre bilen naar den er hardcoded, derfor kan vi tillade os det.

   //Motor B
   digitalWrite(13, HIGH);  
   digitalWrite(8, LOW);      
   analogWrite(11, turnSpeed);   
    delay(360);  

   //motoren koerer ligeud i 700milisekunder  

   //Motor A
   digitalWrite(12, LOW); 
   digitalWrite(9, LOW);  
   analogWrite(3, turnSpeed);  

   //Motor B
   digitalWrite(13, LOW);  
   digitalWrite(8, LOW);  
   analogWrite(11, turnSpeed);   
    delay(700);  

  //motoren drejer om sin egen akse til hoejre i 360 milisekunder
  //360milisekunder svarer ca. til 90grader
     //Motor A
   digitalWrite(12, HIGH); 
   digitalWrite(9, LOW);  
   analogWrite(3, turnSpeed);  

   //Motor B
   digitalWrite(13, LOW);  
   digitalWrite(8, LOW);  
   analogWrite(11, turnSpeed);   
    delay(360);   

   //motoren koerer ligeud i 1.9sekunder 

    //Motor B
   digitalWrite(12, LOW); 
   digitalWrite(9, LOW);  
   analogWrite(3, turnSpeed);  

   digitalWrite(13, LOW);  
   digitalWrite(8, LOW);  
   analogWrite(11, turnSpeed);   
    delay(1900);  

    //motoren drejer 150milisekunder så den drejer ca 30-40 grader og rammer ind paa stregen skraat

         //Motor A
   digitalWrite(12, HIGH); 
   digitalWrite(9, LOW);  
   analogWrite(3, turnSpeed);  

   //Motor B
   digitalWrite(13, LOW);  
   digitalWrite(8, LOW);  
   analogWrite(11, turnSpeed);   
    delay(150);  

    }
    }
    x = 0;  // x nulstilles saa koden kan koerer igen
  }

  // read the input on analog pin 2 and 3:
  int sensorValue1 = analogRead(A2); //VENSTRE  -- LEFT
  int sensorValue2 = analogRead(A3); //HOEJRE   -- RIGHT

  // print out the values you read on the Serial Monitor:
  Serial.print("sensor 1: ");
  Serial.println(sensorValue1); 
  Serial.print("sensor 2: ");
  Serial.println(sensorValue2);
  delay(d); // delay in between reads for stability

  if(sensorValue1 < 400 && sensorValue2 < 400){ //hvis sensor 1 og sensor 2 er over HVID koerer bilen LIGEUD
    //Motor A
    digitalWrite(12, LOW); 
    digitalWrite(9, LOW);  
    analogWrite(3, maxSpeedLeft);  

    //Motor B
    digitalWrite(13, LOW);  
    digitalWrite(8, LOW);  
    analogWrite(11, maxSpeedRight);  //koerer lidt hurtigere
  }
  else if(sensorValue1 > 400 && sensorValue2 > 400){ //hvis sensor 1 og sensor 2 er over SORT koerer bilen LIGEUD 
    //Motor A
    digitalWrite(12, LOW); 
    digitalWrite(9, LOW);  
    analogWrite(3, maxSpeedLeft);  

    //Motor B
    digitalWrite(13, LOW);   
    digitalWrite(8, LOW);  
    analogWrite(11, maxSpeedRight);  //koerer lidt hurtigere

  }
  else if(sensorValue1 < 400 && sensorValue2 > 400){ //hvis sensor 1 er over HVID og sensor 2 sensor er over SORT drejer bilen om sin egen akse til VENSTRE
    //Motor A
    digitalWrite(12, HIGH); 
    digitalWrite(9, LOW);  
    analogWrite(3, turnSpeed);  

      //Motor B
    digitalWrite(13, LOW);  
    digitalWrite(8,LOW);
    analogWrite(11, turnSpeed);  
  }
  else if(sensorValue1 > 400 && sensorValue2 < 400){ //hvis sensor 1 er over SORT og sensor 2 sensor er over HVID drejer bilen om sin egen akse til HOEJRE
    //Motor A
    digitalWrite(12, LOW); 
    digitalWrite(9, LOW);  
    analogWrite(3, turnSpeed);  

      //Motor B
    digitalWrite(13, HIGH);  
    digitalWrite(8, LOW);  
    analogWrite(11, turnSpeed);  
  }

}

Konklusion

Robotten har løst opgaveformuleringen og den var også klart hurtigere end de andre gruppers. Alligevel er der mange forbedringer der kunne laves på den. Bl.a. kunne den optimeres til også at kunne undgå andre forhindringer end den 9×9 kasse som den er “hardkodet” til at køre uden om nu. Batterispændingen har også en kæmpe afgørende faktor for hvordan og hvor hurtigt den kører (frisk-opladet batterier får den fx til at køre af banen da den kører for hurtigt til den nuværende kode). Den kører heller ikke altid banen igennem korrekt. Lidt held var trods alt med os i konkurrencen, da den kørte sin absolut hurtigste tid på 26 sekunder. Den sidste time op til konkurrencen “nægtede” den at køre banen ordenligt igennem.

Video

 

 

Leave a Reply