lørdag den 27. december 2008

An initial autonomous Pong ball

Group members participating:
Morten, Lars og Thomas.


Duration of activity:
28 hours.


Goal:
To figure out a way to construct the ball for the Pong Game, matching the original Pong as closely as possible and still being functional according to the goals of the end project.


Plan:
  1. Test whether it is possible to use the RCX touch sensors to determine what side of the ball is colliding with the wall.
  2. Create a program, using sensor input from a CompassSensor and three RCX touch sensors, to compute a new direction to travel, depending on the previous course travelled and on which of the touch sensors was colliding with the barrier, ie. an algorithm to compute the angle of reflection.
  3. Determine the tone of the sound effect, from the original Atari Pong game, of when the ball hits a bat or the game barrier.


Activities:
  1. Here we encounter a perfect example of the problems that arise when moving from something known to be attainable in theory to something that actually works in practice.

    We ended up with three different Lego constructions, built upon the same basic frame. Of the three, only the last construction seem to functions satisfactorily.


    • For a first approach the Lego rubber springs was used. Testing showed that these was not flexible enough. The motors and wheels was not able to transfer enough power (torque) to press in the strong springs, holding the RCX-touch sensors in place.


    • Another approach inspired by EoCB-aITW was tested, attaching plastic tubes between the robot-frame and the bumper. Testing indicated that this solution was to rigid and also unstable. When the robot collided with the barrier, the bumper would get banged out of place.
    • As a last attempt, ordinary household elastic bands was used. - This simple solution actually seems to work.

    While test driving ball construction, with the three RCX touch sensors attached on the left and right side and on the front, we found that often the hits on the right side would not be detected correctly. We investigated the problem and found that allthough the right sensor was fitted with a fixed resistor, activation of the sensor would still output different readings.
    We were not able to find another better functioning sensor. Intead a new ball construction was made, this time with only two RCX touch sensors mounted on the front corners of the ball frame. The idea is that we are still able to detect collision on the front, by detecting hit on both the left and right side simultaneously.
    Two RCX touch sensors mounted on corners of the ball


  2. By simplifying the number of states the robot-ball can take on, we have managed to construct a fairly simple program.
    The traveled course is measured by the Compass, it is in the integer range [0,359] and its unit vector can be in one of four quadrants { (+x,+y), (+x,-y), (-x,+y), (-x,-y) }.
    The internal coordinate system of the ball is set to match the square of the playing field - on game-startup the ball is placed in parallel with the walls of the playing field, and upon initialization of the software a call is made to the method resetCartesianZero() of the CompassSensor.
    The balls collision is detected by the two RCX touch sensors on the two front corners. Because these are mounted in parallel on the same input port, we get three possible detectable hits { (R_left), (R_right), (R_front = R_left || R_right) }.
    By knowing in which quadrant the unit vector of the current course is together with the knowledge of which side was collided with, we can calculate the angle of reflection.


    Example of calculating the new heading

    The equations used in each case is presented in the table below.
    quadrantdetect collision
    (x,y) right left front
    (-x,y) left right
    (-x,-y) right left
    (x,-y) left right
    equations 180 - d - d d - 180


    The implemented software can be seen here.

  3. Background-research on the old Pong sound came up short and gave very little to work with. The goal is still to find a metallic, retro-computer-like sound.

    In order to test the capabilities of the NXT internal tone generator we created a small testprogram with two for-loops, - an outer loop iterating the frequency band and a inner loop iterating time of the sound length. This was done in order to find an appropriate sound effect for when the Pong ball hits objects. We ended up with a frequency range around 320 Hz - 640 Hz and a sound length around 100 msec.

    With the attained sound, we placed a call to the native method playTone(int freq, int length, int vol); of the class Sound, whenever it is realized on which side of the bumper the collision was.

    It seems however that the internal tone generator of the NXT is not able to be heard above the noise of the motors.

Conclusion:
The main focus in these lab experiments was to solve the problems regarding making the RCX-touch sensors distinguishable and to define an algorithm to mirror the course in the x and y axis of the NXTs coordinate system. This has been done.
The tests showed however that we need to experiment further with the Lego construction to help the movement of the ball to be more precise. This most probably concern the placement of the compass (removing interference with wires, motors and the like of the NXT), and maybe also the wheels of the ball, which should be replaced with smaller, wider ones giving more road-grip.
We chose the bigger wheels to begin with in the hope that the ball here by would be able to gain more speed, keeping the difficult levels of the Pong game in mind.

About the sound effect. We still have not given up on finding the original sound of the game, and hope maybe to find a mp3- or a wav-file to experiment with.
It was mentioned before that the volume of the internal tone generator might not be adequate, this might be solved using an external speaker connected to a port maybe amplified via power op-amp.

fredag den 19. december 2008

End course project description

Goal:
We want to construct a interactive robot game, inpired by the Atari Pong from 1972.

Plan:
The goal of the project is to present a interactive Pong game consisting of three NXTs. One NXT should model the Pong ball, the other two should represent the bats on either side of the playing field.
One bat should be controlable by a human player, the other bat and the ball should be autonomous.

Requirements:
  • Environment:
    1. We want to control the environment of the robots in the sense that the playing field should be delimitted by a outer boundary consisting of walls or other horisontal surfaces.
  • Human controlled bat:
    1. It must be possible for a human player to control one of the bats. This should be enabled by bluetooth either via laptop or cellphone.
    2. It should be adequate to use a single engine to control the movement of the bat, as it will only move along one axis.
  • Ball:
    1. It should be able to calculate an angle of reflection upon collision with a barrier or a bat. This implies an awareness on the balls part about the present course and on which side it collided with the barrier.
      • Awareness of present course should be established by mounting a compass.
      • Collision detection might be established by use of touch sensors on the chassis of the ball.
      • If it is not possible using touch sensors to detect the barrier, it might be using lightsensors to measure color variations on the floor.
    2. The ball should be mounted with two engines, given that the it should be able to make changes to its course.
  • Autonomus bat:
    1. The autonomus bat must be able to place itself relative to the ball.
      • Test must be made to see if this is possible using light sensors and a form of Braitenberg vehicles.
      • If it is not possible using light sensors, instead it might be using a camera.
    2. It should be adequate to use a single engine to control the movement of the bat, as it will only move along one axis.

tirsdag den 9. december 2008

Resistors in RCX touch sensor

Group members participating:
Lars, Morten and Thomas.


Duration of activity:

In total; 6 hours. The actual practical testing took about 2 hours, while the remaining 4 hours was used on finding relevant references and documenting the process.


Goal:
For future work of our project we want to investigate the possibility of using several touch sensors. In order not to consume all input ports of the NXT, we want to understand how the old RCX touch sensor functions, and to see whether it is possible to connect sensors in parallel using only one NXT input port.

Plan:
  1. Investigate the physical construction of the RCX touch sensor.
  2. Determine the measured limit integer value corresponding to a return value true from a call to readBooleanValue on the SensorPort.
  3. Create a graph of the working range of the input port, ie. measured integer value versus resistor load over pin1 and pin2 of the input port.


Activities and Results:
  1. We borrowed 9 defect RCX touch sensors and 1 working see-through RCX touch sensor to experiment with.
    • A working sensor; Looking inside the see-through sensor showed that it has a fixed resistor mounted between the two wires. Using a multi tester gave resistance reading of around 15k ohm when the the touch sensor was not pressed, and a reading of 1.4k when the sensor was pressed. The explanation is that the rubber elastic (its function is to push the plastic button out) is actually also conductive. This means that if the touch sensor is pressed current will flow through both the rubber elastic and the fixed resistor, lessening the total resistance through the sensor (see figure2).

      Figure1; a picture of an open RCX touch sensor

      Figure2 shows resistor diagram of an original working RCX touch sensor

      Measuring the resistance of several touch sensor blocks in their different states gave the results presented in the table below:
      num\state
      unpressedlight press
      hard press
      comments
      015.0 k Ω14.6 k Ω
      1.4 k Ωworks | with pull-up
      1 Ω199.0 k Ω17.0 k Ω≥ 14.26k Ω| never true
      2Ω70.0 k Ω3.9 k Ωworks | no pull-up
      3Ω10.0 M Ω160.0 k Ω≥ 14.26k Ω| never true
      4Ω5.0 M Ω2.6 k Ωworks | no pull-up
      5Ω12.0 M Ω4.0 k Ωworks | no pull-up
      6Ω8.0 M Ω0.7 M Ω≥ 14.26k Ω | never true
      7Ω15.0 M Ω7.0 M Ω≥ 14.26k Ω | never true
      From the table it can be seen that the touch sensors does not only work as switches, ie. they are not strictly on/off, it can potentially work on a variable proportional input / output. - If the sensor is pressed hard, it will give a different readout then if the sensor is only pressed lightly, ie. the rubber elastic acts as a variable resistor.


    • Tampered sensors: 2 of the touch sensors had already been 'tampered' with. The back side of the two is labeled 222 and 119, disassembling one of them showed that a small SMD resistor had been glued on the rubber elastic spring, while the original fixed resistor had been removed.
      The two tampered sensors function by letting pin1 of the input port float in mid air (well actually, internally in the NXT, it is connected to 10k ohm pull up resistor) when not pressed, meaning the value measured by the NXT ADC is the max value (in this case 1023).
      When the sensor is pressed, pin1 is pulled to ground via the SMD resistor, inside the sensor, giving us a voltage divider to let the ADC measure on (see page 6 in HDK).


    • Defect sensors: Opening one of the 9 defect sensors given to us gave an explanation to the dysfunction. The fixed resistor had been removed, no SMD resistor had been attached and some of the rubber elastics had lost most of their liveness properties, meaning that when pressed only a minimal current (close to zero) went through the rubber elastic, ie. the output of the voltage divider inside the touch sensor, is still close to 5V.
      Using a multi tester on the rubber elastic which had lost some liveness showed a reading of about 7M ohm. This means even if the sensor button is fully pressed, the total resistor value is still larger than the 600 integer limit of the corresponding 'isPressed' true/false limit.


  2. Using a test program and bridging pin1 and pin2 with different resistor values, it was possible to establish the true/false limit similar to the integer values 600 = false, and 599 = true. The corresponding ohm value looks to be between 14.16k ohm and 14.26k ohm.


  3. Investigation shows the ADC has a resolution of 10 bit, with a pull-up resistor of 10k ohm, giving the SensorPort a integer range from 0 to 1023.
    The measured integer values from point (2) above, and their corresponding resistor loads was logged, and a graph of the logging can be seen in the figures below.

    Figure3: a plot of measured input of the SensorPort / input-load, with only the resistor axis in logarithmic scale.

    Figure4: a plot of measured SensorPort input / input load, with both axis' in logarithmic scale.

Conclusion:

From the graphs (figure 3 and 4) and the measurement of resistor values, we saw that for a RCX touch sensor to function in a proper fashion (maybe also backward compatible), it should have a fixed pull down resistor (Rfix) of 15k ohm or above. The 15k value gives the NXT a possibility of knowing that something is connected. The measured value on the analog input port of the NXT pin1 is lowered from floating 1023, to a value around 615 for the 15k example.
Given the of the rubber elastic (Rrub) is within the range 1.4k - 12M, and that the 599 integer limit has a similar ohm value of approximately 14.16k ohm, the two resistors inside the sensor housing (Rtot = Rfix || Rrub) should be in the range:

Unfortunately this approach is not applicable for several reasons:
  • Some sensors have lost conductive properties. In the case of (Rfix = 15k) and a defect rubber elastic (Rrubmin = 0.7M), the parallel resistor value of the two will not be below the 600 limit: 14.26k ohm:

  • If we want to connect N sensors with fixed 15k ohm resistors in parallel to the same input port, the parallel resistors will lower the collected resistance to around (15k / N), which for (N=2) already is below the 14.16k-limit, ie. the measured value is less then the 600 integer pressed/un-pressed limit.
  • Further more the nature of the variable elastic rubber resistor makes it impossible to distinguish the different sensors apart.


The final solution should enable the sensor to work in the usual way, ie. that calling SensorPort.S1.readBooleanValue() will still return respectively true/false if an equivalent call to SensorPort.S1.readRawValue() returns a integer value less then 600/greater then 600.

A way to do this is by cheating; as mentioned in point [Tampered sensors] above, gluing a SMD resistor directly on the back of the elastic rubber spring, and letting the input pin float when not pressed, - when pressed - the SMD resistor will act as a pull down resistor. Then from the graphs above (figure3 and 4) it can be seen that, the SMD resistor value then should simply be less then 14.16k ohm and above 50 ohm. This yields a working resistor range, where the individual touch sensors are distinguishable.

Using the aquired results we see, that it is possible to connect several RCX touch sensors in parallel to just one SensorPort.


References:
Page 527 at91sam7s series datasheet http://www.atmel.com/dyn/resources/prod_documents/doc6175.pdf

Page 6 in HDK http://cache.lego.com/upload/contentTemplating/MindstormsOverview/otherfiles/2057/LEGO%20MINDSTORMS%20NXT%20Hardware%20Developer%20Kit(3)_7A0CF630-CCE5-4AAF-91FA-D1E7C911817C.zip

fredag den 28. november 2008

Uge 12; Initial description of end course project

Deltagere: Lars, Thomas og Morten

Goal:

At tage en begrundet beslutning med hensyn til udformningen af vores slutprojekt, herunder at vurdere flere forskellige alternativer udfra de kriterier der står beskrevet i opgaveformuleringen.

Plan:
Analysearbejdet tager udgangspunkt i Capranis liste med forslag, samt gruppens egne ønsker og interesser for indholdet af slutprojektet.
  1. I første omgang skal der udføres en brainstorm. Dette gøres for at få listet egne ideer og ønsker.
  2. For hvert muligt emne skal der:
    • Udformes en kort beskrivelse.
    • Diskuteres hw / sw; antallet a NXT'er, kommunikation, hvilke sensorer og aktuatorer, sw arkitektur med argumentation.
    • Diskuteres muligheder for at konstruere et 'kunstigt miljø', bedre passende for den givne NXT.
    • Påpeges det sværreste at løse i projektet, med argumentation.
    • Listes hvad vi forventer at kunne fremvise til slut.
  3. Efter listen er gennemgået, skal der argumenteres for gruppens valg af slutprojekt.
  4. Herunder skal der laves en dyberegående beskrivelse af projektet, evt. i samarbejde med Caprani.
  5. Sidste punkt er, at udforme en realistisk tidsplan for projekt-processen

Activities:

Liste med projektforslag:
  • Legovej navigation.
  • Evolution.
  • Legway.
  • Interactive Robot Games.
  • Autonom robot med kortopbygning, inspireret af bl.a. Maja J Mataric.
  • Robot som interaktiv legetøj.


Analyser:
Legovej navigation og/eller autonom robot med kortopbygning, inspireret af bl.a. Maja J Mataric.
  • Her kan man i første omgang starte med een NXT, som om nødvendigt kan kommunikere med en stationær PC via bluetooth.
  • Omkring miljø, har gruppens erfaringer vist, at et almindeligt kontormiljø med stole- og bordben er meget besværligt for robotten at manøvrere i. En mulighed for at afhjælpe dette problem vil være at konstruere et kunstigt miljø, f.eks. Legovej elementer, eller et rum kun med klare og tydelige flader, f.eks. større kasser hvor der er mulighed for tydelige ekkoer for UltrasonicSensoren.
  • Der skal bruges flere slags atenuatorer og aktuatorer;
    • CompassSensor - vil kunne gøre navigationen mere præcis, idet kørselsretningen kan korigeres.
    • UltrasonicSensor - kan have flere formål, det primære vil være at måle afstande til større objecter. De målte afstande koblet med vinkler fra kompasset, kan måske vise sig at hjælpe til at korigere navigationen, sammen med en form for virtuel mapbuilding, ie. korektion af cartesisk position.
    • LightSensor - kan bruges til at genkende kunstige pejlemærker eller referencepunkter, f.eks. et grønt farvet stykke karton på gulvet.
    • TouchSensor - en failsafe, hvis der køres ind i stoleben eller andet der kan være for småt til at reflektere ekko tilbage til UltrasonicSensor.
    • 2 eller 3 motorer - minimum 2 motorer med tachomålere til fremdrift, og evt. en motorer for at dreje UltrasonicSensor i flere retninger og tage målinger.
  • Det største problem vil blive at udvikle en abstraktion på og mulig vedligeholdelse af et kort over NXT'ens miljø. En abstraktion der er tilstrækkelig og ikke samtidig bliver uanvendelig, fordi det bliver i et menneskeligt symbolsprog som robotten ikke kan forholde sig til fysisk.
  • Omkring hvad der er muligt at fremvise til slut;
    • 1) En mulighed der har været på tale er en slags 'sentry' eller vagtrobot, der kunne have til opgave at køre rundt og holde øje med om forskellige tilstande i miljøet ændrer sig, f.eks. gennemsnitlig støj- / lys-niveau for forskellige kendte positioner, evt med en form for bevægelses sensor.
    • 2) Der har også været snak om en robot der skal kunne finde en optimal rute gennem en labyrint, via en form for kortopbygning og planlægning.


Evolution manipulation og distribuering af robotgener:
  • Man kan starte med at eksperimentere med 2 NXT-blokke, siden kan man låne sig frem, når/hvis der skal eksperimenteres med større flokke.
  • Omkring miljø, vil det optimale, som nævnt før, være at lave et kunstigt miljø der ikke er besværligt for robotter at manøvrere i. I artiklen fra Embodied Evolutions bruges der jo f.eks. et lys, der hjælper som dommer for hvilke gener der skal overleve og hvilke der ikke skal. I artiklen af striegel er der også en dommer, ie. robotterne selv, hvis de ikke kan komme i kontakt med hinanden uddør de.
  • Der skal bruges flere slags atenuatorer og aktuatorer. I første omgang kan der til hver NXT-blok anvendes to RCX lyssensorer, til at lave fysikken tilsvarende en Braidenberg vehicle, dvs. der også skal bruges 2 uafhængige motorer til at manøvrerer rundt med. Hvis Braidenbergs-behaviour kan komme til at fungere relativ hurtigt kan man udvide antallet af sensorer og ligeledes opførslen.
  • Muligheden forligger at man bare anvender talværdier til at repræsentere gener, ligesom i eksperimenterne fra Embodied Evolution, men det kunne måske være mere interessant at anvende noget lignende reflection, ie. istedet at overføre metoder som gener. Det vil i alle fald forøge spektret af mulige genkonstruktioner. - Er det så et problem at vi bruger Java? - Det ser ikke umiddelbart ud som om, at pakken java.lang.reflect er en del af lejos-API'en.Hvis vi vil bruge noget lignende reflection, vil det så placere projektets indhold udenfor kurset?
  • Produktet kunne ende op i en flok "dumme" NXT'er der starter med køre ind i vægge, men efter et stykke tid, lærer at manøvrere og opfylde nogle mål, gennem distribution af "god" viden, NXT'erne imellem.
Legway / Segway
  • Segway projektet ville hardware-mæssigt komme til at minde meget om det projekt vi lavede under øvelserne, en nxt med to motorer, samt en lyssensor.
  • Selve segway-ideen lægger ikke op til noget specifikt miljø, idet der først og fremmest skal arbejdes på at få en stabil robot. Hvis dette opnåes, kan man dog eksperimentere med at lade robottoen bevæge sig rundt i forskellige miljøer, evt. kunne man kombinere segway-robotten med legovej-findingsprojektet.
  • Den største hurdle i forbindelse med et segwayprojekt ville, som under øvelserne, være at få bygget en robot der ved hjælp af en pid-controller og de tilgængelige sensorer, ville være så stabil, at den faktisk kunne anvendes til andet end at stå og rokke frem og tilbage.

Atari's 'Pong' fra 1972 som interaktiv robot legetøj (Interactive Robot Games):
  • Der skal bruges 3 NXT'er: En NXT til at repræsentere bolden, og to til ketcherne, henholdsvis den til den menneskelige spiller og til 'ai'-spilleren.
  • Miljøet skal være et afgrænset område, omkranset af en barriere til at holde bolden inde. Barrieren kan repræsenteres af fysiske vægge eller kanter, evt. kan de repræsenters ved striber af farve-/nuance-skift på gulvet. Til at hjælpe de to ketcherer i at 'holde kursen', kan der anvendes en skinneanordning, men dette kan give et problem for bolden, hvis den ikke bliver fanget af en ketcheren på vej ud, da bolden ikke nødvendigvis er terrænkørende kan den have svært ved at køre over skinner.
  • Til ketcheren, der skal styres menneskeligt, skal der være mulighed for kommunikation, f.eks. via bluetooth til en laptop eller mobiltelefon.
  • Om det er tilstrækkeligt med to lyssensorer til ai-ketcheren og en tilsvarende lysafgiver på bolden, for at ai-ketcheren kan placere sig korrekt i forhold til bolden, kræver lidt eksperimentation. En anden mulighed kan evt. være et kamera (NXTCam) på ai-ketcheren.
  • Hvis der anvendes fysiske barriere til at holde bolden inde, kræver det et antal (evt. parallelt forbundne) touchsensorer. En anden mulighed er, hvis der bruges et andet farvet underlag til at afgrænse banen, kan der bruges lyssensore på bolden, men så opstår der måske problemer med at mærke om en bold bliver fanget af ketcheren.
  • I teorien er det nok med én motor per ketcher, idet Ketcherne kun skal køre på en akse. Bolden er nødt til at have to motorer, da den skal køre i flere forskellige vinkler. Til at korrigere NXT-boldens kørende vinkel kan der bruges en CompassSensor.
  • Det sværeste vil formentlig være at finde en god måde hvorpå 'ai'-ketcheren skal genkende positionen af 'bold'-robotten. Enten via lyssensor eller kamera.
  • Fremvisningen af dette projekt er ligefrem, et interaktivt Pong-spil, med tre robotter, hvoraf den ener - en ketcher - kan styres af en menneskelig spiller, via piletaster på en laptop, mobiltelefon eller en remote.


Valg af end-course-project, og argumentation herfor:
Den autonome navigations robot vil helt sikkert være et spændende projekt, både interesant og lærerigt, men vi ville gerne finde et projekt der også kunne være interaktivt, i form af f.eks. spil.
Vi er en smule tilbageholdende overfor projektet med robotgener, grundene herfor er nævnt i afsnittet der beskriver dette ovenfor.
Valget af slutprojektet er således faldet på computer spillet fra Atari, Pong, som vi vil forsøge at lave i robotform.

A more detailed description
Dette afsnit skal udfyldes efter samtale med Caprani.

A plan for your work with the end course project
Dette afsnit skal udfyldes efter samtale med Caprani.

torsdag den 20. november 2008

Uge 11; 'Behavior and Arbitrator'

Deltagere:
Morten, Lars og Thomas.

Goal:
At undersøge opførsel-baseret arkitektur, implementeret ved hjælp af klasserne lejos.subsumption.Behavior og lejos.subsumption.Arbitrator.
Samt at lave en alternativ implementation af Arbitrator-klassen.

Plan:
(1) Uploade samples/BumberCar/BumberCar.java til NXT-robotten.
(2) Indse at hvis en Behavior's takeControl metode returnerer sand, efter denne lige har kørt, får den ikke lov igen før en anden behavior har kørt.
(3) Undersøge om takeControl i klassen DriveForward kaldes, hvis den overliggende HitWall er aktiv.
(4) Implementere en tredie Behavior Exit, der reagerer ved tryk på ESCAPE-knappen ved kald af System.exit(0). Exit skal have højeste prioritet.
(5) Undersøg hvad der sker ved tryk på ESCAPE samme tid med at HitWall er aktiveret.
(6) Undersøge om det er muligt, for HitWall-behavioren fortsat at kontrollere motorerne efter suppress metoden er kaldt fra Arbitrator.
(7) Implementere en fjerde Behavior PlaySound, der reagerer ved tryk på ENTER knappen og afspiller en lyd. PlaySound skal indsættes i prioritetsarrayet mellem DriveForward og HitWall.
(8) Forklare hvad der sker når robotten kører og Hitwall aktiveres, hvorefter PlaySound aktiveres mens Hitwall stadig er aktiv (og dernæst escape-behavioren).
(9) Implementere en alternativ Arbitrator, hvor takeControl kaldes for alle Behaviors hver gang løkken gennemløbes. Undersøg betydningen af at metoder kan lave busy-wait og dets indflydelse på action metoden.

Activities:

(1)
Overførslen af BumperCar.java til NXT'en gik uden problemer som forventet.

(2)
Ved udførsel af programmet observeres den forventede opførsel, således at robotten stopper helt når tryksensoren holdes inde. Efter at have studeret kildekoden til Arbitrator, er det klart at en behavior maksimalt må udføres en gang i træk(det står endda kommenteret i koden), derudover er koden struktureret således at en behavior med højere prioritet stadig suppresser andre behaviors selvom den ikke selv er i stand til at køre.

(3)
Ved at studere Arbitratorkoden ser vi, at det kun er muligt for en behavior der ligger over den nuværende, at preempte en allerede kørende behavior. Derfor vil den lavere liggende behavior aldrig blive udført, dette betyder dog ikke at den lavere rangerende behaviors takeControl() metode ikke bliver kaldt, behavioren bliver blot sat til at vente, indtil den overliggende er færdig med at køre.

(4)
Implementationen af escape-behavioren, kan findes her. I al sin simpelhed fungerer den ved at returnere sandt i takeControl, såfremt escape-knappen er trykket ned, hvor efter action-metoden afslutter hele programmet. Exiteren fungerer som ventet, når den indsættes sidst i behavior-arrayet.

(5)
Som ventet ser vi, at programmet terminerer ved tryk på escape-knappen, dette skyldes naturligvis, at den højere liggende behavior bliver injectet i actionthreaden uden at vente på, at denne afslutter den igangværende opgave.

(6)
Det viser sig, at det er muligt for Hitwall-behavioren at bevare kontrollen over motorerne i et forventet kort tidsrum efter suppress metoden er kaldt. Dette kan lade sig gøre, hvis der sker et trådskift lige efter suppress-metoden er kaldt, så vil actionthreaden nå at udføre action metoden, før der igen skiftes så suppress-metoden bliver fuldført.

(7)
Sound-behavioren er implementeret således, den minder meget om exit-behavioren, blot aktiveres den ved en anden knap og i stedet for at lukke programmet spiller den en lille melodi. Efter indsættelsen af sounder-behavioren, ser vores behaviorhieraki således ud:

DriveForward > PlaySound > HitWall > Exit

(8)
Dette eksperiment udførtes ved at starte robotten, aktivere tryk-sensoren og derefter, mens hitwall-behavioren er aktiv, aktivere sounder-behavioren. Vi havde forventet at sounder-behavioren ville overtage når den overliggende hitwall var færdig med at køre, dette var dog ikke tilfældet, istedet begyndte robotten blot at køre lige ud igen. Efter at have gransket koden igen, viser det sig at sounder-behavioren aldrig kommer i kø, da den lavest prioriterede behavior(DriveForward), som altid ønsker at køre, nærmest ikke kan undgå at komme først i køen(med mindre man er endog meget hurtig på knappen) og når der allerede er en behavior i kø ignoreres alle de andres ønske om at køre.

(9)
Her findes implementationen af vores egen abitrator, OurArbitrator.java. Til forskel fra den oprindelige klasse, sikrer vi os at hver behavior får tid til at køre i hvert gennemløb af arbitratorens løkke. Hver behavior startes i en ny tråd, som nedlægges når behaviorens har udført sin handling eller den interruptes af en højere prioriteret behavior, dette står i kontrast til den oprindelige arbitrator hvor den valgte behavior injectes i den allerede kørende tråd. I vores implementation er det hver behaviors ansvar holde øje med hvor vidt den er blevet interrupted. Vores arbitrator giver mulighed for at gentage en behavior lige så mange gange det skulle være nødvendigt og hvis der er tale om en gentagelse hvor den sidste udførelse ikke er færdig, så vil den gamle tråd fortsætte sin udførsel, således opnår vi, at en behavior ikke resettes unødigt.

Conclusion:
Meningen med denne uges labøvelser, var bl.a. at undersøge Arbitrator klassen i lejos.subsumption pakken.
Igennem arbejdet med de opsatte punkter for labøvelsen, fik vi et indtryk af en ikke helt gennemtænkt / veldesignet 'Behaviour-based-architecture'.
Umiddelbart er det ikke oplagt hvorledes pakken skal bruges, dvs. hvis man ikke har lavet ovenstående øvelser eller selv skrevet koden, kan man nemt misse den initielle idé med hvordan koden skal anvendes, dvs. komme til at misforstå intentionen og derved misbruge koden.
Gennem de noget ledende spørgsmål, her ovenfor, viser lejos.subsuption.Arbitrator sig at blive mindre og mindre smuk.

Et delmål for ugens labøvese var også at konstruere en alternativ Arbitrator. Vi mener vi er kommet frem til noget der i det mindste er lidt bedre end den oprindelige. Metoden takeControl kaldes nu for all Behaviour i hvert gennemløb af Arbitrator løkken.
Et trick-spørgsmål var, om der er situationer hvor en lavere prioriteret Behavior ikke bliver suppressed af interrupt mekanismen. Svaret hertil er ja, idet det nu er Behaviour'erne selv der får ansvaret for at tjekke om de er interrupted.
Metoden takeControl i HitWall klassen er nu sat til at returnere den boolske værdi fra touchsensoren OR'et med en boolsk variabel 'working'. 'working' sættes til true som første statement i action metoden, og sættes til false igen som sidste statement i action metoden. I tilfælde af HitWall-Behaviour'en interruptes catches denne og 'working' sættes til false.

Angående returnering af motivationsværdier:
Så nåede vi ikke at eksperimentere med dette. Ideen er dog at i stedet for en absolut boolsk værdi. På f.eks. HitWalls action kunne man subtract'e en factor fra motivationsvariablen, indtil denne bliver nul, og sætte variablen til en maksimal værdi hver gang touch aktiveres.
En Behaviour som DriveForward kan sættes til altid at returnere en "næsten" maks værdi. Den må ikke være den maksimale værdi for en motivation fordi den ligger nederst i hierakiet, og der skal være plads til at højereprioritets behaviour, der meget gerne vil til, for lov at køre istedet.


Uge 10; 'Navigation'

Deltagere:
Morten, Lars og Thomas.


Goal:
Teste præcision af TachoNavigator alene, senere sammenligne med CompassNavigator.


Plan:
(1) Måle og estimere hjul-diameteren.
(2) Måle og estimere afstanden mellem hjulene.
(3) Teste præcisionen af robotten når TachoNavigator klassen anvendes.
(4) Gøre det muligt at nå et mål (tænkt som et punkt i et kartesisk koordinatsystem) selvom der korrigeres ved at at køre udenom evt. fundne forhindringer.


Activities:
Vi gennemførte i første omgang alle test ved brug af lego konstruktionen fra sidste uge, ie. den med bælter (a). Herefter lavede vi de samme test ved brug af en robot med hjul. Her brugte vi kontruktionen, beskrevet i Brian Bagnall's 'Maximum Lego NXTBuilding Robots with Java Brains' kapitel 12 (b).

(1a) Fordi vi havde brugt udveksling med forskellig størrelse tandhjul, til overførsel af kraft fra motor til bælter, var vi nødt til at eksperimentere med forskellige konstanter for 'hjul-diameteren'.
Vi indsatte en værdi for konstanten i konstruktøren til TachoNavigator, og udførte så et program, der fik robotten til, først at køre 60 enheder frem, derefter 60 enheder baglæns dette blev udført to gange. Hvorefter den aktuelle afstand til startstedet blev opmålt.
Det viste sig, at det ikke var muligt at finde en konstant således at robotten aldrig kørte længere end 60 cm og stadig endte ved nulpunktet efter 2 gange frem og tilbage.

Herefter udførte vi testen således at robotten kørte fremad en gang og stoppede. Dette gentog vi, indtil der blev fundet en aktuel konstant, der svarede til 60 cm bevægelse.

Eksperimenterne kan ses i skemaet herunder hjul-diameter-konstanst (hdk) vs. aktuel-kørsels-afstand-i-cm (cm) :




hjk 6.3F 5.6F 5.1F 4.8F
cm 44
53
57 60

Konstanten for 'hjuldiameteren' blev, som det kan aflæses, sat til 4.8F for bælter (Aktivitetstid ca. 35 min).

(2a, 3a) Om pivot-konstanten, ie. afstanden mellem bælterne.
Vi målte afstanden mellem bælterne til 10 cm., indsatte værdien 10.0F som konstant og lod robotten køre i en timeglas-form.
Det viste sig dog at robotten ved denne værdi underkompenserede, den virtuelle afstand var for lille i forhold til den reelle afstand. Det resulterede i at robotten ikke drejede nok rundt når den roterede.
Konstanten eksperimenterede vi os frem til, ved at indsætte forskellige værdier for 'hjul-afstanden' i konstruktøren til TachoNavigator klassen og lade robotten køre ruten, beskrevet i Brian Bagnall's 'Maximum Lego NXTBuilding Robots with Java Brains' kapitel 12.
En skitse for kørslen kan ses herunder :

Den endelige værdi for hjulafstand konstanten blev sat til 12.35F (Aktivitetstid ca. 70 min).


(1b) I første omgang brugte vi det mål der står på siden af hjulet som konstant for hjul-diameteren.
Vi eksperimenterede igen med fremad / baglæns kørsel alene flere gange - Og forsøgte at ende op det samme sted. Vi oplevede igen den samme mangel på præcision ved gentagen kørsel frem og tilbage, og resignerede derfor igen til kun at køre frem en enkelt gang og så aflæse værdien. Konstanten blev til sidst bestemt til 5.6F enheder (Aktivitetstid ca. 35 min).

(2b, 3b) Igen eksperimenterede vi med rotation på stedet ( som beskrevet i 2a og 3a), og at køre en rute med samme slutpunkt som startpunkt, for at kunne approksimere konstanten.
Igennem observationer af flere udførsler på denne test, så det ud som om robotten havde en tendens til at dreje en smule mod venstre, altså når meningen var at den skulle køre ligeud. En værdi på 16.0F enheder for hjulafstanden gav en fornuftig opførsel (Aktivitetstid ca. 45 min).

(4) 4. punkt var at kode en opførsel der muliggør at komme fra punkt A til punkt B og samtidig køre uden om evt. forhindringer.
Vi lavede en wrapper klasse Avoider, der tager en TachoNavigator som argument i konstruktøren. Wrapperen har en public metode goTo der tager to argumenter, - et X og Y koordinat. Koordinaterne bruges argumenter i et kald til TachoNavigator objectets goTo metode der samtidig sættes til at returnere umiddelbart. Herefter spørges TachoNavigator (TN) om vi kører ved vedvarende kald til isMoving, under disse vedvarende kald, bruges en UltrasonicSensor til at måle afstanden foran robotten, - hvis afstanden bliver målt til at være under 20 cm, kalder vi stop på TN og udfører en undvigelses manøvre ved at bakke 20 og dreje 90 grader. Hvis der ikke er forhindringer foran nu, kører vi max 40 cm frem og genoptager søgning mod de oprindelige koordinater. Hvis der efter det forrige drej på 90 grader stadig er forhindringer ( måske lige foran, afstand nul ) bakker vi max 20 cm. Hvis der ikke er forhindringer foran nu, genoptager vi søgning mod de oprindelige koordinater (Aktivitetstid ca. 125 min).

Conclusion:
Tendensen for venstre søgning under ligeud kørsel kan stamme flere steder fra; lille strøm-niveau, en minimal men alligevel forskellig størrelse på de to hjul, fysisk fejl/forskel i de to motorer eller måske timings/syncroniserings fejl/problemer i selve softwaren. Spørgsmål som flere eksperimenter måske vil kunne give et svar på.
Der skal muligvis fastsættes nye konstanter for hjul-afstanden, idet vi måske er kommet til at indlemme den evt. error for venstre søgning i denne konstant, fordi vi testede med Bagnalls rute, der kun laver venstre rotationer og ikke både højre og venstre rotation. En test hvor vi anvender en spejling af den brugte rute, kunne svare på dette spørgsmål.
Vi mangler at eksperimentere med CompassNavigator klassen. Intuitionen siger at det må være en smule mere præcis idet det må være muligt at korigere for tendensen til venstre søgning, ved at sammenligne den målte retning med den beregnede.

fredag den 7. november 2008

Uge 9; 'Niveauopdelt styring'

Deltagere:
Morten, Lars og Thomas.


Goal:
I løbet af dagens labsession skal der bygges en LEGO car, der udviser forskellig opførsel i forskellige situationer, ved brug af en lagdelt styring.


Plan:
Sideløbende med de aktiviteter der er foreslået til dagens labsession, testes forskellige LEGO-konstruktioner til slutprojektet, med hensyn til præcision. Vi valgte at beholde den nuværende bæltekonstruktion under denne lab-øvelse, istedet for LEGO konstruktionen på side 28-30 i instruktionsbogen.


For hurtigt at komme igang med at teste, er det valgt at anvende Capranis subsumption implementation SoundCar.java. Denne aggregerer 3 klasser der nedarver fra Behaviour.java, som igen nedarver fra java.lang.Thread. Meningen er at de 3 opførsler kører samtidig, men at opførsler på et højere niveau kan undertrykke eller forhindre lavere liggende opførsel, ie. suppresse dem.

Planen for dagen er som følger:
(1a) I første skridt observeres bilen med kun RandomDrive.java aktiveret.
(1b) I Andet skridt indkommenteres også AvoidFront.java.
(1c) Tredje skridt er at observere bilens opførsel med alle Behaviours aktiveret.

(2) Beskrive hvad det vil sige at en tråds Daemon-flag sættes til true.

(3) Undersøge og forklare hvorledes 'suppressed' bruges til at opnå kontrolleret adgang til motorerne.

(4) Der skal implementeres en yderligere 'Drive towards light'-behaviour i subsumptionmekanismen i SoundCar.java.


Aktivities:
Udover ovenstående punkter, blev der også brugt lidt tid på at lave justeringer af bælterne på NXT'en. og på at montere Sonar-sensoren. (aktivitetstid: ca. 25 min)

(1a)(1b)(1c) forløb som forventet.
I første skridt blev der alene observeret en kørsel i vilkårlig retning, uden at der blev taget højde for forhindringer, Det var således ikke muligt at undgå forhindringer.
I andet skridt tog AvoidFront.java over for RandomDrive.java, såfremt en forhindring blev detekteret. I de fleste tilfælde bemærkede AvoidFront.java de forhindringer robotten mødte,, og overtog styringen, dvs. satte 'suppressed' på den underliggende opførsel 'RandomDrive.java'.
I tredje skridt tog 'PlaySounds.java' over og kaldte stop() på motorene - udførte sin handling og lod de andre tage over igen. (aktivitetstid: ca. 40 min)

(2) At daemon-flaget sættes, betyder at main-metoden ikke skal vente på at tråden afsluttes, at vi ikke skal vente på et "join" eller interrupt'e, men at vi bare kan stoppe uden videre.

(3) 'suppressed' er en boolsk attribut hos en Behaviour, værdien kan sættes af en 'overliggende' Behaviour. Hvis en Behaviour har fået sin suppressvariabel sat til true, er meningen at den ikke må kunne sende kommandoer til Motoren. Dette er implementeret ved at tilføje en if-sætning inden kaldet til moteren. Hvis suppress er sand ignoreres kaldet til motoren.

(4) ToLight.java blev tilføjet i SoundCar.java, den blev indsat i mellem RandomDrive.java og AvoidFront.java. Vi brugte meget af koden fra forrige og tilføjede en lys-grænse på en værdi af 30. Hvis lysmålingen oversteg grænsen på 30, ville ToLight-opførslen tage over og undertrykke RandomDrive. (aktivitetstid: ca. 110 min)


Conclusion:
I gennem dagens labøvelser blev der opnået en indsigt i princippet for fler-laget kontrolsystem.

Det kunne være spændende, at teste skalerbarheden af Brooks koncept sammen med hardwaren i NXT'en.

Brooks' er tænkt til et meget lavere abstraktions niveau end Javas programmerings paradigme. Dette betyder at der enten bliver en meget tæt kobling, hvilket går imod principper for Java, eller også må man implementere en form for scheduleringsklasse - hvorved simpliciteten mistes, hvilket var det Brooks netop ville undgå.

fredag den 31. oktober 2008

Uge 8; Braitenberg vehicles

Deltagere:
Morten, Lars og Thomas.



Tom Dean figur 1.
Goal:
Med inspiration fra Tom Dean og Braitenberg, vil vi eksperimentere med simple kontrolmekanismer, ie. analoge følere simuleret i NXT'en og forbundet på forskellige måder.
I følge Tom Dean kan vi igennem eksperimenterne forvente at se opførsler, der af uoplyste mennesker nemt kan misforståes og tillægges en psykologisk egenskab eller tolkes som en form for bevidsthed.

Meningen er at bygge simple kontrolmoduler, der så kan forbindes forskelligt og vægtes forskelligt i en større fælles kontrolenhed.
Et andet mål med eksperimenterne er at finde ud af hvorvidt denne simple styring, vil kunne gøre det ud for en kæmpehjerne, med en forholdsvis stor mængde conditional branching.

Plan:
Der skal programmeres en java-klasse, der kan modellere en enkelt analog sensor.
Sensoren skal have en metode, der kan returnere et tal der mapper til et input power til en MotorPort. Den fysiske lego model bliver blot en modificeret udgave af vores LineFollower robot, hvor lyssensorerne peger fremad i stedet for nedad.
Vehicle 1, figur 2
Ved hjælp af disse komponenter vil vi lave vehicle 1 på Dean's figur 1.
Herefter vil det være nemt at konstruere vehicle 2a og vehicle 2b. Ved at instanciere to nye sensorklasser eller vehicle 1, og så forbinde sensor og motor med symbolske ledninger i java main-metoden.

Activities:
Vehicle 1, 2a, 2b:
Vehicle 1 konstrueredes gennem javaimplementationen OldLight.java og V1.java
OldLight nedarver fra Thread så den kan løbe uafhængigt af klassen Car.
I V1 oprettes en ny OldLight med en sensorport som argument. Oldlight har en metode 'readValue()' der returnerer en heltals værdi mellem 0 og 100 der passer til motorportens controlMotor(int a, int b).

V2a.java og V2b.java konstrueres ved som en aggregering af 2 stk OldLight og Car-klassen.

Car-klassen er til denne uges opgaver blevet udvidet, med yderligere metoder til hjælp i de tre vehicle klasser.

I ovenstående, er den værdi der overføres mellem sensor og motor baseret på mængden af lys, dvs. at jo mere lys der observeres, jo større værdi sendes ud til motoren.
Om der er mere eller mindre lys end før, bestemmes ved at sammenligne med gennemsnittet af hvad der er målt før. Dvs. hvis den nuværende sampling er over den forventede værdi så er det ensbetydende med at der er mere lys og derved sendes der en større værdi ud til motoren.

Inhibition (-):
V2bminus.java er et forsøg på at gøre det omvendte i forhold til ovenstående. Bilen starter ud med at køre med fuld power, og når den møder kraftigere lys mindskes den værdi der sendes ud til motoren.

Omkring maxlight og minlight:
Disse bruges i normaliseringen af den målte lysværdi til outputtet.
Der er lavet to versioner af lyssensoren OldLight.java og OldLight2.java. I OldLight.java bruges 'Math.max()' til at tjekke om den nyligt målte lysværdi er højere end hvad der hidtil er set. I så fald gemmes den nye værdi i variablen 'maxlight'. Ligeledes for 'Math.min()' og variablen 'minlight'.

Det kan her nævnes at ved opstart af disse programmer måltes der indledningsvis en maxværdi på 48, dvs. maxlight blev ikke mindre end 48 selvom det var mørkt, ie. at lysniveauet faktisk blev udlæst til 24. Man kan forestille sig at der et eller andet sted under initialiseringen af sensorernes hardware er der blevet målt 48...

For kun at huske max og min værdier for de sidste N målte værdier, er der i OldLight2.java implementeret en form for cirkulær buffer af længde N. Den cirkulære sample buffer gennemløbes for hver runcycle, for at sætte variablerne maxlight og minlight.

Plansforbruget for algoritmen kan aldrig blive under O(n), men tidsforbruget pr måling kan forbedres. Lige nu er det også O(n), men hvis man tjekker om den værdi man smidder væk og den værdi man indsætter påvirker max/min, kan man gøre den forventede tid pr måling betydeligt bedre. Dette under antagelse af, at de værdier man måler er nogenlunde tilfældige. Worstcase-tiden stadig O(n), men de fleste gange vil den være væsentligt bedre,

Observationer:
Det vægtede gennemsnit blev brugt som en form for bang bang kontrol, - således at hvis der blev observeret mere lys end gennemsnittet indenfor de sidste 10 sekunder, vil robotten reagere. I udregningen af det vægtede gennemsnit, brugte vi variablen Beta, der blev sat som en magisk konstant, fundet ved eksperimentering.
Ved N sat til 250 huskedes den gamle værdi i ca. 8 sekunder.

Plan fremtid:
At påmontere et lys på toppen af NXT'en og eksperimentere med flere vehicles på samme tid, - for at se hvorledes de reagere i forhold til hinandens bevægende lyskilder.

onsdag den 15. oktober 2008

Uge 5+6 : Racing bots

Deltagere: Thomas og Morten.

Goal:
Målet med ugernes aktivitet er, at bygge og programmere en liniefølgende robot i stil med den allerførste. Et følgende mål med aktiviteten er, at få robotten til at følge den officielle bane hurtigst muligt.

Plan:
Indledningsvis konstruerer vi en robot med udgangspunkt i den første robot vi byggede, herefter afprøver vi denne med den sidste udgave af vores LineFollower program. Efter de indledende aktiviteter skal designet optimeres, både det fysiske design og programmet.

Activities:
Den første simple model optimerede vi med større hjul og flere lyssensorer og opnåede en omgang på banen på 24 sek. Herefter begyndte vi en radikal ændring af robotten, vi endte med at have en robot med gearing og drejeligt baghjul. Denne model viste sig at være så hurtigt, at vi havde væsentlige problemer med at holde den på banen og således fik vi ikke noget godkendt løb på banen.

torsdag den 2. oktober 2008

secrets...uuuuh!

Kommandoen til rent faktisk at køre et program der forbinder til NXT'en via bluetooth:

java -Djava.library.path=../../lejos_nxj/bin/ -cp ../../lejos_nxj/lib/pccomm.jar:. BTSend "navn" "adresse"

ps. stierne er relative i dette tilfælde...

look ma' allmost w/ no hands!


Første forsøg, upload af Sejway.java
med standard opsætning af variabler.

torsdag den 25. september 2008

Uge 4; Balancing killer

Deltagere: Thomas, Lars og Morten.

Goal:

Målet med dagens aktivitet er, at bygge og programmere en virkende segway-lignende robot. Gennem denne aktivitet ønsker vi at opnå større erfaring med PID-controllers.

Plan:
Indledningsvis konstruerer vi robotten og uploader eksempelprogrammet sejway, herefter tester vi robotten i dens standardkonfiguration. Andel del af dagens program består af eksperimenter med de forskellige parametre i programmet, samt med en eventuel auto-kalibrering af robotten. Ekeperimenterne benytter dataloggeren til dataindsamling.

Activities:
Eksperiment 1.
Med dette eksperiment ønsker vi at undersøge, hvilken betydning den initielle kalibrering af robotten har for dennes evne til at balancere og evt. finde den optimale værdi. Eksperimentet udføres ved, at starte robotten med forskellige kalibreringer og så bringe den i en nogenlunde balancerende position, hvorefter der observeres hvorvidt robotten falder frem- eller bagover og hvor kraftig denne tendens er.

Resultater:
587 - fremover, hurtigt
527 - fremover, langsom
512 - fremover, meget langsom, mange standsninger
509 - skiftende tendens, mange standsninger
506 - bagover, langsomt
504 - bagover, langsomt
487 - bagover, hurtigt

På trods af de meget grove målinger, mener vi dog at kunne konkludere, at vores optimale kalibrering, på det anvendte underlag, ligger mellem 506 og 512. Udover det fundne resultat, giver eksperimentet anledning til at undersøge hvorfor robotten pludseligt standser og hvorvidt dette sker sker mere eller mindre hyppigt under forskellige forhold.

Eksperiment 2.
For at undersøge hvorfor robotten pludseligt standser, tilføjede vi loggerkoden til programmet og starter robotten med en kalibrering på 512. Herefter tolkes dataen for at identificere eventuelle mønstre der standser robotten.

Eksperiment 3.
For at finde en kombination af parametrene KP, KI og KD der giver den optimale balanceevne, gennemførte vi eksperimenter der testede indstillinger af de tre parametre, det skete ved at lade en parameter være variabel og de to andre faste. Til formålet tilføjede vi kode til programmet, således vi kan aflæse et tal(F)der er proportional til antal svingninger frem og tilbage pr. millisekund. Testresultaterne ses nedenunder.





















































KP28282828282828282828
KI1123456789
KD1111111111
F()53





5648445052565752


Generelt virkede robotten meget ustabil med ovenstående settings, dog muligvis lidt mere stabil jo højere værdien var. Vi mener derudover ikke at kunne bruge svingningsmålingen til noget, idet vi er nødt støtte robotten under udførslen, hvilket givetvis har indflydelse på denne måling. Med endnu større værdier af KI(20 og 40) kunne vi dog konstatere, at tendensen til at robotten stopper bliver meget mere udpræget.



















































KP28282828282828282828
KI1

11

1

1

1

1

1

1

1

KD0

5

10

15

20

25

30

35



40

45

F()45

5156104

156

187

226

319

119

327


Med denne række målinger, mener vi at kunne se en tydelig forøgelse af svingningstallet. Dette giver udslag i meget mindre svingninger og hvis robotten anbringes i en fornuftig startstilling, kan den næsten balancere selv fra værdier omkring 25 og op, den bliver dog også mere og mere følsom overfor store udslag i målingerne.



















































KP0

5

10

15

202530

35

40

45

KI011

1

1

1

1

1

1

1

KD1111111111
F()310

4941

4951

5556535656


Bortset fra den første måling, hvor KP er 0, giver de øgede værdier for KP anledning stil større svingninger, men til gengæld bliver den bedre til at modstå store udsving, ved f.eks. lettere skub, som med KD målingerne er robotten ved de høje værdier næsten i stand til at balancere selv.

Som forventet skal den optimale løsning findes som en kombination af de tre værdier.

Eksperiment 4.
Efter at have fået en ide om hvordan robotten opfører sig ved ændringer i parametrene, eksperimenterede vi her med at få tunet løsningen, så robotten selv kan balancere.

<-- Ved øvelsernes afslutning havde vi endnu ikke fundet en virkende løsning -->

torsdag den 18. september 2008

Uge 3; Sound-Sensor-Clapping-Test-Stuff-Ting

goal:
At eksperimentere med SoundSensoren og derved få erfaring med mikrofonens muligheder og begrænsninger.

plan:
Planen er at vi skal ende op med at lave en form for lydgenkendelse, idet vi først analyserer på lydmønstret af forkellige typer af høje klap. Udfra denne dataopsamling skaber vi et billede af et gennemsnitlig klap. Mønstergenkendelsen af klappet skal så forsøges implementeres i en algoritme.

activities:

experiment 1:
Datalogning af forskellige høje lyde.

experiment 2:
I de første eksperimenter, brugte vi dataloggeren for at opsamle data og få skabt nogle lydbilleder af de forskellige typer klap. Herunder ses sammenligningen af 5 forskellige klap.
Med 'KillBot's mikrofon så et gennemsnitlig klap ud som følger: Startende med svag lydniveau på under 15. Herefter følger et skarpt peek på op til et lydniveau på over 80 varende mellem ca. 20 - 50 msek., hvorefter lydniveauet igen stille falder til et lydniveau på under ca. 60 efter en periode på 180 msek. efter peek'en.

EscapeHandling:
Istedet for hele tiden at poll for Escape pressed, har vi lavet en anonym ButtoListener. Koden kan ses herunder. Vi er lidt i tvivl om det er den kønneste løsning, men det er måske bare et spørgsmål om at fravende sig Java's kønne verden og tilvende sig en verden i embedded systemer:

Button.ESCAPE.addButtonListener(new ButtonListener(){
public void buttonPressed(Button b) {
Car.stop();
LCD.clear();
LCD.drawString("Program stopped", 0, 0);
LCD.refresh();
try{
Thread.sleep(1000);
} catch (Exception e){}

System.exit(0);
}

public void buttonReleased(Button b) {}

});


Test-for-clap-algoritme:
Vi skiftede metoden 'waitForLoudSound()' ud med nedenstående. Til at teste og måle tiden imellem samplingerne brugte vi 'System.currentTimeMillis()'. Først venter vi på et lydniveau på over 50, vi sampler i 25 mSek., og tester om niveauet, i en af samplingerne var over 80 (peek), sampler så igen i yderligere 250 mSek og tester om lydniveaut har været tilpas lavt. 'Lavt' er i dette tilfælde sat til at være under 50. Hvis ikke det er tilfældet starter vi forfra.:

private static void waitForClap() throws Exception
{
int soundLevel;
boolean clap = false;
while(!clap){
LCD.clear();
LCD.drawString("Step 1",0,0);
LCD.refresh();

do {
soundLevel = sound.readValue();
} while ( soundLevel < 50 );

LCD.clear();
LCD.drawString("Step 2",0,0);
LCD.refresh();

int now = (int)System.currentTimeMillis();
int maks = 0;
while ((int)System.currentTimeMillis() <= now+25){
soundLevel = sound.readValue();
maks = Math.max(maks, soundLevel);
}

if (maks > 80){

LCD.clear();
LCD.drawString("Step 3",0,0);
LCD.refresh();

now = (int)System.currentTimeMillis();
while ((int)System.currentTimeMillis() <= now+250){
soundLevel = sound.readValue();
if (soundLevel < 50){
clap = true;
break;
}
}
}

}
}

torsdag den 11. september 2008

Uge 2; Ultrasonisk sensorsjov

Goal:
Målet med dagen var at eksperimentere med den ultrasoniske sensor og derved opbygge noget erfaring og forståelse for sensorens virkemåde, muligheder og begrænsninger.

Plan:
I de første eksperimenter brugte vi programmet SonisSensorTest, som bare tager målinger fra sensoren og udprinter dem på LCD'et. - Meget lig de første eksperimenter fra lyssensoren.

De næste eksperimenter går ud på at lege med værdierne i programmet Tracker, programmet søger at flytte sensoren hen i en afstand af f.eks. 35 cm. Med den nuværende opsætning virker det som om at den bare oscilere bl.a. pga. response-tid mellem processor, sensor og motor. Her gælder det om at finde en gylden middelvej i opsætningen af variablerne i programmet.

Sidste opgave går på at lave en wallfollower udfra Philippe Hurbains fremgangsmåde og eksperimentere med forskellige kontrol-algoritmer fra forrige uges forelæsning.

Activity:
Vi uploadede programmet 'SonicSensorTest' og forsøgte os at måle afstande til forskellige objekter.

Eksperiment 1:

Vi testede hvorledes ekkoet fra den udsendte lyd fra UltraSonicSensor opførte sig overfor forskellige overflader. Dvs. først på træpladerne på siderne af testbordet i Zuse-bygningen. Et ret forventet resultat, ie. et 'veldefineret ekko'.
Vi prøvede også med en fleecejakke over kanten - for at se hvorledes det påvirkede ekkoet. Det havde faktisk stor indflydelse, idet det absorberede meget af lyden. Vi skulle ind på mellem 89 - 110 cm for at sensoren kunne opfange et ekko.



Eksperiment 2:

Ud fra plottet herunder kan man se resultatet af 2 forskellige tests med Ultrasonicsensorens viste værdier i forhold til reelt målte værdier.


I den første test målte vi ekkoet på en hård overflade, mens vi i anden test målte en overflade hvorpå vi havde lagt en trøje over.
Vi kom frem til at der er god overensstemmelse med de målte værdier i intervallet fra ca. 20 cm og opefter. Hvis vi forsøgte at måle på afstande under 20 cm begyndte der at være fejl. sensoren mente der var længere end der faktisk var.


Eksperiment 3:

Vi forsøgte også at stille objekter ret foran og skråt foran sensoren, for at teste vinklen for de udsendte lydbølger, samt hvor små objekter der kunne opfanges ekko på. F.eks var det svært at opfange en plastikkop, mens den cylinderformede kaffekande og pladen af træ var nemme at se ret foran.
Når måleobjekterne blev stillet ud i en yddervinkel i forhold til sensoren, kunne sensoren ikke længere modtage ekkoet. Eksperimentet viste en overaskende bred vinkel.


Eksperiment 4:
I dette eksperiment anvender vi programmet Tracker.java. Programmet forsøger at flytte robotten til en given afstand af en genstand, ved hjælp af den ultrasoniske sensor. Efter at have kørt det originale program(minpower=60 , gain=0,5 , samplerate=300) ser vi at robotten bevæger sig ind til den korrekte afstand, hvorefter den begynder at oscillere omkring denne afstand. Trackerprogrammet fungerer som en proportionel controller og den oscillerende opførsel er netop et kendetegn ved denne type controllere. Vi vil dog argumentere for, at der er tale om en påtaget oscillering, idet programmet faktisk ikke forsøger at stoppe robotten når den rammer den præcise afstand. Programmet giver anledning til at eksperimentere med følgende variable: minpower, gain og samplerate.

Til forsøgene har vi rettet programmet til således, at robotten skal stoppe hvis den opnår den korrekte afstand, i stedet for at skulle køre enten frem eller tilbage(med standard indstillinger).

1. forsøg (minpower=60 , gain=0,5 , samplerate=300):
Efter ændringerne i koden observerede vi væsentlig færre oscillationer, i flere tilfælde stoppede robotten endda uden synlig oscillation.


5. Eksperiment
Implementering af wallfollower. Med udgangspunkt i en hurtig og forsimplet oversættelse af programmet og kørsel af dette, kan vi konkludere at det fungerer nogenlunde acceptabelt. Standardudgaven fungerer som en bang-bang controller, som dog til forskel fra en typisk implementering kan vælge mellem 6 forskellige muligheder.

Teksten beskriver henholdsvis en "gentle turning" algoritme og en "three state" algoritme. Gentle turning gør generelt at robotten performer bedre, idet begge hjul drejer hele tiden hvilket igen, som navnet antyder, giver en roligere og mere fremadrettet opførsel. Vi implementerede en lignende algoritme for lyssensoren og det gav samme resultat. Vi har ikke store erfaringer med 3-state algoritmen, men i modsætning til de to andre, giver 3-state ikke noget der ligner harmoniske svingninger, men performancemæssigt er den sammenlignelig med den simple wallfollower.

tagtagtag