Elevation accuracy, revisited
Time to revisit a familiar topic: since a few months we’re using a different algorithm to extract elevation data from uploaded GPS tracks. Without going into too much mathematical detail (which can be quite entertaining though), it consists of a discrete exponential smoothing filter followed by simple thresholding. There are more refined and better filters possible (trigonometric bandpass filters etc), but it is simple, and with only two parameters (RC constant and threshold), it seems to work pretty well for the typical data that gets uploaded to the site.
This data is generally recorded by GPS devices, and usually of decent quality already in its raw form. The best devices combine barometric sensor readings with the trilatered elevation (z-coordinate) from the GPS satellites, the latter typically being used to compensate any slow drift of the barometric sensor (for instance due to weather changes). Nevertheless, even for raw data of such relatively high quality, calculated totals for altitude gain and loss during rides have been a source of doubt and confusion for many people. And this goes both ways: it’s being felt as being either inflated, or underestimated (though mostly the former).

Something people generally do tend to trust, are the totals the device itself displays at the end of the ride – perhaps because of the more tangible nature of the process? But that number is of course also the result of some internal (and unknown) filtering algorithm. Now the issue is mostly for mountain bike rides on rather chunky terrain (technical, many short ups-and-downs), or for very long mountain bike rides (100 milers e.g.), where small errors may accumulate to very large ones – for road rides and other ‘smooth’ tracks there was never much deviation with the old algorithms or ground for discussion.
So back to filtering, which I’ll now try to explain using simple, non-engineering terms. You basically want to get rid of two things: spiky noise in the elevation signal – say points in the datastream that look like they jump up and down for no good reason (but do so because some tiny atmospheric disturbance is messing up the signal of the GPS satellite a bit, or a cosmic ray that happens to impact a chip in your device, etc) – and secondly, slow drift in the signal. To understand where the latter may come from: imagine you’re riding on perfectly flat terrain, which means your total elevation gain should be zero – the sensor data may however still show small changes in elevation from point to point (because of subtle changes in air pressure due to weather conditions that confuse the barometric sensor, or because the circuit in your device is rounding off the numerical values and does so with small errors, etc), and when you add this all up, it gives a non-zero total.
An electrical engineer will say he has both high frequent (the spiky stuff) and low frequent noise (the slow drift) in the signal and he’ll want to get rid of it using a ‘bandpass filter’. The ‘band’ is the part of the signal that is of interest, which can be considered a meaningful measure for elevation changes, and all the rest is noise that needs to be filtered away. Our current algorithm (the exponential smoothing, basically a low-pass filter, followed by thresholding, which is a simple form of high-pass filter) is an implementation of this idea – by no means the best or most refined – but it seems to work well enough: in my experience from the last months (many tracks from a Garmin Edge 305 and 705), the totals calculated by the site match up with the ‘trusted’ totals displayed on the unit itself, mostly within a few percent.
Of course, for units that generate lower quality data (older, less accurate GPS receivers, no barometric sensors, etc) the simple filtering will not magically crank out the right answer, but I figure those who really care about things like how much altitude they’ve gained will get a better device eventually!
Here is a link to the script we use to process the GPX files – if you can run Ruby on your system, you can try it out for your self. The two parameters in our filter (RC constant = 40ft and threshold = 3ft) received values we found to work well but they can of course be played with…

January 14th, 2010 at 7:40 am
To illustrate an issue I have had with my barometric altimeter, I once recall riding as a rare thunderstorm was approaching rapidly. As I road downhill rather quickly, I watched the altitude reading actually rise! LOL
January 19th, 2010 at 12:33 am
[...] recalibrated, and if you don’t happen to be hit by some crazy weather system (see Mike B’s comment [...]
March 23rd, 2010 at 12:41 pm
I like your site, and I should contribute more.
Noticed your blog discussion of altitude and thought you might be interested in a somewhat unusual constant altitude track recorded with an Edge305. The Edge305 was mounted on the stem and I was careful to not lay the bike down during recording of this track. Based on the internet the altitude should be 4215.5 feet (salt flats) plus the approximate 3 feet up to the stem.
I’ve uploaded the track to your site titled Bicycling-Bonneville Salt Flats.
The salt flats are dead flat with absolutely no obstructions. I drew this track on my Garmin 60Cx (no barometric altimeter) and rode head down watching the little triangle follow the track. Then we went to Wendover for a party.
The Edge305 was used to record the track that I uploaded, I can’t remember how long the Edge305 was turned on before starting the ride but it was probably more than 10 minutes and less than 30 minutes. I’ve noticed that the Edge305 can take up to an hour to settle to a correct altitude. Is the 705 better in this respect? The atmospheric pressure and temperature was stable and there was almost no wind during the ride. I have the 60Cx data if you are interested.
I did the ride partially to see what filter settings in the Macintosh program Ascent would give me the correct zero total. He has several filter settings in that program and doesn’t discuss what they do very well. I enjoyed reading your filter discussion.
March 24th, 2010 at 7:20 am
Hi Gene,
Thanks – loved your track, great idea, think that that’s the first time I’ve seen someone ‘writing’ in gpx…
Not sure what the difference between 305 and 705 is, an experiment would be in place. In your profile you can clearly see the (low) noise of the barometric (+-5 ft) with some lower frequent drift superimposed on it (~30ft). I guess this drift could be either atmospheric, thermal (barometric sensors generally have temperature compensation in them) or coming from the GPS signal that is used to recalibrate itself… hard to pinpoint it when we don’t know the procedure/algorithm Garmin applies…
October 28th, 2010 at 12:41 pm
[...] un nuovo e più preciso algoritmo. Se siete interessati ad approfondire il concetto vi consiglio questo articolo. Sarà inoltre possibile avere il grafico della velocità istantanea punto per punto. [...]
November 7th, 2010 at 1:11 pm
[...] di tale misurazione. Per chi vuole approffondire e sa l’inglese consigliamo questo articolo qui. Tale feature è attiva già durante la registrazione perciò può essere consultata anche in tempo [...]
November 9th, 2010 at 10:05 am
[...] di tale misurazione. Per chi vuole approffondire e sa l'inglese consigliamo questo articolo qui. Tale feature è attiva già durante la registrazione perciò può essere consultata anche in tempo [...]
October 17th, 2011 at 10:30 pm
[...] *.gpx file data as recorded by the Garmin GPS. I did some of research about this and discovered a blog article about applying a smoothing filter to the elevation dataset which improves the accuracy by reducing noise in the path. The posting even features code in the [...]