torsdag den 1. november 2007

NXT Programming, Lesson 7

Varighed: 4-timer, Deltagere: Janus, Mads og Rolf

Målet for øvelserne idag er at prøve at bygge og implementere Braitenberg 2a og 2b.

Planen for dagen er først at bygge en bil til at virke som basis for de 2 modeller. Herefter skal vi have lavet et program til at styre bilen.

Bygning af 2a og 2b

Bilen blev bygget omkring selve NXT enheden. Med 2 motorer bagpå, og 2 nxt lys sensorer foran. (Som på billedet)

Først byggede vi bilen med RCXLightSensorer da vi skulle bruge 2 sensorer. Hurtigt viste det sig dog at disse generelt kun gav værdier mellem 51 og 61. Og 61 kunne kun opnåes ved at lyse sensoren i hovedet med en lygte. Derfor lånte vi en NXT light sensor af en anden gruppe og ombyggede bilen så den nu brugte 2 af disse. NXT Light sensorerne varierede fra ca. 14-60, altså et meget bredere udslagsområde.

Implementering af koden

Først lavede vi en BraitenbergLight klasse som skulle modellere et lys som kunne normalizes og langsomt adjuster til omgivelserne

 public int normalizedValue() {
  
  forskel = readValue() - min;
  middel = (max - min);
  
  procent = (float)forskel / (float)middel;
  procent = procent * 50.0f;
  procent = procent + 50;
  
  return (int) procent;
 }
Herover ses koden for den normalizede aflæsning af lyssensoren. (readValue() er en privat metode som læser lyset fra sensoren og opdaterer min og max værdierne).

 private void decayMinMax() {
  minF = minF * (1.0f+DECAY);
  maxF = maxF * (1.0f-DECAY);
  
  min = (int) minF;
  max = (int) maxF;
  
  if( min == 0 ) {
   min = MIN_CONST;
   minF = MIN_CONST;
  }
 }
Herover ses decay metoden, som langsomt justerer min og max, så den rejusterer til sine omgivelser. (Der bruges minF som ekstra variabel, da ændringerne er < 1 og derfor forsvinder hvis det kun var en int). Værdien DECAY kan justeres så min og max justeres hurtigere eller langsommere alt efter behov.

Herefter blev så lavet 2 klasser, NoThreadBraiten og ThreadBraiten, som er hendholdsvis en threaded og non threaded version af selve styreprogrammet. ThreadBraiten bruger yderligere klassen BraitenbergMotorThread som tager en motor og en BraitenbergLight. Denne klasse er så en extension af Thread og kan derfor køre i sin egen thread.

Kontrol programmet i NoThreadBraiten

while(!Button.ESCAPE.isPressed()) {
   Motor.A.setPower(b1.normalizedValue());
   Motor.B.setPower(b2.normalizedValue());
  }

ThreadBraiten ser således ud:

 public ThreadBraiten() {
  BraitenbergLight b1 = new BraitenbergLight(SensorPort.S1);
  BraitenbergLight b2 = new BraitenbergLight(SensorPort.S2);
  
  m1 = new BraitenbergMotorThread(Motor.A, b1);
  m2 = new BraitenbergMotorThread(Motor.B, b2);

  //Activate motor C (We use it for the headlights)
  Motor.C.setPower(100);
  Motor.C.forward();
  Motor.C.regulateSpeed(false);
  Motor.C.smoothAcceleration(false);
  
  m1.start();
  m2.start();
  
  Button.ESCAPE.addButtonListener(this);
 }

Tests af implementationen

Først kørte vi NoThreadBraiten på bilen 2a, og ummidelbart virkede bilen efter hensigten, hvis den ene sensor registrerede mere lys blev den tilhørende motors power øget. Ligeledes når en sensor så mindre lys, fik motoren mindre power. Da en sensor i 2a er koblet sammen med motoren i samme side som sensoren, giver det et indtryk af at bilen prøver at køre væk fra lyset.

Herefter byttede vi ledningerne på sensorerne rundt, så vi nu havde bilen 2b, og som forventet kørte den nu imod lyset istedet for at undvige.

Så kom tiden til ThreadBraiten, altså den multithreadede version af kontrol programmet, men der var ingen synlig forskel i opførslen. Bilen reagerede på samme måde som i den ikke threadede version.

Montering af lys

Der blev nu monteret 3 lamper på fronten af bilen, og disse blev sat til Motor indgang C. Hvis vi nu satte power på motor C til 100, lyste lamperne.

I en test lavet med en anden gruppe hvor vi lod vores 2 biler køre i samme mørkelagte rum, var det tydeligt at de reagerede på hinanden. Men desværre så de også de ting de selv lyste på som "lyse", og kørte derfor ligeså glad imod en væg som imod den anden bil. (Alt efter hvad de så først).

Vi fik ikke mulighed for flere teste med andre gruppers biler.

Problemer

Et problem vi stødte på er at motorerne ikke rigtigt kunne trække bilen hvis de fik mindre end 50 power. Derfor lavede vi vores normalizing om, så den nu normalizede lyset til en værdi mellem 50 og 100.

Som nævnt i bygningen af bilen var der også problemer med at RCX sensorerne ikke havde et stort nok interval de målte i. Dette var forholdsvis nemt at rette ved at låne en NXT sensor mere.

Vi havde problemer med at bilen så sidt eget lys, og derfor virkede den generelt bedst hvis den ikke havde noget lys selv.

Det største problem vi havde var at sensorerne ikke kun så lys forfra, så hvis man lyste på dem fra siden, tror bilen den er i lyset og kører derfor hurtigere, men da lyset ikke var forand men ved siden af bilen, taber den det hurtigt af syne.

Konklusion

Efter at have rettet problemer som at de gamle lyssensorer ikke så i et stort nok interval, og at motorerne skulle have mindst 50 power før de begynder at køre, endte vi med en ganske fin om end noget retningsblind lys søgende bil.

Hvis vi havde haft mere tid, ville vi lave en afskærmning på bilen så den ikke kunne se lyset fra siderne, og evt lave noget spejl (Ligende den spejl kappe der giver billygter retning), så evt. lys forfra ville blive koncentreret.

Vi snakkede også om at slukke for bilens eget lys når den selv ville måle, for ikke at den skulle se sig selv, men dette blev ikke testet. Både fordi vi ikke vidste hvor hurtigt vi kunne tænde og slukke lyset, og fordi mens lyset evt. var slukket, ville andre biler heller ikke kunne se vores bil.

Videoer af bilen i aktion


Kildekode

Kildekoden til denne uges Lesson kan findes her

Ingen kommentarer: