Fredag 23 Aug 2019
19.8.23 22:10
GPX parser
Har spenderat några timmar senaste dagarna med att utveckla en GPX/GPS parser, har ju börjat cykla en hel del & använder endel träningsrelaterade hemsidor för att logga min träning men vore ju roligare att ha allt samlat på min hemsida också, hade inget bättre för mig just nu heller så tänkte att detta kunde vara ett kul projekt
När man använder träningsappar eller cykeldatorer som loggar GPS så kan man hämta ut en GPX fil som loggar 3 datapunkter (4:a om man är petig); latitud/longitud, m.ö.h & tidpunkt & utifrån detta kan man räkna ut nuvarande hastighet, medelhastighet, maxhastighet, distans, lutning, klättring osv osv. Min cykeldator loggar även endel extra metadata om dom är tillgängliga på rundan; temperatur, kadens, puls osv
Så, detta var egentligen inget svårt projekt, "bara" att parsa alla datapunkter & spara resultatet & beräkna mellan varje datapunkt MEN problemet är att GPS data är inte så exakt som man tror, eller jo, i 99% av fallen så är det ganska exakt men ibland görs det ganska ordentliga felmätningar som sparas så använder man bara rådatan i sin parser så kan det snabbt bli ganska fel, tex så dyker det ibland upp GPS jitter eller drift som gör att 2 mätpunkter som har 1 sekunds mellanrum kan fluktuera i distans ganska rejält, speciellt när det är dålig GPS täckning, så om GPS:en tappar täckning helt så kanske mätpunkten är 100 meter bort & är då mätningarna med 1 sekunds mellanrum så motsvarar det en hastighet på 360km/h (mitt rekord är 28'700km/h) & riktigt så snabbt cyklar jag ju inte så dessa mätvärden måste identifieras & därefter kasseras
Så efter man implementerat en parser som använder all rådata från GPS:en så måste man börja filtrera eller helt enkelt kasta bort datapunkter som har absurda värden, vissa scenarion är väldigt enkelt att identifiera men ibland dyker ett absurt scenario upp som ens filter för tillfället inte kan identifiera & så får man implementera det scenariot också & varje gång man tror man täckt in allt så laddar man upp en till GPX fil som man testar emot & så visar det sig att även den har ett absurt scenario som inte täckts
Just nu gör jag bara jämförelse mellan nuvarande datapunkt & föregående datapunkt (eller upp till 5 punkter bakåt om algoritmen börjar identifiera en "klättring"), vilket är så man får fram distans, hastighet, lutning, höjdskillnad osv & oftast är detta tillräckligt för att hitta felmätningar & absurda scenarion MEN det finns utrymme att förbättra i framtiden när jag har lust, tex att göra beräkningarna på hela block, tex om man gör ett block som är 10 mätningar långt så är det lättare att hitta avvikande datapunkter. Vill man ta det ett steg längre så kan man expandera detta till överliggande block, kör man separata block så hittar man inte felmätningar mellan sista mätningarna i första blocket & första mätningarna i andra blocket så implementerar man överliggande block så kan man även hitta dessa fel. Men det är får bli ett projekt i framtiden, att jämföra 2 (5) mätpunkter är tillräckligt exakt för tillfället
Så, algoritmen blir bara mer & mer avancerad för att kunna filtrera bort det mesta & bara spara dom datapunkterna som algoritmen anser vara korrekt. Så mer jobb än vad man först tror, att beräkna på rådatan var enkelt men väldigt missvisande så ja, det tog lite tid att hitta alla "fel", jämförde med Wahoos egna beräkningar, jämförde med Strava & kollade även på Lantmäteriets kartor för att se så att min algoritm stämmer så bra som möjligt & efter typ 20 iterationer så är Wahoo, Strava, Lantmäteriet & min parser inom några få % gentemot varandra, oftast under 1% när det gäller alla mätvärden (distans, klättring, tid, snitthastighet osv osv), eftersom jag såklart inte har tillgång till deras algoritmer så är det ju svårt att veta vad som skiljer oss emellan men våra värden är väldigt lika, skillnaden kan vara något så enkelt som avrundande värden, tex mina datapunkters beräkningar har en precision på float(6) medan dom andra kanske har en precision på 2 decimaler eller kanske bara beräknar på ints, vem vet, spelar inte så stor roll egentligen, allas värden är "fel" ändå
I början testade jag bara GPX filer som producerats av min Wahoo Elemnt Bolt & fick mätvärden inom 1% av ovanstående men sen när jag laddade upp GPX filer som skapats av en iPhone så fick jag helt absurda mätvärden, GPS:er i telefoner är tydligen extremt värdelösa, antagligen för att vara så energisnåla som möjligt & dessutom har dom ganska dåliga antenner så GPS mottagningen är relativt dålig. Så när jag upptäckte det fick jag anpassa algoritmen för iPhone datan också så som sagt, algoritmen blir bara mer & mer avancerad för att täcka in alla scenarion. En GPS enhet är sjukt mycket mer exakt & har striktare uppdaterings tidpunkter, min cykeldator har även barometer för att mäta höjdmeter så ofta har en dedikerad GPS enhet fler sensorer för att få pålitligare data, speciellt i jämförelse med en smartphone
Sen har tex Strava endel konstiga egenheter, min Bolt har också endel av dessa egenheter; tex så är deras threshold vid lutning/klättring ofta satt alldeles för låg så ofta när man cyklar på väldigt små lutningar så registreras det inte att man "klättar", det är ofta jag är ute & cyklar & det är uppenbart att jag cyklar uppför i en lutning på kanske 0.5% men dessa kastas bort av dom, ganska frustrerande, ibland kan man cykla jämte en väg, sen upp på en "påfart" & upp på en bro som är över den vägen man precis cyklade på, så säkerligen minst +6 höjdmeter men eftersom påfartens lutning var så låg så kastas dessa mätningar bort. Jag har dock valt att sätta min threshold lite lägre än vad Strava & Wahoo gör då jag anser att även om det lutar ganska lite så är det markant tyngre när man är ute & cyklar & därför tycker jag att den typen av klättring skall ingå i den totala klättringen. Det är ju inte så att min parser resulterar i mer klättring ändå då detta bara handlar om några få meter men ja...Ibland visar min totala klättring även mindre än dom andra, det beror helt på scenariot & vad man anser är "klättring":
Så vad innebär "klättring" egentligen, använder man bara rådatan från GPS:en & lägger till höjdskillnaden i sin klättrings-"pool" så kommer man få alldeles för höga siffror, tex kan GPS:en mäta ett litet gupp som har en höjdskillnad på 0.2 meter, såpass exakt är den ibland, skall man ta med ett gupp? Visst, det är en höjdskillnad MEN man har ju egentligen inte använt någon energi för att ta sig över guppet, kommer man i 30km/h så kan man säkert rulla över en 4 meter hög kulle utan att använt någon nämnvärd extra energi så i min algoritm (troligen i Stravas & Wahoos också då dessa ger snarlika resultat) måste vissa kriterier uppnås för att anses som "klättring", så små gupp & små kullar sållas bort & istället tar jag bara med backar som man faktiskt måste trampa för att kunna ta sig uppför, först då läggs höjdmetrarna i klättrings-"poolen"
Finns mycket mer att säga om detta projektet & hur alla våra plattformar hanterar GPS datan men redan nu är detta inlägget alldeles för långt så får ta en mer djupdykning om ämnet i framtiden
På #cykling går det att se resultatet av projektet. Lade till "cykel" också som utrustning för träningen så jag kan se hur långt jag cyklat på respektive cykel. Har inte hunnit lägga in så många än, när detta skrivs har jag bara hunnit fram till mitten av 2017, ett år då jag inte cyklade så mycket, 2018 cyklade jag ännu mer så det är sjukt mycket som måste laddas upp, över 250 totalt så det kommer ta ett tag, aja, har lite att göra framöver
4'421 visningar #Programmering