10. joulukuuta 2010

Projekti: GPSBot osa 2

Edellisessä osassa kerroin GPS-robottiautoprojektin rautapuolesta. Tällä kertaa käsitellään softaa ja sen kirjoittamisen aikana vastaan tulleita haasteita.

Missä mennään?
Päätin aloittaa projektin yhdistämällä Garminin GPS-vastaanottimen Arduinoon. Garminin mukana tuli perinteinen DE-9-sarjaliikennekaapeli, joten arvelin sen liittämisen olevan helppoa. Yllättävksi ongelmaksi osoittautui pinnijärjestyksen selvittäminen, mistä ei tuntunut löytyvän minkäänlaista yhteisymmärrystä googlauksen perusteella. Ainoastaan maapinni tuntui olevan kaikilla suunnilleen samassa paikassa. Koululla oli varastossa DE-9-liittimen vastakappaleita, joten otin sellaisen ja päätin selvittää oikeat pinnit kokeilemalla. Noin puolen tunnin askartelun jälkeen sain luettua sarjaliikennedataa Arduinoon.

Datan lukeminen luotettavasti olikin sitten eri juttu. Minulla meni pitkään kirjoittaa sellainen sarjaliikenteenlukualgoritmi, mikä ei yli- tai alivuotaisi jossain vaiheessa.

Seuraavaksi oli vuorossa datan parsiminen. Otin jälleen googlen kauniiseen käteen ja aloin selvittämään olemassa olevia implementaatioita Arduinolle. Pian selvisi, että alan de facto on NMEA, mutta siinä oli kuitenkin minun sovelluksen kannalta useita ongelmia.

  • useita viestilauseita parsittavaksi, 8-13 laitteesta riippuen
  • lauseet sisältävät päällekkäistä dataa
  • eri laitteet lähettävät eri lausekokoelmaa
  • saadakseni kaiken haluamani tiedon minun pitäisi parsia ainakin kolmea eri lausetta
  • lauseiden pituus vaihtelee datan sisällön mukaan
Vaihtoehdoksi NMEA:lle löysin Garminin oman Text Out -moodin. Vaikka tuntui arveluttavalta tehdä parseri tietyn valmistajan omalle viestimuodolle, mikä välttämättä ei olisi siirrettävissä laitteesta toiseen, niin Garminin Text Outin edut olivat kiistattomat. Ensinnäkin lauseita oli vain yksi ja se alkaa @-merkillä, mikä teki lauseen alun etsimisestä helppoa ja tuo yksi lause sisälsi kaiken tarvitsemani tiedon. Toiseksi lauseet olivat taatusti aina 52 merkkiä pitkiä, mikä sekin helpotti niiden lukemista. Kolmanneksi data päivittyi kerran sekunnissa, toisin kuin NMEA mikä päivittyi vain kahden sekunnin välein. Jos saisin nopean auton, niin tällä voisi olla merkitystä.

Parserin kirjoittaminen tämän jälkeen oli melko suoraviivainen homma, joskin yhteen mielenkiintoiseen ongelmaan törmäsin matkalla. Päätin tallentaa luokan sisällä koordinaatit long-tyyppiseen muuttujaan muotoon (d)ddmmmmm siten, että kolme viimeistä numeroa ovat minuuttien desimaaliosa.



Huomaa rivillä viisi, miten luku 10000 pitää pakottaa long-tyyppiseksi. Muuten jos siinä indeksissä oleva numero on suurempi kuin kolme, niin tapahtyy int-muuttujan ylivuoto ja koorinaatit menevät sekaisin. Tämän kanssa jouduin painiskelemaan hyvän tovin ennen kun se löytyi. Debuggeriahan ei Arduino IDE:n mukana tule.

Ollaanko perillä jo?
Maapallo (taiteilijan näkemys)
Koordinaattien välisten etäisyyksien laskeminen osoittautui mielenkiintoiseksi ongelmaksi. Kuvaa katsomalla helposti ymmärtää, että vaikka leveyspiirit ovat melko lailla saman mittaisia sijainnista riippumatta, niin pituuspiirien pituus vaihelee suuresti riippuen siitä miten kaukana päiväntasaajasta ollaan. Wikipedia on omistanut kokonaisen artikkelin erilaisten algoritmien esittelemiseen ongelman ratkaisemiseksi. Ne ovat kuitenkin mikroprosessoreilla melko raskaita, eivätkä silti kovin tarkkoja. Pohdin ongelmaa ääneen jollain Arduino-aiheisella IRC-kanavalla ja sain mielenkiintoisen kommentin. Muistista vapaasti suomentamalla sen sisältö oli suunnilleen "Tässä taas nähdään ero fyysikon ja insinöörin välillä. Fyysikko yrittää tehdä yhden lauseen, millä voisi ratkaista ongelman koko maapallon tapauksessa ja mielivaltaisilla etäisyyksillä, kun insinööri vain yksinkertaisesti laskee pituuspiirin pituuden määränpään läheisyydessä ja laskee siitä Pythagoraan lauseen avulla. Se on tarpeeksi tarkka, jos etäisyys ei ole suuri.".


Kommentoija osui naulan kantaan. Olinhan entinen fysiikan opiskelija ja vasta aloittanut opiskelemaan insinööritieteitä ja siksi ajattelumallini oli todellakin väärä. Vastauksen ei tarvitse olla yleispätevä eikä pedantti, kunhan se toimii sovelluksen tapauksessa riittävän hyvin. Wikipediasta löytyi yksinkertainen kaava pituuspiirin mitan laskemiseksi ja sen jälkeen etäisyyden laskeminenkin muuttui peruskoulumatematiikaksi.

Minne nenä näyttää?
Nyt robottini tiesi missä se on ja milloin se on perillä. Seuraavaksi pitäisi tietää mihin suuntaan pitää kääntyä, että oltaisiin menossa oikeaan suuntaan. Tämä oli ehkä koko projektin haastavin probleema. Aluksi olin ajatellut laskea nopeuden GPS:n antamasta datasta. Sen mukana tuli kaksi nopeuskomponenttia desimetrin sekuntivauhdin tarkkuudella. Siitä trigonometriaa soveltamalla saisi helposti suunnan laskettua. Teoriassa. Osoittautui, että robottiautoalustani ei ollut nopeimmasta päästä. Sen nopeus on vain pari senttiä sekunnissa, joten GPS:n antaman nopeuden erottelutarkkuus ei riittänyt suunnan laskemiseen. Seuraavaksi päätin laskea suunnan auton liikkuessa koordinaattien muutoksesta. GPS-paikkatiedon kohina oli kuitenkin aivan liian suuri ja mittavien tutkimusten jälkeen tulin siihen tulokseen, että luotettavan suutatiedon saamiseksi robotin olisi pitänyt ajaa aina samaan suuntaan minuuttitolkulla kerrallaan. En olisi halunnut hankkia erillistä kompassimodulia, koska se lisäisi koko auton kompleksisuutta sekä rauta- että softapuolella, muuta näytti siltä, että vaihtoehdot olivat vähissä.

Hitachi HM55B -kompassimoduli
Tilasin koulun piikkiin Hitachin HM55B-kompassimodulin ja aloin etsimään sille ajuria. Käyttäjä nimeltä kiilo oli julkaissut Arduino-saitilla artikkelin kyseisen modulin käyttämisestä Arduinon kanssa, joten otin hänen koodinsa oman ajurini pohjaksi. Pian selvisi, että kompassin kohina oli jotain aivan käsittämätöntä. Välillä mittasin jopa 60° heittoja sen antamassa signaalissa kun robotti oli paikallaaan pöydällä. En ymmärtänyt ihan täysin kiilon kirjoittamaa koodia, joten vian etsiminen oli melko epätoivoista. Toisaalta muut käyttäjät kertoivat saaneensa omansa toimimaan samalla koodilla modulin kalibroinnin jälkeen. Kalibointi vaati kuitenkin Windowsin käyttämistä, joten en harkinnut sitä vakavissani. Turhauduin kuukausiksi kompassin epäluotettavuuden vuoksi. Palasin aina tauon jälkeen tuoreilla silmillä tarkastelemaan koodia ja etsimään vikaa. Huomasin, että kompassin koodi toimi erillisenä ohjelmana melko hyvin, mutta yhdistettynä auton koodiin se meni sekaisin. Lopulta tulin siihen tulokseen, että kyse on pakko olla jostain ajoituksista. Turhautuneena päätin vain alkaa mukiloimaan auton ja kompassin koodia muuttelemalla viiveitä kunnes kompassi alkaisi toimia. Hämmästyksekseni metodi toimi. Sitten aloin poistamaan tekemiäni muutoksia yksi kerrallaan selvittääkseni, mikä oli se maaginen rivi, mikä sen korjasi. Lopulta olin mielestäni poistanut kaikki muutokset, mutta kompassi toimi silti! Edessä oli koeajo.



Tätä juttua varten päätin siistiä ja julkaista kaiken autoon kirjoittamani koodin. Se on nyt kaikkien ihailtavissa Gitorious-repossani.

Ei kommentteja:

Lähetä kommentti