Opgaven

POPG02

Følgende robot er lavet med udgangspunkt i opgave POPG02 som kan læses ved at klikke på linket ovenover.

Kort fortalt går opgaven ud på at lave en semi-autonom robot, der kan følge en sort streg som vist på tegningen i opgaven. Midt på banen er der opstillet en forhindring som robotten skal undgå ved at opfange den med en valgfri sensor.

Robottens opbygning:

I designet med min robot har jeg arbejdet med flere forskellige løsninger og har undervejs haft tre forskellige prototyper. Jeg har opstillet alle tre modeller og vil herunder gennemgå dem.

1. Model

Dobbel Gearing fra siden
Første forsøg med gearing

Denne model, er som billedet viser, lavet med gearing. Jeg fik ikke helt det resultat ud af gearingen som jeg havde ønsket, og valgte derfor at gå væk fra denne model.

2. Model

2013-03-21 14.14.35
Larvefødder uden gearing

På denne model er gearingen fjernet, hvilket måske er lidt svært at se, men det er den altså.
Jeg valgte at fortsætte med larvefødderne, da jeg tænkte det ville give robotten bedre manøvre muligheder og et bedre bedre greb i underlaget.

Denne model fik jeg prøvet af med den algoritme der ses længere nede. Der opstod dog hele tiden problemer, når den skulle dreje. Specielt venstre sving havde den svært ved. Da det ud fra algoritme så ud til at, den sagtens skulle kunne gennemføre banen, valgte jeg at lave et forsøg hvor T-bot drejede højre rundt om sig selv. Her kunne det tydeligt ses at, larvefødderne ikke var den rigtige løsning og der skulle hjul på i stedet.

3. Model

4wd
Baghjulstrukket med 4 hjul

På denne model blev det tydeligt at, robotten ikke skulle have 4 hjul, men kun 2 og eventuelt et enkelt foran. På næste billede ses den endelige løsning.

4. Model

T-bot med 'slider' monteret foran
T-bot med ‘slider’ monteret foran

Jeg valgte dog en lidt utraditionel løsning, hvor der er monteret en ‘slider’ foran. Denne løsning er kun beregnet til den testbane opgaven var blevet stillet til. Den gule ‘slider’ foran, har en meget lav friktionsmodstand, hvilket gør det let for robotten at dreje, samtidig vil den dog have utrolig svært ved at køre andre steder end på det whiteboard, som testbanen var bygget på.

På den sidste model valgte jeg at gå tilbage til at bruge en gearing, da friktionsmodstanden var blevet væsenligt lavere og motorkraften ville være for høj, hvilket kan ses på nedenstående billede.

Den endelige model
Den endelige model set bagfra med gearing

På billedet ses T-bot bagfra.

Bagerst ses Arduino boardet, med tilhørende motorshield. Et motorshield er på forhånd bygget til at kunne køre to DC9V motorer. Et motorshield gør det lettere at styre funktioner som at bremse, dreje og bestemme fart via PWM. Det har på forhånd reserveret nogle pins til disse funktioner:

Function                 pins per Ch. A pins per Ch. B
Direction                        D12                   D13
PWM                                D3                     D11
Brake                              D9                     D8
Current Sensing            A0                     A1

Øverst på robotten ses der et breadboard. Dette bruges til at lave de mange forskellige forbindelser robotten har. F.eks. at forbinde lightsensoren med motorshield med resistore imellem.

Bluetooth

Til at skabe en trådløs forbindelse fra min computer til min robot, brugte jeg et bluetooth modul der hedder Bluesmirf.

Som default er bluesmirf normalt indstillet til at være ‘ukendt’, hvilket betyder den kan modtage data og ikke fungere som en bestemt trådløs enhed. Af en eller anden årsag var min bluesmirf indstillet til at fungere som tastatur, hvilket betyder den godt kan skabe forbindelse til min computer, men den kan ikke modtage input, kun sende input til min computer. Det tog mig noget tid at finde en løsning til dette problem. Men med nedenstående kode, lykkedes det mig at ændre modulets indstillinger, så jeg kunne sende input til min robot via bluetooth. Yderligere hjælp til at ændre bluesmirf konfigurationer kan findes her

bool configuration = false;

void setup() {
Serial.begin(115200);

delay(500);
}

void readData() {
while(!Serial.available());
delay(200);
while(Serial.available()) Serial.read();
delay(200);
}

void loop() {
if (!configuration) {
Serial.print("$$$");
configuration = true;
readData();

Serial.println("S~,0");
readData();

Serial.println("R,1");
readData();
}
}

Kode og algoritme i robotten

Den første del af koden består i at aktivere de forskellige pins og oprette variabler til at aflæse forskellige input. I den sidste del af kode blokken bestemmes der hvilken funktion de forskellige pins skal udføre, det er den del der hedder Void Setup().

#include <SoftwareSerial.h>
// Define pins you're using for serial communication
// for the BlueSMiRF connection
#define TXPIN 4
#define RXPIN 7

// Create an instance of the software serial object
SoftwareSerial BTSerial(RXPIN, TXPIN);

// Set pins to motorcontrol
int dirA = 12; //Motor A - retning (LOW/HIGH)
int dirB = 13; //Motor B - retning (LOW/HIGH)
int speedA = 3; //Motor A - hastighed/power (0-255)
int speedB = 11; //Motor B - hastighed/power (0-255)

// Set pin to lightsensor
int light = A5;

char val; // variable to receive data from the serial port
int ledpin = 5; // LED connected to pin 13 (on-board LED)

void setup() {
  // Alle Pins opsættes som output-pins
  pinMode (dirA, OUTPUT);
  pinMode (dirB, OUTPUT);
  pinMode (speedA, OUTPUT);
  pinMode (speedB, OUTPUT);
  // Undtaget light der er et input fra light sensor
  pinMode (light, INPUT);
  //
  digitalWrite (light, HIGH);
  pinMode(ledpin, OUTPUT);  // pin 13 (built-in LED) as OUTPUT
  Serial.begin(115200);       // start serial communication at 115200bps (default for BlueSMiRF modem)

  // Begin communicating with the bluetooth interface 
  BTSerial.begin(115200);

}

I mit program til at styre robotten, har jeg valgt at dele de forskellige funktioner op i mindre dele. Dette har jeg gjort for at gøre programmet mere overskuelig og selve koden mindre. Det gør det også langt nemmere at lave ændringer, hvilket der sker tit, da det er en prototype der arbejdes med. Nedenstående blok viser eksempler på dette.

// Function turn left
void right(){
  digitalWrite(dirA, HIGH);
  digitalWrite(dirB, LOW);
  analogWrite (speedA, 200);
  analogWrite (speedB, 200);
} 

// Function turn right
void left(){
  digitalWrite(dirA, LOW);
  digitalWrite(dirB, HIGH);
  analogWrite (speedA, 210);
  analogWrite (speedB, 210);
}

// Function drive straight
void gerade(){
  digitalWrite(dirA, LOW);
  digitalWrite(dirB, LOW);
  analogWrite (speedA, 150);
  analogWrite (speedB, 150);
}

// Function stop
void halt(){
  digitalWrite(dirA, HIGH);
  digitalWrite(dirB, HIGH);
  analogWrite (speedA, 0);
  analogWrite (speedB, 0);
}

Disse funktioner kalder jeg så i min algoritme, som skal styre robotten rundt på banen efter den sorte streg.

// Stay on  line algorithm
void offLine(){
  boolean dirLeft = true;
  int degree = 20;

  while(analogRead(light) < 400){
    for(int i=0;i<degree;i++) {
      left();
      if (degree==20) {
        delay(5);
      } else {
        delay(10);
      }

      if(analogRead(light) > 400)
        break;
    }
    halt();
    for(int i=0;i<degree;i++) {
      right();
      delay(10);
      if(analogRead(light) > 400)
        break;
    }
    halt();
    degree+=10;
  }

}

Da en del af opgaven bestod i at starte og stoppe robotten via et interface, har jeg valgt at indsætte min algoritme i en hoved funktion, der så kan starte og stoppe min robot via computeren. Hovedfunktionen ser således ud.

//Main function
void loop() {
  int lightValue = analogRead(light);
  BTSerial.println(lightValue);
  Serial.println(lightValue);

  if( BTSerial.available() )       // if data is available to read
  {
    val = BTSerial.read();         // read it and store it in 'val'
  }
  if( val == 'H' ) 
  {

      if(lightValue > 350){
      gerade();
      }else if(lightValue < 350 ){
      offLine();
      }

}else if( val == 'L' ){

      halt();
      }

  // Bestemmer hvor ofte programmet skal køre koden. Tiden tælles i millisekunder
  delay(5);
}

Samlet set udgør ovenstående blokke af kode hele mit program til at styre min robot.

Konklusion

I opgaven brugte jeg en stor del af min tid på finde den rette fysiske form til min robot. Dette gjorde mig opmærksom på at en robot ofte er andet end hardware og software, men at den ofte også skal indgå i et fysisk rum.
Jeg nåede desværre ikke at få tilkoblet en sensor der kan ‘læse’ en forhindring i rummet, men fik dog tilsidst T-bot til at følge den sorte streg rundt på banen, hvilket han gjorde til UG. Det skal han have ros for!

I en version 2 af robotten ville en sensor til at læse forhindringen have været fokuspunktet. Som sensor kunne en simpel knap eller en ultralydssensor have været løsningen. Når sensoren havde opfanget forhindringen, kunne den have udløst et stykke kode der først stoppede den igangværende process og derefter aktiverede en funktion der førte robotten uden om forhindring. Når robotten så igen opfanger den sorte streg efter forhindringen, skulle processen fortsætte som før.

En anden ting der kunne tilføjes, er en kalibrerings funktion. Dagslyset der kom ind ad vinduerne i rummet havde stor indflydelse på de værdier lys-sensoren registrerede, derfor kunne værdierne ændrer sig i løbet af dagen. Dette kunne der tages højde for, ved at lave et stykke kode der gemmer min- og max-værdierne i løbet af de første fem sekunder imens sensoren føres frem og tilbage over den sorte streg. Disse værdier kunne så bruges til at bedømme hvornår robotten bevæger sig på stregen.

Jeg har også lært fordelen ved at bryde sin kode ned i så mange funktioner som muligt. Dette gør det langt nemmere at prøve forskellige idéer af uden at starte forfra hver gang.

Leave a Reply