Garmin FIT failide töötlemine
Sisukord
Sissejuhatus
Käesolev artikkel keskendub Garmin FIT failidele, mis on pärit Garmini seikluskaameratest. Sama formaati kasutab Garmin andmete talletamiseks ka kõigil muudel oma seadmetel (navigaatorid, tervisespordi abivahendid, ...), millel sensorid küljes on (GPS, kiirendusandur, ...).
Tegemist on väga rikkaliku formaadiga, kuhu on tavaks talletada väga palju erinevaid parameetreid. Samuti on seal palju rõhku pandud andmete ajalisele täpsusele. Erinevalt näiteks GPX formaadist, kus rajapunktid talletatakse sekundi täpsusega, on FIT failis ajaühikuks millisekund.
Teisalt on FIT faili parsimine palju keerulisem kui GPX parsimine. Tegemist on binaarse formaadiga, mis võimaldab talletada võimalikult palju andmeid võimalikult vähese andmemahu kuluga.
Meid huvitab FIT faili parsimine hetkel peamiselt kahel eesmärgil:
- Saada sealt kätte kaamera rajalogi.
- Saada kätte kaamera sündmuste ajatemplid - ehk siis millal algas filmimine, millal lõppes ja millal kaamera automaatselt video tükeldas.
Neist esimene on võrdlemisi lihtne ülesanne, teine mitte nii väga. Aga skriptitav lahendus on allpool ära toodud siiski mõlema jaoks.
FIT faile kasutab näiteks Garmin Virb Edit - seal oleva info baasilt näidatakse kaardil filmimise asukohta, samuti on võimalik sensorite info baasilt videosid stabiliseerida. Samuti on võimalik FIT faile avada otse Garmin BaseCamp-is.
Rajalogi eksport
Rajalogi oskab FIT failidest kätte saada näiteks Garmin BaseCamp.
Skriptitavaks lahenduseks sobib aga GPSBabel. Tasub mainida, et koos korrektsete ajatemplitega oskab FIT failidest andmed kätte saada ainult GPSBabel arendusversioon, mitte aga 2017. aasta jaanuarist pärit viimane väljalase 1.5.4. Täpsemalt saab nendest nüanssidest lugeda GPSBabel lehelt.
Konverteerimine näeb välja näiteks nii:
gpsbabel -t -i garmin_fit -f input.fit \ -x nuketypes,waypoints,routes -x track,start=2000 \ -o gpx -F out.gpx
Selgituseks veel:
- Esimene rida impordib FIT faili.
- Teine rida jätab alles ainult rajalogi ning ainult need punktid, millel on olemas ka ajatempel ning see pärineb vähemalt aastast 2000.
- Kolmas rada ekspordib GPX faili.
Kui on soov saadud GPX faili kasutada Garmin Virb Edit-is, siis tuleks viimasel reana kasutada järgmist:
-o gpx,gpsver=1.1 -F out.gpx
Nimelt ei saa Garmin Virb Edit hakkama GPX versiooniga 1.0, mida GPSBabel antud juhul aga vaikimisi ekspordiks.
Kaamera sündmuste eksport
Sissejuhatus
Kuigi FIT failidest rajalogi eksportimiseks kõlbab GPSBabel hästi, siis sellega tema tugi ka piirdub - mingeid muid andmeid GPSBabel abil kätte ei saa. Seetõttu tuleb kaamera sündmuste kättesaamiseks kasutada siin peatükis kirjeldatud keerukamat meetodit.
Eelduste paigaldamine
Internetist leitud juhend, mis käesolevaks lahenduseks inspiratsiooni andis, on see.
Järgnevalt on ära toodud aga konkreetne meie jaoks välja töötatud lahendus. Tööle sai see pandud Ubuntu all, nagu ikka. Kõigepealt tuleks paigaldada eeldused:
sudo apt-get install python3-pip sudo pip install --upgrade pip sudo mkdir -p /opt/fitparse cd /opt/fitparse sudo pip3 install -e git+https://github.com/dtcooper/python-fitparse#egg=python-fitparse
Python skript
Järgnevalt sai loodud Python skript, mis võtab parameetrina FIT faili nime ning trükib konsooli välja kõik kaamera sündmused. Iga rida vastab ühele sündmusele ning reas on kaks tühikuga eraldatud tulpa: sündmuse Unix Timestamp (koos komakohtadega) ja sündmuse nimi ("video_start", "video_end", "video_split", "photo_taken" jne).
import sys import calendar import datetime import fitparse # Usage: python3 print_fit_camera_events.py <FIT file name> def main(): file=sys.argv[1] fitfile = fitparse.FitFile(file, data_processor=fitparse.StandardUnitsDataProcessor()) zero_time=find_zero_timestamp(fitfile) print_camera_events(fitfile,zero_time) def find_zero_timestamp(fitfile): required_fields = ['timestamp','timestamp_ms', 'system_timestamp','system_timestamp_ms'] data = find_fields(fitfile,required_fields) if len(data) != 1: print('Expected exactly one time reference, but found %d' % len(data)) return 0 else: entry = data[0] return (calendar.timegm(entry['timestamp'].timetuple()) + entry['timestamp_ms'] / 1000 - entry['system_timestamp'] - entry['system_timestamp_ms'] / 1000) def print_camera_events(fitfile,zero_time): required_fields = ['timestamp','timestamp_ms','camera_event_type'] data = find_fields(fitfile,required_fields) for entry in data: print('%f %s' % (zero_time + entry['timestamp'] + entry['timestamp_ms'] / 1000, entry['camera_event_type'])) def find_fields(fitfile,req_fields): messages = fitfile.messages data = [] for m in messages: skip=False if not hasattr(m, 'fields'): continue fields = m.fields mdata = {} for field in fields: if field.name in req_fields: mdata[field.name] = field.value for rf in req_fields: if rf not in mdata: skip=True if not skip: data.append(mdata) return data if __name__=='__main__': main()
Selgituseks siia juurde veel:
- FIT failid kasutavad kahte erinevat ajatemplit - faili suhteline aeg ning absoluutaeg. Nende omavaheline seostamine on jäetud faili parsija hooleks. Suhteline aeg hakkab lugema siis kui andmete talletamine alguse saab. Kui kaamera GPS signaali kätte saab, siis lisatakse logisse üks rida, mis absoluutaja ja suhtelise aja omavahel kokku viib. Ülal tegeleb selle info välja lugemisega funktsioon find_zero_timestamp.
- Tasub eraldi rõhutamist, et FIT faili absoluutne ajatempel ei ole sama, mis Unix TimeStamp. FIT faili aeg hakkab lugema 31. detsembrist 1989, UTC aja järgi kell 0:00 öösel. Samas ülal skriptis seda teisendust teha ei ole vaja - näib, et fitparse teek teisendab tulemuse ise juba Unix Timestamp-iks.