Sunday, July 18, 2010

Rating Climbs: rating difficulty using full profile data

There's been two principal weaknesses with the methods I've described so far as ratings of difficulty:
  1. They neglect the difficulty associated with extended steep sections embedded withing a longer climb. In extreme cases, the optimal rating comes from rating a subset of the total climb, but this obviously neglects the additional difficulty presented by the additional, more gradual climbing.
  2. A climb with a short descent which then climbs steeply to make up the altitude lost in that descent rates the same as a climb which is flat for the distance taken up by that segment (the descent followed by the climb to restore the lost altitude). This really affects a climb like Mount Hamilton, which has two significant descents along its path.
I wish to address this. To do so, however, really requires using full profile data. Some have suggested using "maximum gradient" in the formula to account for sections of steepness. But this obviously doesn't work well: a road like Alba which repeatedly pummels the rider with steep gradients would need to rate higher than a road which has a single steep switchback. So the solution is to use the full profile data.

That used to be an issue, as full profile data was rare, but in this era of archived GPS + altimeter data like MotionBased and on-line profile generators like MapMyRide it's fairly easy to get a full representation of altitude versus distance.

Before writing numbers, it's important to decide what the assumptions are. For my rating, I'll use the following observations:
  1. Something which gains zero altitude rates zero: it's not "a climb".
  2. For the same average steepness, a climb which has more variability in its steepness is harder than one which is more uniform. This isn't always the case, actually, as gradual segments can provide some rest, but I think most of the time most riders agree the rest from the gradual portion fails to fully compensate for the increased steepness of the remaining portion.
  3. A series of steep sections which can be climbed in 5 seconds each (like steep switchbacks) are easier than a single steep section of the same total distance and altitude gained.
  4. A descending section reduces difficulty relative to a climb which was flat for the same segment.
  5. Per unit altitude lost, a steep descent has no more effect than a gradual descent. This is unlike the case for climbing, where a steep climb has more effect per unit climbing than a gradual climb.
Once these observations are written, a formula becomes almost obvious.

For the first observation, it's clear the total rating needs to be proportional to altitude gained. This also takes care of observations 4 and 5.

For the second observation, the rating needs to be proportional to an integral of a function of the local steepness. This function needs to be an increasing function of the local steepness.

For the third observation, the steepness as a function of time needs to be smoothed with a convolution function. Note I use time because physiologically, the body doesn't know anything about distance, it just senses force (which depends on grade) and time. So I need to come with some representation of how long it takes to traverse each segment of road. This will be tricky, which suggests a numerical algorithm. Of course slower riders take more time than faster riders, but riders riding to "survive" may ride the flatter sections slower relative to the steeper sections than a rider who's racing, but this one is worth a credible attempt. One could assume constant power and solve power-speed equations, but that's not how riders typically ride: usually they use higher power on steep climbing than on descents, for example, and if the grade is varying, they'll use shallower segments for a bit of recovery to focus more on the steep arts where the effort pays off more. Of course with GPS data distance versus time may be available already. But that's only for a given rider, and the formula shouldn't depend on who's riding a climb or when.

Next is to determine what the function of steepness should be and how we should integrate it. We'll multiply an integral of this function by the net climbing to get the rating formula. this is perhaps the key question in the whole business, and it causes me difficulty every time I think about it. The most challenging part always comes down to how to give gradual climbing sections the credit they're due while handling descending segments properly.

What I want an integral which has a contribution close to a constant value for gradual climbing sections,  increases sharply with grade for steep segments, but does not increase in magnitude for sharply descending portions.  If that description doesn't scream "exponential", I don't know what does. So the function I propose for the integral is:

f(g) = (1 / L) exp ( g* / g0),

where L is the length of the climb (distance), g* is the smoothed function of rate of climbing with respect to distance and g0 is a characteristically steep grade. I assume the integral is conducted with respect to distance. All that remains is to determine g0. And the best way to do this is to run examples, then check to see if the relative ranking is consistent with experience. A value of 10% would make a 10% climb rank about twice as high as a 3% climb assuming a uniform grade. It then makes a 20% grade rate 5.5 times as high as the 3% grade, and a 30% grade around 15 times higher. This makes 100 meters gained at 30% (climbing over distance) rank the same as 1500 meters gained at 3% (climbing / distance). That seems like a good starting point. So that's what I'll use:

f(g) = (1 / L) exp ( g* / 0.075 ).

Now for the smoothing function. I already noted I wanted to smooth with respect to time, not distance. So I need to relate time to distance and g (the unsmoothed rate of altitude gain with distance).

Obviously for high g, speed is inversely proportional to g, as this is the condition of constant power. For negative g*, speed is probably relatively constant, as safety rather than physics limits the average speed. So I want a function relating time per unit distance which is constant for negative g, but proportional to g for sufficiently positive g. The following function has this behavior:

d t / d s = (1 / vmax)[ 1 + ln | 1 + exp (g/g₁ ) | ],

where t is time, s is distance, vmax is a peak descending speed, and g₁ is a constant constants. A typical value for might be vmax = 14 meters/second (around 50 kph) which yields a speed on the flats of 30 kph. Peak rate of altitude gain is gvmax. Picking g0 = 2% yields a VAM of 1000 meters / hour, a good climbing pace. So I get the following equation:

d t / d s = (1 second / 14 meters) ( 1 + ln | 1 + exp (50 g) | ).

Then there's the smoothing function to use. For example, a sine-squared function with a 15-second full-width-half-maximum (FWHM) will significantly reduce the contribution of steep sections taking up to around 15 seconds to ride. Assuming a rate of ascent of 1000 meters / hour, in 15 seconds a rider can climb around 4.2 meters, which is how far uphill a rider can coast from a starting speed of 32 kph. So both from the perspective of inertia and from the perspective of ATP metabolism (short-term power), it seems this is a decent value to use.

That's basically it, except for one additional step. To this point, I assumed profile data is precisely accurate. Unfortunately, most altimeters, even the GPS + barometric units like the Garmin Edge 500, make small errors in altitude which can result in big errors in grade. So the first step when dealing with data like this is to apply additional smoothing, for example a convolution with respect to distance with FWHM = 50 meters, to the profile. It's better if you use a computer which measures grade directly, most notably the iBike units.

So, in summary, here's the algorithm:
  1. Smooth the initial profile with a a convolution function proportional to cos²(π Δs / 100 meters) for ‒50 meters < Δs < 50 meters, unless the data is from a computer with a gradiometer such as an iBike and thus grade data are available directly.
  2. Determine the rate of altitude gain over the climb: g as a function of s.
  3. Translate this to a function g as a function of t, using the relationship between d t / d s and g already described.
  4. Smooth this function with a convolution function proportional to cos²(π Δt / 30 seconds) for ‒15 seconds < Δt < 15 seconds, yielding g* as a function of time, which is then converted back to a function of distance.
  5. Integrate with respect to distance (1 / L) exp ( g* / 0.010 ), where L is the length of the climb.
  6. Multiply by net climbing.
There it is, the difficulty rating. That wasn't so bad, really, other than that gnarly smoothing operation. If all you have are data every 500 meters or even every kilometer, the smoothing can be skipped (the profile is already smoothed). But otherwise, just a bit of Perl coding will do the trick.

An example next time.

No comments: