Ik heb een app gemaakt voor op mijn Garmin sporthorloge.
In deze app zie ik de tijd, hartslag, tijdsduur training.
Tevens kan deze app het trainingschema weergeven zodat ik geen papieren schema bij me hoef te hebben of het uit mijn hoofd te leren.
Middels de GPS functie wordt de training samen met de overige sensor gegevens in een activity vastgelegd zodat dit naar Gamin Connect en Strava kan.
Ronde tijden vastleggen ging tot nu toe door handmatig op de lap button te drukken, maar dit zou ook automatisch moeten kunnen dacht ik.
auto lap
Ik heb nagedacht en gezocht naar manieren waarop ik deze functie zou kunnen uitwerken.
Uiteindelijk heb ik 3 varianten bedacht en 1 hiervan redelijk werkend gekregen.
Optie 1: heb ik voorlopig als niet haalbaar gemarkeerd doordat het eigenlijk onmogelijk is om 2 exact matchende GPS locaties te hebben door de afwijkingen in GPS en de snelheid waarmee bewogen wordt.
Optie 2: Dit lijkt mij de meest nauwkeurige methode, echter heb ik geen idee hoe ik de virtuele finishlijn kan berekenen om zo te controleren of ik de lijn passeer.
Optie 3: Deze optie heb ik vrij eenvoudig uit kunnen werken tot een werkende versie. Ik heb deze optie nu een aantal keren gebruikt en moet zeggen dat het goed werkt maar ik heb het idee dat het iets nauwkeuriger zou kunnen. Heel af en toe wordt er een ronde gemist en de afstand van de ronden is nogal wisselvallig waardoor de rondetijden eigenlijk ook geen waarde hebben.
Op de baan van 333m varieren de ronde afstanden tussen de 300 en 380 m.
Werkende functie
Hieronder de code welke ik nu gebruik voor het detecteren van de Auto Lap. Geen hoogstaande code maar het werkt wel.
Optimalisatie
Het werken en rekenen met GPS is nieuw voor mij, en ik merk dat mijn wiskunde knobbel hiervoor niet genoeg is ontwikkeld en ik dus nog het een en ander bij moet leren.
Zijn er mensen wie wellicht optimalisaties zien waardoor mijn bestaande functie nauwkeuriger werkt of wellicht weten hoe ik de lap detectie beter vorm kan geven?
In deze app zie ik de tijd, hartslag, tijdsduur training.
Tevens kan deze app het trainingschema weergeven zodat ik geen papieren schema bij me hoef te hebben of het uit mijn hoofd te leren.
Middels de GPS functie wordt de training samen met de overige sensor gegevens in een activity vastgelegd zodat dit naar Gamin Connect en Strava kan.
Ronde tijden vastleggen ging tot nu toe door handmatig op de lap button te drukken, maar dit zou ook automatisch moeten kunnen dacht ik.
auto lap
Ik heb nagedacht en gezocht naar manieren waarop ik deze functie zou kunnen uitwerken.
Uiteindelijk heb ik 3 varianten bedacht en 1 hiervan redelijk werkend gekregen.
- Controleer of de GPS positie van het horloge matched met de GPS positie van het startpunt van de ronde
- Trek op het startpunt van de ronde een virtuele finishlijn en controleer of de GPS positie van het horloge deze lijn doorkruist
- Controleer de afgelegde afstand in de huidige ronde en kijk wat de afstand is tussen Horloge en start positie. Zodra de afgelegde afstand >= min afstand en de afstand tussen het horloge en het startpunt aan het vergroten is tov het vorige punt een ronde markeren.
Optie 1: heb ik voorlopig als niet haalbaar gemarkeerd doordat het eigenlijk onmogelijk is om 2 exact matchende GPS locaties te hebben door de afwijkingen in GPS en de snelheid waarmee bewogen wordt.
Optie 2: Dit lijkt mij de meest nauwkeurige methode, echter heb ik geen idee hoe ik de virtuele finishlijn kan berekenen om zo te controleren of ik de lijn passeer.
Optie 3: Deze optie heb ik vrij eenvoudig uit kunnen werken tot een werkende versie. Ik heb deze optie nu een aantal keren gebruikt en moet zeggen dat het goed werkt maar ik heb het idee dat het iets nauwkeuriger zou kunnen. Heel af en toe wordt er een ronde gemist en de afstand van de ronden is nogal wisselvallig waardoor de rondetijden eigenlijk ook geen waarde hebben.
Op de baan van 333m varieren de ronde afstanden tussen de 300 en 380 m.
Werkende functie
Hieronder de code welke ik nu gebruik voor het detecteren van de Auto Lap. Geen hoogstaande code maar het werkt wel.
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
| function autoLAP (pos1, pos2) { // pos1 = coordinaat waarop de eerste ronde is gestart en dus ook het punt waarop iedere ronde geteld moet worden (finishlijn) // pos2 = huidige positie op de ronde var lat1, lat2, lon1, lon2, lat, lon; var dx, dy, distance; lat1 = pos1.toDegrees()[0].toFloat(); lon1 = pos1.toDegrees()[1].toFloat(); lat2 = pos2.toDegrees()[0].toFloat(); lon2 = pos2.toDegrees()[1].toFloat(); var currCoordDist = distanceInKmBetweenEarthCoordinates(lat1, lon1, lat2, lon2); lat = (lat1 + lat2) / 2 * 0.01745; dx = 111.3 * Math.cos(lat) * (lon1 - lon2); dy = 111.3 * (lat1 - lat2); distance = 10 * Math.sqrt(dx * dx + dy * dy); var info = Activity.getActivityInfo(); // activity info var LapDetectDistCurr = info.elapsedDistance; // totaal afgelegde afstand tot nu toe var LapDistDiff = LapDetectDistCurr - LapDetectDist; // afgelegde afstand sinds vorige ronde var gpsinfo = Sensor.getInfo(); var refDistance = 0.02; // afstand tot lap 0-punt moet kleiner zijn dan 20 meter if (gpsinfo has :speed){ var tmpSpeed = gpsinfo.speed; // snelheid in m/s refDistance = tmpSpeed / 1000; // snelheid ik km/s } // wanneer de afgelegde afstand groter is dan 250 m // en de afstand van lap basepoint tot curr location < referentie snelheid // lap recorden if(currCoordDist < refDistance && LapDistDiff >= 250){ if(currCoordDist < prefCoordDist){ // afstand tot 0-punt wordt nog kleiner dus we zijn nog bezig aan onze ronde prefCoordDist = currCoordDist; activeLap = true; } else { // lijkt of we aan een nieuwe ronde beginnen activeLap = false; LapDetectDist = LapDetectDistCurr; session.addLap(); // ronde toevoegen aan de sessie } } else if(activeLap == true){ activeLap = false; // wanneer we hier belanden is er een grote kans dat we een lap te pakken hebben wie gemist is hierboven LapDetectDist = LapDetectDistCurr; session.addLap(); // ronde toevoegen aan de sessie } } function degreesToRadians(degrees) { return degrees * Math.PI / 180; } function distanceInKmBetweenEarthCoordinates(lat1, lon1, lat2, lon2) { var earthRadiusKm = 6371; var dLat = degreesToRadians(lat2-lat1); var dLon = degreesToRadians(lon2-lon1); lat1 = degreesToRadians(lat1); lat2 = degreesToRadians(lat2); var a = Math.sin(dLat/2) * Math.sin(dLat/2) + Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2); var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); return earthRadiusKm * c; } |
Optimalisatie
Het werken en rekenen met GPS is nieuw voor mij, en ik merk dat mijn wiskunde knobbel hiervoor niet genoeg is ontwikkeld en ik dus nog het een en ander bij moet leren.
Zijn er mensen wie wellicht optimalisaties zien waardoor mijn bestaande functie nauwkeuriger werkt of wellicht weten hoe ik de lap detectie beter vorm kan geven?