Vor wenigen Jahren glichen tragbare GPS-Geräte noch Mobiltelefonen der frühen 90er. Heute brauchen Sportler keinen Ballast mehr mit sich zu schleppen, denn Geräte wie der Garmin Forerunner 10 [2] sind auf die Größe einer LED-Digitaluhr aus den 70ern geschrumpft (Abbildung 1). Das Sportleraccessoire zeichnet während eines Jogginglaufs die Ortskoordinaten auf.
So erfährt der Läufer, wie schnell er momentan unterwegs ist und ob er zulegen muss oder nachlassen darf, um ein gestecktes Zeitziel zu erreichen. Nach abgeschlossener Muskelaktivität kann er dann hoffentlich genussvoll neue Geschwindigkeitsrekorde verbuchen, auf einer Landkarte die abgespulten Kilometer Revue passieren lassen oder ein Höhenprofil der Strecke bestaunen.
Mein unter Ubuntu in den USB-Eingang eingestöpseltes Gerät erkennt der Linux-Kernel sofort als Speichereinheit und mountet die auf dem Gerät gespeicherten Dateien unter »/media/GARMIN«
. Dazu benötige ich allerdings ein spezielles Adapterkabel, das sich wie eine Kreatur aus dem Film "Alien" an die GPS-Uhr anschmiegt und dem Gerät beim Kauf beliegt. Im Verzeichnis »GARMIN/ACTIVITY«
findet der Linuxer FIT-Dateien, in denen die Herstellerfirma Bewegungsaktivitäten in einem proprietären Binärformat speichert.
Solche Dateien kann der Sportler unter einem neu angelegten Account auf die Garmin-Website http://connect.garmin.com hochladen und bekommt dort die Laufdaten schön präsentiert (Abbildung 2). Das Beispiel zeigt eine etwa 7 Kilometer lange Route rund um den Lake Merced, einen Binnensee nahe des pazifischen Ozeans etwas südlich von San Francisco, die ich für den Perl-Snapshot in etwa 40 Minuten gerannt bin.
Zu bestaunen sind an der Grafik nicht nur die Gesamtzeit, sondern auch die durchschnittliche Zeitdauer pro Meile (8:45 Minuten) und die überwundenen Höhenmeter (300 Fuß). Wer keine amerikanischen Einheiten mag, kann auf der Website natürlich auch Kilometer und Höhenmeter einstellen.
Abbildung 1: Der armbanduhrgroße GPS-Empfänger zeichnet beim Joggen die Geokoordinaten der zurückgelegten Strecke mit Zeitstempeln auf.
Abbildung 2: Auf die Webseite Connect.garmin.com darf der Sportler seine FIT-Daten hochladen und grafisch aufbereiten lassen.
Der 6-Sekunden-Takt
Das GPS-Gerät ermittelt etwa alle 6 Sekunden die Position des Läufers mit Hilfe erdumkreisender Navigationssatelliten und speichert die Datenpunkte in geografischer Breite und Länge ab. Außerdem misst es die aktuelle Geschwindigkeit und die zurückgelegte Strecke.
Das Garmin 10 zeichnet übrigens – anders als andere GPS-Geräte – während des Laufs nicht die aktuelle Höhe über Normalnull auf, anscheinend ist deren Bestimmung recht aufwändig. Aber die Garmin-Webseite füllt diese topografische Lücke im Bewegungsprofil anhand der Geokoordinaten mühelos auf, denn sie nutzt ein Server-seitig statisch vorliegenden Höhenprofil, das wohl für alle bewohnten Punkte der Erde deren Höhe über dem Meeresspiegel weiß. Wer nicht gerade in einem Hochhaus die Treppen hochläuft, erhält präzise Höheninformationen zur Laufstrecke.
Selbst ist der Mann
Aber selbst die schönste Webseite lässt sich noch verbessern, manch einer möchte die Daten gar für esoterisch anmutende Zwecke ummodeln. Damit Open-Source-Freunde das Format nicht mühselig entschlüsseln müssen, liegt unter [3] das Garmin-SDK vor. Es definiert zwar kein Perl-API, dokumentiert aber doch alle verwendeten Felder.
Der Entwickler Kiyokazu Suto hat anhand der Informationen ein Perl-Modul [4] unter einer Public-Domain-artigen Lizenz gebaut, es bislang allerdings nicht aufs CPAN hochgeladen. Garmin::FIT kann jedenfalls FIT-Datei lesen, die Abbildung 3 zeigt beispielhaft, wie das dem Modul beiliegenden Utiliy »fitdump«
Daten ausspuckt.
Trotz offengelegten Formats erweist sich das Herausfieseln der Daten aus dem Binärwust als Sisyphusarbeit. Das Modul Garmin::FIT bietet die Methode »print_all_fields()«
an, mit der ich schnell den Dumper in Listing 1 zusammengeklopft habe, der die Ausgabe in Abbildung 3 erzeugt. Um die Daten weiterzuverarbeiten, müssen Entwickler aber tiefer bohren und eigene Funktionen schreiben.
Abbildung 3: Die aus dem FIT-Format ausgelesenen Rohdaten zeigen, dass das Gerät etwa alle 6 Sekunden geografische Breite und Länge, die aktuelle Geschwindigkeit und die zurückgelegte Strecke bestimmt.
01 #!/usr/bin/perl
02 use warnings;
03 use strict;
04 use Garmin::FIT;
05
06 my $fit = Garmin::FIT->new();
07 $fit->file( "354I2029.FIT" );
08 $fit->data_message_callback_by_name('',
09 \&dump_it);
10
11 $fit->open();
12 $fit->fetch_header();
13 1 while $fit->fetch();
14
15 ###########################################
16 sub dump_it {
17 ###########################################
18 my ($self, $desc, $v) = @_;
19
20 if( $desc->{message_name} ) {
21 print "$desc->{message_name} ";
22 } else {
23 print "Unknown ";
24 }
25
26 print "($desc->{message_number}):\n";
27
28 $self->print_all_fields($desc, $v,
29 indent => ' ');
30 }