As @Nate_Pearson mentioned in the latest podcast (287) in response to the question at 1:23:40 (regarding how TrainerRoad estimates distance) he said he’d be interested in having this as a microservice on AWS or Azure.

To help get this done here’s python code for calculating the speed from a fit file using a basic physics model (the code details all the assumptions). http://www.robertoneil.com/TrainerRoad/ParseFitDistance_r3.html

I haven’t made a microservice before, but for anyone who wants to take the basic physics model and port it into a microservice it seems you just need to accept a file file, and have the ability to also take in CdA values and the combined rider bicycle mass which will allow for customization.

I previously went through the math for the physics in this thread: [request] Stop sending speed data to strava and here’s a python notebook that shows the formula and different ways to calculate the results: http://www.robertoneil.com/TrainerRoad/Example_ParseFit2.html

Oh and for anyone who wants to weigh in on whether or not Nate’s idea of doing this is a good or bad idea - please do that back on the previous thread. Let’s keep this just for folks who want to work on coding this.

Thanks.

[edit - realized how to post code]

```
#fitdecode from https://pypi.org/project/fitdecode/
import fitdecode
#for online use point this to the location of the fit file to analyze
fit_file = 'rob0-2020-12-04-glassy-95960008.fit'
g = 9.81 #gravity in m/s^2
m = 79.4 + 1 #rider + bike mass in kg with 1kg more simulating the wheel's rotational intertia
Crr = 0.005 #approximate rolling resistance
CdA = 0.324 #approximate CdA in m^2 - hands on hoods elbows bent - can be varied
Rho = 1.225 #air density sea level STP
dt = 1 #time step from the fit file; will be updated below
speed_total = 0 #add up all the speeds, later divide by total steps to get average
Vi = 0 #initialize the starting speed at 0
count = 0 #used to average the speed
time_prev = None #last fit message time, for edge cases when not just 1 second intervals
total_time = 0 #length of the ride in seconds
with fitdecode.FitReader(fit_file) as fit:
for frame in fit:
if isinstance(frame, fitdecode.FitDataMessage) and frame.has_field('power'):
time_current = frame.get_field('timestamp').value
if time_prev:
dt = (time_current-time_prev).seconds
total_time += dt
p=(frame.get_field('power').value)
Vf = ((-dt*(CdA*Rho*Vi**3-2*p+2*Crr*Vi*g*m)+Vi**2*m)/m)**.5
speed_total += Vf
count += 1
Vi = Vf
time_prev = time_current
v = speed_total* 2.23694/count #convert from m/s to mph and average
t = total_time/3600
print ("Average Speed: {:.2f} mph - Time: {:.2f} hours - Distance: {:.2f} miles".format(v,t,(v*t)))
```

Average Speed: 20.48 mph - Time: 1.33 hours - Distance: 27.30 miles