Closed prochlorothrix closed 4 years ago
I'm afraid I can't really help without access to the fit file you're trying to read. The file format is pretty complex with many options, and I suspect the Suunto app is producing a file with some feature that fitFileR doesn't recognise and parses incorrectly.
I'm willing to share the file but I don't want it to be publicly available (it's an activity of one of the athletes I'm training). Is it OK if I send it to your private email address?
Yes, sure. You can find my email in the DESCRIPTION file.
You might also want to try again with the latest version of the package. I made some updates to address #4 and there's a chance that'll fix you issue too. If not feel free to send me the file.
I tried the new version. The error still occurs:
fit <- readFitFile("SuuntoExample.fit") Error: Column
0
can't be converted from integer to listtraceback() 5: stop(list(message = "Column
0
can't be converted from integer to list", call = NULL, cppstack = NULL)) 4: bindrows(x, .id) 3: bind_rows(scaffold[idx]) 2: .renameMessages(tmp[[1]], tmp[[2]], merge = mergeMessages) 1: readFitFile("SuuntoExample.fit")
This file contains records of the type hrv
, which I haven't seen before. Sometimes these are a single value, other times groups of 2, 3 or 4 values per record. This messes up my strategy of merging all records of the same type in fitFileR.
You should be able to read the file by setting the argument mergeMessages = FALSE
. You'll get back a list where each entry is a data.frame
consisting of all records that are contain identical fields, and the names of the entries indicate the type of record.
The list should contain almost all the data from the file, but there might be quite a bit of processing required depending on what features are of interest to you.
library(fitFileR)
suunto <- readFitFile("~/Downloads/SuuntoExample.fit", mergeMessages = FALSE)
names(suunto)
#> [1] "file_id-1" "developer_data_id-1" "field_description-1"
#> [4] "field_description-2" "field_description-3" "hrv-1"
#> [7] "record-1" "record-2" "hrv-2"
#> [10] "hrv-3" "record-3" "record-4"
#> [13] "hrv-4" "record-5" "record-6"
#> [16] "event-1" "record-7" "lap-1"
#> [19] "lap-2" "lap-3" "lap-4"
#> [22] "lap-5" "event-2" "session-1"
#> [25] "activity-1"
That's a step ahead anyway. The most relevant information seem to be in 'record-6:
head(fit$
record-6
)A tibble: 6 x 8
timestamp position_lat position_long distance heart_rate altitude speed
1 2020-07-15 10:21:04 679087931 176876698 19 97 660. 1.58 2 2020-07-15 10:21:06 679087931 176877233 22 102 660. 1.38 3 2020-07-15 10:21:08 679087931 176877806 25 114 660. 1.42 4 2020-07-15 10:21:10 679088007 176878531 29 107 660 1.58 5 2020-07-15 10:21:12 679088007 176879123 32 97 660 1.56 6 2020-07-15 10:21:14 679088160 176879657 35 90 660. 1.56 # … with 1 more variable: vertical_speed
While most fields do make sense, latitude and longitude do not (at least to me). Any hint about how they are represented? The altitude is wrong as well (exactly 500m higher than it should, I guess not by chance)
The coordinates are stored as signed 32-bit integers in the FIT format, and we need to map them to signed degrees. Something like this should do the transformation for you:
> fit$`record-2` %>%
dplyr::mutate(position_lat = position_lat * (180 / (2^31)),
position_long = position_long * (180 / 2^31))
# A tibble: 1,545 x 8
timestamp position_lat position_long distance heart_rate altitude
<dttm> <dbl> <dbl> <dbl> <int> <dbl>
1 2020-07-15 10:21:04 56.9 14.8 19 97 660.
2 2020-07-15 10:21:06 56.9 14.8 22 102 660.
3 2020-07-15 10:21:08 56.9 14.8 25 114 660.
4 2020-07-15 10:21:10 56.9 14.8 29 107 660
5 2020-07-15 10:21:12 56.9 14.8 32 97 660
6 2020-07-15 10:21:14 56.9 14.8 35 90 660.
# … with 1,535 more rows, and 2 more variables: speed <dbl>,
# vertical_speed <dbl>
Regarding altitude, you're absolutely correct. Looking at the FIT specification, altitude is stored with a 500m offset which I don't currently take into account when reading the data out. You can safely subtract 500 to get the correct value, but I'll probably add this in an update soon.
I've also now realised how annoying that -
in the list names is!
That works fine. Thank you.
I tried to open a .fit file downloaded from the Suunto app (iOS) and got the following error:
I don't understand why this happens. The data types seem fine to me