Calibration calculations – part 1

To recap the approach from the last post – in ergo mode we calculate a resistance level that should match a given speed and wattage. In slope mode we first need to estimate a wattage for the current speed and slope, and then use that estimated wattage in the ergo mode calculation.

Power required for a given speed & slope

In order to estimate the ‘real-world’ power required to hold a given speed on a gradient, I’m using calculations from

// Wind Resistance     Fw = 1/2 A Cw Rho Vmps2
// Rolling Resistance  Frl = Wkg 9.8 Crr
// Gravity Forces      Fsl = Wkg 9.8 Slope
// Power             Power = (Fw + Frl + Fsl) Vmps

With a wattage estimate from this formula, I can now use the same resistance calculation for both slope and ergo mode.

Resistance required for a given wattage and speed

Level      1       2      3     4      5      6      7      8      9      10
Slope      3.73    5.33   6.87  8.27   10.07  11.40  13.13  14.40  15.93  17.73
Intercept -28.67 -36.67 -43.33 -47.33 -66.33 -67.00 -83.67 -82.00 -89.67 -114.67

Using curves derived from the published Satori graphs as a starting point, I’ve plotted a series of data points for each resistance level.

This gives a table of speed (x-axis), power (y-axis), and resistance (z-axis) – a small extract of this table is shown below. The original 1-10 levels of resistance from the handlebar lever have been converted to their matching levels in the 1-100 range that I’m using for this prototype.

x     y        z

10    34.37    45
15    84.72    45
20    135.07   45
25    185.42   45
30    235.77   45
35    286.12   45
40    336.47   45
45    386.82   45
50    437.17   45
55    487.52   45
60    537.87   45

Given this table as input, I then need to calculate the resistance level that matches any given speed and power combination. My initial approach has been to use the online curve & surface fitting site to provide the formula & coefficients.

One useful aspect of this site is that I don’t need to know the best equation type for matching the input data, I can simply paste the data into the “function finder” section, which will then search for the best fit across a whole range of equation types.

Here’s a contour plot, and an error plot for the selected function. Although the contour plot looks pretty close, you can see that the model starts to break down below about 200 watts.


The site can also generate a complete C (or other language) function with the correct formula and coefficients that can be pasted into the project code (generated function body below).

double GetResistance(double x_in, double y_in)
    double temp;
    temp = 0.0;

    // coefficients
    double a = -1.5551745362491399E+01;
    double b = -1.4121261534412761E+00;
    double c = 1.9523034800130676E-01;

    temp = (a+y_in)/(b+c*x_in);
    return temp;


Here’s a screenshot from my very first ergo session. You can see that it’s vaguely tracking the target load, but the calibration isn’t really close enough just yet…


Next post

I’m sure I can do better on the accuracy, so am trying a couple of different approaches. Firstly, a series of calibration rides to populate the speed/power/resistance table based on my own PowerTap data. Secondly, instead of the surface fitting approach, I’m going to try indexing into the table directly, using bilinear interpolation to estimate the resistance value based on the surrounding four data points.