GPS-usikkerhed og tolerance i backendens forretningslogik

I projekt QuestGame skal en Student bevæge sig fysisk hen til forskellige QuestItems og løse dem. Mobilapplikationen kan løbende beregne afstanden til de QuestItems, der indgår i den aktuelle QuestSession, og bruge afstanden til at give spilleren visuel feedback. Et QuestItem kan eksempelvis begynde at lyse op, når spilleren nærmer sig.

Det rejste imidlertid et backendmæssigt spørgsmål: Hvem skal afgøre, om spilleren faktisk er tæt nok på til at åbne et QuestItem?

Fra klientberegning til server-side validering

Den første og simpleste løsning ville være at lade klienten håndtere hele processen. Telefonen kender spillerens GPS-position, har allerede modtaget QuestItemets lokation og kan derfor selv beregne afstanden.

Problemet er, at klienten dermed også bliver autoriteten for en central regel i spillet. En manipuleret klient kunne i princippet blot påstå, at spilleren befinder sig inden for den nødvendige afstand.

Derfor valgte vi i stedet, at klientens afstandsberegning primært skal bruges til brugeroplevelsen, mens den endelige validering sker på serveren.

Når en Student forsøger at åbne et QuestSessionItem, sender klienten blandt andet den aktuelle latitude og longitude til backend. Backend anvender derefter PostGIS til at kontrollere afstanden mellem spillerens rapporterede position og den gemte QuestSessionLocation.

Det giver en tydelig ansvarsfordeling:

Klient
→ måler position og giver løbende feedback

PostGIS
→ beregner geografisk afstand

Backend
→ håndhæver reglen om hvorvidt QuestSessionItem må åbnes

Denne opdeling var i sig selv forholdsvis ligetil. Under arbejdet opstod der dog en ny problemstilling.

GPS-positionen er ikke nødvendigvis præcis

Selv om PostGIS kan beregne afstanden mellem to koordinater korrekt, betyder det ikke nødvendigvis, at spillerens koordinat repræsenterer den præcise fysiske placering.

GPS kan være upræcis. Det kan blandt andet være tilfældet mellem høje bygninger, under tæt bevoksning eller andre steder, hvor telefonens modtagelse er dårlig.

En spiller kan derfor fysisk stå lige ved et QuestItem, mens telefonen rapporterer en position flere meter væk.

Hvis backend udelukkende bruger en hård regel som:

afstand <= 30 meter

kan en spiller blive afvist på grund af teknisk unøjagtighed, selv om vedkommende reelt står det rigtige sted.

Det ændrede min opfattelse af valideringen. En streng validering er ikke nødvendigvis en god validering. Reglen skal også passe til den kontekst, systemet anvendes i.

GPS-usikkerhed som input til forretningsreglen

Telefonens location-data indeholder normalt også et estimat for målingens præcision. Klienten kan derfor sende både position og den rapporterede usikkerhed:

{
  "latitude": 55.1234,
  "longitude": 10.1234,
  "accuracyMeters": 8
}Code language: JSON / JSON with Comments (json)

Backend kan bruge denne information som en del af valideringen.

Hvis den normale aktiveringsradius eksempelvis er 30 meter, og telefonens rapporterede GPS-usikkerhed er 8 meter, kan backend acceptere en effektiv radius på 38 meter.

Reglen bliver dermed konceptuelt:

effectiveRadius =
activationRadius + accuracyMeters

Samtidig bør der være en øvre grænse for, hvor dårlig en måling systemet vil acceptere. En GPS-usikkerhed på eksempelvis 150 meter bør ikke automatisk give spilleren en tilsvarende stor aktiveringsradius.

Backend kan derfor først kontrollere, om GPS-målingen er tilstrækkeligt præcis og frisk. Hvis den er det, anvendes usikkerheden som tolerance i afstandsvalideringen.

På den måde ligger beslutningen stadig på serveren. Klienten rapporterer målingen, men bestemmer ikke selv, om QuestSessionItem må åbnes.

Validering handler også om brugeroplevelse

Arbejdet gjorde det tydeligt for mig, at backendens forretningslogik ikke kun handler om sikkerhed og strenge regler.

QuestGame er ikke et system, hvor en geografisk grænse skal fungere som fysisk adgangskontrol. Det er et bevægelsesbaseret spil til blandt andet skoleelever, og oplevelsen skal være forholdsvis afslappet og venlig.

Hvis en Student fysisk står ved den rigtige post, er det dårligere for spiloplevelsen at afvise vedkommende på grund af GPS-drift end at acceptere en spiller, der måske står enkelte meter længere væk end den nominelle radius.

Det betyder, at en vis tolerance ikke er en fejl i valideringen. Den er en bevidst del af forretningsreglen.

En meget streng radius kunne teknisk set gøre valideringen mere restriktiv, men samtidig gøre systemet mindre robust over for den virkelighed, det skal fungere i.

Konklusion

Jeg startede med at betragte afstandsvalideringen som en forholdsvis simpel regel: Spilleren skulle være inden for en bestemt radius, og backend skulle kontrollere dette ved hjælp af PostGIS.

Arbejdet viste, at problemet også omfatter kvaliteten af de inputdata, backend modtager.

Backend kan kontrollere den rapporterede position, men kan ikke gøre GPS-signalet mere præcist. Derfor skal forretningsreglen tage højde for den usikkerhed, som følger med GPS-målingen.

I QuestGame har vi derfor valgt en relativt tolerant model, hvor den rapporterede GPS-præcision kan udvide aktiveringsradius inden for en fastsat grænse. Samtidig afvises målinger, der er for upræcise eller for gamle.

For mig er den vigtigste læring, at god backendvalidering ikke nødvendigvis betyder den strengest mulige regel. Valideringen skal understøtte systemets formål. I et afslappet, bevægelsesbaseret spil er det vigtigere at håndtere naturlig GPS-usikkerhed på en robust og brugervenlig måde end at håndhæve en geografisk grænse med unødvendig hårdhed.

Implementeringen af backendvalidering giver desuden mulighed for, på et senere tidspunkt, at tilføje ekstra validering og antisnyde-foranstaltninger, der f.eks. kan forebygge GPS-spoofing eller brug af hurtige transportmidler som bil eller cykel til at snyde sig færdig med spillet.