Øvelsens varighed: 3 timer
Gruppemedlemmer: Annette, Samuel og Rasmus
Mål
Sidste øvelse handlede om Braitenbergs vehicles der kunne køre mod en kilde eller væk fra en kilde (lys, lyd). De havde alle kun én behavior. Denne øvelse handler om at en agent kan have flere synlige opførsler og hvilken opførsel der skal vælges på hvilket tidspunkt.
Baggrundsinfo
Subsumption architecture is a reactive robot architecture heavily associated with behavior-based robotics. The term was introduced by Rodney Brooks and colleagues in 1986.
Fremgangsmåde
1. Robotten
Der bygges en ultralydssensor på robotten.
2. SoundCar program
SoundCar.java programmet bruges sammen med klasserne AvoidFront.java, Behavior.java, Car.java, PlaySounds.java og RandomDrive.java. Projektet downloades til robotten og opførslen observeres.
3. Concurrent tråde
De tre forskellige opførsler; drive, avoid og play er implementeret som tre forskellige tråde. Koden til de tre opførsler undersøges og sammenlignes med hvad vi har observeret i det foregående.
4. Behavior suppression
Figur 1 - Kilde http://people.csail.mit.edu/brooks/papers/AIM-864.pdf
Hver af klasserne til de tre opførsler bygger på suppression, se Figur 1. De højere niveauer undertrykker de lavere niveauer. En lignende figur laves for vores program ud fra hvad vi har observeret og samtidig beskrives koden. Hele projektet kan ses i http://www.daimi.au.dk/~u071252/DL/Practice8/SoundCar.rar.
5. Drive towards light
I sidste øvelse skrev vi til sidst FollowLight projektet om til et flertrådet program. Til denne del af øvelsen bruges FollowLight klassen, så robotten får en ekstra opførsel, det vil sige et ekstra niveau. Udover instanser af de tre andre opførsler oprettes nu en instans af FollowLight og den bliver gjort aktiv som niveau 2, se Figur 2. Det nuværende projekt ændres ved at føje FollowLight klassen til projektet og lave nogle enkelte tilpasninger fx er det ikke direkte Car klassens forward og backward metoder der skal bruges, men Behavior klassens.
Figur 2
Forventningen til robottens kørsel er, at vi ikke vil se den tilfældige kørsel på må og få som vi hidtil har set, men i stedet en målrettet kørsel efter lys. Avoid og PlaySound er stadigvæk de højeste niveauer, så hvis den er ved at køre ind i noget vil den undgå det i stedet for at blive ved med at køre mod lyset og PlaySound vil stadigvæk sørge for at den stopper op hver tiende sekund og spiller et lille nummer. Hele projektet kan ses i http://www.daimi.au.dk/~u071252/DL/Practice8/SoundCarMedLys.rar.
Resultater
1. Robotten
Med ultralydssensoren ser robotten ud som vist i Figur 3.
Figur 3
2. Robottens opførsel
Robotten kører tilfældigt rundt. Den kører og holder stille – kører og holder stille i intervaller af ca. 3 sekunder. Strækningerne den kører er forskellige.
Ca. hvert tiende sekund spiller den en lyd. Længden af lyden der bliver spillet er forskellig.
Hvis der er en forhindring foran ultralydssensoren bakker den en smule og drejer lidt så den måske kommer fri af forhindringen.
Displayvisninger
Den første kolonne angiver hvilke opførsler der er undertrykt når en given opførsel udføres. Ved drive er ingen af opførslerne undertrykt. Når bilen er ved at undgå en forhindring er opførslen drive undertrykt. Når den spiller er både drive og avoid undertrykte.
Den anden kolonne angiver afstanden som ultralydssensoren måler så længe avoid ikke er undertrykt.
Den sidste kolonne angiver hvilken vej motorerne kører. Når bilen skal køre tilfældigt rundt skifter den mellem at køre frem og stoppe og det vises på displayet med f og s ved drive. Når bilen skal avoide er drive undertrykt og der vises s (stop) ud for drive. Ved avoid kører den først tilbage (b) og derefter drejer den lidt ved at køre tilbage på venstre hjul (b) og fremad på højre hjul (f). Når den spiller er både drive og avoid undertrykte og bilen holder stille så der står s ud for drive og avoid.
3. Concurrent tråde
RandomDrive
Random drive opførslen er styret vha. tid. Når robotten får besked om at den skal køre fremad gør den det i et tidsinterval der er givet med et kald til Math.random() der bruges til delay. Power til motorerne er også tilfældigt givet med random(). Delayet mellem fremadkørsel og stop er også tilfældigt med random(). Stop udføres også i et tidsinterval givet ved et tilfældigt delay. Vi havde observeret denne opførsel som mere kontrolleret, med kørslen fremad og tilbage i de samme intervaller hver gang, men det har været tilfældigt at random() funktionen har returneret værdier der har ligget så tæt på hinanden at vi ikke har kunnet skelne.
Avoid
Avoid aktiveres når en forhindring er mindre end tyve centimeter fra robotten, det er altså styret af en ekstern påvirkning. Reaktionen på dette er at robotten bakker i 1 sekund og efterfølgende drejer til venstre ved at sætte power på højre motor. Det var også denne opførsel vi observerede under testen.
PlaySounds
PlaySounds sker i et fast interval af ti sekunder. Hvorimod intervallet lyden bliver spillet i varierer ved kald til random() metoden, der bruges i delay().
4. Behavior suppression
Vores observationer af robotten under de tidligere tests gør det muligt at lave en figur der viser specifikt hvad de forskellige niveauer er i robotten. Drive er nederst og undertrykkes hvis det er nødvendigt at lave en avoid manøvre og playsound er øverst og undertrykker både avoid og drive opførslerne.
Figur 4
KodenI SoundCar klassen oprettes én instans af klasserne RandomDrive, AvoidFront og PlaySounds, som alle nedarver fra klassen Behavior. Ved oprettelsen sendes en instans af den klasse, der ligger ét niveau under og som derfor skal undertrykkes, med som argument.
rd = new RandomDrive("Drive",1, null);
af = new AvoidFront ("Avoid",2,rd);
ps = new PlaySounds ("Play ",3,af);
Bemærk at instansen, rd, får en null-pointer med som argument. Det skyldes at RandomDrive klassen i dette tilfælde repræsenterer det nederste niveau i suppress-mekanismen. Når en instans af de forskellige opførsler, som klasserne repræsenterer, skal undertrykke de underliggende instanser, sker det igennem et kald til metoden suppress.
public synchronized void suppress() {
if ( subsumedBehavior != null ) {
subsumedBehavior.suppressCountIncrement();
subsumedBehavior.suppress();
}
}
Suppress metoden kalder suppressCountIncrement() metoden for den instans af behavior-klassen som ligger ét niveau under. Samtidig kaldes dens suppress-metode som undertrykker dens underlæggende instans, og sådan fortsættes indtil vi når bunden af niveauet. I vores tilfælde ligger rd (RandomDrive) nederst i hirakiet, og derfor er dens instans af subsumedBehavior sat lig med null. Derfor blokerer den ikke nogle underlæggende instanser pga. if-sætningen.
Behavior-klassen implementerer også sine egne forward og backward metoder som kalder forward og backward metoderne fra Car-klassen. Behavior-klassens implementering sørger for at Car-klassens metoder kun kan kaldes hvis den kaldende instans ikke er undertrykt.
5. Drive towards light
Testen foregår i et mørkt rum med døren stående åben, men robotten søger i første omgang ikke mod lyset men mod mørket. Det gjorde dog at vi fik testet avoid opførslen, fordi den så var ved at køre ind i en væg, og avoid bryder fint ind og undertrykker FollowLight, så den ikke kolliderer med væggen.
At den kørte mod mørke i stedet for lys skyldes at venstre sensor styrede venstre motor og højre sensor højre motor og det er forkert når den skal køre mod lyset. Da det var ændret kørte den mod døråbningen og blev undervejs afbrudt hver tiende sekund af en gang musik.
Vi observerede at der var et problem hvis den kom for tæt på en grå kopimaskine i rummet fordi den fra den afstand er lysere. Ved at der kom dagslys ind gennem døren kan man sige at der var en aktiv lyskilde og det var den vi gerne vi finde og derfor er det ikke ønskeligt at den finder den lyseste overflade. Det lys sensoren registrerer, er lysrefleksionen fra kopimaskinen.
Konklusion
Øvelsen har gjort teorien fra sidste undervisningstime mere konkret. Vi har nu selv prøvet at stille en model op for robottens opførsler og tilføje en opførsel og implementere den. Først var det et eksisterende program der blev afprøvet på robotten og vi kunne nogenlunde skelne dens opførsel og bestemme hvad der aktiverede de forskellige opførsler. Til sidst tilføjede vi en ny opførsel ved at bestemme hvor i arkitekturen den skulle ligge og bagefter implementere den i testprogrammet. Dette lykkedes også som forventet.
Referencer
1. Kilder til Baggrundsinfo:
Robot Architectures by Thomas Dean.
http://www.cs.brown.edu/people/tld/courses/cs148/02/architectures.html
Wikipedia Subsumption architecturehttp://en.wikipedia.org/wiki/Subsumption_architecture
2. Kilde til arkitektur: http://people.csail.mit.edu/brooks/papers/AIM-864.pdf.
3. SoundCar projektet af Ole Caprani: http://www.daimi.au.dk/~u071252/DL/Practice8/SoundCar.rar.
4. SoundCarMedLys projektet SoundCarprojektet videreudviklet af gruppen: http://www.daimi.au.dk/~u071252/DL/Practice8/SoundCarMedLys.rar.
Ingen kommentarer:
Send en kommentar