Commit aca27539 authored by Martin Bjerrum Henriksen's avatar Martin Bjerrum Henriksen
Browse files

markdown files

parent b501ee78
Pipeline #2775 skipped
## NXT programming lesson 5
**Goals:**
Målet med denne opgave er at undersøge hvordan vi ved hjælp af forskellige sensorer og PID controller kan få en Lego-robot til at kunne balancere selv.
**Plan:**
Vores plan er at følge opgavebeskrivelsen [1], hvor vi starter med at eksperimenterer med lyssensoren, derefter kigger vi på at lave, program kode til at kunne lave changes on the fly. Herefter vil vi kigge på hvordan en farvesensor og en lyssensor, kan blive brugt at få Lego-robotten til at balancerer. Til sidst vil vi prøve at få Lego-robotten til at balancere ved hjælp af en gyro-sensor.
**Setup:**
Vi har brugt to forskellige Lego-robot konstruktioner den ene var jævnfør Phillippe Hurbain [2] den anden var jævnfør [3]. Udover dette har vi sat en gyro-sensor på setup nr. 2 dette kan ses på figure 3.2 i opgave 3.
**Exercise 1 - Self balancing robot with light sensor**
I denne exercise skal vi prøve at balancere en Lego-robot ved hjælp af en lyssensor. Programmet vi har brugt i denne øvelse er SejWay.java af Brian Bragnall, hvor vi har fulgt Phillipe Hurbains råd om at få en Lego-robot til at balancere. I denne exercise har vi udelukkende fokuseret på hvorvidt omgivelserne, såsom lysstyrke, og terrænet (jævnt/ujævnt gulv) har en indflydelse på hvor godt Lego-robotten kan balancerer, og har derfor valgt ikke at justere på PID værdierne, hvilket vi først gør i den næste opgave med farvesensoren.
Phillipe Hurbains:
* *"T**he lighting must not interfere with light sensor. Try your NXT in a dark room, or a room lit only by fluorescent light (fluorescent lamps emits little or no infra-red light so the light sensor is almost insensitive to their light).*
* *It works best on a clear but non uniform surface. Some patterns give NXTway something to "zero" on.*
* *When you press the run button, NXTway must be perfectly balanced, as light level measured at that time determines the equilibrium position." *[2]
Vi startede med at kører programmet i et velbelyst lokale, hvor vi observerede Lego-robottens adfærd. Et billede af omgivelserne kan ses på fig.1.1
![image alt text](image_0.jpg)
Fig. 1.1 Omgivelser for første test. Masser af naturligt lys og på et træbord
Dette var for at observere hvordan Lego-robotten og koden fungerede uden indvinding fra os.Istedet for at balancere og stå stille som vi forventede, bevæger Lego-robotten sig hurtigt med små ryk frem og tilbage og vælter ca. indenfor 3 sekunder uden støtte.
Efter dette eksperiment, fulgte vi Phillipe Hurbains råd om at balancere en Lego-robot. Det første råd handler om at placere Lego-robotten i et mørkt område. Et billede af omgivelserne kan ses på fig.1.2
![image alt text](image_1.jpg)
Fig.1.2 Omgivelserne til mørkt rum test.
Lego-robottens adfærd i dette eksperiment var markant bedre, da den havde færre små ryk frem og tilbage og balancerede uden støtte, i ca. 8 - 10 sekunder.
Det andet råd Phillipe Hurbain anbefaler er at kører programmet på Lego-robotten på et ikke ensartet gulv (ujævnt). Vi har i dette eksperiment fået Lego-robotten til at kører på gulvet i chomsky laboratoriet, som er bestående af små sten, i et mørklagt område se figur 1.3.
![image alt text](image_2.jpg)
Fig. 1.3 Chomsky lab’s gulv.
I dette eksperiment observerede vi Lego-robottens adfærd og så at den var bedre end på det første eksperiment ved normalt lys og ensartet gulv. Den balancerede i en længere tidsperiode på det ikke ensartede gulv end på det ensartede gulv med normalt lys. (i ca. 4 - 5 sekunder)
Vi har ud fra denne øvelse lært at omgivelserne spiller en yderst væsentlig rolle i hvor godt Lego-robotten balancerer, hvilket vores eksperimenter også viser.
**Exercise 2 - Self balancing robot with color sensor **
I denne øvelse udskiftede vi lys sensoren med en farvesensor, hvor vi startede med at teste Lego-robottens adfærd med en farvesensor. Det første eksperiment var på jævnt gulv med normalt lys, hvor vi observerede at den slet ikke kunne balancere. Samme adfærd gjorde sig gældende for et mørklagt lokale, hvor Lego-robotten havde rigtig svært ved at balancere (se fig. 2.1 og fig.2.2)
![image alt text](image_3.jpg)![image alt text](image_4.jpg)
Fig. 2.1. Lyse omgivelser Fig. 2.2 Mørke omgivelser.
Efter de indledende eksperimenter med Lego-robotten der kører SejWay.java koden med de PID værdier der var med fra starten, prøvede vi at kalibrere PID værdierne for at se hvilke PID værdier der ville være bedst til at få Lego-robotten til at balancere:
pid:
<table>
<tr>
<td>P</td>
<td>I</td>
<td>D</td>
</tr>
<tr>
<td>28</td>
<td>4</td>
<td>33</td>
</tr>
<tr>
<td>14</td>
<td>4</td>
<td>16</td>
</tr>
<tr>
<td>40</td>
<td>4</td>
<td>20</td>
</tr>
<tr>
<td>60</td>
<td>4</td>
<td>20 (god)</td>
</tr>
<tr>
<td>80</td>
<td>0</td>
<td>20</td>
</tr>
<tr>
<td>60</td>
<td>4</td>
<td>40</td>
</tr>
<tr>
<td>60</td>
<td>4</td>
<td>10</td>
</tr>
<tr>
<td>70</td>
<td>4</td>
<td>25 (god)</td>
</tr>
<tr>
<td>80</td>
<td>4</td>
<td>30</td>
</tr>
<tr>
<td>100</td>
<td>4</td>
<td>30</td>
</tr>
<tr>
<td>100</td>
<td>4</td>
<td>40</td>
</tr>
<tr>
<td>100</td>
<td>5</td>
<td>35</td>
</tr>
<tr>
<td>100</td>
<td>6</td>
<td>35</td>
</tr>
<tr>
<td>110</td>
<td>6</td>
<td>35 (god)</td>
</tr>
<tr>
<td>110</td>
<td>6</td>
<td>45 (god)</td>
</tr>
<tr>
<td>110</td>
<td>7</td>
<td>40 (bedst)</td>
</tr>
</table>
Tabellen viser de PID værdier vi afprøvede, i rækkefølge. her definere vi værdi kombinationer som (god) hvis Lego-robotten kunne stå i omkring 7 sekunder og (bedst) når vi fik til at stå i en 15 sekunder.
Efter en række ændringer på PID værdierne, kan vi ud fra vores observationer konkludere at omgivelserne havde en stor betydning for hvor længe Lego-robotten balancerer (ligesom i exercise 1).
Udover at ændre PID værdierne, justerede vi også på bilens omgivelser. Istedet for at køre på gulvet, brugte vi et hvidt underlag, fordi gulvet ikke var ensartet. Vi brugte også et bord og en træplade til at skygge for området som den kørte i. Det var fordi bilen skyggede for sig selv og kørte i forskellige lysniveauer. (se figur 2.3). Ved PID værdierne P = 110, I = 7, D = 40, fik vi Lego-robotten til at holde balancen i mere end 1 minut, hvor den stod relativt stille og lavede yderst minimale ryk frem og tilbage for at ramme setpoint.
![image alt text](image_5.jpg)
Fig. 2.3 Test setup med hvidt underlag og skygge af bord og tavle.
Grundet skiftende undervisningslokaler måtte vi lave nogle nye omgivelser som ses på fig. 2.4, som blev brugt til fremtidige forsøg.
![image alt text](image_6.jpg)
Fig. 2.4 Nye omgivelser som består af hvidt underlag og bord til at skabe skygge.
Vi fortsatte med at eksperimentere med forskellige PID værdier og nåede til et punkt hvor Lego-robotten kunne stå selv i 5 min. hvor den eneste grunden til at den væltede var at vi begyndte at udfordre dens stabilitet ved at skubbe til den. Vi begyndte herefter at ændre koden så vi kunne ændre værdierne on the fly, derved håbede vi at øge hastigheden på vores tests.
Vi gjorde det muligt for os at ændre både PID værdierne og offsettet da det til tide bare ikke var spot on når vi gjorde det. Herefter lavede vi en række eksperimenter hvor vi prøvede forskellig værdier af. både for at gøre Lego-robotten bedre men også for at se hvad ændringer gjorde ved Lego-robottens adfærd. De værdier vi prøvede er som følger:
<table>
<tr>
<td>P</td>
<td>I</td>
<td>D</td>
<td>Offset</td>
</tr>
<tr>
<td>100</td>
<td>10</td>
<td>40</td>
<td>550</td>
</tr>
<tr>
<td>100</td>
<td>10</td>
<td>40</td>
<td>552</td>
</tr>
<tr>
<td>100</td>
<td>10</td>
<td>40</td>
<td>554 </td>
</tr>
<tr>
<td>110</td>
<td>10</td>
<td>40</td>
<td>550</td>
</tr>
<tr>
<td>110</td>
<td>10</td>
<td>60</td>
<td>550</td>
</tr>
<tr>
<td>130</td>
<td>10</td>
<td>60</td>
<td>550</td>
</tr>
<tr>
<td>130</td>
<td>20</td>
<td>50</td>
<td>558</td>
</tr>
<tr>
<td>130</td>
<td>40</td>
<td>50</td>
<td>558</td>
</tr>
<tr>
<td>130</td>
<td>60</td>
<td>50</td>
<td>558</td>
</tr>
</table>
Den sidste måling er den der fungerede bedst og er den vi har en video af
her: [https://drive.google.com/open?id=0B58sHV1jvaf6ZWFrRHBQM0tqNjA](https://drive.google.com/open?id=0B58sHV1jvaf6ZWFrRHBQM0tqNjA)
Når man skal få robotten til at balancere kan man mærke forskel på hvilke PID værdier vi bruger fordi det har betydning for robottens opførsel.
**Exercise 3 - Self balancing robot with gyro **
Vi vil nu prøve at kigge på om vi kan få Lego-robotten til at stå mere stabilt ved at bruge en gyro-sensor i stedet for lys eller farvesensor. Først satte vi gyroen på Lego-robotten som vist på fig. 3.1
![image alt text](image_7.jpg)
Fig. 3.1 Her ses første setup af Lego-robotten med gyrosensor monteret på rytterens ryg.
Vi brugte testkoden *GyroTest.java*[4] der omtales og linkes til i opgavebeskrivelsen til at teste gyro-sensoren ved at bevæge robtotten frem og tilbage. Vi observerede en værdi omkring 601-602 og kunne ikke få den til at ændre sig mere end 5 værdier. Det fandt vi underligt, da det er et meget lavt interval der i så fald skulle identificere om hvorvidt Lego-robotten var ved at vælte eller ej og hvor meget der skulle justeres for at det ikke skete. Vi kom så i tanke om at den anvendte gyro-sensor, er 1-akset og derfor kun måler på en akse. Vi forsøgte så at bevæge Lego-robotten fra side til side, hvilket gav nogle større udsving og derved fandt vi ud af hvordan gyro-sensoren skulle vende. Vi kunne også se at gyroen kun reagerede når den var i bevægelse og ikke hvor meget den havde bevæget sig når bevægelsen stoppede. Vi fandt derfor ud af, at gyro-sensorens værdi ikke direkte fortalte os hvor meget Lego-robotten have bevæget sig eller hvilken vinkel den var rykket til. Efter vores observationer, ændres påsætningen af sensoren som vist på fig. 3.2 for at vi kunne få målinger for om Lego-robottens bevægelse frem og tilbage i stedet for fra side til side.
![image alt text](image_8.jpg)
Fig. 3.2 Her ses det andet setup med gyroen på Lego-robotten, her sidder den på siden af rytteren. I denne position kunne vi aflæse når rytteren faldt.
For at finde ud af hvad gyro-sensorens offset er, brugte vi en datalogger som i uge 2 [5] til at logge gyro-sensorens værdier. Derefter loggede vi 700 samples, med en sample tid på 4 ms. I følge [6] og [7] er gyro-sensoren i stand til at måle 300-333 gange i sekundet. Vi udregnede hvor mange ms der burde være af forsinkelse mellem hver måling for at være sikker på at man får en ny måling hver gang. Ved at dividere antallet af målinger pr. sekund med 1000 ms, udregner vi hvor mange ms, der burde være mellem hver måling til 1000/300 = 3,333 ms. Da vi ikke kan sætte tråden til at sove med et decimaltal, rundet vi op til 4 ms. I følge [6] er 500 samples nok til at give et godt offset. Vi brugte 700 samples, men undlod de 200 første samples, da vi vurderede at Lego-robotten lige skulle ligge stille efter vi havde startet målingen ved at trykke på enter-knappen. Vi lavede et gennemsnit over de 500 samples og fandt et offset på 601,986. På figur 3.3 ses et punktdiagram over de 700 samples, hvor vi kan se støjen fra at have trykket på enter-knappen ved de første 170 samples. Resten af værdierne er 602 (+/- 1).
![image alt text](image_9.png)
Fig. 3.3 Punktdiagram (antal målinger ad x-aksen og sample-værdi ad y-aksen) over 700 samples for at bestemme offset for gyro-sensoren. Offsettet bestemmes til 601,986.
Vi udførte endnu et eksperiment for at undersøge hvordan vi kunne anvende de værdier vi fik ud ved at benytte funktionen *readValue()* brugt i *GyroTest.java *[4]. Forsøget blev udført ved hjælp af en datalogger som i uge 2 [5] til at registrere gyro-sensorens værdier. Forsøget blev udført ved at have Lego-robotten i stående i lodret position, ligge den ned bagud, rejse den op igen, ligge den ned forlæns og rejse den op igen. Sekvensen ses på figur 3.4.
![image alt text](image_10.jpg)
Fig. 3.4 Sekvens for eksperimentsudførsel og hvordan data fra readValue() hænger sammen med bevægelser.
Vi lavede et punktdiagram ud fra data fra dataloggeren. Ses på Fig. 3.5.
![image alt text](image_11.png)
Fig. 3.5 Punktdiagram (tid hen ad x-aksen og sample-værdi ad y-aksen) over data optaget ved sekvensen vist i Fig. 3.4.
Man kan se 4 tydelige udsving på punktdiagrammet i Fig 3.5. Det første udsving er hvor Lego-robotten lægges 90 grader bagud, det andet udsving er når den rejses op igen, det tredje udsving er når robotten lægges 90 grader fremad og det fjerde udsving er det Lego-robotten rejses op igen. Ud fra punktdiagrammet fandt vi, at ved at trække vores offset fra tidligere (601,983 - afrundet til 602) fra de målte værdier, burde vi få omkring 0 ved at tage summen af alle målingerne. Det var dog ikke tilfældet, da summen af de målte værdier blev -1437. Dette blev dog set som at det var en fejlkilde der var skyld i denne afvigelse. Der blev foretaget 1239 målinger i alt, hvilket giver en afvigelse pr. måling på 1,15981. Der blev identificeret 3 mulige fejlkilder: Forsøget blev foretaget ved at vende Lego-robotten i hånden, gyro-sensoren havde været tændt i noget tid og kunne derfor være blevet varm (i følge [6] påvirker temperaturen offsettet). Derudover påvirker strøminput også offsettet[6], dette forsøgte vi dog at kompensere, ved at have strømkablet sat til under forsøget. Vi fandt ud af, at man ud fra et punktdiagram kan identificere hvornår Lego-robotten har været påvirket i den ene eller anden retning.
I næste forsøg forsøgte vi, på baggrund af [6] som beskriver at offsettet påvirkes af strøminputtet, at se hvilken påvirkning motorens strømforbrug havde offsettet. Vi benyttede igen dataloggeren fra uge 2 [5], til at logge gyro-sensorens værdier. På Fig. 3.6 ses et punktdiagram over motorens påvirkning af offsettet.
![image alt text](image_12.png)
Fig 3.6 Punktdiagram (tid hen ad x-aksen og sample-værdi ad y-aksen) over motorens påvirkning af offsettet.
Det ses på Fig 3.6, at offsettet hvor motoren kører, har rykket sig i forhold til Fig. 3.3 hvor motoren ikke kører. Når motoren kører ligge offsettet størstedelen af tiden på 601, men der er mange gange hvor den er nede på 600 og få gange hvor den er oppe på 602. Det gennemsnitlige offsettet når motoren kører udregnes til at være 600,9012 hvilket er lavere end det tidligere fundne offset på 601,983. En fejlkilde kunne være at det er to separate kørsler der er refereres til. Mere optimalt burde man have lavet målinger hvor motoren kører og hvor motoren ikke kører i samme eksperiment. Vi kan dermed ikke helt afvise dette offset har været påvirket af at gyro-sensoren havde været tændt i kortere eller længere tid end ved det tidligere forsøg.
Følgende eksperiment tager udgangspunkt i forsøget fra [8]. Vi har tænkt os at dreje robotten med gyroskopet på, logge vinkelhastighederne og derefter forsøge at udregne rotationen i grader.
Udover readValue, har gyroskopet også en metode, getAngularVelocity, som der ifølge beskrivelsen giver os vinkelhastigheden i grader pr. sekund. Det kan bruges til at udregne rotationen i grader. Vi gentog eksperimentet som vist på Fig. 3.4 og loggede vinkelhastigheden fra getAngularVelocity. Grafen ses på Fig 3.7.
![image alt text](image_13.png)
Figur 3.7 Data fra rotationseksperiment. Grafen viser Vinkelhastighed i °/sek som funktion af tid i ms efter eksperimentets start.
Vi testedet for hver af de fire udsving i kurven, at arealet mellem kurven og x-aksen summer til cirka 90 grader. Det gjorde vi blot ved at tage den gennemsnitlige værdi i intervallet, og gange med forskellen i tid.
For eksempel for det første udsving, foretog vi følgende beregninger på vores data:
Kurven er stabil cirka indtil målingen som tages ved tid 354 ms, hvor det første udsving begynder. Den er stabil igen ved tid 862. Udsvinget varede derfor i 508 ms, og i dette tidsrum har vi taget 69 målinger. Deres vinkelhastigheder summer til 12219 °/s hvilket giver os en gennemsnitlig vinkelhastighed på 177 °/s. 177 °/s gange 508 ms giver os en baglæns rotation på 90,0 grader. Her er nogle af decimalerne fra beregningen udeladt men den fulde data for dette eksperiment kan ses på ark 10 i excelfilen der ligger på [https://gitlab.au.dk/group16-16/Lesson5/blob/master/Gyrov%C3%A6rdier.xls](https://gitlab.au.dk/group16-16/Lesson5/blob/master/Gyrov%C3%A6rdier.xls).
Vi lavede desværre ikke et eksperiment som loggede robottens vinkel som funktion af tiden.
Det kunne gøres ved løbende at holde de to sidste målinger af vinkelhastigheden i to variable.
I hvert gennemløb af kontrolløkken, udregner man så gennemsnittet af de to. Det antages at være et rimeligt estimat for robottens vinkelhastighed imellem de to målinger. Dette estimat ville man så gange med forskellen i tid mellem målingerne, og resultatet lægges til en variabel som repræsenterer robottens vinkel og som nedskrives med dataloggeren.
Ud fra disse eksperimenter forsøgte vi at programmere Lego-robotten så den kunne balancere ved hjælp af gyro-sensoren.
Koden til dette eksperiment findes i *package gyrostuff *and in java class *Sejway.java*. Vi forsøgte først med den beregningsmetode vi fandt i eksperimentet overnfor: "*angle += (((currentAV + currentAV)/2) * ((currentTime-lastTime))/1000);*". Da vi forsøgte at køre Lego-robotten observerede vi at, at hjulene stort set ikke drejede rundt, heller ikke når man løftede robotten for at give hjulene mindre modstand. Vi prøvede derefter at ændre vores PID-værdier, specielt p-ledet for at se om vi kunne få øget den power-værdi vi sender videre til de to motorer. Dette resulterede ikke i nogen forskel og vi forsøgte at finde ud af hvad der ellers kunne være galt. Vi forsøgte at ændre udregningen af vinklen, som også påvirker motor-kraften. Vi fjernede den sidste del af formlen, så den ser ud som følgende: “*angle += (((currentAV + currentAV)/2) * ((currentTime-lastTime)));*”. Vi undlod altså at dividere med 1000, da vi mente at det var dette led der gjorde at motoren ikke fik nok kraft. Ledet gjorde, at vi fandt den vinkel hældningen af robotten gjorde i løbet af et sekund. Det vil sige at vi ikke får vinkelændringen pr. sekund. Denne ændring fik Lego-robotten til at køre, dog fandt vi ud af, at vores offset langsomt ændredes, så robottens balancepunkt blev flyttet længere og længere fremad. Vi nåede til at Lego-robotten kunne stå i 2 sekunder, når vi ændrede PID-værdierne til {p=1,2}, {i=0,01} og {d=0,1}. Vi ændrede samtidig SCALE variablen og med disse PID-værdier, satte vi {SCALE=150}. I videoen [9] eller dette link, viser at vores Lego-robot står ca. 2 sekunder ved hjælp af gyro-sensoren. [https://drive.google.com/open?id=0B6Aetf7tBQrgLUt5TV9fU0MzczQ](https://drive.google.com/open?id=0B6Aetf7tBQrgLUt5TV9fU0MzczQ).
**Konklusion: **
Vi har igennem vores forsøg lært at bruge lyssensor, farvesensor og gyro-sensor til at få en Lego-robot til at balancere selv. Vi kan ud fra vores eksperimenter se at en lyssensor er meget følsom overfor omgivelserne, farvesensoren er på trods af at være afhængig af lyset fra omgivelserne og overfladen som Lego-robotten køre på ikke nær så følsom til ændring i lyset eller overfladen på gulvet. Gyroen har ikke et problem med omgivelserne, men har dog selv et problem i form af *drift*. Vi kan se at dette *drift* får offsettet til at drifte i en retning så Lego-robotten kan starte med at stå i 90 graders vinkel og efter et par sekunder vil Lego-robotten mene at den er på 85 grader.
Vi har også fundet at PID værdierne skal ændres alt efter omgivelserne. I tilfælde med lys og farvesensoren skyldes det at lyset ændrer sig alt efter tiden på dagen og forskellige overflader læses forskelligt, i modsætning til gyroen hvor værdierne også afhænger af driften fra sensoren.
**Litteraturliste:**
[1] [http://legolab.cs.au.dk/DigitalControl.dir/NXT/Lesson5.dir/Lesson.html](http://legolab.cs.au.dk/DigitalControl.dir/NXT/Lesson5.dir/Lesson.html) (d. 9/4-16)
[2] [http://www.philohome.com/nxtway/nxtway.htm](http://www.philohome.com/nxtway/nxtway.htm) (d. 9/4-16)
[3] [http://www.nxtprograms.com/NXT2/segway/steps.html](http://www.nxtprograms.com/NXT2/segway/steps.html) (d. 9/4-16)
[4] [http://legolab.cs.au.dk/DigitalControl.dir/NXT/Lesson5.dir/Lesson5Programs/GyroTest.java](http://legolab.cs.au.dk/DigitalControl.dir/NXT/Lesson5.dir/Lesson5Programs/GyroTest.java)
(d. 9/4-16)
[5] [http://legolab.cs.au.dk/DigitalControl.dir/NXT/Lesson3.dir/Lesson3programs/DataLogger.java](http://legolab.cs.au.dk/DigitalControl.dir/NXT/Lesson3.dir/Lesson3programs/DataLogger.java) (d. 9/4-16)
[6] [https://nxttime.wordpress.com/2010/11/03/gyro-offset-and-drift/](https://nxttime.wordpress.com/2010/11/03/gyro-offset-and-drift/) (d. 9/4-16)
[7] [https://www.hitechnic.com/cgi-bin/commerce.cgi?preadd=action&key=NGY1044](https://www.hitechnic.com/cgi-bin/commerce.cgi?preadd=action&key=NGY1044) (d. 9/4-16)
[8] [https://nxttime.wordpress.com/2013/04/19/the-gyro-sensor/](https://nxttime.wordpress.com/2013/04/19/the-gyro-sensor/) (d. 9/4-16)
[9] [https://drive.google.com/open?id=0B6Aetf7tBQrgLUt5TV9fU0MzczQ](https://drive.google.com/open?id=0B6Aetf7tBQrgLUt5TV9fU0MzczQ) (d. 11/4-16)
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment