muktihari / fit

A FIT SDK for decoding and encoding Garmin FIT files in Go supporting FIT Protocol V2.
BSD 3-Clause "New" or "Revised" License
42 stars 4 forks source link

MaxSpeedScaled() and AverageSpeedScaled() both return Nan #395

Closed Oupsman closed 2 months ago

Oupsman commented 2 months ago

Hi guys,

I'm working on an activity tracker and I have an issue with this module. I've tried with files coming from differents bikes computers and from a Fenix 7X and I have the issue every time.

Here is my code :

package main

import (
    "fmt"
    "github.com/muktihari/fit/decoder"
    "github.com/muktihari/fit/profile/filedef"
    "os"
)

func main() {
    // filePath := "FIT/Karoo-Morning_Ride-Sep-06-2022-061544.fit"
    filePath := "2024-04-29-18-28-29.fit"
    f, err := os.Open(filePath)
    if err != nil {
        panic(err)
    }
    defer f.Close()

    dec := decoder.New(f)
    // Read the fit file

    for dec.Next() {
        fit, err := dec.Decode()
        if err != nil {
            panic(err)
        }
        activity := filedef.NewActivity(fit.Messages...)

        fmt.Printf("File Type: %s\n", activity.FileId.Type)
        fmt.Printf("Average Speed: %f\n", activity.Sessions[0].AvgSpeedScaled())
        fmt.Printf("Max Speed: %f\n", activity.Sessions[0].MaxSpeedScaled())

    }

}

and the result :

oupsman@Surface:~/IdeaProjects/mysportwebgo/prototypes$ /usr/local/go/bin/go run read_fit.go 
File Type: activity
Average Speed: NaN
Max Speed: NaN

what am I doing wrong ?

thanks for you answer.

muktihari commented 2 months ago

Hi @Oupsman,

A message may contains only few fields and the rest of the fields will be set to its corresponding invalid value. It's up to the creator of the FIT file what's to include in the message. When the field is invalid, in this case AvgSpeed, AvgSpeedScaled() will return NaN value to indicate that the field AvgSpeed is invalid. The best practice is to check the validity of the value first before processing the field:

if activity.Sessions[0].AvgSpeed != basetype.Uint16Invalid {}
// or
if !math.IsNaN(activity.Sessions[0].AvgSpeedScaled()) {}

For AvgSpeed and MaxSpeed, some manufactures may prefer using EnhancedAvgSpeed and EnhancedMaxSpeed fields. We need to check those value as well.

muktihari commented 2 months ago

Another suggestion, you can use fitconv or fitprint CLI to help you debug what's in the file since you might be working with FIT files created from different manufacturers. Some manufacturers may prefer using some fields over the others.

Oupsman commented 2 months ago

Thanks, I did not thought of checking if Enhanced values were available.

The worst part is that I already check in my code if I have to use SpeedScaled() or EnhancedSpeedScaled() to get the speed in a record. My bad.