De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole...

82
“De Vliegende Hollander” - Een zelfstandig varende robot-zeilboot Willem Melching 26 januari 2012 N.B. Klik op het plaatje voor een filmpje Willem Melching Valeriusstraat 202 1075GJ Amsterdam [email protected] Het 4e gymnasium Amsterdam Begeleider: Sven Aerts

Transcript of De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole...

Page 1: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

“De Vliegende Hollander” - Een zelfstandig varende

robot-zeilboot

Willem Melching

26 januari 2012

N.B. Klik op het plaatje voor een filmpje

Willem MelchingValeriusstraat 202

1075GJ [email protected]

Het 4e gymnasium AmsterdamBegeleider: Sven Aerts

Page 2: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

English summary

Purpose

Oceanographic research requires large, pol-luting and expensive ships. The goal of myresearch was to develop a cheaper, less pol-luting alternative to these research ships. Ihave designed and built an autonomous con-trol system that transforms a sailing vesselinto a sailing robot. Since robot ships can besmaller and do not require human operatorsthey are much cheaper.

They use the wind as their main sourceof energy and therefore they can be self-supporting for a very long time.

The sailing robot should be capable of fol-lowing a pre-defined route, and should reactto its environment, like the wind and the wa-ves. My research was threefold. First, toinvestigate the minimal requirements for afully functioning autonomous sailing robot.Second, to build this ship and write the ne-cessary software. Third, to test whether thisship is fit for the purpose it was designed for:independent sailing.

In my project I have combined theoreticaland practical insights from different scienti-fic fields such as electrical engineering, signalprocessing, control theory, informatics andlast but not least: sailing.

Method

To be autonomous, the sailing ship must atall times have information about three essen-tial variables: wind direction, position andheading. This information is supplied by sen-sors and is processed in the on-board compu-ter. This computer controls through actu-ators - the rudder and the sails of the ship.The software translates the information fromthe sensors into commands that control thevessel.

1) To control the position of the sails, theon-board computer must know the wind di-rection. The wind direction is determined bymeans of a wind vane. Every wind directioncorresponds to an ideal position of the sails[1]. This position is transferred to the sailactuator. Because a sailing ship cannot sailagainst the wind, the information about thewind direction is also required for planningthe route.

2) To plan the route, the current position

of the boat on earth is required. This in-formation comes from a Skylab SKM53 GPSmodule. The on-board computer uses thisinformation to calculate the path, a rhumbline, to the next waypoint of the current pre-defined route. In case the boat needs to sailtoo close to the wind, the route will not bea straight line but the boat will follow a zig-zag pattern. Sailors call this beating. Toaccomplish this, I investigated several algo-rithms that calculate a beating pattern [2].Then I developed my own version of such analgorithm, to make it suitable for implemen-tation on my low-end hardware and improvethe efficiency of the trajectory.

3) To keep the boat on course the on-board computer needs to know the currentheading of the boat. The current heading ismeasured by a HMC6343 tilt compensateddigital compass. The information from thecompass is filtered by a 5 pole Butterworthlow pass filter to reduce unwanted oscillati-ons that originate from fluctuations in thecompass reading. Then this signal is fed intoa PID controller that calculates a new rudderposition.

All information from the sensors is com-bined in the on-board computer, an ARMlpc1768 development board, the mbed. Tentimes per second the on-board computer pro-cesses this information and uses the predefi-ned route to calculate a new rudder and sailposition. Since there is no code available forsailing robots, I created a C++ software fromscratch to run on the mbed microcontroller.

Results

The result of my experiment is a ship thatcan sail autonomously and make decisions onits own. My tests show that under normalconditions (light to medium wind) the boatwas able to complete any given route. All ne-cessary intelligence is located on-board andtherefore it can function without any contactwith the shore. This makes it a true autono-mous sailing robot. I succeeded in creatinga proof of concept of an autonomous sailingvessel for only e350. Since the boat lacks so-lar cells, it is not completely self-sufficientyet. An improved version could serve asan alternative to full size research ships andcould costs less than e600 (<$785) only.

Page 3: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

Inhoudsopgave

1 Inleiding 1

2 Nut 3

3 Zeilen 43.1 De voornaamste onderdelen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

3.1.1 De zeilen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43.1.2 Schoten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43.1.3 Mast . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53.1.4 Zwaard, kiel en roer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

3.2 De windrichtingen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63.2.1 Voor de wind . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63.2.2 Ruime wind . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63.2.3 Halve wind . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73.2.4 Aan de wind . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73.2.5 In de wind & opkruisen . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

4 Automatisering en de kernbegrippen van het robotzeilen 94.1 Regeltechniek - de PID . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104.2 PID regeling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

4.2.1 P deel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124.2.2 I deel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124.2.3 D deel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134.2.4 Combineren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

4.3 Polar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154.4 Grootcirkel en loxodroom . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

5 Robotzeilen: hardware en software 175.1 De boordcomputer: multitasking en efficientie . . . . . . . . . . . . . . . . . . . . 175.2 PID regeling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175.3 Loxodroom . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195.4 Kompas: de koersbepaling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205.5 Filtering . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215.6 GPS: de positiebepaling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225.7 Servo’s aansturen: het roer en de zeilen . . . . . . . . . . . . . . . . . . . . . . . 235.8 Communicatie tussen de laptop en de boordcomputer: Sailcom . . . . . . . . . . 235.9 PC Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23

5.9.1 Hoofdvenster . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245.9.2 Roer & zeil . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255.9.3 Kompas & vaantje . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265.9.4 PID . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275.9.5 Route . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28

6 Route plannen 296.1 Opkruisen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29

6.1.1 Wat is opkruisen? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 296.1.2 Algoritme van Stelzer en Proll . . . . . . . . . . . . . . . . . . . . . . . . 306.1.3 Mijn algoritme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

Page 4: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

7 Hardware: sensoren en actuatoren 347.1 Boot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34

7.1.1 Vorige pogingen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 347.1.2 Micromagic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34

7.2 Sensoren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 367.2.1 GPS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 367.2.2 Kompas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 367.2.3 Vaantje . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36

7.3 Actuatoren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 387.3.1 Servo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

7.4 Elektronica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 397.4.1 ARM microcontroller . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 397.4.2 Draadloze communicatie met de wal . . . . . . . . . . . . . . . . . . . . . 39

7.5 Schema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40

8 Resultaten en evaluatie 418.1 Algemene indruk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 418.2 Hardware . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 418.3 PID regelaar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 438.4 Route plannen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43

9 Discussie 45

10 Conclusie 46

11 Appendix A: Foto’s 49

12 Appendix B: De Programmacode van de boordcomputer 54

Page 5: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

Dankwoord

Voordat ik begin wil ik een aantal mensen bedanken. Zonder hen was dit profielwerkstuk nooitgeslaagd. Als eerste wil ik de school bedanken voor het profielwerkstuk-fonds. Met dit geldkon ik de dure onderdelen van mijn boot aanschaffen. Ook wil ik Pieter Adriaans bedanken,bedenker van de RoboSail, hij heeft mij ook veel adviezen gegeven over hoe ik dingen aan moestpakken. Verder wil nog aan aantal andere mensen bedanken: Estevan Veenstra als luisterendoor, Robert Rosen Jacobson, minitransat solozeiler en overbuurman, van wie ik het modelbootjegekocht heb. De MicroMagic vereniging en zijn leden hebben mij bij hun evenement gastvrijontvangen en veel tips gegeven. Tot slot wil ik Sven Aerts, mijn begeleider, bedanken. Hijwas mijn steun en toeverlaat bij het bouwen en testen van de boot, en het schrijven van hetwerkstuk. Hij heeft mijn werkstuk talloze keren nagekeken, heeft geholpen met het oplossenvan problemen en heeft mij met eindeloos geduld dingen uitgelegd.

Page 6: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

1 Inleiding

Iedereen kent het verhaal van de “Vliegende Hollander”, het spookschip dat zonder bemanningeeuwig over de oceanen bleef varen. Een automatisch varende zeilboot spreekt tot de verbeeldingvan elke kapitein. Stel je voor dat de VOC schepen vanzelf naar Indonesie hadden kunnenvaren en de bemanning niet maanden op gevaarlijke en onhygienische schepen had hoevendoorbrengen. Maar ook tegenwoordig zouden zelfstandig zeilende boten goed van pas komen.

De eerste vormen van zelfstandige besturing waren heel simpel, men zette dan gewoon hetroer vast zodat er een paar uurtjes geslapen kon worden. Het echt automatisch sturen is pasiets van de afgelopen honderd jaar, omdat toen pas de machines en materialen om de benodigdemechanica te maken beschikbaar waren[3]. De eerste stuurautomaat was een mechanisch sys-teem dat de kracht van de wind gebruikte om het roer te bewegen. Deze stuurautomaat volgdede wind, dus als de wind draaide, dan draaide de boot mee. Pas na de snelle ontwikkelingenin de microelektronica was het mogelijk om een vaste koers te volgen. Vanaf toen waren dezeregelaars elektronisch en dreven met behulp van een motor het roer aan.

Deze stuurautomaten gebruikten echter geen slimme regelingen of algoritmes, dus raaktenze bij wat zwaarder weer al gauw van slag. Bovendien gingen ze ook nog uiterst kwistig metelektriciteit om, en dat is aan boord een schaars goed. Moderne stuurautomaten zijn doorverdere ontwikkelingen in de automatiseringstechniek, regeltechniek en elektronica al veel betergeworden. Ze gebruiken bijvoorbeeld een GPS om zelf de koers naar een ingesteld punt uit terekenen. Ondanks al deze vooruitgang is er nog steeds een kapitein vereist. Mijn profielwerkstukbestaat dan ook uit het bouwen van een boot die zonder kapitein van A naar B kan zeilen, endesgewenst via C weer terug.

Het idee voor dit profielwerkstuk ontstond eigenlijk toen ik een bootje bij ons in de kelder vond.Dit bootje is daar minstens dertig jaar geleden door de vorige bewoners achtergelaten. Hetbootje heeft daar gestaan sinds mijn ouders en ik in dit huis wonen, maar er is nooit wat meegedaan. Dus na dertig jaar heb ik het bootje uit de kelder gehaald en ontdaan van een dikkelaag stof. Wat te voorschijn kwam was een houten rompje van een modelboot van circa 50 cmlang. Bij nadere inspectie bleek er onder het kajuitdakje een naam te staan. Hier stond dat denaam van het bouwpakket “Astrid” was. Na wat googelen bleek dat de Astrid een bouwpakketwas van rond 1970 van de firma Suls uit Lunteren. Deze firma bestaat echter niet meer. Deboot had de tand des tijds redelijk doorstaan, maar dat wilde natuurlijk niet zeggen dat hetbootje vaarklaar was. Verre van dat zelfs, het was zo lek als een mandje, het roer zat muurvasten er ontbraken nog een mast en zeilen.

Dit was het beginpunt van mijn profielwerkstuk. Mijn idee was een modelboot met robot-besturing te maken. Daarvoor heb ik zowel de hardware als de software zelf gebouwd en ge-programmeerd. De hardware bestaat uit een samenspel van sensoren, zoals een kompas en eengps, en een aantal servomotoren die de zeilen en het roer bedienen. De software bestaat uiteen boordcomputer die aan boord van het schip informatie verwerkt en commando’s uitvoert.Vanaf de wal kan de boot voorzien worden van een opdracht. Om deze opdrachten te gevenen informatie van de boot te ontvangen heb ik een grafische bedieningsomgeving geprogram-meerd en een communicatie protocol bedacht. Zo kon ik al mijn interesses combineren: zeilen,knutselen, programmeren, elektronica, natuurkunde en wiskunde.

Robotzeilen is een ingewikkeld computerprobleem omdat zeilen een complexe beweging is waarenorm veel variabelen een rol spelen. Bij mijn literatuuronderzoek en de praktijktesten ontdekteik al snel dat er geen behoorlijke methode bestond om een boot slim en efficient tegen de windin te laten zeilen. Laveren - zig zag tegen de wind in varen - is een van de ingewikkeldste

1

Page 7: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

onderdelen van het zeilen. Er was een bestaand algoritme, maar ik heb een eigen algoritmegeprogrammeerd wat meer geschikter was voor mijn boordcomputer. Dat maakt mijn werkstukook in theoretisch opzicht innovatief.

Ik ben niet de eerste die zich op dit probleem gestort heeft. De eerste was Pieter Adriaans.Een pionier op het gebied van robotzeilen[4]. Hij wilde echter geen volledig autonome robotbouwen maar een ondersteuning voor solozeilers. Ik heb ook een gesprek met hem gehad, waarinik de details van zijn boot met hem besproken heb. Daarnaast zijn er nog een aantal anderemensen bezig geweest. Bijvoorbeeld Stelzer en Proll die een systeem bedacht hebben om opte kruisen[2]. Maar ook Colin Sauze en Mark Neal[5] zijn bezig geweest met het maken vaneen dergelijke robot. Ik maak echter een compleet systeem dat alle benodigde technieken entheorieen combineert.

Voor een goed begrip: ik heb geen boot met een afstandsbediening gemaakt, maar eenvolledig zelfstandig varende boot. Mijn boot is een eigentijdse versie van de Vliegende Hollander,zolang de boordcomputer en de servo’s stroom heeft kan hij over de oceanen blijven varen.

2

Page 8: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

2 Nut

Niet alleen solo-zeilers zullen heel blij zijn met een extra elektronisch bemanningslid die hunbijna al het werk uit handen neemt als ze willen gaan slapen. Ook voor wetenschappelijkonderzoek zijn zelfstandig bestuurde zeilboten handig. Niet alleen vanwege de verminderdekosten, maar ook vanwege een nieuwe methode van gegevens verzamelen die de komende jarenwaarschijnlijk steeds meer toegepast gaat worden.

De belangrijkste kostenbesparing zit in het bootje en de afwezigheid van personeel die hetbootje moet besturen. Een autonoom modelbootje kost in massaproductie zeer weinig en hetkost geen manuren om zo’n bootje op zijn bestemming te krijgen, dit in tegenstelling tot dekosten van een complete wetenschappelijke expeditie. Zo kan er flink bespaard worden bijregulier onderzoek. Bovendien creeert dit ook nieuwe mogelijkheden voor onderzoekers (zoalsstudenten en scholieren) met een klein budget[6].

Ook is er een verandering aan het plaatsvinden in de manier waarop data worden verza-meld. De TU-Delft heeft bijvoorbeeld met hun Delfi-n3Xt project kleine goedkope satellietengemaakt. Het doel daarvan is om een grote satelliet door een hele wolk van kleintjes te ver-vangen. Doordat deze kleine satellieten samenwerken kunnen ze beter data verzamelen, en alser eentje stuk gaat kan zijn taak makkelijk door anderen worden overgenomen. Als zo bijvoor-beeld een telescoop gevormd wordt, is de resolutie door de onderlinge afstand ook nog eens veelhoger dan met conventionele satellieten mogelijk zou zijn. Bovendien zijn deze kleine satellietenveel goedkoper waardoor de financiele drempel om onderzoek in de ruimte te doen aanzienlijkwordt verlaagd[7][8]. Hetzelfde principe kan natuurlijk ook op bootjes toegepast worden. Steldat je iets op verschillende plekken op aarde wil meten, dan stuur je een groot aantal bootjes,bijvoorbeeld duizend stuks, met de juiste sensoren de oceaan op. Je kan dan in korte tijd eengroot aantal precieze metingen doen op veel verschillende plekken tegelijk.

3

Page 9: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

3 Zeilen

Zeilen lijkt simpel. Iedereen die op de fiets wel eens wind mee heeft gehad, heeft gezeild. Dewind duwt je voort en verder hoef je niet veel te doen. Tenminste, zo lang je wind mee hebt.

Zeilen is een van de meest complexe manieren van voortbewegen. Want een zeilboot kanmeer dan met wind mee voortdrijven. Al een paar duizend jaar proberen zeilers en ontwerperszo slim mogelijk gebruik te maken van de wind.

Ze kunnen ook goed overweg met wind van opzij. Recht tegen de wind in varen, dat luktniet, maar met een kleine hoek ten opzichte van de wind lukt het om bijna tegen de wind invaren. In de loop der eeuwen is de boot van een simpel vlot met een doek om wat wind tevangen, geevolueerd tot een efficiente racemachine.

Zoals waarschijnlijk bekend houden zeilers er van om alles aan boord met speciale termenaan te duiden. Deze termen komen in de rest van mijn werkstuk ook voor, dus ik zal ze eenvoor een doornemen.

3.1 De voornaamste onderdelen

Een moderne boot is een complex stuk techniek. Daarom zal ik eerst de belangrijkste onderdelenvan de boot bespreken en aangeven welke onderdelen in mijn robot een rol spelen. Daarna zalik de verschillende hoeken waaronder een boot kan varen doornemen en aangeven waar bij mijnrobotzeilboot de grote problemen zaten.

3.1.1 De zeilen

Een zeilboot heeft een zeil. Meestal zelfs twee (of meer) zeilen: een voorzeil en een hoofdzeil.Het voorzeil noemen we de ‘fok’, en het hoofdzeil het ‘grootzeil’. Het grootzeil zit vast aan demast.

Tussen de top van de mast en de punt van de boot loopt een draad. Zeilers noemen dit het‘voorstag’. Het voorzeil zit aan zijn voorkant vast aan dit stag, de onderkant en de achterkantkunnen vrij bewegen.

Het grootzeil zit met zijn voorkant, de lange rechte kant, aan de mast vast. De onderkantvan het grootzeil zit vast aan een lange buis, deze buis heet de‘giek’. De giek zorgt dat hetgrootzeil min of meer op zijn plaats blijft zitten. De achterkant van het grootzeil - de langsteen schuine kant - is open.

3.1.2 Schoten

Aan los wapperende zeilen heb je niet veel, die vangen geen wind. Daarom worden de zeilenaangetrokken door touwen. Maar aan boord heet dat natuurlijk geen ‘touw’. Zeilen trek je aanmet een ‘schoot’. Deze schoten zitten aan de punt van de fok en onder aan de giek. Daarmeekun je de zeilen strakker of losser zetten. Afhankelijk van de wind trek je de zeilen strakker aanof laat je ze juist vieren.

Zeilen zijn zo gesneden dat ze een profiel vormen wanneer je ze met de schoten aantrekt.Dat profiel is in principe vergelijkbaar met het profiel van de vleugel van een vliegtuig. Paswanneer het zeil een mooi profiel vormt heb je ‘lift’. De boot stijgt niet op zoals een vliegtuig,maar zal wel vooruitgaan door het water. De kracht die er bij een vliegtuig voor zorgt dat hijin de lucht blijft, oefent hier een kracht uit die haaks op het zeil staat. De stand van de zeilenis dus van essentieel belang.

Mijn robotzeilboot heeft ook een fok en een grootzeil. De schoten worden bediend metservomotoren en via de software worden de zeilen strakker of losser gezet. Daarbij probeert het

4

Page 10: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

programma natuurlijk een optimale snelheid te behalen. Anders dan veel mensen denken gaateen boot die schuin vaart niet sneller. Integendeel, een boot moet bijna recht op varen.

3.1.3 Mast

Een zeilboot heeft altijd een mast. De mast zit vast, en blijft netjes overeind omdat hij op zijnplaats wordt gehouden door sterke kabels. Deze kabels heten de verstaging, je kunt daarmeede mast niet alleen vastzetten maar ook een beetje buigen of juist losser zetten. Op wedstrijd-boten wordt telkens de stand van de mast veranderd. Ik heb deze factor bij mijn boot buitenbeschouwing gelaten.

3.1.4 Zwaard, kiel en roer

Wanneer een fietser harde wind van opzij heeft, dan wordt de fietser opzij geduwd. De bandenzorgen er echter voor dat je niet naar de weg af glijdt. De wind duwt op jouw en je fiets, terwijlde onderkant op zijn plaatst blijft. Dit moment zorgt er voor dat je schuin gaat. Je snelheidzorgt er echter voor dat je toch redelijk rechtop blijft en vooruit gaat.

Figuur 1: Een roer en een kiel bij een modelboot

Een boot wordt bij zijwind ook opzij ge-duwd. Maar in de loop der eeuwen zijn daarwel remedies voor bedacht. Ouderwetse bo-ten zoals platbodems hebben twee grote plan-ken, zwaarden, aan de zijkant van de boot.Zo heeft een moderne boot midden onder zijnromp een uitstekende ‘plank’ (zie figuur 1).Deze plank noemen we zwaard of kiel. Dezeplank is geplaatst in de vaarrichting, hierdoorondervindt een boot nauwelijks weerstand alshij rechtuit gaat. Als de boot echter door dewind weggezet wordt, zorgt het oppervlaktevan de plaat er voor dat de boot op zijn plekblijft. Net als bij de fiets zorgt dit voor een moment waardoor de boot schuin gaat. Om deboot toch recht te houden kan er iemand op de rand van de boot gaan zitten, maar als datniet mogelijk is (bijvoorbeeld als de krachten te groot zijn) kan er een gewicht aan het zwaardgehangen worden. Een zwaard met een gewicht er aan heet een kiel.

Ook het besturen van de boot gebeurt door middel van een langwerpig en dun voorwerponder water. Dit voorwerp zorgt er voor dat de stroming van het water onder de boot geregeldkan worden. Hierdoor kan de boot van richting veranderen. Moderne boten hebben achteraande boot een roer. Met dit roer kun je de boot sturen, ook is het een goede manier om de boottegen afdrijven bij zijwind te beschermen.

Mijn boot heeft een kiel en een roer. Het roer kan ik met servomotoren aansturen. Dit is eenessentieel onderdeel om de boot op koers te houden en natuurlijk zo efficient mogelijk gebruikte maken van de wind.

5

Page 11: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

3.2 De windrichtingen

Zowel de koers als de wind zullen in de praktijk geregeld veranderen. Dat betekent dat de windtelkens uit een andere hoek de boot bereikt. Daarom moet de zeiler - al dan niet bewust -voortdurend beslissingen nemen. Steeds als de wind op de koers van de boot verandert moethij de stand van zeilen en roer aanpassen. Daarbij moet hij ook nog voortdurend zijn snelheidblijven controleren en ook nog in de gaten houden of hij zijn einddoel zal bereiken. Zeilen is -zoals gezegd - een complexe handeling.

3.2.1 Voor de wind

Figuur 2: Verschillende koersen enzeilstanden - de wind komt van links

Als je op de fiets wind mee hebt, dan komt de windrecht van achteren. In Figuur 2 is het bootje aan deonderkant van de cirkel. Zeilers noemen dat ‘voor dewind’. Het zeil moet dan helemaal los zodat het haaksop de boot (en de wind) staat. Op die manier vang je demaximale hoeveelheid wind. Omdat de fok daarbij ‘inde schaduw’ van het grootzeil kan terecht komen, wordtde fok meestal aan de tegenovergestelde kant gezet.

Ondanks het spreekwoord ‘voor de wind gaan’ isdit niet de koers waarbij de grootste snelheid bereiktwordt. Ook is het een lastige koers om veilig te varen.Als de koers (of de wind) een beetje verandert kan dewind, die natuurlijk nooit precies van achteren komt,plotseling aan de andere kant van de boot gaan waaien.Het grootzeil gaat dan vanzelf naar de andere kant, endit gebeurt met een enorme snelheid. Dat is gevaarlijken kan bemanningsleden verwonden en zelfs de mastdoen breken. Deze onverwachte manoeuvre heet een klapgijp. Gelukkig is een klapgijp voormijn schaalmodel geen probleem omdat alle onderdelen relatief licht zijn.

3.2.2 Ruime wind

Figuur 3: De krachten die op het zeilwerken

Het zeilt veel prettiger als de wind niet precies recht vanachteren komt, maar een beetje schuin van achter. Dezewindrichting heet ‘ruime wind’. Je draait de boot daneen beetje naar de de wind toe. Door dit ‘oploeven’ -zoals zeilers zeggen - komt de wind schuin van achteren.De wind valt in met ongeveer 135 graden.

Bij ruime wind staat je zeil iets strakker, maar nogsteeds vrij open op de wind. De snelheid zal hogerliggen dan bij voor de wind. Door de grote hoek vaninval ligt de boot vrij plat op het water. Het is daardooreen snelle en comfortabele koers.

6

Page 12: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

3.2.3 Halve wind

Figuur 4: De krachten op het zeil bij verschil-lende koersen

Als je nog verder naar de wind toe stuurt -oploeft - staat de wind haaks op de boot, ditheet ‘halve wind’. Bij halve wind staat je zeilin een hoek van ongeveer 45 graden op je boot.Je vraagt je natuurlijk af hoe een boot voor-uit kan gaan als de wind van de zijkant komt.Vroeger kon dit ook niet. Zo moesten de sche-pen van de VOC wachten tot de wind gunstigwas en ze naar het zuiden konden varen. Te-genwoordig is het mogelijk om wel met halvewind te varen.

De wind die in het zeil komt zorgt vooreen kracht die haaks op het zeil staat, schuinnaar voren dus. Deze kracht is te ontbindenin twee losse krachten, een kracht naar vo-ren en een kracht naar opzij. De kracht naarvoren - dankzij het profiel in het zeil - zorgtvoor snelheid. De kracht naar opzij zou deboot uit koers duwen, maar dankzij de kielonder de boot blijft de boot min of meer opkoers. De kiel zorgt voor een enorme water-weerstand als de boot naar opzij probeert tegaan. Het nadeel hieraan is wel dat de bootals het ware over de kiel heen valt en de bootscheef zal gaan. Om omslaan tegen te gaan enhet schuingaan te beperken is er een gewichtonderin de kiel geplaatst.

3.2.4 Aan de wind

Als je nog verder naar de wind toestuurt, dankomt de wind schuin van voren, deze koersheet ‘aan de wind’. De hoek van inval is tus-sen de 40 en 25 graden. Bij aan de wind vaarje bijna tegen de wind in, en is de kracht inhet zeil bijna geheel naar de zijkant gericht ennog maar voor een klein deel naar voren. Desnelheid is dus relatief laag, maar toch is hetmogelijk om naar de wind toe te zeilen, ietswat op het eerste gezicht onmogelijk lijkt. Bijaan de wind zet je je zeil zo strak mogelijk,dus bijna boven het midden van de boot.

7

Page 13: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

3.2.5 In de wind & opkruisen

Figuur 5: De route bij het opkruisen

Verder oploeven kan niet, je zou dan ‘in dewind’ komen te liggen. De wind komt danrecht van voren en je komt niet meer vooruit.Punten die in de wind liggen zijn dus niet ‘be-zeild’. Toch is het mogelijk om deze puntente bereiken, daar is een speciale manoeuvrevoor, namelijk het opkruisen oftewel laveren.Bij opkruisen vaar je niet rechtstreeks naarhet doel, maar vaar je zo scherp mogelijk aande wind. Als je een tijdje over de ene boeggevaren hebt, dan gooi je bij een flinke snel-heid het roer een heel eind om. De punt vande boot draait naar de wind toe, maar dankzij de snelheid ga je ‘door de wind heen’ enje vangt weer wind. Maar nu van de anderekant. Je vaart dan zo scherp mogelijk over deandere boeg verder.

Bij ‘door de wind gaan’ ga je dus door dewind heen om vervolgens over de andere boegte varen. de complete manoeuvre heet ‘overstag’ gaan. Op deze manier ga je zijwaarts heenen weer, maar kom je wel steeds dichter bij je doel. De snelheid is redelijk hoog, maar omdatje ‘zig-zaggend’ op je doel afgaat (zie figuur 5) wordt de afstand groter en ben je uiteindelijkrelatief lang onderweg.

Het juiste moment van overstag gaan om het traject zo efficient mogelijk af te leggen iseen kwestie van inschatting van de stuurman, ervaring en locale omstandigheden. Op een langtraject zul je minder vaak overstag gaan dan op een korte baan.

8

Page 14: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

4 Automatisering en de kernbegrippen van het robotzeilen

Is zeilen dan zo ingewikkeld dat je er geavanceerde computers voor nodig hebt? Ja, want zeilenbestaat namelijk niet alleen uit het varen van een rechte lijn. Een zeilboot kan bijvoorbeeld niettegen de wind in varen, om toch bij de bestemming aan te komen moet er een route wordengepland die wel helemaal te varen is en toch zo efficient mogelijk naar het doel gaat (zie par. 6.1).Een zeilrobot heeft dus zeer uiteenlopende taken. Om de stabiliteit van een robot te bevorderenis het belangrijk om de verschillende onderdelen goed te scheiden. Elk onderdeel opereert opzichzelf en geeft zijn resultaten door aan andere onderdelen. Systemen die hoger in de hierarchiestaan gebruiken dan de resultaten van onderdelen lager in de hierarchie[9].

Een robot bouwen die goed op zijn omgeving reageert is een zeer complexe taak. Stel datje een boot op koers wil houden. Dat is lastig omdat er veel factoren zijn die kracht op deboot uitoefenen en waardoor hij dus van koers raakt. We kunnen deze factoren opsplitsen inoverzichtelijke en onoverzichtelijk factoren.

De overzichtelijke factoren zijn makkelijk te meten of te voorspellen. De voornaamste zijn:

• Koers De koers is vrij precies te meten met een elektronisch kompas. Dit kan op eenhoge frequentie (10 keer per seconde) en ook nog eens met een grote nauwkeurigheid.

• Positie De positie is te meten met een GPS. De meetfrequentie van een GPS is al lager(1 keer per seconde), en de nauwkeurigheid is slechts drie meter[10]. Toch is dit nog ruimvoldoende voor zeilers.

• Windrichting De windrichting is ook belangrijk, en goed te meten met een windvaan.De benodigde sensor is alleen vrij lomp, waardoor ik hem op de kant moest zet in plaatsvan op het bootje.

Ook zijn er een aantal onoverzichtelijke factoren, deze zijn moeilijk te meten, of zelfs onvoor-spelbaar. Dat zijn:

• Wind De windkracht is een belangrijk iets om te weten, want bij een sterkere wind moeter anders gestuurd worden. De windkracht is wel te meten, maar het grootste probleemzijn de vlagen. Deze zijn niet te voorspellen, en pas te meten als het eigenlijk al te laat is.

• Golven De golven zijn net als de wind moeilijk te voorspellen, en toch een belangrijkefactor om rekening me te houden bij het zeilen. Een schipper ziet een golf aankomen enkan hier tijdig op reageren, een robot kan pas reageren als het al te laat is.

Om een robot automatisch te laten zeilen moet deze een aantal taken zelfstandig uitvoeren.Hierbij kwamen allerlei problemen naar voren. Voor elk van deze problemen moest ik eenoplossing bedenken. Ik zal in deze paragraaf elke oplossing kort toelichten en bij sommige eenwiskundige onderbouwing geven. Ook zal ik de algoritmes bespreken die ik geımplementeerdheb om de boot zijn taak te laten volbrengen. Het zelfstandig plannen en varen van een routevergt een ingewikkeld samenspel van een aantal elementen. Om goed te begrijpen hoe al dezeelementen samenwerken en elkaar beınvloeden zal ik de verschillende concepten apart uitleggen.

Uitrekenen hoe een boot een route moet varen is niet van te voren uit te rekenen. Je kan nietzeggen: “Vaar 200 meter rechtdoor en ga dan rechtsaf.”. Er hoeft maar een golf of windvlaag tekomen en je komt nooit meer op je bestemming aan. Om een boot op koers te houden moet deomgeving constant in de gaten gehouden worden en hier moet tijdens het varen op gereageerdworden.

9

Page 15: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

PID-regelingOm de boot op koers te houden moet er een regeling zijn die continue het roer bijstelt zodat deboot de juiste kant op vaart. Een oplossing uit de regeltechniek is de zogenaamde proportionele,integrerende en differentıerende regelaar, afgekort de PID regelaar. Deze gebruikt de afwijkingten opzichte van de juiste koers om het roer in te stellen.

OpkruisenOok een belangrijke vraag is wat de ideale koers is als de te zeilen route in de wind ligt, oftewelniet bezeild is. Omdat je niet direct naar het doel kan varen moet je opkruisen. Doordat elkekoers in dit patroon wel bezeild is kan de route wel gevaren worden. Maar de vraag is wat deideale hoek ten opzichte van de wind is. Als je de hoek kleiner neemt hoef je minder afstandaf te leggen, maar zeilt de boot langzamer. Als je de hoek vergroot gaat de boot sneller, maarmoet je ook weer meer afstand afleggen. De oplossing hiervoor is om een grafiek te makenwaarin je de snelheid ten opzichte van de wind uitzet tegen de snelheid. Uit deze grafiek kun jede beste koers aflezen[1].

Bij het opkruisen is het ook belangrijk wanneer er overstag gegaan wordt. Op papier zijnalle routes even lang, het maakt dus niet uit of je met twee slagen opkruist of met tien. In depraktijk blijkt het wel uit te maken. Een overstagmanoeuvre kost tijd en snelheid, waardoorhet beter is om zo min mogelijk overstag te gaan. Maar dit heeft ook weer twee nadelen. Teneerste wordt de benodigde ruimte voor het opkruisen groter omdat hij veel meer breedte inbeslag neemt. Dit is niet handig als je in nauw vaarwater of in een vaargeul moet varen. Hettweede nadeel is wanneer na een hele tijd varen de wind plotseling zou draaien. Dan heb jeeen heel stuk voor niets gevaren en moet je feitelijk weer opnieuw beginnen. Het is dus zaakom de gulden middenweg te vinden. Hier heb ik in de software een mogelijkheid gemaaktom de breedte van de manoeuvre in te stellen, om zo experimenteel vast te stellen wat voorverschillende omstandigheden ideaal is.

KoerslijnEr moet ook uitgerekend worden welke kant je op moet varen om in een rechte lijn naar eenbepaald punt te varen. De kortste route heeft echter een nadeel, de koers is door de bolling vande de aarde niet gedurende de hele route constant. Dit is tamelijk een ingewikkeld probleem enkomt in paragraaf 4.4 uitgebreid aan de orde.

4.1 Regeltechniek - de PID

Leonardo da Vinci bedacht al in de 15e eeuw al een regeling om de snelheid van wind enwatermolens te regelen. Ongeveer een eeuw later, toen het mogelijk was om metaal te bewerken,ontwierp een Nederlander een temperatuurregeling die gebruik maakte van het uitzetten eninkrimpen van een metaal bij temperatuursveranderingen. De ontwikkelingen in de regeltechniekraakten in de 18e eeuw in een stroomversnelling. James Watt bouwde toen een regeling die metbehulp van de zwaartekracht en de centrifugaalkracht de hoeveelheid stoom regelde die in eenstoommachine gaat. Voor die tijd moest dat met de hand gebeuren[11].

Regelingen zijn echter pas gemeengoed geworden na 1960. Het Amerikaanse bedrijf Honey-well presenteerde toen een lijn van sensoren die druk en temperatuur konden meten. Deze sen-soren gaven een luchtdruk af die proportioneel was met de gemeten waarde. Deze luchtdrukkon vervolgens gebruikt worden om mechanische of analoge elektronische regelaars aan te stu-ren. Niet veel later, in de jaren zeventig, kwamen ook digitale computergestuurde regelingenop de markt.

10

Page 16: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

Figuur 6: Regeling op een stoommachine

Alle regelaars, of ze nu mechanisch, analoog of digitaal zijn, werken volgens dezelfde basis-principes. De regelaars hebben een input, afkomstig van een sensor. Op deze manier kunnen deregelaars de werkelijkheid of het ‘proces’ in de gaten houden. De input wordt ook wel ‘processvariable’ genoemd. Ook heeft de regelaar een waarde om de input mee te vergelijken, deze heethet ‘setpoint’. De regelaar neemt vervolgens het verschil tussen de input en het setpoint, dezewaarde is de afwijking of ‘error’. Vervolgens wordt deze afwijking vertaald in een output. Dezevertaalslag kan simpel zijn, maar ook gebeuren met ingewikkelde formules en algoritmes. Dezeoutput stuurt het proces aan. De regelaar krijgt vervolgens via de input weer terugkoppelingof ‘feedback’ van zijn acties, en stelt zijn ouput weer bij als dat nodig is[12].

Figuur 7: Blokschema van een regelsysteem

In de regelaar op het bootje zijn al deze elementen ook terug te vinden. De input is hetkompas, die de richting meet waarin het bootje vaart. Het setpoint komt van de GPS, namelijkde koers die de boot moet varen om zijn doel te bereiken. Vervolgens wordt de error berekenden worden hier drie formules op losgelaten. De output van de regelaar wordt dan gebruikt omhet roer te bedienen. Het roer zorgt er dan weer voor dat de koers van het bootje verandert.Op deze manier krijgt de regelaar via het kompas weer feedback van zijn acties.

4.2 PID regeling

Om de roerstand van het bootje te berekenen en voortdurend aan de nieuwe omstandighedenaan te passen maak ik gebruik van een proportionele, integrerende en differentierende regeling,kortweg een PID regeling. De regelaar bestaat uit drie losse onderdelen die op het einde samen-gevoegd worden.

De werking van deze drie onderdelen is het beste uit te leggen met een simpel voorbeeld.Als je ’s ochtends onder de douche stapt dan moet je de temperatuur van het water instellen.Om te beginnen draai je de kraan met koud water open om vervolgens met warm water detemperatuur te regelen. Eerst voel je temperatuur van het water, en vergelijk je deze met degewenste temperatuur. Vervolgens schat je hoeveel je de warmwaterkraan in eerste instantieopen moet draaien om de gewenste temperatuur te bereiken. Dit is het eerste deel van deregeling.

Daarna warmt het water op en neemt de afwijking af. Dan komt het tweede deel van deregeling in actie, nu wordt over langere tijd bekeken hoeveel warm water er ongeveer nodig is

11

Page 17: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

om de temperatuur zo goed mogelijk op de gewenste waarde te houden. Maar er is ook nogeen derde deel nodig, dat ingrijpt in onverwachte situaties. Stel: iemand draait elders in huisde koud water kraan helemaal open, daardoor zou jouw douche plotseling veel te heet worden.Daarom moet er nu direct worden ingegrepen. Daarom kijkt het derde deel van de regeling hoesnel de temperatuur verandert.

De PID-regeling bestaat altijd uit deze drie onderdelen die elk een deel van de uitgangs-waarde van de regeling bepalen. Elk van de drie onderdelen berekent apart een uitgangswaardeaan de hand van de afwijking met de ingestelde koers. Daarna worden deze drie waarden metparameters vermenigvuldigd en opgeteld[13]. Voor mijn boot is de PID regelaar geschikt ge-maakt voor het aanhouden van een koers en het reageren op onverwachte gebeurtenissen.

4.2.1 P deel

Het P of proportioneel deel is het deel van de uitgangswaarde dat recht evenredig is met deafwijking tot de ingestelde waarde. Dit is in formulevorm weer te geven als:

P (t) = e(t) (1)

Waarin e(t) de afwijking op tijdstip t is.Op het bootje kan de afwijking niet continue gemonitord worden, daarom wordt de afwijking

op vaste tijdstippen bemonsterd. Daarom is er naast deze continue versie van het P deel ookeen discrete variant nodig. Deze ziet er als volgt uit:

P (ti) = e(ti) (2)

Het P deel is het belangrijkste deel van de regelaar. Het belangrijkste van een regeling isnamelijk dat hij de afwijking met een ingestelde waarde elimineert. Daarom heeft het P deeleen direct verband met de afwijking. Als er alleen een P deel toegepast zou worden zou deregelaar al redelijk werken, er treden dan alleen een aantal vervelende dingen op. Er ontstaanoscillaties en een constante afwijking wordt niet opgemerkt.

4.2.2 I deel

Het I of integrerend deel is het deel van de uitgangswaarde dat een maat is voor de cumulatieveafwijking. Dus hoe langer een afwijking aanwezig is hoe groter de waarde van het I deel.Wiskundig kan dit berekend worden door de integraal van de afwijking te nemen van het beginvan de tocht tot het huidige moment. De formule van het I deel is:

I(t) =

∫ t

0e(t) dt (3)

Ook hier is weer een discrete versie nodig om hem in het bootje te implementeren. De tijdtussen de verschillende metingen is ∆t. De discrete versie ziet er zo uit:

I(ti) =

i∑k=0

∆t · e(tk) (4)

Dit deel is vooral bedoeld om krachten te compenseren die constant op de boot werken. Steldat de stroom de boot continu naar rechts duwt, dan moet de boot voortdurend naar linksbijsturen. In het begin - als de boot nog niet op koers ligt - zal de waarde van het I deel steedsblijven toenemen. Als de boot op koers ligt is het I deel precies groot genoeg om deze stroom

12

Page 18: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

tegen te werken. Omdat de boot op koers ligt en de afwijking (bijna) 0 geworden is, veranderthet I deel daarna niet meer.

4.2.3 D deel

Het D of differentierend deel is het deel van de uitgangswaarde dat een maat is voor hoe snelde boot van koers verandert. Dit is te berekenen door de afgeleide te nemen van de afwijking,oftewel hoeveel de afwijking e de afgelopen t seconden veranderd is. In formulevorm ziet dat erzo uit:

D(t) =de(t)

dt(5)

En de discrete versie zoals toegepast wordt in het bootje:

D(ti) =e(ti) − e(ti−1)

∆t(6)

Het D deel zal vooral de effecten van golven en korte invloeden, zoals windvlagen, compenseren.Omdat dit soort invloeden vaak heftige en snelle bewegingen veroorzaken zal de uitgangswaardevan het D deel dan relatief hoog zijn.

4.2.4 Combineren

Het berekenen van de afzonderlijke delen is nog niet genoeg. Ze moeten ook in een bepaaldeverhouding gecombineerd worden. Om dit te bewerkstelligen worden ze allemaal met een eigenparameter vermenigvuldigd en vervolgens opgeteld. De totale formule van een PID regelaarwordt dan:

u(ti) = Kp ∗ P (ti) +Ki ∗ I(ti) +Kd ∗D(ti)

u(ti) = Kp · e(ti) +Ki ·i∑

k=0

∆t · e(tk) +Kd ·e(ti) − e(ti−1)

∆t(7)

Dit afstellen van de PID regeling gebeurt door experimenteel de waardes van Kp, Ki en Kd tevinden waarbij de boot zich het beste gedraagt. Dit is vaak een lastig klusje omdat de factorenelkaar onderling beınvloeden. Ook bij mijn robotzeiler was dit een flink karwei.

13

Page 19: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

Figuur 8: Invloed van verschillende Kp’s

Figuur 9: Invloed van verschillende Ki’s

Figuur 10: Invloed van verschillende Kd’s

14

Page 20: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

De invloed van de parameters is goed te zien in de grafieken van figuur 8, 9 en 10. In elkplaatje wordt bijvoorbeeld de hoeveelheid P (de parameter Kp) veranderd terwijl de andereparameters constant blijven. De blauwe lijn is de waarde die de regelaar probeert te bereiken,en de gekleurde lijnen de werkelijke toestand volgens de sensoren.

Verschillen tussen de instellingen zijn:

• InsteltijdDe insteltijd is de tijd die nodig is om de uitgangswaarde de ingestelde waarde te latenbereiken. Zoals te zien is zorgt een lage I waarde voor een grote insteltijd.

• OvershootOvershoot is hoeveel de uitgangswaarde over de ingestelde waarde heen schiet voordathij weer naar beneden geregeld wordt. Zoals een lage Ki waarde een lange insteltijdveroorzaakt, zorgt een hoge Ki voor een korte insteltijd, maar heeft last van veel overshoot.

• OscillatieOscillatie is hoelang het duurt voordat de uitgangswaarde stabiel wordt. Bij veel instel-lingen gebeurt dit helemaal nooit en blijft het systeem instabiel.

4.3 Polar

Figuur 11: Polar

Een boot zeilt niet op alle koersen even hard,dit komt door de vorm van de boot en de zei-len. Voor het plannen van de route is hethandig om te weten onder welke hoeken deboot optimaal zeilt. Deze snelheden wordenweergegeven in een poolgrafiek - ook wel polargenoemd - waarbij de hoek van de invallendewind ten opzichte van de vaarrichting wordtafgezet tegen de snelheid. Omdat deze waar-des ook van de windkracht afhangen is hetnodig om voor elke windkracht een eigen gra-fiek te maken. Als je al deze grafieken overelkaar plot en de linker helft weglaat (die isbijna gelijk aan de rechterhelft) krijg je eenplaatje als in afbeelding 11.Uit een polargrafiek is veel informatie te halen, wij gebruiken de grafiek voornamelijk voor hetbepalen van de ideale koers voor het aan de wind zeilen.

15

Page 21: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

4.4 Grootcirkel en loxodroom

Figuur 12: Constante rich-ting bij een loxodroom

Er zijn verschillende manieren om de koers tussen twee puntenop aarde uit te rekenen. Sommige complexer dan andere. Decomplexere formules houden rekening met de kromming van deaarde, terwijl andere dat niet doen. De kortste route tussen tweepunten op een bol loopt namelijk niet recht. Deze kortste routeheet een grote cirkel. Deze lijn heeft echter een belangrijk nadeel,de koers die de boot moet sturen is niet constant waardoor dezecontinu opnieuw moet worden berekend[14].

De lijn die geen rekening houdt met de bolling van de aardeheet loxodroom of in het Engels een rhumb line1. Bij deze lijnis de koers wel gedurende de hele route constant, maar de lengtevan deze route is langer[15]. Zie afbeelding 13 voor het verschiltussen een grote cirkel route en een loxodroom.

Ik heb gekozen om te varen over een loxodroom, dat is de route die een boot vaart als hijeen constante kompaskoers aanhoudt. Dat is ook een rechte lijn op een kaart met een merca-torprojectie2. Deze lijn is weliswaar niet de kortste route, maar op korte afstanden maakt datniet heel veel uit. Om namelijk een grootcirkel (de kortste route) te varen moet het beginpuntworden onthouden en moet er steeds voor de huidige plek op de route een nieuwe koers wordenuitgerekend.

De formule om de loxodroom uit te rekenen is als volgt:

∆ϕ = ln(tan( lat22 + π

4 )

tan( lat12 + π4 )

)

q = cos(lat1)

∆lat = lat2 − lat1

∆lat = lon2 − lon1

d =√

∆lat2 + q2 · ∆lon2 · 6371 km (8)

θ = atan2(∆lon,∆ϕ) (9)

In deze formule is (lat1,lon1) het beginpunt en (lat2,lon2) het doel.

Figuur 13: Verschil tussen een grote cirkel en een loxodroom (rhumb line)

1Loxodroom komt van het griekse λoχoσ (schuin) en δρoµoσ (lopen)2De mercatorprojectie is een manier om de wereldbol op een plat vlak af te beelden. Het is bedacht door

de Vlaamse Cartograaf Gerardus Mercator in 1569. De kaart komt tot stand door de wereldbol op een cilinderte projecteren. Gebieden die verder van de evenaar liggen worden dus groter afgebeeld. Omdat een route meteen constante kompaskoers een rechte lijn is op een kaart met een mercatorprojectie wordt deze projectie in descheepvaart veel gebruikt.

16

Page 22: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

5 Robotzeilen: hardware en software

Voor het robotzeilen heb je hardware en software nodig. In de boot zit een boordcomputer diezijn eigen programma draait. Op de kant staat een laptop met daarin software om de boot inde gaten te houden. Deze laptop is geen afstandsbediening, de boot vaart immers zelfstandig.Wel kunnen vanuit de laptop de parameters worden aangepast en een nieuwe route op wordengegeven.

Verder is de boot voorzien van een aantal sensoren, zoals de GPS en het kompas. Ook kande boot met servomotoren sturen en de zeilen aantrekken dan wel vieren. Op de kant staat ookeen sensor: een windvaan. De communicatie tussen de boot en de laptop op de kant gaat viaeen zender- en ontvangersysteem.

Aanvankelijk werkte mijn software via een opdrachtregel met ingewikkelde commando’s.Dat heb ik inmiddels vervangen door een grafische bedieningsinterface.

5.1 De boordcomputer: multitasking en efficientie

Op de boot draait de software op een boordcomputer, deze software is in C++ geschreven omeen zo efficient mogelijk programma te krijgen. C++ staat relatief dicht op de machinetaal dieook daadwerkelijk uitgevoerd wordt. Dat kost meer tijd om te schrijven, maar daarmee hebje meer invloed op wat er precies onder de motorkap gebeurt. De C++ code wordt door eencompiler omgezet in machinetaal, geschikt voor de boordcomputer.

Het is belangrijk om te bedenken dat de boordcomputer geen besturingssysteem heeft, zoalseen PC. Het voordeel daarvan is dat al je geheugen en rekenkracht beschikbaar zijn voor jeprogramma waardoor je heel snel en efficient de hardware kan aanspreken. Het nadeel is echterdat je niet meerdere programma’s tegelijkertijd kan draaien zoals op een PC. Eigenlijk kaneen gewone PC ook niet meerdere dingen tegelijkertijd doen. Windows geeft elk programmasteeds een voor een tijd. Dat gaat heel snel waardoor het lijkt alsof alles tegelijkertijd werkt.In mijn software doe ik dat eigenlijk ook. Het programma bestaat uit een eeuwige lus waarinsteeds elk onderdeel een beetje tijd krijgt toebedeeld. Sommige stukjes programma kunnenechter voorrang krijgen als het belangrijk is dat er heel snel iets gedaan moet worden. Als erbijvoorbeeld een instructie van de wal ontvangen wordt, stopt het programma tijdelijk waar hijmee bezig was om de boodschap te verwerken.

5.2 PID regeling

De PID regeling heb ik eigenlijk geımplementeerd zoals formule 7. Ik doe de losse stukjes eenvoor een om ze dan op te tellen. De code ziet er dan als volgt uit:

void Pid::update(void){

float p,i,d; //variabeles declaren die later gebruikt gaan worden

Setpoint = sp->get(); //SP ophalen

Input = pv->get(); //Koers ophalen

state["sp"] = Setpoint; //sp opslaan op een plek waar andere processen

// dat ook kunnen zien

if (state["roer_auto"]){ //als het roer autmoatisch bestuurd moet worden

float error = verschil(Input,Setpoint); //afwijking uitrekenen

17

Page 23: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

float schaal = state["schaal"]; //Deelfactor voor de paramters uitlezen

state["error"] = error; //afwijking opslaan

ITerm += ((state["ki"] / schaal ) * SampleTime * error); //I term uitrekenen

//en optellen bij vorige I

if(ITerm > 25) //Zorgen dat de I niet te groot wordt

ITerm = 25;

else if(ITerm < -25)

ITerm = -25;

float dInput = verschil(lastInput,Input); //Afgeleide berekenen

p = (state["kp"] / schaal ) * (error + state["roll"] * 0.01 * state["pid_roll"]); //P uitrekenen

i = ITerm; //I uitrekenen

d = - ( (state["kd"] / schaal ) / SampleTime) * dInput; //D uitrekenen

Output = p + i + d; //Optellen

if(Output > outMax) //Zorgen dat de output niet te groot wordt

Output = outMax;

else if(Output < outMin)

Output = outMin;

lastInput = Input; //Huidig setpoint opslaan voor later

state["p"] = p; //P,I,D waardes opslaan

state["i"] = i;

state["d"] = d;

output->set( (int)Output + 50); //Roer instellen

}

}

De blauwe tekst achter “//” is toelichting, en heeft verder geen invloed op de code. In decode zitten een aantal beveiligingen en extra dingen ingebouwd die in de formule niet zitten. Intotaal heb ik een viertal toevoegingen gemaakt, die de PID geschikt maken voor een boot[16].

De eerste toevoeging is de formule om de het kleinste verschil tussen twee koersen te berekenen.Normaal kun je het verschil tussen de huidige waarde en de ingestelde waarde berekenen doorze van elkaar af te trekken. Maar met koersen werkt dat niet. Het is namelijk mogelijk om doorde 0 heen naar de 360 te gaan. Het verschil tussen 359 graden en 1 graad is slechts twee gradenen niet 358 (359 − 1).

De tweede toevoeging is een beveiliging dat de I term niet te groot wordt. Als de te varenkoers plotseling verandert, bijvoorbeeld als er overstag gegaan moet worden, dan wordt deafwijking ineens ook veel groter. Deze afwijking wordt steeds maar opgeteld bij de I term,

18

Page 24: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

daardoor zou deze term veel groter worden dan nodig is. In de tijd die de boot nodig heeft omde nieuwe koers te gaan varen is de I term al zo groot geworden dat het roer alleen nog maarmaximale uitslag blijft gegeven, ook als de te varen koers reeds bereikt is. De beveiliging zorgter voor dat de I term niet groter kan worden dan een bepaalde waarde.

De derde toevoeging zit in de manier waarop de afgeleide berekend wordt. Je kan de afge-leide van de afwijking nemen, maar dan zou deze reageren op veranderingen van de koers enveranderingen in het setpoint. Het roer krijgt dan een zwiep als de ingestelde waarde verandert,en dat is niet de bedoeling. Daarom wordt de afgeleide van de koers genomen.

De vierde en laatste toevoeging is een beveiliging die ervoor zorgt dat het roer nooit deopdracht kan krijgen om meer dan een vooraf ingesteld maximum te sturen, anders zou deservomotor het roer of de boot zelf kapot kunnen maken.

5.3 Loxodroom

Ook de loxodroom (Engels: rhumb line) is volgens formule 8 en 9 geprogrammeerd. Omdatde ingebouwde goniometrische functies van de boordcomputer in radialen rekenen, en de restvan het systeem in graden werkt, moeten de hoeken eerst omgerekend worden van graden naarradialen, en op het einde weer terug naar graden.

double afstand(pos *cur, pos *tar){

double lat_cur_r = cur->lat * deg2rad;

double lon_cur_r = cur->lon * deg2rad;

double lat_tar_r = tar->lat * deg2rad;

double lon_tar_r = tar->lon * deg2rad;

double df = log(tan(lat_tar_r/2.0 + PI/4.0)/tan(lat_cur_r/2.0 + PI/4.0));

double dla = lat_tar_r - lat_cur_r;

double dlo = lon_tar_r - lon_cur_r;

double q;

if (df == 0)

q = cos(lat_cur_r);

else

q = dla / df;

double r = 6371.0;

double d = sqrt(pow(dla,2) + pow(q,2) * pow(dlo,2)) * r;

return d;

}

double koers(pos *cur, pos *tar){

double lat_cur_r = cur->lat * deg2rad;

19

Page 25: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

double lon_cur_r = cur->lon * deg2rad;

double lat_tar_r = tar->lat * deg2rad;

double lon_tar_r = tar->lon * deg2rad;

double df = log(tan(lat_tar_r/2.0 + PI/4.0)/tan(lat_cur_r/2.0 + PI/4.0));

double dla = lat_tar_r - lat_cur_r;

double dlo = lon_tar_r - lon_cur_r;

double k = atan2(dlo,df) * rad2deg;

if (k < 0)

k += 360;

return k;

}

5.4 Kompas: de koersbepaling

Het elektronische kompas is met een I2C (Inter-Integrated circuit) bus aan de boordcomputerverbonden. Een uitgebreide beschrijving is voor onze doeleinden niet nodig. Wat belangrijkis om te weten is dat het een serieel protocol is waarbij elk van de “slaves” (het kompas indit geval) een eigen adres heeft. Om een van de “slaves” uit te lezen, stuurt de “host” (deboordcomputer) een adres. Om het kompas aan te spreken is dit 50 (of 0x32 hexadecimaal).Hierdoor begint het kompas te luisteren. Daarna stuurt de host een opdracht, in dit geval 80(0x50) wat “sample heading” betekent. Het kompasje gaat dan aan het werk om de koers temeten. Hier moet even op gewacht worden. Daarna kunnen er 6 waardes uitgelezen worden,deze waardes worden tot slot omgerekend in een werkbaar formaat[17].

void Kompas::update(void) {

//wat variabeles om als zend en ontvang buffer te fungeren

char compass_out[1];

char compass_in[6];

//als het kompas niet bezig met calibreren kan er gelezen worden

if (cal == 0) {

//zet 0x50(="sample heading") in zend buffer

compass_out[0] = 0x50;

//stuur deze buffer over de bus

compass.write(ADDR,compass_out,1);

//geef het kompas even de tijd om de opdracht uit te voeren

wait_ms(1);

//Daarna kunnen er 6 8bits waardes uitgelezen worden

compass.read(ADDR,compass_in,6);

20

Page 26: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

//Deze 6 8 bits waardes moeten omgerekend worden naar 3 16 bits waardes

int compass_heading = (int)compass_in[0] << 8 | (int)compass_in[1];

int compass_pitch = (int)compass_in[2] << 8 | (int)compass_in[3];

int compass_roll = (int)compass_in[4] << 8 | (int)compass_in[5];

int n = compass_heading / 10;

int verschil = n - prev;

if (verschil > 180)

verschil -= 360;

if (verschil < -180)

verschil += 360;

if (abs(verschil) > 60) {

if (verschil > 0)

prev += 20;

else

prev -= 20;

} else {

koers = n;

}

} else

koers = 0;

}

5.5 Filtering

Het signaal wat uit het kompas kwam bleek echter niet helemaal zuiver. Er zat nog een kleinehoeveelheid ruis op. Deze ruis zorgde voor kleine maar snelle veranderingen in het signaal.Het probleem hiervan was dat het differentierende deel van de PID regelaar heel heftig op dezeveranderingen reageerde. Daarom moest deze ruis worden geelimineerd.

Eerst heb ik geprobeerd een lopend gemiddelde te nemen over een aantal metingen. Ditwerkte nog niet naar behoren. Ten eerste kwam er nog steeds te veel ruis door dit filter heen.Ten tweede zorgde het ook nog eens voor onacceptabele vertraging, hierdoor duurde het veel telang voordat een verandering in de koers zichtbaar werd.

Daarom ben ik op zoek gegaan naar een ander filter. Het gewone signaal heeft een vrijlage frequentie, de boot verandert nooit meer dan een paar keer per seconde van koers. Deongewenste fluctuaties van het kompas hebben een hogere frequentie. Daarom moet dit filterde lage frequenties doorlaten maar de hogere tegenhouden.

Een geschikt filter voor dit doeleinde is een Butterworth laag doorlaat filter. Dit filterbestond oorspronkelijk uit weerstanden en condensatoren om hem in een analoge schakeling toete passen. Later is ook de wiskundige basis van dit filter gebruikt om formules te vinden diedoor de computer gebruikt kunnen worden. Het te filteren signaal wordt dan in deze formulesingevoerd en dat levert dan een gefilterde versie van het signaal op.[18]

21

Page 27: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

Figuur 14: Het effect van het aantal polen ophet gedrag rond de cutoff frequentie

In deze formules zitten een aantal para-meters die het gedrag van het filter bepalen.Deze parameters zijn afhankelijk van een aan-tal eigenschappen van het filter. De eersteeigenschap is de ‘cutoff’ frequentie, dit is defrequentie waarbij het filter signalen begint teverzwakken. De tweede eigenschap is hoevel‘polen’ het filter heeft, dit bepaald hoe hetfilter zich gedraagt rond de cutoff frequentie.Als een filter veel polen heeft worden signa-len die vlak boven de cutoff frequentie zittennauwelijks meer doorgelaten, terwijl dit ver-loop vloeiender gaat voor een filet met minderpolen. In figuur 14 is het gedrag van het fil-ter te zien als het aantal polen verandert wordt. Op de horizontale as staat de frequentie en opde verticale as de verzwakking. Om de juiste parameters te berekenen heb ik gebruik gemaaktvan een website[19], maar programma’s als matlab kunnen dit ook. Ik heb een filter gebruiktmet 5 polen, een sample frequentie van 10Hz en een cutoff frequentie van 1Hz.

Het filter is op de volgende manier geımplementeerd:

GAIN = 7.796778047e+02;

xv[0] = xv[1]; xv[1] = xv[2]; xv[2] = xv[3]; xv[3] = xv[4]; xv[4] = xv[5];

xv[5] = meting / GAIN;

yv[0] = yv[1]; yv[1] = yv[2]; yv[2] = yv[3]; yv[3] = yv[4]; yv[4] = yv[5];

yv[5] = (xv[0] + xv[5]) + 5 * (xv[1] + xv[4]) + 10 * (xv[2] + xv[3])

+ ( 0.1254306222 * yv[0]) + ( -0.8811300754 * yv[1])

+ ( 2.5452528683 * yv[2]) + ( -3.8060181193 * yv[3])

+ ( 2.9754221097 * yv[4]);

koers = yv[5];

5.6 GPS: de positiebepaling

De GPS geeft de boot informatie over de positie, maar een GPS stuurt veel meer informatiedan ik nodig heb. Mijn programma haalt uit de stroom van data de benodigde informatie. Eenvoorbeeld van wat de GPS elke seconde stuurt:

$GPGGA,075851.891,5611.5305,N,00302.0369,W,0,00,4.8,44.0,M,52.0,M,,0000*77

$GPGSA,A,1,,,,,,,,,,,,,4.8,4.8,0.7*37

$GPGSV,3,1,12,20,82,116,,01,79,246,,32,54,077,,17,48,254,*70

$GPGSV,3,2,12,23,46,168,,24,40,128,,04,25,295,,11,24,143,*73

$GPGSV,3,3,12,31,22,065,,13,15,190,,12,11,343,,25,00,019,*7D

$GPRMC,075851.891,V,5611.5305,N,00302.0369,W,002.2,252.9,160411,,,N*68

$GPVTG,252.9,T,,M,002.2,N,004.1,K,N*0B

Hierin staat alle informatie over de positie, de actuele tijd, de snelheid en nog veel meer.Zo vaart de boot uit dit voorbeeld om 7:58:51 UTC op 56 graden noorderbreedte en 3 gradenwesterlengte. Gelukkig volgt de GPS een protocol dat makkelijk is uit te lezen: het NMEAprotocol. Elke NMEA-string begint met een $ en daarna volgen een aantal kenletters. De

22

Page 28: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

verschillende gegevens zijn gescheiden door een komma. De voor mijn programma belangrijkstestring is de GPGGA string, hierin staat namelijk de informatie over de actuele positie[20].

5.7 Servo’s aansturen: het roer en de zeilen

Een servo moet aangestuurd worden met pulsjes (later meer hierover). Deze pulsjes moetengemaakt worden in de boordcomputer maar het zou voor de programmeur erg lastig zijn alshet programma ook echt elke 20ms moet stoppen waar hij mee bezig is om een puls te maken.Daarom is de mbed voorzien van een pulsgenerator. Als deze eenmaal ingesteld is blijft hijzelfstandig pulsjes genereren[21].

5.8 Communicatie tussen de laptop en de boordcomputer: Sailcom

Met de laptop op de wal kan ik de boot en de boordcomputer in de gaten houden. Ook is hetmogelijk om de boot een nieuwe koers en informatie over de windrichting te geven. De laptopis geen afstandsbesturing maar een monitor voor de verrichtingen van de boot.

Om de communicatie mogelijk te maken heb ik zelf een protocol bedacht: SailCom. Elkcommando begint met een ‘$’ om het begin aan te geven, en de opdracht wordt afgesloten meteen‘#’. Er zijn twee soorten opdrachten: leesopdrachten en schrijfopdrachten. Elke leesopdrachtbegint met get, gevolgd door de naam van de waarde die gelezen moet worden. Als antwoordstuurt de boot dan de waarden. Elke schrijfopdracht begint met set, gevolgd door de naamvan de te schrijven waarde en de te schrijven waarde. Een commando ziet er dus zo uit: “$getkoers#” of “$set ki 12.4#”.

5.9 PC Interface

De software werd op een gegeven moment zo complex dat bediening met een opdrachtregelte lastig werd. Daarom heb ik een grafische bedieningsinterface gemaakt. Deze interface ismuisgestuurd en kan geschikt gemaakt worden voor een touchscreen. De informatie van en naarde boot wordt volledig gevisualiseerd met virtuele instrumenten en grafieken. Ook zit er eenkaart in het programma om de route makkelijk te kunnen bekijken en aan te passen. Data engrafieken worden automatisch in een logboek opgeslagen.

Het programma dat op de laptop draait is geschreven in Python, een minder efficiente taaldan C(++) maar veel geschikter voor het maken van grafische interfaces[22]. Hiermee heb ik eengrafische schil gemaakt om met de boot te communiceren. Het eerste deel van het programmazorgt voor de communicatie met de boot en zorgt er voor dat er steeds actuele data voorhandenis en dat deze ook wordt opgeslagen voor latere referentie. Het tweede deel zorgt dat deze dataduidelijk op het scherm weergegeven wordt en geeft de gebruiker de mogelijkheid de boot tebedienen zonder dat hij allemaal ingewikkelde commando’s uit zijn hoofd hoeft te leren. Hetderde deel communiceert met de windvaan en zorgt ervoor dat de boot weet waar de windvandaan komt. Ik zal de software bespreken aan de hand van screenshots van het programma.

23

Page 29: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

5.9.1 Hoofdvenster

Figuur 15: Het hoofdvenster

In het hoofdvenster kun je snel de belangrijkste dingen aflezen en instellen. Koers, windrichting,roerstand en zeilstand worden met virtuele instrumenten weergegeven. Met behulp van deschuifjes kun je de belangrijkste dingen instellen, waaronder het roer, het zeil en de parametersvan de PID regelaar.

24

Page 30: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

5.9.2 Roer & zeil

Figuur 16: Roer & Zeil

In het tweede venster kun je alles zien over het roer en het zeil. Je kan de actuele stand aflezenen ze instellen. Ook kan je instellen of het roer en het zeil automatisch of handmatig bediendmoeten worden. Ook zijn er grafiekjes van de roer- en zeilstand over de afgelopen 100 seconden.

25

Page 31: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

5.9.3 Kompas & vaantje

Figuur 17: Kompas & Vaantje

In het derde venster kan je de koers en de windrichting aflezen met een instrument en eengrafiekje. Ook zit er een knopje om de kalibratie van het kompas in en uit te schakelen.

26

Page 32: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

5.9.4 PID

Figuur 18: PID

In het vierde venster kun je alles van de PID regelaar aflezen en instellen. Bijna alle belangrijkedingen zijn in een grafiekje of een tekstvakje af te lezen. Ook is het mogelijk om de parameters(Kp, Ki en Kd) in te stellen. Daarnaast kan het setpoint met de hand worden ingesteld. Het isook mogelijk om in te stellen in welke mate de helling van de boot mee genomen wordt in hetregelproces.

27

Page 33: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

5.9.5 Route

Figuur 19: Route

In het laatste venster is het mogelijk om de route die het bootje vaart aan te passen. Links kunje de actuele gegevens van de route aflezen: de positie, de afstand tot het volgende punt en of eropgekruist wordt of niet. Ook kun je daar kiezen tussen gewoon rechtuit varen langs een vastekoers of dat er een van te voren ingestelde route gevaren moet worden waarbij eventueel ookwordt opgekruist. Met de schuifjes kun je instellen hoe hoog de boot aan de wind gaat zeilenen hoe breed de rakken mogen zijn bij het opkruisen (zie ook paragraaf 6.1).

Rechts daarvan is een lijst met de punten waaruit de route bestaat. Deze punten zijn teverwijderen en te verplaatsen met de knopjes rechts van de lijst. Het toevoegen van nieuwepunten kan op drie manieren. De eerste manier is door direct de coordinaten in te voeren.De tweede manier is door een koers en een afstand in te geven. Er wordt dan een waypointtoegevoegd met die afstand en koers ten opzichte van de huidige koers. Tenslotte is het mogelijkom de huidige positie als waypoint toe te voegen.

Helemaal rechts wordt een kaartje getoond van de lijst met waypoints de huidige positie(met een rood puntje). Tussen deze punten wordt de route aangegeven die gevaren gaat worden.Hierbij wordt ook rekening gehouden met opkruisen.

28

Page 34: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

6 Route plannen

6.1 Opkruisen

6.1.1 Wat is opkruisen?

Hoewel een zeilboot niet tegen de wind in kan varen, is het toch mogelijk om naar een bovenwindsgelegen punt te varen. Dit doe je door op te kruisen (zie ook paragraaf 6.1). Bij opkruisen vaarje niet direct naar je doel, maar vaar je in een zig-zag koers naar je doel. Omdat je dit wiltbekorten, probeer je wel tamelijk recht in de wind te varen. Zeilers noemen dit hoog of scherpaan de wind. Deze hoek is afhankelijk van de constructie van de boot en de zeilen die gevoerdworden. Na een tijd gevaren te hebben ga je door de wind en ga je over de andere boeg weeraan de wind varen. In theorie kun je elk bovenwinds doel bereiken met slechts een keer overstag te gaan. Je hakt de route als het ware in stukjes, elk stukje noemen we een rak.

Deze aanpak heeft nadelen maar ook voordelen. Wanneer je vaak overstag gaat wordt detotale afstand niet korter, maar je verliest snelheid en dus tijd bij elke overstag manoeuvre.Dus waarschijnlijk duurt het langer om je doel te bereiken. Slechts een keer overstag gaan is intheorie wellicht sneller, maar heeft in de praktijk een groot nadeel. Wanneer namelijk de winddraait terwijl je onderweg bent dan zul je alsnog vaker overstag moeten gaan. Bovendien heeftde route met maar twee slagen een veel breder vaarwater nodig.In de praktijk zul je dus eenafstand verdelen in meerdere rakken.

Mijn robotzeilboot kan niet alleen de complete overstag manoeuvre maken, maar bepaaltook zelfstandig wanneer en hoe vaak de boot overstag moet gaan om zo snel mogelijk het doelte bereiken. Dankzij de software en de instrumenten weet de boot ook wanneer het doel isbereikt. Deze vaardigheid komt zelfs op de dure, professionele stuurautomaten van zeiljachtenniet voor.

29

Page 35: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

6.1.2 Algoritme van Stelzer en Proll

v vmg

Figuur 20: vmg

Stelzer en Proll stellen een algoritme voor om op te kruisen[2]. Zijmaken hierbij gebruik van de vmg (velocity made good), oftewel decomponent van de bootsnelheid richting het doel. Hun algoritme be-rekent op elk moment de vmg op de huidige koers en de vmg als zeop dat moment over de andere boeg zouden varen, op het momentdat die een factor n hoger is dan de huidige vmg besluit het algoritmeoverstag te gaan. Het resultaat van dit algoritme is te zien in afbeel-ding 21. Zoals je ziet zorgt dit er voor dat als de boot dichter bij hetdoel komt het aantal slagen zou toenemen. Om dit op te lossen heb-ben Stelzer en Proll een correctie toegepast op de factor n. Zij hebbendie afhankelijk gemaakt van de afstand tot het doel: n = 1 + Pc

d metparameter Pc. Dit maakt het resultaat al een stuk beter maar het lost het probleem nog steedsniet op.

Figuur 21: Algoritme van Stelzer en Proll

30

Page 36: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

6.1.3 Mijn algoritme

α

δ

ld

Figuur 22: Mijn algoritme voor hetopkruisen

Omdat het algoritme van Stelzer en Proll voor alle mo-gelijke koersen een vmg moet uitrekenen is het vrij re-kenintensief. Het moet immers 360 berekeningen uit-voeren en hier de koers met de hoogste vmg uitkiezen.Dit is een verspilling van energie en een zeer inefficientgebruik van de boordcomputer. Daarom heb ik zelf eenander algoritme geschreven. In plaats van het volle-dige pooldiagram van de boot door te rekenen, heeftmijn algoritme genoeg aan de scherpste koers die deboot kan varen. Daarna besluit het algoritme of er op-gekruist moet worden of niet. Als er niet opgekruisthoeft te worden, vaart hij rechtstreeks naar zijn doel,anders gaan er een aantal dingen gebeuren.

Bij opkruisen doorloopt het algoritme een viertalstappen. Als eerste wordt de huidige positie opge-slagen als begin van het opkruisen en als begin vanhet eerste rak. Deze positie wordt later nog gebruikt.Daarna moet de keuze gemaakt worden over welke boeger wordt opgekruist. Hier wordt de kant gekozen die opdat moment het dichtste bij de richting van de boot ligt;die is immers het snelste te bereiken. Daarna moet delengte van het te varen stuk uitgerekend worden. Delengte van het stuk is van verschillende dingen afhan-kelijk: de totale afstand van het traject en de hoekmet de wind. Als er recht tegen de wind in opgekruistmoet worden zijn de twee stukken even lang, maar alsde wind schuin inkomt moet het ene stuk langer zijndan het andere om zo efficient mogelijk naar het doelte gaan.

De twee lengtes worden als volgt berekend:

l =d

sin(α± δ)(10)

Hier is d de afstand die elke slag richting het doel moetworden afgelegd (zie Afbeelding 22), α de hoek tussende richting naar het doel en de wind en δ de scherpstehoek die gezeild kan worden. De ± is afhankelijk vanover welke boeg er gevaren wordt.

31

Page 37: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

Dit is de C++ code van het algoritme:

double Goto::get(void){

if (holdcourse)

return course;

double k = koers(&huidig->get(),&doel->get()); //koers naar doel berekenen

double d = afstand(&huidig->get(),&doel->get()); //afstand nar doel berekenen

double ware_wind = vaantje->get(); //ware wind uit vaantje halen

if (ware_wind > 360)

ware_wind -= 360;

if (fabs(verschil(k,ware_wind)) < minhoek + hys){ //kijken of er moet worden opgekruist

if (!opkruisen){ //kijken of er niet al opgekruist wordt

begin_opkruisen = huidig->get(); //huidige positie opslaan als begin van het

// opkruisen

begin_rak = huidig->get(); //en als begin van het huidige rak

koers_begin = k; //de koers van de layline opslaan

eerste = 1; //installen dat het eerste rak is

}

else{

reset = 0;

}

opkruisen = 1;

}

if (fabs(verschil(k,ware_wind)) > minhoek + hys){ //kijken of het al bezeild is

opkruisen = 0;

eerste = 0;

}

if (!opkruisen){ //als er niet opgekruist hoeft te worden

return k; //direct naar het doel varen

}

else //anders:

{

double boeg1 = ware_wind + (double)minhoek; //twee koersen uitrekenen

double boeg2 = ware_wind - (double)minhoek;

if (boeg1 > 360)

boeg1 -= 360;

if (boeg2 < 0)

boeg2 += 360;

//lengte van de rakken uitrekenen

double lengte = afstand(&begin_opkruisen, &doel->get()) / 5.0;

double a = fabs(verschil(ware_wind,koers_begin));

double lengte1 = lengte / sin(((double)minhoek+a) * deg2rad);

double lengte2 = lengte / sin(((double)minhoek-a) * deg2rad);

if (eerste){

//eerste rak 2x zo kort

lengte1 /= 2.0;

lengte2 /= 2.0;

//bij eerste rak kiezen welke koers het dichste bij de huidige licht

32

Page 38: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

if (fabs(verschil(boeg1,kompas->get())) < fabs(verschil(boeg2,kompas->get())))

boeg = 1;

else

boeg = 2;

}

if (boeg == 1){

if (afstand(&begin_rak,&huidig->get()) > lengte1){ //als het einde van

// het rak bereikt is

eerste = 0;

boeg = 2; //ga overstag

begin_rak = huidig->get();

}

return boeg1;

}

if (boeg == 2){

if (afstand(&begin_rak,&huidig->get()) > lengte2){

eerste = 0;

boeg = 1;

begin_rak = huidig->get();

}

return boeg2;

}

}

}

33

Page 39: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

7 Hardware: sensoren en actuatoren

In dit hoofdstuk zal ik van elk onderdeel op de boot de werking en het nut uitleggen. Al dezeonderdelen zorgen er namelijk samen voor dat de boot niet alleen kan varen, maar ook dejuiste beslissingen kan maken om zijn doel te bereiken. Ik heb de onderdelen in vier groepenonderverdeeld:

1. De bootAlles wat te maken heeft met de boot en het zeilen zelf

2. De sensorenAlles wat zorgt dat de boordcomputer genoeg informatie heeft om beslissingen te nemen

3. De actuatorenAlles om te zorgen dat de beslissingen van de boordcomputer ook uitgevoerd worden

4. ElektronicaDe boordcomputer en de verbinding met de wal

7.1 Boot

7.1.1 Vorige pogingen

Zoals ik al in de inleiding schreef is het idee voor dit profielwerkstuk ontstaan toen ik eenmodelbootje in de kelder vond. Er moest echter nog veel gebeuren om het bootje vaarklaar temaken, van robotzeilen was toen nog geen sprake. Bij deze eerste boot - De Astrid - heb ik deromp en het dek waterdicht gemaakt door ze te voorzien van een aantal lagen epoxy. Ook heb ikwaterdichte luikjes gemaakt om nog bij de elektronica te kunnen. Deze luikjes heb ik voorzienvan tochtstrip om de aansluiting waterdicht te maken. Het was lastig om een kabeldoorvoer temaken om de verschillende compartimenten te verbinden.

Voor de mast heb ik in de modelbouwwinkel een aluminium profieltje gekocht en dit heb ikafgezaagd tot een lengte van een meter. De verstaging bestand uit staalkabel met een diametervan 0,5mm en werd met miniatuurspannertjes op spanning gebracht. De zeilen heb ik metbehulp van het computerprogramma Sailcut CAD ontworpen. In dit programma geef je deeigenschappen van je zeil in zoals bolling, lengte van de mast en lengte van de giek. Daarnaberekent het programma de maten van de losse banen van het zeil. Deze banen print je uit entrek je over op spinnakerdoek. Daarna heb ik de losse banen uitgeknipt en aan elkaar genaaid.Dit heb ik voor het grootzeil en de fok zo gedaan.

Met dit bootje heb ik de eerste testen van de hardware gedaan en toen is de liefde voorzelfstandig varende modelbootjes ontstaan. Figuur 23 is een foto van de Astrid. Bij het testenbleek toch dat de motoren niet sterk genoeg waren en de boot niet waterdicht genoeg was voorde dure elektronica die ik er in wilde plaatsen. Helaas bleek het bootje dus uiteindelijk mindergeschikt dan ik gedacht had. Ik heb toen niet opgegeven en een nieuw bootje gezocht om mijnprofielwerkstuk af te kunnen maken. Daarom heb ik een commercieel, op afstand bestuurbaarmodelzeilbootje gekocht en deze aangepast: de micromagic.

7.1.2 Micromagic

Ik gebruik nu een Micromagic, een modelzeilboot waar over de hele wereld wedstrijden meegevaren worden. De boot is gemaakt voor radiografische besturing, dus is hij goed waterdichten is er voldoende ruimte voor de inbouw van servomotoren, batterijen en elektronica. Ik hebde oorspronkelijk elektronica eruit gehaald om plaats te maken voor de boordcomputer en de

34

Page 40: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

Figuur 23: Foto van de eerste boot: De Astrid

bijbehorende onderdelen. Het is een modern en licht ontwerp. Het bootje is daarom zeer snelen wendbaar. Dat maakt het makkelijker om de regelingen af te stellen.

Figuur 24: Foto van de huidige boot: MicroMagic - De Vliegende Hollander

35

Page 41: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

7.2 Sensoren

7.2.1 GPS

Figuur 25: GPS module

Om de plek van het bootje op aarde te bepalen (en dus ook depositie ten opzichte van het doel) heb ik gebruik gemaakt van eenGPS module. Deze GPSmodule stuurt een keer per seconde depositie van het bootje over een seriele uitgang die verbonden ismet de hoofdcomputer.

7.2.2 Kompas

Figuur 26: Elektronischkompas

Het kompas is het belangrijkste instrument op een zeilboot. Envoor deze autonome zeilboot worden aan dit kompas een aantalhoge eisen gesteld: ten eerste mag er geen grote afwijking ontstaanals het kompas gekanteld werd (iets wat veel kompassen wel heb-ben), en ten tweede moest het een flink aantal keer per secondede koers kunnen meten. Het elektronisch kompas dat ik gevondenheb is een Honeywell HMC6343[17]. Dit kompas is, in tegenstellingtot veel andere elektronische kompassen, niet gevoelig voor kante-len. Dit komt omdat het kompas het magnetisch veld van de aardeniet in een richting meet maar door het in drie loodrechte vecto-ren in de X, Y en Z richting te meten. Samen met de helling kanhet kompas uit deze gegevens exact de koers uitrekenen, zelfs alsde sensor gekanteld is. Bovendien kan het kompas dit tot 10x per

seconde. Ook bezit het kompas de mogelijkheid om zichzelf te kalibreren waardoor hij niet meerbeınvloed wordt door metalen objecten (zoals de servomotoren) in de omgeving.

7.2.3 Vaantje

Figuur 27: Windvaantje

Om een boot te laten zeilen moet jenatuurlijk wel weten waar de windvandaan komt. Daarom moest hierwat op gevonden worden. Er zijnveel verschillende manieren om dewind te meten, het kan bijvoor-beeld door een sensor te makendie rondom de temperatuur meet(de kant waar de wind vandaankomt is ietsje kouder), maar dat isniet zo’n precieze methode. Ookkan er gebruik gemaakt worden vanultrasoon-pulsen, maar dit zijn heledure systemen. De enige oplossingdie nog over bleef was een klassiekwindvaantje. Het windvaantje heefteen vaan, deze vaan vangt wind en

draait naar de wind toe. Onder de vaan zit een systeem dat de richting bepaalt.Het vaantje was oorspronkelijk een onderdeel van een stuurautomaat voor een grote boot.

Daarom was er helaas geen documentatie die vertelde hoe de elektronica van de sensor in elkaar

36

Page 42: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

zat. Er zat dus niets anders op dan de sensor uit elkaar te halen en zelf een kijkje in hetbinnenwerk te nemen. De elektronica om de windhoek te meten bestond uit een ledje en vierlichtgevoelige weerstanden (LDR’s) die samen twee spanningsdelers vormden. Hierboven zateen spiegelend plaatje dat in elke positie een andere mate van reflectie had. Door deze matevan reflectie kwam er afhankelijk van de hoek een andere hoeveelheid licht op de weerstanden.Nadat ik 5 volt op de spanningsdelers en het ledje gezet had kwamen er twee spanningen uithet vaantje.

Met een oscilloscoop kon ik zien dat er twee sinusvormige signalen uit het vaantje kwamenwanneer je er aan draaide. Deze spanningen verschillen 90 graden in fase.

Figuur 28: Gemeten spanningen

Helaas was het vaantje te groot en te zwaar om op het bootje te plaatsen, daarom staathet vaantje op een oud fotostatief op de kant en zorgt het programma op de computer ervoordat de boot weet waar de wind vandaan komt. Als er een tweede versie van dit bootje komtmaak ik de boot iets groter waardoor het vaantje wel op de boot kan en het bootje niet meerafhankelijk is van de computer op de kant om te weten waar de wind vandaan komt.

37

Page 43: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

7.3 Actuatoren

7.3.1 Servo

Om de bewegingen van het roer en het zeil te regelen, gebruik ik elektromotoren. Echter geengewone elektromotoren maar servo’s. Servo’s zijn elektromotoren met een ingebouwde regeling.Je zegt tegen een servo in welke positie hij moet staan en vervolgens gaat de servo naar die plaatstoe bewegen. Als hij de positie bereikt heeft stopt hij met draaien. Ook als bijvoorbeeld dewind aan het zeil trekt zorgt de servo er voor dat hij toch op zijn plek blijft door een tegenkrachtuit te oefenen. Dit is heel handig omdat je er daarna van uit kan gaan dat je roer en zeil inde ingestelde stand blijven staan. De servo is aan te sturen met pulsjes met een welbepaaldelengte. De lengte van deze pulsjes geeft dan positie aan.

Figuur 29: Golfvorm servo

Zoals in figuur 29 te zien is, heeft het signaal een periode van 20ms oftewel een frequentievan 50Hz. Aan het begin van elke periode wordt er een puls gestuurd. De lengte van deze pulsbepaalt de stand van de servo; als deze 1ms is draait de servo helemaal naar links, als deze 2msis dan draait de servo helemaal naar rechts. Het is erg belangrijk dat deze pulsen ook echt elke20ms herhaald worden, anders staat de as van de servo wel in de juiste positie, maar staat dezeniet meer vast omdat de servo geen kracht meer levert.

Figuur 30: Servomotor

38

Page 44: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

7.4 Elektronica

7.4.1 ARM microcontroller

De boordcomputer van het robot-bootje wordt aangedreven door een ARM microcontroller.Het is het kleine broertje van het type processor dat in moderne smartphones zit. Ik maakgebruik van een Mbed, een ontwikkelbordje voor de LPC1768 ARM microcontroller. Op ditontwikkelbordje zit de processor zelf, een stukje elektronica dat nieuwe programma’s in de chipkan laden, een geheugen om dingen op te slaan en spanningsregelaars om te zorgen dat de (tehoge) spanning van de batterijen omgezet worden naar een spanning waar de andere elektronicaiets mee kan. De processor loopt op 100MHz en kan met 32 bits getallen werken. Ook heeft hijspeciale instructies voor goniometrische functies waardoor er zeer snel met coordinaten gewerktkan worden. Bovendien was het nodig dat hij minstens twee seriele poorten moest hebbenom met de GPS en met de zender te kunnen communiceren en een uitgang moest hebben omautomatisch pulsjes te genereren die de servo’s aansturen. Ten slotte heeft hij voldoende in- enuitgangen voor eventuele uitbreidingen.

Figuur 31: Microcontroller met aansluitmogelijjkheden

7.4.2 Draadloze communicatie met de wal

Figuur 32: Zigbee module

Voor de communicatie tussen de wal en het schip heb ik gebruikgemaakt van Xbee Pro zenders. Dit zijn industriele modules voordraadloze communicatie. Ze gaan volgens de specificaties tot 1,5km. In deze Xbee modules zit speciale software, die door deingebouwde foutcorrectie en andere algoritmes ervoor zorgt datmet grote waarschijnlijk alle data die verzonden wordt, ook zoontvangen wordt.

Ik gebruik deze modules om de boot te vertellen als deze eenandere route moet gaan varen. Ook kan ik voor testdoeleindenwaardes opvragen, bijvoorbeeld de actuele koers. Deze waardeskan ik dan op de computer tonen. Ik gebruik deze modules en decomputer dus niet als afstandbediening. Als de route ingesteldis, is de zender niet meer nodig.

39

Page 45: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

7.5 Schema

Om al deze hardware samen te laten werken moest ik deze wel op de juiste manier aansluiten.Ik heb toen aan de hand van de datasheets van de verschillende onderdelen een aansluitschemagemaakt, zie figuur 33. Vervolgens heb ik alles volgens dit schema aan elkaar gesoldeerd.

3.3V

GND

100u

GND

100u

GND

3.3V

GND

3.3V

GND

3.3V

GND VCC

GNDVCC

VCC GND

VCC GND

4x A

A

MBE

D

GPS

Kom

pas

Zeil Ro

er

+ -

GND

VIN

VB NR 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 2021222324252627282930D+D-

TD+

TD-

RD+

RD-

IF+IF-

VUVO

UT

VCC

GND

SIG

VCC

GND

SIG

GND

VCC

SDA

SCL

VCC

GND

TXD

RXD

VCC

1DO

UT2

DIN

3DO

84

RESE

T5

PWM

0/RS

SI6

PWM

17

RESE

RVED

8DT

R/DI

89

GND

10AD

4/DI

O411

CTS/

DIO7

12ON

/SLE

EP13

VREF

14AS

C/AD

5/DI

O515

RTS/

AD6/

DIO6

16AD

3/DI

O317

AD2/

DIO2

18AD

1/DI

O119

AD0/

DIO0

20

C1

C2

RXD

RXD

SCL

SDA

TXD

xy

zHMC6343

XBee

+

+

Figuur 33: Het aansluitschema

40

Page 46: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

8 Resultaten en evaluatie

Nadat ik al deze losse onderdelen samengevoegd had kon ik met mijn bootje gaan varen. Bijelke proefvaart heb ik nieuwe ideeen opgedaan en deze heb ik vervolgens direct verwerkt in desoft- en hardware. Als afsluiting ben ik naar een landelijke dag van de MicroMagic-club gegaan.Ik heb natuurlijk niet aan de wedstrijd meegedaan, maar ik heb de boot uitgebreid kunnentesten. Ook heb ik veel tips gekregen over de zeilvoering, dat maakte de boot een stuk betercontroleerbaar. Ook heb ik daar de tip gekregen om met kleinere zeiltjes te varen.

De boot werkte deze dag volledig naar behoren en ik heb alle data die uit het bootje kwamopgeslagen. Tijdens deze en eerdere vaartochten heb ik foto’s en filmpjes gemaakt. In dithoofdstuk zal ik verslag doen van deze vaartochten en mijn bevindingen ondersteunen metkaartjes en grafieken.

8.1 Algemene indruk

Mijn algemene indruk van mijn robotzeiler was zeer goed. De robot volgde vrij precies de routeen kwam altijd bij zijn doel uit. De ene keer deed hij er wat langer over dan de andere keer.De software bleek in de praktijk goed te bedienen te zijn om het bootje snel te vertellen wat hijmoest doen, en het bootje luisterde hier dan ook prima naar. Ook zorgde de regelaar er voordat de boot dicht in de buurt zat van de koers die hij moest varen.

De boot had nog wel last van weersinvloeden als golven en wind. Maar een echte kapiteinheeft natuurlijk ook moeite met het op koers houden van zijn boot als het weer minder goedis. Vaak reageerde de boot niet alleen te laat, maar ook nog tamelijk heftig, of juist niet heftiggenoeg omdat de boot de aard van de verstoring niet kende. Als een mens een kleine afwijkingmerkt kan hij door de dingen om hem heen waar te nemen voorspellen of de afwijking gewooneen kleine afwijking was of dat er nog meer gaat komen. Denk hier bijvoorbeeld aan een grotegolf die op de boot afkomt. Een echte kapitein ziet de golf aankomen en op het moment dat hijmerkt dat de golf bij de boot is stuurt hij extra heftig. Door de verkeerde reactie lag de bootvaak uit koers waardoor het even duurde voordat de regelaar de koers weer hersteld had.

Ook had de boot moeite met het sturen in hele lichte wind en in hele zware wind. De bootstuurde dan teveel of juist te weinig, ik moest daarom voor elk windtype de regelaar andersinstellen. Dit probleem kwam vooral naar voren bij het overstag gaan. Hier werd bij een lagesnelheid te weinig gestuurd. Doordat de boot te langzaam door de wind gaat heeft hij vrij langde wind recht van voren. De snelheid neemt enorm af en de manoeuvre duurt daardoor veel telang, soms wel vijftien tot twintig seconden. En als de boot dan eenmaal overstag was schoothij vaak voorbij de ingestelde koers van 35 graden ten opzichte van de wind. De boot moestdan na de overstagmanoeuvre ook nog herstellen. Wel kwam de boot altijd weer op koers enbereikte altijd zijn doel.

8.2 Hardware

De grootste vijand van elektronica is het water. Ik was dan ook bang dat er water bij deelektronica zou komen. Toch had ik hier nog niet genoeg rekening mee gehouden want bijde eerste proefvaarten had ik nog last van water in de boot, met gelukkig nauwelijks ernstigegevolgen. Alleen de communicatie met de laptop was uitgevallen. Gelukkig was de boot op datmoment geen route aan het varen, en doordat ik aan lagerwal zat dreef de boot uiteindelijkvanzelf terug. Ik was toen gewaarschuwd en heb daarna alle elektronica ingesmeerd met eenspeciaal soort coating om ze tegen water te beschermen.

41

Page 47: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

Het vaantje kon door zijn gewicht en grootte helaas niet op het bootje geplaatst worden. Ik hadtoen besloten om hem op een statief op de kant te zetten en dan op de laptop aan te sluiten.De laptop zou dan de windrichting doorgeven aan het bootje. Het was alleen heel onhandig dathet vaantje met een kabel aan de laptop vast zat. Als je aan het experimenteren bent wil jesoms de laptop even meenemen om dichter bij het water te kunnen staan. Ook viel me op datde wind meestal relatief constant bleek te zijn. Ik heb er toen voor gekozen om de windrichtingsoms met de hand in te stellen en daarna zonder vaantje en dus zonder kabel te werken.

De servo’s bleken inderdaad zo goed te werken als ik gedacht had. Dit was niet heel verassendomdat servo’s in bijna elke vorm van modelbouw gebruikt worden, en dus goed beproefd zijn.Ze waren makkelijk aan te sturen en luisterden prima naar wat de boordcomputer ze vertelde.Ook waren ze snel en krachtig genoeg om bij harde wind snel de zeilen aan te kunnen passenen vlot te sturen.

Over de zender en ontvanger die de communicatie verzorgden tussen het bootje en de laptop wasik iets minder tevreden. Het gespecificeerde bereik van 1,5km werd lang niet altijd gehaald. Toenik tussen allemaal andere mensen in stond die ook hun afstandsbediening gebruikten was het alna 75 meter afgelopen. Ik denk dat (naast de storing van andere zenders) het grootste probleemis dat de antenne op de boot zo dicht bij het water zit. Vlak boven het wateroppervlakte kande Xbee last hebben van reflecties van de elektromagnetische straling op de golven. Hierdoorkan het bereik heel erg verkort wordt. Ook hier zou een langere of hogere antenne welkom zijn.

De boordcomputer deed zijn werk uitstekend. Hij was snel genoeg om de route te plannen, desensoren in te lezen, bij te houden waar hij was, de roer en zeilstanden te berekenen en de servo’saan te sturen. Dat hij ook nog constant door de laptop op de wal lastig gevallen werd bleekhem niet te hinderen bij zijn werk. De laptop vraagt namelijk regelmatig aan het bootje waarhij is en wat hij aan het doen is. Deze commando’s werden dus tegelijkertijd geınterpeteerd enhet juiste antwoord werd terug gezonden.

De sensoren werkten ook goed. Het kompas was zijn hoge prijs zeker waard. Terwijl het bootjedoor de elementen alle kanten op werd geschud bleef het kompas keurig de juiste koers doorgeven.Met de GPS was het nog wel even experimenteren voordat deze goed werkte. Doordat deantenne zo dicht op het water zat bleek de plaatsing heel belangrijk. Een herpositioneren vanenkele centimeters maakte al een verschil tussen geen ontvangst en perfecte ontvangst. Na veelexperimenteren bleek hij het best te werken als hij tegen de onderkant van het dekseltje geplaktzat. Nadat hij daar geplaatst was, heb ik verder geen problemen meer gehad. Bij een volgendeversie van mijn robot zou ik de antenne hoger willen plaatsen. Wellicht een losse antenne aandek of in de mast.

De energievoorziening van de boot bleek ook prima te werken. De vier AA batterijen kondende boot voor circa vijf uur van stroom voorzien. Als de boot zijn servo’s niet hoefde te bewegennam dit zelfs toe tot tien uur. Daarom zou de boot zichzelf met zonnecellen van stroom kunnenvoorzien. Deze zouden dan lithium-ion accu’s op kunnen laden om ’s nachts door te varen.Ook zou de software meer bewust gemaakt kunnen worden van het stroomverbruik wat hijveroorzaakt. Als de accu’s bijvoorbeeld bijna leeg zijn zou hij kunnen besluiten om mindervaak zijn roer aan te passen.

42

Page 48: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

8.3 PID regelaar

De PID regelaar werkte redelijk tot goed. De boot bleef in de buurt van de te varen koers, maarwas wel gevoelig voor externe factoren. Het eerste probleem was dat er een kleine ruis in hetsignaal van het kompas zat. De differentierende deel regeerde heel heftig op deze kleine dochsnelle veranderingen. Ik heb toen een filter toegepast wat de ruis er uit filterde, het signaalwerd zo veel strakker en de regelaar reageerde daarna veel beter.

Het grootste probleem kwam naar voren bij serieuze proefvaarten. Er bleek door de con-stante druk van de wind een constante afwijking te ontstaan. Het integrerende deel van de re-gelaar moet deze afwijking oplossen. Het bleek echter dat de afwijking wel verdween als ik hetintegrerende zwaarder liet wegen. Er ontstond daardoor echter een nog groter probleem: deboot ging niet meer overstag. Doordat het integrerende deel na een stuk varen een bepaaldewaarde had aangenomen bleef de boot goed op koers. Bij het overstag gaan moet dit deel alshet ware omkeren. Het moet de andere kant op compenseren omdat de wind na de overstag-manoeuvre van de andere kant komt. Dit omkeren duurde echter zo lang dat de boot rondjesbegon te varen. Daardoor moest ik het integrerende deel uitschakelen.

Figuur 34: Constante afwijking in de koers

In figuur 34 is een stukje van een proefvaart te zien. In het stuk van 10 tot 100 seconden isdeze aan het opkruisen. De boot heeft in het stuk van 30 tot 50 seconden moeite om overstagte gaan. Verder is de constante afwijking goed te zien. De rode lijn is de koers zoals hij hadmoeten zijn en de blauwe lijn de werkelijk gevaren koers. In de hele grafiek is er een afwijkingvan soms wel enkele tientallen graden. Aan het feit dat deze afwijking vrij constant blijft, is tezien dat het probleem in het integrerende deel zit. Verder zien we in de grafiek dat in het stukvan 25 tot 50 seconden de boot moeite heeft met overstag gaan. De te varen koers gaat daar ineen keer 70 graden omhoog terwijl het vrij lang duurt voordat de boot echt begin te draaien.

8.4 Route plannen

Het plannen van de route ging goed. Ten eerste kwam de boot altijd waar hij moest komen.Dat hij hier soms wat langer over deed dan nodig was lag niet aan de route, maar aan de manierwaarop deze uitgevoerd werd. Door de slechte overstagmanoeuvres wordt bijvoorbeeld heel veeltijd verloren.

In figuur 35 is een kaart afgebeeld van een gevaren route. Ik had het bootje de opdrachtgegeven om tussen twee punten heen en weer te varen. De wind kwam hier van rechts, dusom van punt A naar punt B te varen moest er worden opgekruist; terug kon er voor de windgevaren worden. Laten we in het bespreken bij punt A beginnen en naar onder vertrekken.

43

Page 49: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

De boot is bij punt A en gaat naar punt B. Hij merkt dat er opgekruist moet worden en erwordt een route gepland. Het bootje vaart dan schuin naar onder, zo scherp aan de wind als hijmaar kan. Als de berekende afstand afgelegd is krijgt de regelaar van de software de opdrachtom overstag te gaan. Op dat moment gaan er een aantal dingen mis. Op het kaartje is niet tezien dat het lang duurt, maar er is wel een ander probleem zichtbaar. Na de overstagmanoeuvreschiet de boot te ver door. Daarom lijkt het bootje een stukje terug te varen. Het duurt daneven voordat de juiste koers hersteld is. De boot gaat dan schuin naar boven. Als hij bovenis gekomen gaat hij weer overstag en gaat er weer hetzelfde mis. En na nog een keer overstagheeft hij punt B bereikt. Het bootje draait dan en gaat voor de wind naar punt A terug. Hetvoordewindse rak wordt efficient afgelegd.

Figuur 35: Een kaartje van een gevaren route

44

Page 50: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

9 Discussie

Uit de resultaten blijkt dat het doel van het werkstuk gehaald is: de boot vaart zelfstandig vanA naar B en zelfs via C weer terug. Dit doet hij nog niet op de beste manier, maar hij komt erwel. Alle problemen die er nu nog zijn kunnen verbeterd worden. Daarvoor is wel een grotereboot nodig is.

De boot is in zijn huidige staat nog niet echt autonoom: de boot heeft nog geen windvaanaan boord. Dit probleem is op te lossen door een grotere boot te nemen en daar een windvaanop te plaatsen.

Een ander probleem is de energievoorziening. De boordcomputer en de overige hardwarelopen nu op batterijen, maar die kunnen zichzelf niet opladen. En door deze beperking kande boot maximaal vijf uur achtereen varen, daarna zijn de batterijen leeg. Om de boot quastroom zelfvoorzienend te maken moeten er twee dingen gebeuren. Ten eerste moet de boot zelfenergie opwekken met zonnecellen. Deze energie moet hij opslaan in batterijen zodat er genoegstroom opgeslagen is om de nacht door te komen. Aan de andere kant moet ik de hardwaremeer bewust maken van de energie die hij gebruikt. Als er bijvoorbeeld door bewolking minderenergie beschikbaar is moet de boot minder vaak aanpassingen aan het roer en zeil doen. Hetzuinig omgaan met energie moet naast snelheid een factor zijn waar de boot rekening mee moethouden.

De boot kan nu ook nog geen objecten en andere schepen ontwijken. Hiervoor zou er eenradar of een sonar op de boot geplaatst moeten worden. De resultaten hiervan zouden er dansamen met een aangepast routeplan systeem voor moeten zorgen dat de boot niet tegen andereschepen of boeien opvaart.

De communicatie is nu nog niet geschikt om de boot op praktische manier in te zetten. Hetis dan nodig om op afstand meetresultaten te ontvangen en nieuwe routes in te stellen, maardat gaat niet als je na een paar honderd meter geen contact meer hebt. Daarom moet er eeniridium satelliettelefoon op komen. Via deze dataverbinding kan de boot dan bijvoorbeeld eenkeer per dag zijn meetresultaten doorsturen en een nieuwe route binnenhalen.

De problemen met het overstag gaan zou ik in een volgende versie graag willen oplossen.Mijn plan is om de actuele snelheid mee te nemen in de regeling. De bootsnelheid is namelijkvan invloed op het gedrag van de boot bij roeruitslag. Bij overstag gaan is de snelheid laag enmoet er meer roeruitslag worden gegeven dan bij kleine correcties op een hoge snelheid.

Ook de filters die gebruikt worden moeten nog verbeterd worden. Deze filters zorgen nuvoor een vertraging in de koersinformatie. Dit komt niet door een gebrek aan rekenkracht maardoordat het even duurt voordat een verandering in koers aan de uitgang van het filter zichtbaarwordt. Een oplossing hiervoor zou een Kalman filter zijn. Deze filters halen niet de ongewenstedelen uit vorige metingen, maar proberen juist de volgende meting te voorspellen. Deze voor-spelling wordt daarna constant verbeterd door naar de vorige metingen en voorspellingen tekijken.

Bij zwaar weer gaat de boot nu heel schuin waardoor deze nauwelijks meer te controlerenis. Het zou mooi zijn als de boot zijn zeilen aan kon passen aan de windkracht. De boot zoubijvoorbeeld bij harde wind de zeilen een stukje kunnen inrollen. Hierdoor wordt het oppervlaktekleiner en gaat de boot minder schuin. Zo kan de boot bij zwaar weer toch doorvaren. Ook zoude boot bij licht weer extra zeilen kunnen voeren, zoals bijvoorbeeld een spinnaker.

Om de stabiliteit te bevorderen zou ik als volgende boot graag een multihull bouwen. Dezegaan sneller en gaan veel minder scheef. Dit maakt metingen van bijvoorbeeld de waterdiepteveel eenvoudiger analyseerbaar en betrouwbaarder.

Om al deze wijzigingen door te voeren is er een nieuwe en grotere boot nodig. Het lijkt me ergleuk en leerzaam om deze boot nog te bouwen, ook al is het niet meer voor mijn profielwerkstuk.

45

Page 51: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

10 Conclusie

Het doel van mijn werkstuk was het bouwen van een boot die zelfstandig van A naar B kan zei-len, desgewenst via C en langs D weer terug. De kapitein en zijn bemanning worden volledigvervangen door een computer die een route plant en zelfstandig de nodige acties onderneemt omde boot zijn doel te laten bereiken. Ik heb eerst uitgezocht uit welke onderdelen een dergelijksysteem moest bestaan. Daarna heb ik alles over deze onderdelen uitgezocht en ze samenge-voegd. Na veel testen en aanpassen ben ik zo tot een resultaat gekomen.

Ik heb in dit proces heel veel uit moeten zoeken en ik heb hier heel veel van geleerd. Ikheb me verdiept in regeltechniek. Ik heb leren knutselen aan modelbootjes. En ik heb veelbijgeleerd over C++, door boeken te lezen en vooral veel te programmeren. Doordat de datarealtime verwerkt moest worden ga je veel beter op je programmeerstijl letten: elke instructiedie je te veel gebruikt zorgt dat je programma langzamer regeert op de sensoren. Ook heb ikleren opmaken in LATEX, een programma wat zeer veel gebruikt wordt om wetenschappelijkeartikelen en verslagen mee te schrijven.

Maar het belangrijkste wat ik van dit werkstuk geleerd heb is dat het mogelijk is om metveel doorzettingsvermogen, interesse en gezond verstand iets te maken wat tien jaar geledennog science fiction was. Iets wat nu ook in academische kringen onderzocht wordt. Ik hoopdaarom dan ook dat dit werkstuk andere mensen aan zal moedigen om ook een dergelijk projectte beginnen en hun resultaten te publiceren.

Tot slot verwacht ik dat dit soort bootjes echt gebruikt gaan worden bij onderzoek. Ze zijnrelatief goedkoop en makkelijk te vervangen. Omdat ze volledig autonoom metingen kunnendoen, zijn maar weinig mensen nodig om de data te verzamelen. Ook kunnen grote groepenbootjes samenwerken om een groot gebied te bestuderen. Dit kan mogelijkheden bieden voorkleine groepen onderzoekers met een klein budget die toch graag data willen verzamelen.

Terwijl ik met mijn werkstuk bezig was heeft mijn bootje al veel aandacht gekregen. Ik benop dit moment aan het overleggen met Waternet om mijn bootje in te zetten bij metingen vande waterdiepte. De bedoeling is dat mijn bootje regelmatig een kaart maakt van de diepte vaneen meer. Mijn bootje is natuurlijk de ideale kandidaat om zoiets langere tijd in de gaten tehouden. Ik hoop dat Waternet mij die kans geeft mijn boot verder te ontwikkelen en hem tegebruiken bij hun metingen. Maar zelf ga ik er in ieder geval mee door.

46

Page 52: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

Referenties

[1] Ross Garrett (1987). The Symmetry of Sailing. Adlard Coles Nautical, 2nd edition.

[2] Tobias Proll Roland Stelzer (2007). Autonomous sailboat navigation for short course ra-cing. Elsevier Journal of Robotics, 56 (7):604–614. URL http://www.cci.dmu.ac.uk/

administrator/components/com_jresearch/assets/publications/1266686445.pdf.

[3] Peter Christian Frthmann (1998). Self-Steering Under Sail. Mcgraw-Hill. URL http:

//www.windpilot.com/n/pdf/bookeng.pdf.

[4] Pieter Adriaans (2003). Robot op Zee. Boom.

[5] Mark Neal Colin Sauze (2008). Design considerations for sailing robots performing longterm autonomous oceanography. URL http://cadair.aber.ac.uk/dspace/bitstream/

handle/2160/643/robotdesign.pdf.

[6] Mark Neal (2006). A hardware proof of concept of a sailing robot for ocean observation.IEEE Journal of Oceanic Engineering, 31 (2):462–469. URL http://citeseerx.ist.psu.

edu/viewdoc/download?doi=10.1.1.103.1486&rep=rep1&type=pdf.

[7] Wikipedia: Cubesat. URL http://en.wikipedia.org/wiki/CubeSat, bezocht op 22-1-2012.

[8] Leonard David (September 2004). Cubesats: Tiny spacecraft, huge payoffs. URL http://

www.space.com/308-cubesats-tiny-spacecraft-huge-payoffs.html, bezocht op 22-1-2012.

[9] Rodney A. Brooks (1988). A robust layered control system for a mobile robot. IEEE Jour-nal of Robotics and Automation, 4 (6):14–23. URL http://mit.dspace.org/bitstream/

handle/1721.1/6432/AIM-864.pdf?sequence=2.

[10] Skm53 datasheet. URL http://www.skylab.com.cn/datasheet/SkyNav_SKM53_DS.pdf.

[11] Morton Dan Morris H. Michael Newman (1994). Direct digital control of building systems.John Wiley & Sons, Inc.

[12] Wikipedia: Closed-loop transfer function. URL http://en.wikipedia.org/wiki/

Closed-loop_transfer_function, bezocht op 22-1-2012.

[13] Wikiepdia: Pid controller. URL http://en.wikipedia.org/wiki/PID_controller, be-zocht op 22-1-2012.

[14] Wikipedia: Great circle. URL http://en.wikipedia.org/wiki/Great_circle, bezochtop 22-1-2012.

[15] Wikipedia: Rhumb line. URL http://en.wikipedia.org/wiki/Rhumb_line, bezocht op22-1-2012.

[16] Brett Beauregard (4 2011). Improving the beginners pid. URL http://brettbeauregard.

com/blog/2011/04/improving-the-beginners-pid-introduction/.

[17] Hmc6343 datasheet. URL http://www51.honeywell.com/aero/common/documents/

myaerospacecatalog-documents/Missiles-Munitions/HMC6343.pdf.

47

Page 53: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

[18] Wikipedia: Butterworth filter. URL http://en.wikipedia.org/wiki/Butterworth_

filter.

[19] Tony Fisher (Octobre 1999). Interactive digital filter design. URL http://www-users.cs.

york.ac.uk/~fisher/mkfilter/trad.html.

[20] Dale de Priest. Nmea data. URL http://www.gpsinformation.org/dale/nmea.htm,bezocht op 22-1-2012.

[21] Lpc1768 datasheet. URL http://www.nxp.com/documents/data_sheet/LPC1769_68_67_

66_65_64_63.pdf.

[22] Mark Lutz (1999). Learning Python. O’Reilly, 4th edition.

48

Page 54: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

11 Appendix A: Foto’s

49

Page 55: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

50

Page 56: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

51

Page 57: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

52

Page 58: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

53

Page 59: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

12 Appendix B: De Programmacode van de boordcomputer

Ik heb in mijn werkstuk slechts een klein deel van de programmacode behandeld die gebruiktwordt door het bootje. Deze losse stukjes zijn nog veel te weinig om een bootje te laten varen.Om toch een volledig overzicht te geven heb ik alle programmacode in deze bijlage gezet.

Main

main.cpp

#include "mbed.h"

#include "split.h"

#include <string>

#include <vector>

#include "pws.h"

#include "roer.h"

#include "zeil.h"

#include "kompas.h"

#include "gps_wrapper.h"

#include "route.h"

#include "vaantje.h"

#include "pid.h"

#include "state.h"

#include "GPS.h"

std::map<std::string, float> state;

std::map<std::string, float> updateable;

DigitalOut led(LED1);

//invoer

GPS g(NC, p27);

Gps gps(&g);

Kompas kompas;

Vaantje vaantje;

//uitvoer

Roer roer;

Zeil zeil;

//verwerking

Route route(&gps);

Goto got(&gps,&route,&kompas,&vaantje);

Pid pid(&got,&kompas,&roer);

//zender

Serial zender(p13,p14);

string buffer;

Ticker blinker;

Ticker updater;

void blink(void){

54

Page 60: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

led = !led;

}

void newData(void){

char c;

while (zender.readable()) {

c = zender.getc();

if (state["echo"])

zender.putc(c);

if (c == ’$’) {

buffer.clear();

}

else if (c == ’#’){

if (state["echo"])

zender.printf("\n\r");

std::vector<std::string> commands = split(buffer);

if (commands[0] == "get" && commands.size() >= 2)

zender.printf("%f \n\r", state[commands[1]]);

else if (commands[0] == "set" && commands.size() >= 3){

if (commands[2] == "True")

updateable[commands[1]] = 1;

else if (commands[2] == "False")

updateable[commands[1]] = 0;

else{

float n;

sscanf(commands[2].c_str(),"%f",&n);

updateable[commands[1]] = n;

}

}

else if (commands[0] == "route_set"){

route.update(commands);

}

else if (commands[0] == "route_get"){

zender.printf("%s\n\r", route.lees().c_str() );

}

else if (commands[0] == "gps_gga"){

zender.printf("%s\n\r", gps.getgga().c_str() );

}

}

else

buffer += c;

}

}

55

Page 61: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

void update(void){

std::map<std::string, float>::iterator iter;

for (iter = updateable.begin(); iter != updateable.end(); iter++) {

if (state["echo"])

zender.printf("%s Updated: %f\n\r", iter->first.c_str(),iter->second);

state[iter->first] = iter->second;

}

updateable.clear();

}

int main(void) {

//setup zender

zender.baud(115200);

zender.attach(&newData);

//attach tickers

blinker.attach(&blink, 0.5);

updater.attach(&update, 0.1);

//echo off

state["echo"] = 0;

while (1) {

;

}

}

56

Page 62: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

Invoer

gps wrapper.h

#ifndef GPS_WRAPPER_H

#define GPS_WRAPPER_H

#include "mbed.h"

#include "pws.h"

#include "math.h"

#include "GPS.h"

#include "state.h"

#include <string>

#include <map>

class Gps{

pos positie;

GPS * gps;

Ticker updater;

public:

char gga[128];

Gps(GPS *);

void update();

void set(pos *);

pos get(void);

void simuleer(double,double);

string getgga(void);

};

#endif

gps wrapper.cpp

#include "gps_wrapper.h"

Gps::Gps(GPS * g){

gps = g;

gps->baud(9600);

gps->format(8, GPS::None, 1);

gps->setGga(gga);

updater.attach(this,&Gps::update,1.0);

}

void Gps::update(void){

state["lat"] = gps->latitude();

state["lon"] = gps->longitude();

}

void Gps::set(pos* new_pos){

positie.lat = new_pos->lat;

positie.lon = new_pos->lon;

}

57

Page 63: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

pos Gps::get(void){

positie.lat = state["lat"];//gps->latitude();

positie.lon = state["lon"];//gps->longitude();

/*//update state

state["lat"] = positie.lat;

state["lon"] = positie.lon;*/

return positie;

}

string Gps::getgga(void){

string s = gga;

return s;

}

void Gps::simuleer(double koers, double afstand){

koers *= deg2rad;

afstand /= 6371.0;

double lat1 = positie.lat * deg2rad;

double lon1 = positie.lon * deg2rad;

double dlat = afstand * cos(koers);

double lat2 = dlat + lat1;

double df = log(tan(lat2/2.0 + PI/4.0)/tan(lat1/2.0 + PI/4.0));

double q;

if (df == 0)

q = cos(lat1);

else

q = dlat / df;

double dlon = afstand * sin(koers) / q;

double lon2 = fmod((lon1 + dlon + PI),(2.0 * PI)) - PI;

positie.lat = lat2 * rad2deg;

positie.lon = lon2 * rad2deg;

}

kompas.h

#ifndef KOMPAS_H

#define KOMPAS_H

#include "mbed.h"

#include <math.h>

#include "state.h"

#include <string>

#include <map>

#define ADDR 0x32

#define NZEROS 5

58

Page 64: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

#define NPOLES 5

class Kompas{

I2C compass; // sda, scl

int cal;

int koers,prev;

Ticker refresh;

int opslag[10];

int filter_num;

float xv[NZEROS+1], yv[NPOLES+1];

float GAIN;

public:

Kompas();

int get(void);

void update(void);

void startcal(void);

void stopcal(void);

void set_num(int n){filter_num = n;}

int get_num(void){return filter_num;}

};

#endif

kompas.cpp

#include "kompas.h"

Kompas::Kompas():compass(p9, p10) {

koers = 0;

prev = 0;

cal = 0;

state["filter_num"] = 1;

wait(0.5);

char compass_out[3];

compass_out[0] = 0xF1;

compass_out[1] = 0x05;

compass_out[1] = 0x02;

compass.write(ADDR,compass_out,3);

wait_ms(1);

refresh.attach(this,&Kompas::update,0.1);

}

void Kompas::update(void) {

//wat variabeles om als zend en ontvang buffer te fungeren

char compass_out[1];

char compass_in[6];

59

Page 65: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

//als het kompas niet bezig met calibreren kan er gelezen worden

if (cal == 0) {

//zet 0x50(="sample heading") in zend buffer

compass_out[0] = 0x50;

//stuur deze buffer over de bus

compass.write(ADDR,compass_out,1);

//geef het kompas even de tijd om de opdracht uit te voeren

wait_ms(1);

//Daarna kunnen er 6 8bits waardes uitgelezen worden

compass.read(ADDR,compass_in,6);

//Deze 6 8 bits waardes moeten omgerekend worden naar 3 16 bits waardes

int compass_heading = (int)compass_in[0] << 8 | (int)compass_in[1];

state["pitch"] = ((int)compass_in[2] << 8 | (int)compass_in[3])/10.0;

state["roll"] = (int)((int)compass_in[4] << 8 | (int)compass_in[5]) /10.0;

if (state["roll"] > 180)

state["roll"] -= 6553.6;

if (state["pitch"] > 180)

state["pitch"] -= 6553.6;

int n = compass_heading / 10;

int verschil = n - prev;

if (verschil > 180)

verschil -= 360;

if (verschil < -180)

verschil += 360;

if (abs(verschil) > 60) {

//grote uitschieters filteren

if (verschil > 0)

prev += 20;

else

prev -= 20;

} else {

//butterworth

if (state["filter_num"] == 1){

GAIN = 7.796778047e+02;

xv[0] = xv[1]; xv[1] = xv[2]; xv[2] = xv[3];

xv[3] = xv[4]; xv[4] = xv[5];

xv[5] = n / GAIN;

yv[0] = yv[1]; yv[1] = yv[2]; yv[2] = yv[3];

yv[3] = yv[4]; yv[4] = yv[5];

yv[5] = (xv[0] + xv[5]) + 5 * (xv[1] + xv[4]) + 10 * (xv[2] + xv[3])

+ ( 0.1254306222 * yv[0]) + ( -0.8811300754 * yv[1])

+ ( 2.5452528683 * yv[2]) + ( -3.8060181193 * yv[3])

+ ( 2.9754221097 * yv[4]);

koers = yv[5];

60

Page 66: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

}else if (state["filter_num"] == 2){

GAIN = 4.557963942e+01;

xv[0] = xv[1]; xv[1] = xv[2]; xv[2] = xv[3];

xv[3] = xv[4]; xv[4] = xv[5];

xv[5] = n / GAIN;

yv[0] = yv[1]; yv[1] = yv[2]; yv[2] = yv[3];

yv[3] = yv[4]; yv[4] = yv[5];

yv[5] = (xv[0] + xv[5]) + 5 * (xv[1] + xv[4]) + 10 * (xv[2] + xv[3])

+ ( 0.0112635125 * yv[0]) + ( -0.1111638406 * yv[1])

+ ( 0.3863565587 * yv[2]) + ( -0.9738493318 * yv[3])

+ ( 0.9853252393 * yv[4]);

koers = yv[5];

}else{

koers = n;

}

if (koers > 360)

koers = 360;

if (koers < 0)

koers = 0;

}

} else

koers = 0;

//update state

state["koers"] = koers;

}

int Kompas::get(void) {

return state["koers"];

}

void Kompas::startcal(void) {

char compass_out[1];

if (cal == 0) {

cal = 1;

compass_out[0] = 0x71;

compass.write(ADDR,compass_out,1);

}

}

void Kompas::stopcal(void) {

char compass_out[1];

if (cal == 1) {

compass_out[0] = 0x7E;

compass.write(ADDR,compass_out,1);

cal = 0;

61

Page 67: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

}

}

vaantje.h

#ifndef VAANTJE_H

#define VAANTJE_H

#include "state.h"

class Vaantje{

public:

Vaantje();

int get(void);

void set(int);

};

#endif

vaantje.cpp

#include "vaantje.h"

Vaantje::Vaantje(){

state["wind"] = 180;

}

int Vaantje::get(void){

return state["wind"];

}

void Vaantje::set(int h){

state["wind"] = h;

}

62

Page 68: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

Uitvoer

roer.h

#ifndef ROER_H

#define ROER_H

#include "mbed.h"

#include "state.h"

//#include <string>

//#include <map>

class Roer{

PwmOut led;

PwmOut rudder;

Ticker updater;

public:

Roer();

void set(int);

void write(void);

};

#endif

roer.cpp

#include "roer.h"

Roer::Roer():led(LED2),rudder(p21) {

state["roer"] = 50;

updater.attach(this,&Roer::write,0.1);

}

void Roer::set(int a) {

state["roer"] = a;

this->write();

}

void Roer::write(void){

if (state["roer"] > 76)

state["roer"] = 76;

if (state["roer"] < 5)

state["roer"] = 5;

led = state["roer"] / 100.0;

rudder.pulsewidth(0.001 + state["roer"] / 100000.0);

}

63

Page 69: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

zeil.h

#ifndef ZEIL_H

#define ZEIL_H

#include "vaantje.h"

#include "mbed.h"

#include "state.h"

#include "pws.h"

class Zeil{

PwmOut led;

PwmOut sail;

Ticker updater;

public:

Zeil();

void set(int);

void write(void);

};

#endif

zeil.cpp

#include "zeil.h"

Zeil::Zeil() : led(LED3),sail(p22) {

state["zeil"] = 50;

state["koers_sp"] = 50;

updater.attach(this,&Zeil::write,0.1);

}

void Zeil::set(int a) {

state["zeil"] = a;

this->write();

}

void Zeil::write(void){

if (state["zeil_auto"]){

int s;

if (state["opkruisen"]){

s = 35;

}

else{

double hoek = fabs(verschil((state["sp"] * (100 - state["koers_sp"])

+ state["koers_sp"] * state["koers"]) / 100.0, state["wind"]));

if (hoek <= 40)

s = 35;

else if (hoek > 40 && hoek <= 100)

s = (hoek - 40) * (55.0/60.0) + 35;

64

Page 70: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

else

s = 90;

}

state["zeil"] = s;

}

if (state["zeil"] > 90)

state["zeil"] = 90;

if (state["zeil"] < 35)

state["zeil"] = 35;

led = state["zeil"] / 100.0;

sail.pulsewidth(0.001 + state["zeil"] / 100000.0);

}

65

Page 71: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

Status

state.h

#ifndef STATE_HPP

#define STATE_HPP

#include <map>

#include <iostream>

extern std::map<std::string, float> state;

#endif

66

Page 72: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

Verwerking

goto.h

#ifndef GOTO_H

#define GOTO_H

#include "pws.h"

#include "gps_wrapper.h"

#include "route.h"

#include "vaantje.h"

#include "kompas.h"

#include "rhumb.h"

#include <math.h>

#include "state.h"

#include <string>

#include <map>

class Goto{

Gps * huidig;

Route * doel;

Vaantje * vaantje;

Kompas * kompas;

int opkruisen;

int eerste;

int reset;

int rak;

int hys;

pos begin_opkruisen;

pos begin_rak;

double koers_begin;

int boeg;

int holdcourse;

int course;

int minhoek;

public:

Goto(Gps *, Route *, Kompas *, Vaantje *);

double get(void);

void setminhoek(int m){minhoek = m;}

void sethys(int h){hys = h;}

int getminhoek(void){return minhoek;}

};

#endif

67

Page 73: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

goto.cpp

#include "goto.h"

Goto::Goto(Gps * g, Route * r, Kompas * k, Vaantje * v){

huidig = g;

doel = r;

kompas = k;

vaantje = v;

opkruisen = 0;

eerste = 1;

reset = 0;

rak = 0;

state["holdcourse"] = 1;

state["course"] = 0;

state["minhoek"] = 35;

state["breedte"] = 20;

hys = 5;

}

double Goto::get(void){

if (state["holdcourse"])

return state["course"];

double k = koers(&huidig->get(),&doel->get()); //koers naar doel berekenen

double d = afstand(&huidig->get(),&doel->get()); //afstand nar doel berekenen

state["cts"] = k;

state["afstand"] = d;

double ware_wind = vaantje->get(); //ware wind uit vaantje halen

if (ware_wind > 360)

ware_wind -= 360;

if (fabs(verschil(k,ware_wind)) < state["minhoek"] + hys){ //kijken of er moet worden opgekruist

if (!opkruisen){ //kijken of er niet al opgekruist wordt

begin_opkruisen = huidig->get(); //huidige positie opslaan als begin van het

// opkruisen

begin_rak = huidig->get(); //en als begin van het huidige rak

koers_begin = k; //de koers van de layline opslaan

eerste = 1; //installen dat het eerste rak is

}

else{

reset = 0;

}

opkruisen = 1;

}

68

Page 74: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

if (fabs(verschil(k,ware_wind)) > state["minhoek"] + hys){ //kijken of het al bezeild is

opkruisen = 0;

eerste = 0;

}

state["opkruisen"] = opkruisen;

if (!opkruisen){ //als er niet opgekruist hoeft te worden

return k; //direct naar het doel varen

}

else //anders:

{

double boeg1 = ware_wind + (double)state["minhoek"]; //twee koersen uitrekenen

double boeg2 = ware_wind - (double)state["minhoek"];

if (boeg1 > 360)

boeg1 -= 360;

if (boeg2 < 0)

boeg2 += 360;

double lengte = afstand(&begin_opkruisen, &doel->get()) * state["breedte"]/100.0; //lengte van de rakken

// uitrekenen

double a = fabs(verschil(ware_wind,koers_begin));

double lengte1 = lengte / sin(((double)state["minhoek"]+a) * deg2rad);

double lengte2 = lengte / sin(((double)state["minhoek"]-a) * deg2rad);

if (eerste){

//eerste rak 2x zo kort

lengte1 /= 2.0;

lengte2 /= 2.0;

//bij eerste rak kiezen welke koers het dichste bij de huidige licht

if (fabs(verschil(boeg1,kompas->get())) < fabs(verschil(boeg2,kompas->get())))

boeg = 1;

else

boeg = 2;

}

if (boeg == 1){

if (afstand(&begin_rak,&huidig->get()) > lengte1){ //als het einde van

//het rak bereikt is

eerste = 0;

boeg = 2; //ga overstag

begin_rak = huidig->get();

}

return boeg1;

}

if (boeg == 2){

if (afstand(&begin_rak,&huidig->get()) > lengte2){

eerste = 0;

boeg = 1;

begin_rak = huidig->get();

}

return boeg2;

}

}

}

69

Page 75: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

pid.h

#ifndef PID_H

#define PID_H

#include "pws.h"

#include "kompas.h"

#include "goto.h"

#include "roer.h"

#include "state.h"

#include <string>

#include <map>

class Pid{

/*working variables*/

float Input, Output, Setpoint;

float ITerm, lastInput;

float SampleTime; //0.1 sec

float outMin, outMax;

Goto * sp;

Kompas * pv;

Roer * output;

Ticker updater;

public:

Pid (Goto *, Kompas *, Roer *);

void update(void);

};

#endif

pid.cpp

#include "pid.h"

Pid::Pid(Goto * p, Kompas * k, Roer * r){

sp = p;

pv = k;

output = r;

SampleTime = 0.1; //0.1 sec

outMax = 50;

outMin = -50;

state["kp"] = 0;

state["ki"] = 0;

state["kd"] = 0;

state["schaal"] = 200;

state["pid_roll"] = 100;

updater.attach(this,&Pid::update,0.1);

70

Page 76: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

}

void Pid::update(void){

float p,i,d; //variabeles declaren die later gebruikt gaan worden

Setpoint = sp->get(); //SP ophalen

Input = pv->get(); //Koers ophalen

state["sp"] = Setpoint; //sp opslaan op een plek waar andere processen dat ook kunnen zien

if (state["roer_auto"]){ //als het roer autmoatisch bestuurd moet worden

float error = verschil(Input,Setpoint); //afwijking uitrekenen

float schaal = state["schaal"]; //Deelfactor voor de paramters uitlezen

state["error"] = error; //afwijking opslaan

ITerm += ((state["ki"] / schaal ) * SampleTime * error); //I term uitrekenen en

//optellen bij vorige I

if(ITerm > 25) //Zorgen dat de I niet te groot wordt

ITerm = 25;

else if(ITerm < -25)

ITerm = -25;

float dInput = verschil(lastInput,Input); //Afgeleide berekenen

/*Compute PID Output*/

p = (state["kp"] / schaal ) * (error + state["roll"] * 0.01 * state["pid_roll"]); //P uitrekenen

i = ITerm; //I uitrekenen

d = - ( (state["kd"] / schaal ) / SampleTime) * dInput; //D uitrekenen

Output = p + i + d; //Optellen

if(Output > outMax) //Zorgen dat de uitput niet te groot wordt

Output = outMax;

else if(Output < outMin)

Output = outMin;

lastInput = Input; //Huidig setpoint opslaan voor later

state["p"] = p; //P,I,D waardes opslaan

state["i"] = i;

state["d"] = d;

output->set( (int)Output + 50); //Roer instellen

}

}

rhumb.h

#ifndef RHUMB_H

#define RHUMB_H

//#include "route.h"

71

Page 77: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

#include "pws.h"

double afstand(pos *, pos *);

double koers(pos * , pos *);

#endif

rhumb.cpp

#include "rhumb.h"

#include <math.h>

double afstand(pos *cur, pos *tar){

double lat_cur_r = cur->lat * deg2rad;

double lon_cur_r = cur->lon * deg2rad;

double lat_tar_r = tar->lat * deg2rad;

double lon_tar_r = tar->lon * deg2rad;

double df = log(tan(lat_tar_r/2.0 + PI/4.0)/tan(lat_cur_r/2.0 + PI/4.0));

double dla = lat_tar_r - lat_cur_r;

double dlo = lon_tar_r - lon_cur_r;

double q;

if (df == 0)

q = cos(lat_cur_r);

else

q = dla / df;

double r = 6371.0;

double d = sqrt(pow(dla,2) + pow(q,2) * pow(dlo,2)) * r;

return d;

}

double koers(pos *cur, pos *tar){

double lat_cur_r = cur->lat * deg2rad;

double lon_cur_r = cur->lon * deg2rad;

double lat_tar_r = tar->lat * deg2rad;

double lon_tar_r = tar->lon * deg2rad;

double df = log(tan(lat_tar_r/2.0 + PI/4.0)/tan(lat_cur_r/2.0 + PI/4.0));

double dla = lat_tar_r - lat_cur_r;

double dlo = lon_tar_r - lon_cur_r;

72

Page 78: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

double k = atan2(dlo,df) * rad2deg;

if (k < 0)

k += 360;

return k;

}

route.h

#ifndef ROUTE_H

#define ROUTE_H

#include <iostream>

#include <string>

#include <sstream>

#include <vector>

#include "pws.h"

#include "split.h"

#include "rhumb.h"

#include "gps_wrapper.h"

#include "state.h"

#include <map>

using namespace std;

class Route{

vector<pos> waypoints;

Gps * gps;

public:

Route(Gps *);

void update(std::vector<std::string>);

string read(void);

pos get(void);

string lees(void);

};

#endif

route.cpp

#include "route.h"

Route::Route(Gps * g){

state["loop"] = 0;

73

Page 79: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

state["active"] = 0;

state["near"] = 0.003;

gps = g;

pos tmp;

tmp.lat = 1;

tmp.lon = 2;

waypoints.push_back(tmp);

}

void Route::update(std::vector<std::string> positions){

vector<pos> nieuw;

string line;

pos tmp;

int n;

for (n=1;n!=positions.size();n+=2){

tmp.lat = atof(positions[n].c_str());

tmp.lon = atof(positions[n+1].c_str());

nieuw.push_back(tmp);

}

waypoints = nieuw;

}

pos Route::get (void){

if (state["active"] > waypoints.size()-1)

state["active"] = waypoints.size() -1;

if (afstand(&gps->get(),&waypoints[state["active"]]) < state["near"]){

state["active"]++;

if (state["active"] == waypoints.size() ){

if (state["loop"])

state["active"] = 0;

else

state["active"] = waypoints.size() -1;

}

}

return waypoints[state["active"]];

}

string Route::lees(void){

stringstream ss (stringstream::in | stringstream::out);

string r;

74

Page 80: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

int n;

for (n=0;n!=waypoints.size();n++){

ss << waypoints[n].lat << " " << waypoints[n].lon << " ";

}

r = ss.str();

return r;

}

75

Page 81: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

Other

pws.h

#ifndef PWS_H

#define PWS_H

#define PI 3.14159265

#define deg2rad PI / 180.0

#define rad2deg 180.0 / PI

struct pos{

double lat;

double lon;

};

double verschil(double,double);

#endif

pws.cpp

#include "pws.h"

double verschil(double van, double naar){

double error = naar - van;

if (error > 180)

error -= 360;

if (error < -180)

error += 360;

return error;

}

split.h

#ifndef SPLIT_H

#define SPLIT_H

#include <string>

#include <vector>

#include <sstream>

std::vector<std::string> split(std::string);

#endif

split.cpp

#include "split.h"

std::vector<std::string> split(std::string str){

std::string buf;

76

Page 82: De Vliegende Hollander - Een zelfstandig varende robot ...€¦ · compass is ltered by a 5 pole Butterworth low pass lter to reduce unwanted oscillati-ons that originate from uctuations

std::stringstream ss(str);

std::vector<std::string> tokens;

while (ss >> buf)

tokens.push_back(buf);

return tokens;

}

77