Skip to content

Refleksjon rundt prosjektet

Simon Konglevoll Lønnestad edited this page Dec 8, 2019 · 7 revisions

Rent teknisk har dette prosjektet vært både utfordrende og lærerikt. Til å begynne med er Arduino noe helt nytt for oss; noe vi aldri har utviklet med tidligere. Dette innebar med andre ord å sette seg inn i både hvordan en Arduino opererer, men også selve programmeringsspråket (C++).

Når det kommer til implementasjonen vår i Arduino så måtte vi først og fremst sette oss inn i hvordan tilkoble den til nettverk. Av åpenbare grunner måtte vi velge å tilkoble til internett via WiFi. På grunn av valget av hvilken Arduino vi bruker har vi ikke trengt å lodde fast en WiFi modul (ESP8266), noe som har spart oss for ekstra arbeid. Siden dette er et Arduino prosjekt så finnes det mange åpne og tilgjengelige biblioteker for hvordan koble seg til nettverk, så dette viste seg å ikke være problematisk.

Akselerometeret vi har benyttet har også tilgjengelige biblioteker for oppsett, så vi slet heller ikke med å få satt opp denne. Vi hadde derimot problemer med selve loddingen av denne enheten, men etter litt prøv-og-feil fikk vi det til. Når det gjelder selve implementasjonen av den kodemessig benyttet vi enkle metoder som hører med biblioteket vi har benyttet. Strengt tatt trengs det ikke avansert funksjonalitet for å få registrert bevegelse, men det som var mer utfordrende var å konfigurere akselerometeret til å reagere på de riktige verdiene. Det vil si hvor mye kraft må til for at den skal registrere det vi vil. Ideelt sett ønsket vi å oppnå den verdien for når et «ekte kast» hadde blitt registrert, men dessverre kom vi aldri så langt som å anskaffe oss en ball. Dette medførte at vi kun har brukt en midlertidig verdi for testing av prosjektet.

Etter at Arduino’en klarte å tilkoble til nettverk og registrere bevegelse måtte vi videre til å implementere kjernefunksjonaliteten i prosjektet; å generere en Pokémon. Rent teknisk er ikke det så vanskelig; det skal genereres en tilfeldig ID for en Pokémon.

Utfordringene startet når selve kommunikasjonen mellom Arduino’en, API’et og databasen måtte iverksettes. Til å begynne med utforsket vi muligheten å hente data direkte fra PokéAPI.

Den første utfordringen vi støtte på var å sette opp en kommunikasjon mellom Arduino og PokéAPI (og hvilken som helst HTTP-server). Det resulterte bare i HTTP feilmeldinger alt ut ifra hvordan vi sendte requestet. Det første forsøket fikk vi HTTP 403 feilmelding. Etter litt undersøkelser og analysering av hvordan pakkene ble sendt til PokéAPI viste det seg at PokéAPI klarte å forstå requestet, men den nekter å autorisere oss (Ref. https://tools.ietf.org/html/rfc7231#section-6.5.3). Dette har med at PokéAPI ikke klarer å tolke Arduino’en som en «gyldig» klient.

En enkel løsning på dette var å putte inn en parameter brukt i HTTP requests kalt User-Agent. Kort fortalt tillater User-Agent parameteren serveren som mottar HTTP requestet å identifisere klienten. Vi mistenker at dette er for å styrke forsvaret mot potensielle DDOS angrep.

Deretter hadde vi en del trøbbel med HTTP 400. Denne er ganske enkel å forstå; kort fortalt betyr det at HTTP requestet vårt er ikke satt opp riktig. Det er derimot vanskelig å diagnostisere. Det kan være alt fra ett mellomrom for mye til å ha en ugyldig parameter. Det viste seg i vårt tilfelle at klienten vi bruker for å spørre PokéAPI ikke bruker SSL kryptering (HTTPS). For at kommunikasjon mellom to enheter skal bli satt så må klienten støtte SSL dersom serveren gjør det. Dette var en relativt lett løsning siden biblioteket vårt for WiFi kommunikasjon støtter nettopp SSL; man må bare definere det. Dette gjør man i koden gjennom to enkle steg: første endre fra WiFiClient til WiFiSSLClient, også må porten som trafikken skal gå gjennom endres fra standard porten til HTTP server 80 endres til porten for SSL trafikk 443.

Utklipp av feilmelding HTTP 400

Etter å ha klart å sette opp ett riktig HTTP request (med SSL) klarte vi å kommunisere med PokéAPI. Men på grunn av de tekniske begrensingene med Arduino i forhold til minne, så viser det seg at Arduino ikke klarer å innhente så mye data som PokéAPI responderer med. Alt ettersom hvilket aksesspunkt vi prøver å «requeste», så returnerer PokéAPI med for mye data for det aksesspunktet vi trenger, og Arduinoen rebooter av seg selv som en naturlig respons til overflødig minne. Dette medførte til at vi måtte ta et valg mellom to alternativer: enten «scrape» all data fra PokéAPI og lagre i en database, eller lage et egendefinert API som «speiler» data fra PokéAPI. Av relativt åpenbare grunner valgte vi å lage et egendefinert API på grunn av at først og fremst så vet vi ikke nødvendigvis hvilken data vi trenger, og for det andre så hadde vi endt opp med altfor mye data for databasen dersom vi skulle hentet all data fra PokéAPI.

Dette medførte til at vi måtte sette oss inn i hvordan sette opp ett API. Med den tidligere kunnskapen i PHP kunne vi allerede sette opp en webserver som hoster dette API’et. I tillegg med kunnskapen vi har fått tidligere med hvordan HTTP servere fungerer, så vet vi at vi må definere hvilken datatype som representeres på webserveren. Dette gjøres gjennom parameteret Content-Type, og er vitalt for at PHP skal forstå at det er JSON data som returneres fra PokéAPI, og ikke vanlig klartekst. Uten dette parameteret hadde ikke PHP klart å «parse» data fra API’et. I tillegg er det også viktig å definere at dette aksesspunktet har JSON data. Uten dette hadde ikke Arduino klart å dekode dataen som den henter, noe som vi fant ut av senere.

Det vi derimot måtte finne ut av var å først og fremst hvordan hente data fra PokéAPI, og for det andre vise data fra PokéAPI.

I utgangspunktet var ikke dette rent teknisk vanskelig. PHP har allerede innebygget metoder for å både dekode JSON data, og kode JSON data, så det var null problemer med å hente og vise data fra PokéAPI. Til å begynne med siden dette var ett nytt felt har vi valgt å hente en balansert mengde med data for det prosjektet krever. Utfordringen derimot var å sette oss inn i hvordan Arduino kan håndtere JSON data.

Etter at det lokale API aksesspunktet var satt opp, kunne Arduino hente data fra den med null problemer. Det viste seg derimot at Arduino ikke har noen måte å dekode JSON data på, så vi klarte ikke å hente ut de variablene vi trengte. Løsningen var relativ enkel; Arduino har et bibliotek for å dekode JSON data.

Etter å ha inkludert dette biblioteket kunne vi lese data problemfritt. Dette medførte til at vi nå kunne komme så langt som å:

  • Bevege på Arduino; registrere bevegelse
  • Generere en tilfeldig ID
  • Hente data fra lokalt API om Pokémon ut ifra ID *Bruke data for å regne ut om den blir fanget eller ikke

Neste utfordring er altså å sende data til database. Slik vi har lært av Arduino og Arduino prosjekter generelt så vet vi at det finnes biblioteker for nesten alt, og selvfølgelig var det et bibliotek for å tillate støtte mellom Arduino og MySQL databaser.

Dette var også en relativt lett prosess. Man må ha en WiFi klient for å kommunisere mellom Arduino og database. Siden vi allerede hadde en WiFi klient for å kommunisere mellom Arduino og API’et, så ønsket vi å bruke denne. Dette viste seg derimot å ikke fungere; vi endte bare opp med at når Arduino’en skulle koble seg til databasen så satt den fast i en evig loop.

Rent teknisk vet vi ikke hvordan det ble forårsaket, men vi vet hvorfor. MySQL biblioteket til Arduino støtter ikke WiFi klienter som krypteres med SSL. Siden vi er nødt til å ha SSL kryptering for å kommunisere med API’et, så var eneste løsning å lage en egen klient for MySQL.

Dette gikk smertefritt, og vi fikk kommunisert med databasen. Dette inkluderte å hente data og sende data, og ingen nye problemer oppsto. Med andre ord, vi klarer nå å fange Pokémon!

Utklipp av en vellykket fangst


I etterkant av prosjektet så viste det seg at TDD var en passende utviklingsmetode i forhold til hvordan prosjektet ble gjennomført. Om vi skulle gjort prosjektet på nytt så ville vi planlagt det litt forskjellig, og antakelig tatt i bruk Scrum. Med det vi har lært så kunne vi gjennomført prosjektet på en måte som lar oss ende opp med mer omfattende funksjonalitet. Som å ha en mobilapplikasjon som brukergrensesnitt. Og da hadde det vært svært passende å ta i bruk Scrum, ettersom det hadde vært flere deler av prosjektet som vi kunne arbeidet på samtidig, for å ha en mer koordinert utvikling.

Vi har fått mer erfaring og kunnskap innen spillutvikling som følge av prosjektet. Spilleavhengighet er reell tilstand og har blitt klassifisert som en psykisk lidelse. Dermed er det vårt ansvar som spillutviklere å designe spillet vårt på en måte som kan bidra til å begrense hvor utsatte spillerne våre kan være i forhold til spillavhengighet, samtidig som at det ikke går utover opplevelsen til en gjennomsnittlig spiller som ikke har dette problemet. Det er dermed noe vi tar med oss videre. Vi har også blitt flinkere på å tenke sikkerhet når det gjelder programvare. Ikke bare i forhold til angripere som ønsker å stjele verdifull informasjon som de potensielt kan tjene penger på, men også innenfor en situasjon der en gjennomsnittlig spiller som bare vil ha et lite fortrinn; med andre ord jukse.