grimbough / FITfileR

R package for reading data from FIT files using only native R code, rather than relying on external libraries.

Home Page:https://msmith.de/FITfileR

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Reading records results in endless(?) loop of setting new names

Toniiiio opened this issue · comments

Reading file usually works great for me, so thanks a lot for the package!

The following file i created for once with Wahoo on iOS and it fails while reading records. (All the files recorded with wahoo on android work.)
Meiringen_Hergiswil.zip

Reproducible example:

file_name <- "biketrainr-master/data/Meiringen_Hergiswil.fit"
strava <- FITfileR::readFitFile(file_name)
strava_records <- FITfileR::records(strava)
New names:
  • `0` -> `0...1`
• `0` -> `0...2`

New names:
  • `0` -> `0...1`
• `0` -> `0...2`
New names:
  • `0` -> `0...1`
• `0` -> `0...2`
New names:
  • `0` -> `0...1`
• `0` -> `0...2`

It will eventually finish printing, so you can get some data out.

It looks like the issue is a bug in how "developer messages" are handled, which are data messages not defined in the FIT specifications. This file has a lot of them and FITfileR does not deal with them properly. I'm working on a patch for this.

Thanks for the very useful package!

Unfortunately I am having the same problem when reading a fit file with developer messages.
It take a while and make R crash!

Any update on this?

This should now be fixed in version 0.0.16:

There's quite a few developer fields defined in the file, but the only ones I can actually seeing being used are called lat_gps and lon_gps. Here's an example which shows them being read and included in the record messages extracted by FITfileR:

library(FITfileR)
library(dplyr)

## download and extract the example file
destfile = tempfile(fileext = ".zip")
url = "https://github.com/grimbough/FITfileR/files/8985612/Meiringen_Hergiswil.zip"
dl = download.file(url = url, destfile = destfile)
example_file = unzip(destfile, exdir = tempdir())

## read and extract the records
fitFile <- readFitFile(example_file)
records <- records(fitFile) 

## We can see "lat_gps" and "lon_gps", which are non-standard fields defined in the file
records$record_1 |> 
    select("timestamp", "position_lat", "position_long", "lat_gps", "lon_gps")
#> # A tibble: 70 × 5
#>    timestamp           position_lat position_long   lat_gps  lon_gps
#>    <dttm>                     <dbl>         <dbl>     <int>    <int>
#>  1 2022-06-19 08:41:28         46.8          8.32 557951840 99284776
#>  2 2022-06-19 08:41:58         46.8          8.32 557951704 99284525
#>  3 2022-06-19 09:23:54         46.8          8.36 558056243 99705640
#>  4 2022-06-19 09:24:41         46.8          8.36 558056015 99705663
#>  5 2022-06-19 09:24:59         46.8          8.36 558055742 99705276
#>  6 2022-06-19 09:25:05         46.8          8.36 558056015 99705515
#>  7 2022-06-19 09:25:07         46.8          8.36 558055651 99705503
#>  8 2022-06-19 09:25:12         46.8          8.36 558056015 99705185
#>  9 2022-06-19 09:25:23         46.8          8.36 558055924 99705492
#> 10 2022-06-19 09:26:09         46.8          8.36 558055606 99705754
#> # … with 60 more rows

I've no idea why this device/file type chooses to store the positional information twice, but that's what it seems to do. Just to confirm it matches with the other data here's lat_gps converted from semi-circles to degrees, which FITfileR does automatically for the standard position_lat column.

## this is the conversion between semi-circles and degrees
records$record_1$lat_gps * (180 / 2^31) |> head()
#>  [1] 46.76698 46.76697 46.77573 46.77571 46.77569 46.77571 46.77568 46.77571
#>  [9] 46.77571 46.77568 46.77570 46.77571 46.77571 46.77571 46.77571 46.77570
#> [17] 46.77571 46.77574 46.77573 46.77570 46.77568 46.77568 46.77547 46.77548
#> [25] 46.77549 46.77549 46.77549 46.77549 46.77549 46.77549 46.77549 46.77549
#> [33] 46.77549 46.77549 46.77549 46.77549 46.77548 46.77549 46.77549 46.77549
#> [41] 46.77549 46.77549 46.77549 46.77834 46.77835 46.77837 46.77838 46.77840
#> [49] 46.77843 46.77361 46.77360 46.77358 46.77357 46.77356 46.77356 46.77357
#> [57] 46.77358 46.77359 46.77361 46.77363 46.77365 46.77369 46.87617 46.87616
#> [65] 46.87619 46.87621 46.87624 46.87627 46.87631 46.87635

Hopefully this is fixed. Please re-open if you find the same problem with another file.