torsdag den 26. april 2012

NXT Programming, Lesson 10

Varighed:  3,5 Timer
Deltagere: Mikkel, Bjarke, Jesper


Plan:



  1. Lav BumperTeddy - Installer Bumpercar på Teddy.
  2. Udvid BumperTeddy med presure sensor og ultralydsensor.
  3. Test de forskellige behaviors, som beskrevet i Bumpercar afnittet.
  4. Følg planen i afsnitet "Motivation functions", for at gøre Teddy til en MotivationalTeddy.

Resultater:


1: Vi fandt BumperCar classen i samples-mappen og fik det overført til Teddy.

2: Da vi allerede havde en grund-bil tilføjede vi bare en touch-sensor og en ultrasonicsensor - tog lige to forsøg at få sat sensorer og motorer i de rigtige porte.

3:

 "Press the touchsensor and keep it pressed - what happens": Ved at holde touchsensoren nede og holde den nede, bliver robotten ved med at prøve og dreje til venstre. Den kører i fuld "drej til venstre" behavior hver gang før den næste begynder.

"Implement and Exit Command, so i has highest priority - test how it works": 
  • Vi har implementeret vores exit-metode som et nyt behavior, som tager kontrol hvis Esc er trykket ned. 
  • Ved test skal Esc holdes nede et lille stykke tid før den exiter. Den opfører sig også forskelligt om den er igang med "DetectWall" eller "DriveForward". Når den kører detectWall  kan skyldes at "Rotate" kommandoen ikke går videre i koden for at robotten har roteret det angivende antal grader. Når den kører DriveForward ser det ud til at man skal vente på at hjulene er stoppet helt. 
"... figure out if takeControl of DriveForward is called when the triggering condition of DetectWall is true": Det gør den ikke. Den løber igennem arrayet og hvis den finder en behavior med højere prioritet breaker den og den når aldrig at tjekke om TakeControl for DriveForward er True.

"To avoid the pause in the takeControl method of DetectWall a local thread in DetectWall could be implemented that sample the ultrasonic sensor e.g. every 20 msec and stores the result in a variable distance accessible to takeControl. Try that." - Vi flyttede læsning af sensor ud i sin egen tråd. Første implementation virkede ikke som det skulle. Dette var fordi vi havde glemt at "Pinge" sonaren med sonar.ping.

"Try to implement the behavior DetectWall so the actions taken also involve to move backwards for 1 sec before turning." - Vi implementede det ved at indsætte sætte motorne til at køre bagud (hvilket pga vores konstruktion af robotten er forward() ), derefter sleeper tråden i et sekund og fortsætter derfra. 




"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". Vi startede med at flytte action'en fra DetectWall ud i en tråd for sig selv, da tanken var at stoppe og genstarte tråden hvis touchsensoren blev aktiveret. Dette var umuligt da funktionaliteten af tråde i java ikke understøtter dette. Vi ændrede derfor koden til at kalde:



public void rotate(int angle, boolean immediateReturn)
  causes motor to rotate through angle;
  iff immediateReturn is true, method returns immediately and the motor stops by itself 



Derved kunne vi, i et while loop, kontrollere hvornår rotation var færdig ved at kalde:



public boolean isMoving()
  Returns true iff the motor is in motion.

While loopet blev holdt kørende delvist af isMoving() og en variabel vi kunne ændre udenfor tråden, hvor vi kontrollerede om touchsensoren blev aktiveret.
Udover at være dårligt designet, kastede koden også forskellige exceptions vi ikke var i stand til at genkende eller fikse. Derfor opgav vi tråden og rykkede aktiviteten ind i en metode. Koden for dette kan ses nedenfor:



  Motor.A.rotate(-180, true);// start Motor.A rotating backward
   Motor.C.rotate(-360, true);  // rotate C farther to make the turn
   while(Motor.C.isMoving() || Motor.A.isMoving()) {
    if(touch.isPressed()) {
    Motor.A.stop();
    Motor.C.stop();
    break;
    }
   }

Status

Alt er gået efter planen i dag, men vi nåede ikke at implementere sidste del af vejledningen ("Motivation Functions") selv. I stedet hentede vi Oles implementation af BumperCar og Arbitrator, overførte den til robotten og iagtog opførslen. Derefter gik vi igennem koden for at forstå præcis hvad der skete.

torsdag den 19. april 2012

NXT Programming, Lesson 9

Varighed: 2.5 timer.


Deltagere: Bjarke, Jesper, Mikkel


Plan


Vi følger vejledningen [1]
1. Vi skal implementerer en robot lig den beskrevet i [2].
2. Som følge af erfaringerne fra første punkt, skal vi diskutere hvorledes en sådan robot kan undgå forhindringer på en bane.
3. Basert på [3] og [4] skal vi undersøge hvorledes positions bestemmelse fungerer og om dette kan forbedres.


Resultater


1. 
Vi har anvendt differentialPilot-klassen til at styre robotton. Vi instansierer denne med hjulenes diameter og afstanden mellem hjulene, i samme måleenhed. Vores kode er inspireret af koden fra [1].
Som udgangspunkt bør robotten, hvis den er blevet instansieret med de korrekte værdier, være i stand til at styre ved hjælp af parametre.



public void rotate(double angle)
Rotates the NXT robot through a specific angle. Returns when angle is reached. Wheels turn in opposite directions producing a zero radius turn.
Note: Requires correct values for wheel diameter and track width. calls rotate(angle,false)

Som det fremgår af ovenstående uddrag kan robotten drejes et antal grader. Ligeledes kan den køre et stykke frem.
Robotten kører frem og tilbage som forventet når robot.travel(distance) kaldes. Dvs. den kører ret præcist den forventede distance. Derimod er ovenstående metode, robot.rotate(angle) betydeligt mere problematisk. Problemet består i at den ikke drejer 90 grader, selvom den instrueres til det. Den drejer enten for lidt eller for meget. 
Hvor robot.travel(distance) er afhængig udelukkende af hjulenes diameter (hvilket står på hjulene), så er rotate(angle) også afhængig af afstanden mellem hjulene, hvilket vi selv har måtte måle. Indledningsvist var denne afstand ikke korrekt og vi har løbene justeret den.
For at justere robotten har vi monteret en tuch på den og anbragt den på et whiteboard, således at vi kan se robttons bevægelser. (Se billedet)





Ved at lade den køre fremad, efterfulgt af en 90 graders rotation i samme retning, fire gange, burde robotten køre i en perfekt firkant, forudsat at den er givet de korrekte værdier. Efter mange tests og små ændringer i vores værdier konkluderede vi at afstanden mellem hjulene på vores robot er 16,7cm. Dette er næppe den korrekte afstand (vi målte den til 15cm, hvorfor 1,7cm er en stor difference). Antageligt har tuchen en indflydelse, da den giver modstand og skubber lidt til robotten når den kører. Se video af den bedste version nedenfor.



2.
Baseret på vores resultater fra første punkt, kan vi se, at vi med stor præcision kan dreje et ønsket antal grader og kører en bestemt distance frem. Når vi har denne præcision, burde vi kunne køre udenom forhindringer, hvis robotten har ultralyds sensorer der kan opdage disse forhindringer. Vi har forsøgt at illustrere vores overvejelser på følgende tegning:


Ved at anvende tre sensorer kan vi konstant kontrollere om robotten blokeres både forfra og fra siden, hvorfor vi efter at have undveget forhindringen kan overvåge hvornår vi har passeret den. Robotten skal naturligvis huske hvor langt den kørte for at undvige forhindringen, således at den kan nå tilbage på sporet bagefter.
En anden mulighed, istedet for at dreje 90 grader ved mødet med en forhindring, er at lade robotton dreje langsomt, indtil den er fri af forhindringen. Denne løsning vil kræve at robottens interne software holder styr på hvor mange grader den er drejet og hvor langt den er kørt indtil den var fri af forhindringen.

3.
Dette punkt nåede vi desværre ikke.

Konklussion

Vi nåede desværre kun igennem to af dagens opgaver. Disse gav os dog et indtryk af de udfordringer man møder, når man ønsker at styre sin robot via en tachocounter. Også selvom vi anvendte differentialPilot-klassen som er en abstraktion.


Referencer
[1]: http://www.legolab.daimi.au.dk/DigitalControl.dir/NXT/Lesson9.dir/Lesson.html
[2]: Brian Bagnall, Maximum Lego NXTBuilding Robots with Java Brains, Chapter 12, Localization, p.297 - p.298.
[3]: http://www.ridgesoft.com/tutorials.htm
[4]: http://www.cs.umu.se/kurser/TDBD17/VT07/utdelat/kinematics.pdf

fredag den 13. april 2012

TeddyClimber, session 6

Deltagere: Mikkel, Troels, Bjarke
Varighed: 5 timer

Plan

1. Få koden til at virke med den nye robot (fix it)
2. Nå til toppen.

Resultat

1. Efter den ikke helt velovervejede ombygning af robotten, virker vores "følg linje" kode ikke mere. Vi har fundet et problem med vores setScale metode, da den ikke scaler P,I,D værdierne, når scale bliver ændret. Årsagen til brugen af skalering er, at vi gerne vil anvende kommetal, når vi sætter P, I og D, mens vi samtidig gerne vil undgå brugen af floats, da anvendelsen af forskellige formater kan være ødelæggende. Derfor bruger vi en skalering, således at P, I og D ganges med denne skalering når de sættes (og tilpasses hvis en scale ændres), hvilket gør at vi kan nøjes med integers.

Vi har fundet et problem med den måde vi finder ud af om vi læser sort eller hvid. Vores funktion sammenligner de læste værdier med det threshold vi sætter når vi kallibrerer robotten. Funktionen ser om de læste værdier ligger indenfor et fastsat værdi af den kallibrerede værdi. Denne fastsatte værdi er svær at sætte pga forskellen mellem de gamle og nye sensorer, da forskellen mellem sort/hvid værdierne er større for de nye sensorer end for de gamle. Vi omskrev derfor funktionen således at den er baseret på en %-sats af differencen mellem sort og hvid, hvilket tager højde for dette problem. Når vi bruger en værdi der er mellem 20 og 30% af differencen, reagerer robotten fint på de forskellige farver.

2. Vi nåede ikke toppen.
Vi brugte meget tid på at fjerne de to beskrevne fejl og derefter tilpasse forskellige variable. Da dette var gjort kunne vi dog fortsætte fra hvor vi slap i slutningen af sidste sæssion. Med den nuværende opbygning og indstillinger klarer robotten fint turen op ad første rampe. Den opdater at den når toppen, fordi alle tre sensorer læser hvid, da den ikke kan dreje tilstrækkeligt hurtigt ved sådan en pludselig retnings-ændring. Når det sker fortager vi ca. en 180° rotation mod højre. Her mister den forbindelsen med stregen og det næste job bliver at genfinde den.
Da vi bruger et tilstands-system, har vi dedikeret en tilstand til at genfinde stregen og komme ordenligt ind på den, således at vores tilstand der kører ligeud kan overtage og køre op til næste rampe, hvor vi går over i tilstanden der er ansvarlig for at dreje robotten. Udover disse tre skal vi tilføje en tilstand ansvarlig for at dreje os 180° på stedet, når vi når toppen.

Konklusion

Vi fik robotten til at følge en lige linje, finde svinget og foretage et sving.Næste gang skal vi sørge for at robotten kan genfinde stregen og så finpudse styring så den kan finde toppen konsistent.

torsdag den 12. april 2012

TeddyClimber, session 5


Deltagere: Jesper, Bjarke, Troels og Mikkel

Tid: 4 timer


Plan

Vores plan for i dag er at komme til toppen af banen.
Robotten skal:
1. køre mere præcist fremad
2. kunne foretage et sving
3. kunne finde linjen igen efter et sving
4. kunne køre til toppen
Derudover vil vi
5. lave et klassediagram der giver et overblik over kodestrukturen.

Resultat

1. For at køre mere lige fremad, vil vi tilføje et D (derivative term [1]) til vores "køre ligeud" kode.

Vi har opdaget et problem med vores forreste sensor (en RCX-lyssensor). Der er ikke så stor en forskel på sort og hvid på den sensor i forhold til vores to andre sensorer (NXJ-lyssensorer). Dette kan muligvis skyldes at lysdioden ikke lyser så stærkt som på NXJ-sensorerne.

Vi har fået den til at følge linjen godt ved at have justeret vores Proportional control [1].

2. Vi skal sørge for ikke at svinge 180 grader, men mindre, så vi kører imod den sorte linjen.

Vi har bygget robotten om da gearingen ikke var nogen fordel.




3. Når vi skal finde linjen, så leder vi efter "sort" på vores venstre sensor (i første sving - højre i andet sving, osv).

4. Vi har valgt at lave nogle moduler (f.eks. "kør fremad", "drej", "drej på toppen"), så vi kan arbejde på forskellige moduler på samme tid. Ideen er så at vi har en Control klasse der finder ud af hvilket modul der skal aktiveres og derefter aktiverer modulet. Dette gør at vi kan slippe for at skrive næsten ens kode for f.eks. højre/venstre sving, og kører ligeud opad/nedad.

5. Vi har lavet et UML-diagram der prøver at synliggøre strukturen på koden. På nuværende tidspunkt er AbstractTeddy og AbstractTeddyClimber en klasse (AbstractTeddy), men målet er at det bliver ligesom i diagrammet, hvor de mere specifikke elementer (som kalibrering kommer ned i AbstractTeddyClimber). Dette gør at vi kan genbruge AbstractTeddy til andre opgaver.


Konklusion

Vi må konkludere at det er problematisk at skifte robot design når man er godt igang med at kalibrere de nogle specifikke bevægelses-moduler. Det har gjort at vi har spildt en del arbejde.

Referencer

1. http://www.inpharmix.com/jps/PID_Controller_For_Lego_Mindstorms_Robots.html

tirsdag den 10. april 2012

TeddyClimber, session 4


Deltagere: Jesper, Bjarke, Troels og Mikkel

Tid: 5 timer


Plan

1. Få Lejos/bluetooth til at fungere på mere end en af vores computere.
2. Finde ud af hvor hurtigt vi kan få robotten til at stoppe.
3. Få robotten til at følge linien op ad rampen.
4. Få robotten til at svinge når vi kommer til en platform.

Resultat

1. Vi har nu fået installeret java, eclipse og nxt installeret i 32bit på 3 PCere i alt. På en af dem er vi nødt til at bruge Bluetooth donglen for at kunne sende til robotten. Den 4. og sidste PC har vi fået alt installeret på, men vi kan ikke få SVN til at virke, da den bliver ved med at give Access denied uanset bruger. 3 ud af 4 betyder dog at vi hver gang vi mødes vil have i hvert fald en PC vi kan udvikle på.

2.  Vi har fået robotten til at stoppe når to af sensorene ser Sort. Det var dog nødvendigt at tvinge robotten til at køre baglæns lidt lige når den ser det, da den ikke kan bremse hurtigt nok ellers.

3. Vi har lavet en PID-Kontrol, som gjort i en af de tidligerer uger. Endtil videre anvender vi dog kun P'et, hvor I og D er sat til 0 og derfor ikke har en betydning. Robotten følger linien op til enden af den første rampe, vi skal dog have introduceret D for at få den til at følge bedre og reagere bedre når stregen drejer. 

4. Vi er gået tilbage til at have et 3 sensor setup. Vi vil bruge den 3. sensor til at se om vi er på en platform og skal til at svinge. Vi har hardcoded at den skal lave et sving hvis det er at "front sensor" ser hvid i for lang tid. Det virker i et hvis omfang, men det er svært at få sat motorkraft så det passer med at den svinger rundt til næste rampe.

Konklusion

Vi nåede vores to første mål fuldt ud, det har også gjort underværker for produktiviteten at der kan udvikles på flere computere på en gang. Vores to sidste mål ligger der stadig en del arbejde i og da de er essensen i at få robotten hele vejen op og ned igen, er det ikke så mærkeligt.

mandag den 9. april 2012

TeddyClimber, session 3

Deltagere: Jesper, Troels og Mikkel

Tid: 4 timer


Plan

1. Vi skal have bekræftet at sensorerne virker
2. Vi skal kunne følge en linje

Resultat

1. Vi har fundet ud af at vores kode til at kalibrere sensorerne var forkert. Dette resulterer naturligt i at vi fik en forkert opførsel. Vi kalibrerede i forkert rækkefølge, så forkerte værdier blev bundet til de forskellige sensorer.
Vi startede med at bruge Raw-værdierne fra sensorerne, men er gået væk fra dette da vi bedre kunne få den normaliserede værdier til at virke. Resultatet er at vi nu har pålidelige værdier fra vores sensorer.

2. Vi skal finde ud af hvilken taktik vi vil bruge til at følge stregen. Vi starter med at lave en PID dreven 1-sensor løsning til at følge stregen og så vil vi bygge videre ud fra dette som vi kommer videre i banen.
Vi har følgende plan for hvordan TeddyClimber skal køre:
1. Start på grøn i højre side, kør frem.
2. Når vi rammer hvid med vores sensor, kører vi mod venstre indtil vi rammer sort, så kører vi mod højre, så mod venstre når den læser hvid.
3. Vi skal så finde en måde at opdage at vi rammer hjørnet, her skal vi skifte over på den anden side af stregen og køre (2) igen med omvendte retninger.
4. Hvis vi læser sort med alle vores sensorer, er vi på vej ind i målzonen, så skal vi køre lidt frem og vende og køre tilbage, her bruger vi så de to varianter af (2).
5. Når vi rammer grøn med alle vores sensorer kører vi lidt frem og stopper.

Dette resulterer i følgende model for hvordan vi vil køre op af banen:
Bemærk at vi kører på forskellige sider af stregen!
De runde cirkler på tegningen viser de steder hvor vi skal læse "sort" på begge sensorer. Dette viser os at vi skal gå videre til næste konfiguration (altså om vi skal køre på den ene side af stregen eller den anden).

Vores første problem er at kunne følge en linje med vores PID kode fra en tidligere uge-opgave.
Vi har valgt at lave en abstrakt klasse "AbstractTeddy", som står for kommunikation med pc'en. Denne klasse nedarver vi i forskellige implementationer af TeddyClimber. TeddyClimber har en Control (interface) klasse, der bestemmer hvad der skal ske for hvert gennemløb af while-loopet i TeddyClimbers run metode. Dette gør at vi kan skifte Control klassen ud for de forskellige løsninger vi har til at finde igennem banen.

Vi har lavet en SingleControl-klasse der implementerer interfacet Control. Heri vil vi prøve at implementere ovenstående plan. Vi har lavet et første forsøg som gerne skulle kunne følge en linje på venstre side af den højre sensor. Vi har dog ikke nået at teste implementationen.

Vi har her opdaget at vores bluetooth kommunikation ikke helt fungerer så vi kan sætte P,I,D værdier "on-the-fly".
Vi har også valgt at lave en "restart" feature der gør at vi kan resette vores pc-program, så vi ikke behøver at lukke og starte det hver gang vi slukker robotten.

Konklusion

Vi har fikset en masse problemer med bluetooth forbindelsen. Vi har skabte en struktur der gør det let at udskifte strategier for hvordan vi finder igennem banen og vi har lavet lidt kode til en første skridt i planen for at komme igennem banen.