torsdag den 5. november 2009

Lego lab lesson 9: Car that exhibits several behaviors.

Plan for idag:
  1. Afprøv programmet SoundCar.java og besvarelse af de stillede spørgsmål i ugens opgave
    beskrivelse.
  2. Tilføj ny opførsel som følger en lyskilde. Vi vil eksperimentere med denne opførsel ved at lade denne opførsel undertrykke alle andre opførsler og derefter placere den forskellige steder i hierakiet.
  3. Ombytning af opførsels niveauer: AvoidFront > FollowLight.
Afprøvning af SoundCar.java:
Vi kan aflæse på displayet, at bilen i åbne omgivelser kører ved hjælp af RandomDrive.java. Hvert 10. sekund bliver denne tråd blokeret af PlaySounds tråden som stopper bilen og afspiler en lyd. Samtidig ser vi, at RandomDrive tråden kan undertrykkes af AvoidFront tråden, hvis bilen kommer for tæt på en genstand.

Vurdering af suppress:
Vi ser i koden, at suppress() undertrykker tråde som befinder sig lavere i hierakiet. Hierakiet defineres inde i SoundCar.java, hvor vi ser at RandomDrive tråden befinder sig nederst i hierakiet (oprettet med under-niveau værdien null). RandomDrive tråden kan altså ikke undertrykke andre tråde, da den er nederst i hierarkiet. Over RandomDrive findes AvoidFront tråden som kan undertrykke RandomDrive hvis en genstand kommer for tæt på (denne afstand måles med en UltraSonicSensor). Øverst i hierakiet finder vi PlaySound tråden, som kan undertrykke de to andre tråde og gør dette hvert 10. sekund.

Suppress funktionaliteten er implementeret vha. variablen suppressCount. Denne variable holder styr på hvor mange gange et givet niveau er undertrygt af højere niveauer. En tråd får kun adgang til actuators (motorne) hvis dens suppressCount variablen er 0. F.eks. hvis robotten kører rundt grundet opførselen i RandomDrive niveauet, men kommer for tæt på en stol. AvoidFront niveauet vil opdage dette og undertrykke RandomDrive niveauet, for at fortage en undvige manøvre. RandomDrive har nu en suppressCount på 1 - AvoidFront niveauet undertrykker RandomDrive. Imens undvige manøveren bliver fortaget af AvoidFront, beslutter PlaySound niveauet sig for at spille en yndig mellodi. PlaySound niveauet undertrykker nu AvoidFront og RandomDrive niveauerne. AvoidFronts suppressCount er nu på 1 og RandomDrive's suppressCount er på 2. Når PlaySound er færdig med at spille musik, løfter den sin undertrykkelse af de nedre niveauer. AvoidFronts suppressCount er nu på 0 og kan dermed få adgang til motorne og fortsætte undvige manøvren. RandomDrive har stadigvæk en suppressCount på 1, da den stadigvæk er undertrykt af AvoidFront. Når AvoidFront løfter sin undertrykkelse vil RandomDrive igen få adgang til motorne (suppressCount på 0) og robotten vil fortsætte med at udvise denne opførsel.

"Kør mod lys" opførsel:
Vi har benyttet resultater og kode fra vores LightFollower fra sidste uge. Denne nye tråd ligger vi øverst i hierakiet og vi vil teste om suppress() virker korrekt ved, at lade bilen følge en lyskilde helt ind i en væg. Hvis dette forsøg virker, antager vi at AvoidFront tråden undertrykkes. Om PlaySound tråden undertrykkes er nemt at aflæse, da lyden ikke afspilles hvert 10. sekund.

LightFollower opførslen er baseret på følgende kode:

import lejos.nxt.LightSensor;
import lejos.nxt.SensorPort;


public class FollowLight extends Behavior {

private LightSensor lsl;
private LightSensor lsr;

private static int NORMAL_VALUE = 55;
private static int NORMAL_VALUE_BUFFER = NORMAL_VALUE+5;

public FollowLight(String name, int LCDrow, Behavior subsumedBehavior) {
super(name, LCDrow, subsumedBehavior);
lsl = new LightSensor(SensorPort.S2, true);
lsr = new LightSensor(SensorPort.S3, true);
}

public void run() {

while (true) {
int currentLeft = lsl.readValue();
int currentRight = lsr.readValue();

if (currentLeft > NORMAL_VALUE_BUFFER || currentRight > NORMAL_VALUE_BUFFER) {
suppress();
drawString("l");
drawInt(currentLeft);

forward(currentRight+30, currentLeft+30);

release();
}}}}


Resultat af "kør mod lys" opførslen placeret øverst i hierakiet:
Bilen reagerer helt som forventet. Vi kan tvinge bilen ind i en væg ved at placere en kraftig lyskilde foran UltraSonicSensoren. Så snart lyskilden fjernes, vil AvoidFront (eller PlaySound) opførslen tage over og navigere bilen væk fra væggen. Herefter tager RamdomDrive tråden så over igen. Se video:



Som det fremgår af videoen kan vi tvinge robotten ind i en væg ved at få den til at følge en lyskilde. FollowLight opførselen undertrykker nemlig AvoidFront opførselen. Bemærk dog at der bliver spillet musik imens robotten følger lyset - 00:35 inde i videoen. Dette er dog ikke pga. PlaySound niveauet ikke er undertrykt når der følges en lyskilde. Musikken starter med at spille fordi lyskilden et kort sekundt ikke bliver rettet imod lyssensorne. Det får FollowLight niveauet til at release og PlaySound niveauet får lov at spille musik. Grunden til der omgående bliver spillet musik er at PlaySound tråden har været aktiv selvom dens adgang til actuators har været blokeret af FollowLight tråden. Det vil sige PlaySound tråden er klar til at spille når den får lov. Musikken fortsætter med at spille selvom FollowLight niveauet igen overtager, da FollowLight niveauet ikke bruger eller blokerer lyd actuatoren.

Efter at have flyttet AvoidFront opførselen til det højeste niveau, optog vi den her video:


Som det kan ses, følger robotten lyset så længe ingen forhindring kan ses. Men når UltraSonicSensorn måler at der er et objekt indenfor 20 cm afstand aktiveres AvoidFront og robotten bakker.

Tidsforbrug: 3 timer

Ingen kommentarer:

Send en kommentar