[Garmin iQ] AutoLap op basis van GPS

Pagina: 1
Acties:

Vraag


Acties:
  • +1 Henk 'm!

  • skate master
  • Registratie: September 2004
  • Laatst online: 02-10 16:22

skate master

Autodesk Educator Expert

Topicstarter
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.
  1. Controleer of de GPS positie van het horloge matched met de GPS positie van het startpunt van de ronde
  2. Trek op het startpunt van de ronde een virtuele finishlijn en controleer of de GPS positie van het horloge deze lijn doorkruist
  3. 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.
Uitwerking opties
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?

Alle reacties


Acties:
  • 0 Henk 'm!

  • Knutselsmurf
  • Registratie: December 2000
  • Laatst online: 10:50

Knutselsmurf

LED's make things better

Je hoeft bij optie 1 toch niet een exacte match te hebben?

Als je een cirkel om je startpunt heen trekt, kun je detecteren wanneer je weer binnen die cirkel komt. Als je weer terug bent in die cirkel, heb je een rondje gehad. Vervolgens moet je weer naar buiten de cirkel gaan voordat de volgende ronde geteld kan worden.

Je berekent continu de afstand tot het beginpunt en tussendoor moet je een aantal vlaggetjes bijhouden. Na het starten van een ronde moet de afstand bijvoorbeeld langer dan een aantal seconden groter zijn dan X meter. Dit om te voorkomen dat er extra rondes geteld worden terwijl je op je startpunt rondhangt. Als dat sein op groen staat, kijk je of de afstand tot het startpunt kleiner is dan Y meter. Zo ja, dan heb je een rondje gehad en kun je opnieuw beginnen.

Je hoeft dan dus niet te rekenen met de totale afgelegde afstand, maar je hoeft alleen de afstand tot je start- of referentiepunt in de gaten te houden.

Ik neem aan dat je in je GPS-data ook de nauwkeurigheid van het signaal kunt zien? Dan kun je de afstanden X en Y daar nog van af laten hangen.

- This line is intentionally left blank -


Acties:
  • 0 Henk 'm!

  • skate master
  • Registratie: September 2004
  • Laatst online: 02-10 16:22

skate master

Autodesk Educator Expert

Topicstarter
@Knutselsmurf ik ga eens kijken naar jou idee.
Waar ik nog even mee zit is welke afstand ik moet aanhouden tussen startpunt en device.
Bij een te kleine afstand is er de kans dat er niet geregistreerd wordt en bij een te grote is de registratie te vroeg.

Denk dat ik maar eens een paar testritjes moet maken om de afstand uit te vogelen.

Acties:
  • 0 Henk 'm!

  • Knutselsmurf
  • Registratie: December 2000
  • Laatst online: 10:50

Knutselsmurf

LED's make things better

Alt je de metingen van eerdere activiteiten hebt, kun je deze natuurlijk gebruiken om je algoritme te testen en die drempelwaarden te finetunen.

- This line is intentionally left blank -


Acties:
  • 0 Henk 'm!

  • Moofnor
  • Registratie: April 2010
  • Laatst online: 07:53

Moofnor

King of my castle

Je zou ook nog zowel het eerste als laatste punt binnen de buffer kunnen registreren en hier de gemiddelde tijd van nemen. Bij een beetje constante beweging zou dit in de buurt van de finish moeten zijn.

- I can accurately say I was born on Earth, but it's not very precise. I can precisely say I was born at latitude 37.229N, longitude 115.811W, but that is not at all accurate - Matt Parker


Acties:
  • 0 Henk 'm!

  • Matis
  • Registratie: Januari 2007
  • Laatst online: 08:08

Matis

Rubber Rocket

Ik waardeer je nauwkeurigheid om in je berekening rekening te houden met de kromming van de aarde, maar dat gaat op zo'n stukje echt 0 verschil maken.

Je zou kunnen kijken naar LERP tussen twee GPS coördinaten en die virtuele lijn kunnen gebruiken om optie 1 uit te werken. Je zult altijd een kleine bandbreedte/marge moeten houden, maar ik denk dat dat de meest betrouwbare resultaten geeft.

If money talks then I'm a mime
If time is money then I'm out of time

Pagina: 1