Thursday, January 20, 2011

Lab 16 - Evaluering og konklusion af projektet

Lab 15 - Arbejde med projektet


Videoer
Video 1 - Procedure for kalibrering af NXT’ers lyssensorer:

Video 2 - Hvorledes forbindelse mellem PC og alle NXT’er opnås

Video 3 - Hvordan robotterne selv kører til ny start position

Video 4 - Spil hvor den menneskelige hunter taber

Video 5 - Spil hvor den menneskelige hunter vinder

Referencer
Link til referencer

Banedesign
Link til byggesten for banedesignet

Kildekode

Lab 14 - Arbejde med projektet

Lab 13 - Arbejde med projektet

Lab 12 - Detaljeret projektbeskrivelse og uddeling af opgaver

Lab 11 - Projektformulering og afgrænsning

[Link til PDF fil med lab øvelse 11]

Thursday, November 18, 2010

Lab 10 - BumperCar (Behavior-based Architecture)

Dato: 18/11 2010
Varighed: 11-14
Deltagere: Daniel, Leni, Martin A og Martin N

1. Formål
Formålet med denne øvelse er at arbejde med behavior-based arkitektur i form af LejOS' indbyggede subsumption klasse og implementere blocking og non-blocking behaviors.

2. Øvelsesgennemgang

Press the touch sensor and keep it pressed. What happends ? Explain.

Bilen kører baglæns og drejer til venstre, holder en kort pause, og kører derefter baglæns og drejer til venstre igen. Dette fortsætter så længe knappen er holdt inde.

Dette kan forklares ved at DetectWall klassens takeControl() funktion bliver kørt, hvilket tager et kort øjeblik grundet ultralydssensoren. Når denne funktion returnerer true (da knappen er trykket ind), bliver klassens action() udført, hvilket er at dreje den ene motor 180 grader, og den anden 360 grader. Dette resulterer i at bilen bakker og derefter drejer til venstre.
Programmet fortsætter nu med at afvikle Arbitratorens løkke der leder efter den behavior med højest prioritet der returnerer true fra takeControl(). Da DetectWall klassen har højest prioritet, bliver dens takeControl() først afviklet, og da den returnerer true, bliver DriveForward klassens takeControl() ikke afviklet.


Both DriveForward and DetectWall have a method takeControl that are called in the Arbitrator. Investigate the source code for the Arbitrator and figure out if takeControl of DriveForward is called when the triggering condition of DetectWall is true.

Som beskrevet ovenfor, så bliver DriveForward klassens takeControl() ikke afviklet når DetectWall (der har højere prioritet) returnerer true fra dens takeControl().

Dette sker i Arbitratorens Monitor loop:

for (int i = maxPriority; i >= 0; i--)
{
  if (_behavior[i].takeControl())
  {
    _highestPriority = i;
    break;
  }
}

Implement a third behavior, Exit. This behavior should react to the ESCAPE button and call System.Exit(0) if ESCAPE is pressed. Exit should be the highest priority behavior. Try to press ESCAPE both when DriveForward is active and when DetectWall is active. Is the Exit behavior activated immediately ?

Når DriveForward er aktiv, så slutter programmet med det samme når der trykkes på Escape, men hvis DetectWall er aktiv, skal Escape holdes nede i lidt tid inden programmet afsluttes.

What if the parameter to Sound.pause(20) is changed to 2000 ? Explain

Nu bliver bilen ved med at køre fremad et stykke tid efter den har ramt væggen, og Escape skal holdes nede i lang tid for at afslutte programmet.
Dette skyldes at DetectWall klassens takeControl() tager 2 sekunder at afvikle, og i denne tid bliver der hverken reageret på Escape eller på tryksensoren.

To avoid the pause in the takeControl method of DetectWall a local thread in DetectWall could be implemented that sample the ultrasonic sensor every 20 msec and stores the result in a variable distance accessible to takeControl. Try that.

Ved at implementere denne tråd, bliver takeControl() i DetectWall simplere og hurtigere at udføre:

DetectWall::takeControl()
{
  return touch.isPressed() || detector.getDistance() < 25; 
}

Vores implementering af tråden til at overvåge ultralydssensoren ser således ud:

class UltraSoundDetector extends Thread
{
  private int Distance;
  private UltrasonicSensor sensor;
  public UltraSoundDetector(SensorPort port) {
    sensor = new UltrasonicSensor(port);
  }
  public void run() {     while(true) {
      Distance = sensor.getDistance();
      try {Thread.sleep(20);} catch (Exception e) {}     }
  }
  public int getDistance() {
    return Distance;
  }
}

Ulempen ved denne metode er dog at Arbitratoren igen blokeres i 1 sekund af gangen når DetectWall's action udføres.

Try to implement the behavior DetectWall so it can be interrupted and started again e.g. if the touch sensor is pressed again while turning.

Denne funktionalitet er besværlig at implementere med subsumption arkitekturen, men det lykkedes at få det til at virke, ved at implementere en Dummy behaviour med en prioritet lige under DetectWall. Ved at lave et unblocking RotateTo() kald i DetectWall, og derefter lade Dummy klassen returnere true fra takeControl() så længe DetectWall er ved at udføre sin motor kommando (tjekkes med Motor.C.isBackward(), da Motor.C.isRotating() ikke er implementeret i vores version af LejOS...), er det muligt for højere prioritets behaviors at interrupte DetectWall's "kør baglæns og drej" funktionalitet.

Hvis vi ikke havde inkluderet denne Dummy klasse, så ville DriveForward få kontrollen over motorene, så snart DetectWall ikke længere modtager input fra sensorne, og derfor vil DetectWall ikke nå at køre særligt langt tilbage eller dreje, inden DriveForward vil sætte motorerne til at køre fremad igen. Resultatet ville være at bilen køre frem og tilbage ind i muren uden at komme væk.

How could takeControl be programmed to give high values when touch is pressed and lower values when it is ok to reactivate the action method ?

Dette kunne implementeres ved at returnere en høj værdi når sensorene er aktive, og en lavere værdi når Motor.A.rotating() er aktiv.

3. Konklusion
Det lykkedes at implementere en bil der indeholde 3 forskellige uafhængige behaviours og en central Arbitrator. Ved at benytte en Dummy behaviour kunne vi desuden lave samtlige behaviours non-blocking, og derved sikre at en højere prioritets behaviour bliver kørt så snart dens trigger condition er opfyldt.

4. Referencer
The leJOS Tutorial, Behavior Programming