Creating a Virtual Power Meter

Posted by Jason Stratford on 3 January 2013 | 6 Comments

CyclistIt's not all web design and Apps you know! One of my other passions is competitive road cycling. I dabbled as a teenager and have fond memories of riding a 40mile charity ride with an old school friend. I also did a very short stint riding with my University Team although got thourougly demotivated by the ability gap between myself and the core team members. And lets face it given the choice between the many other social activities whilst at University compared with hours on the road in appalling weather getting thourougly destroyed by much stronger riders, the cycling got forgotten. Roll forward 20 years, marriage, two kids and far too comfortable a life style and something needed to be done.

So back to cycling, however this time the bug caught hold properly and this year I completed my first season as a competitive rider at club level. I've had a great year, developed a fitness level to rival if not exceed that of my youth and there is still plenty of scope to improve. So how does that improvement happen?

In general terms improvement happens in the same way that you improve any skill or ability. Lots of hard work, hours riding on the road and on indoor trainers (Turbo Trainers), as well as cross training for general fitness for the truly commited. Now for me being very technically minded I like to see something tangible for my efforts. I need to see some raw data to analyse and digest to pin point exactly how I'm improving. In cycling this is most easily done using a power meter. Power meters come in a number of forms, crank based ones, wheel hubs and pedals. By far the most popular and accurate are the crank based units, but there is a problem. Cost. Even the most basic crank based power meter is over £1,200 which is a lot of money to justify these days. But where there's a will there's a way, a much cheaper way as it turns out.

Turbo TrainerAs part of my training plan I have to complete a couple of indoor sessions each week. These are done on a Turbo trainer under much more controlled conditions than the open road. With careful research I selected a Turbo trainer that is known to have a fairly reliable and predictable resistance behaviour. So for a given speed ridden on the trainer the resistance is at a certain and predictable level. As power is a measure of how much energy is required to overcome a certain resistance, there is a direct correlation between the speed I ride on the trainer to the amount of power I am exerting. So if I can capture the speed I can calculate the power without the need for an expensive power meter.

As it turns out capturing the speed I am riding at is relatively easy, there is a pervasive tracking system in sports called ANT+. ANT+ is a communications standard allowing various monitoring devices such as speed, cadence or heart rate monitors to transmit their readings to a paired reciever. These recievers generally take the form of light weight on-bike computers such as the Garmin Edge units. However as ANT+ is an open standard implemented by many manufacturers it's not just Bike Computers that can tap into this stream of tracking data. In fact the nice people at Garmin created a USB stick for doing just that. So getting the data as a live stream into a computer can be achieved. The next problem is what to do with that raw data.

Golden CheetahSports tracking is a big area online. There are many services that offer different views on how this should be done, with some being multi disipline, some being sport specific and others being GPS location centric. Also each vender of these monitoring devices usually has some sort of desktop App for tapping into the data and doind some sort of analysis. The problem is they mostly want to sell you expensive power meters rather than let you bypass that with some cobbled together virtual system. Of course the internet is vast and most problems have an Open Source solution. In this case the space is filled by a project called Golden Cheetah. This project does an excellent job of reading in performance data for cyclists and producing all sorts of analytics, reports, charts and predictions. Just what I'm after to understand my performance improvements.

The other great thing about Golden Cheetah is that it already has provision for getting Virtual Power from Turbo Trainers. The problem is that it can't do it from my particular trainer. Now this is a problem as each type of trainer has a very different 'power curve' with some being fairly linear and others being very progressive. My particular trainer, the CycleOps JetFluid Pro, has a progressive power curve, one that gets very much harder the faster you ride. This type of curve is supposed to simulate the sort of resistance that you get when riding on the road. Remember that as your speed increases wind resistance increases as a cube of the speed! None of the included virtual devices were close to my device. What now. Break out the code!

So right now its a real benefit being a developer as I'm able to grab the source code for Golden Cheetah and build it myself to add in the necessary power curve to represent my trainer. But it's never that simple. As it turns out Golden Cheetah is a pretty complicated beast. It is a cross platform product available for Windows, Mac and Linux. To achieve this it must use techniques and frameworks that support all platforms, in this instance the primary one is the QT User Interface Library. It also incorporates about a dozen other Open Source Libraries to achieve connection to USB devices, format graphs, talk to Google for Maps, export XML files and many other things. All of these sub-projects need to be obtained and built before you can go anywhere near building the actual program.

This didn't go as smoothly as I'd have liked. Golden Cheetah is a fairly old project, its been around a while and has been through many versions. This is good as it means there is a core of developers keeping the project going and it gets new features on a regular basis. However it also means that some of the libraries used are out of date as they have not been kept up to date in the project. This happens quite often, especially if there is no need to improve or tweak that part of the project. For the embeded developers this is not a problem as their build environments are built up over time. For me however this caused quite a few issues. Finding and compiling old libraries with new build tools is not always easy. In this case it actually took the best part of two days work to get all the components and get them all compiled and hooked together to build the project. It then took about five minutes to add my virtual power device!

Polynomial EquationBut how do you represent a virtual power device in code? How does that specific speed to power curve get translated and distilled down to an equation? Now I'm no math geek, but there is a whole area of math that addresses this called polynomial equations. Essentially using polynomial equations you can represent curves on graphs. Better still given a set of data points on a graph you can derive a suitable polynomial equation. No idea how you do that, but the Internet knows and I was able to find an excelent tool to solve this particular problem that took my data points and spat out an equation in C/C++ format. But where did I get the data to build the curve?

Unfortunately the manufacturer was less than helpful in this area. Aparently the power curve for the trainer is proprietory and so could not be divulged. This seems crazy as there is an easy way to work it out. You stick a bike with a power meter and a willing test subject (my coach in this case) on it onto the trainer and then record regular speed and power figures across the range used for training. Of course this does mean you need access to a power meter, but borrowing one is a lot easier than buying one. So after a session of tourturing my test subject I had the raw data, the online tool gave me the equation and I could then build the program.

Training TraceThe proof is in the riding of course. My next training session produced a power trace and bingo the numbers matched up with the data gathered during the test session so I'm pretty confident that everything stacks correctly. Of course this is not as acurate as using a power meter, variance in temperature in the trainer and tire pressure, even cadence level during the session all impact on the true power levels I put out. But it is consistent enough and conservatively the margin for error is around 5%. So as long as I stick to this method I will see changes over time which will be a reflection of my improvement over the course of my training season. Power solved for the cost of a USB dongle (£25) and a few days of geeking out over some Open Source Code. Bringing the geek into cycling.

No test subjects were harmed for the purposes of this experiment, well not much at least. Consolation to the test subject as he did hit an impressive 700W peak power output during the testing.

Post your comment


  • Have you taken this concept any further?


    Posted by Rubin Johnson, 15/01/2014 6:14pm (11 months ago)

  • Indeed different trainers have different power curves. I have measured quite a few and created a simple USB sensor that doesn't require an ANT transmitter and receiver.

    With a third order polynomial curve fitting algorithm the power curves are very precise by taking various data points (watts versus speed).

    You can see the results here,



    Posted by Michel, 24/11/2013 1:55am (1 year ago)

  • Just looking for this.
    I'm a programmer too.
    I want to implement the speed-power curve.
    In which source file must this be done?
    Jason can jou give us some support?

    Posted by Pietje, 04/03/2013 1:35pm (2 years ago)

  • @Joe I had to do a similar jig around with data that had already been recorded into GoldenCheetah once I had worked out the equation. I looked at the published chart and as I had access to a power metre decided that it would give better results and more importantly specific to my unit.
    As for exporting to other services. I export to a tcx file and manually upload to Strava as the Strava API does not allow the upload of speed data!! So I get heart rate, cadence and power but no speed. Via the tcx file I get it all. I can't comment on the Garmin side as I have not used it for a long time. By the way I'm using the development build for the export that has had fixes which may not be in the current production builds.

    @Jim unfortunately although it's an easy process to add the equation into the GoldenCheetah code, getting the project to compile is far from easy! Your best bet is to post your equation to one of the core developers for inclusion in the current development builds.
    Although the build I have works for me, it's not stable across the whole feature set and I have had to disable a few bits that are still under heavy development from the core team, or that I just could not get to build as I don't have access to the legacy libraries.
    It would be great if you could add a new trainer equation via the settings section, unfortunately I don't have enough knowledge of the QT framework to make this happen.

    Posted by Jason Stratford, 08/02/2013 2:37pm (2 years ago)

  • Hello: I have been trying to do something similar, but I had hoped to "plug in" a column for power into my Garmin .fit file, then just easily upload it to Garmin Connect.

    I took the published CycleOps power curve for this trainer (the Jet Fluid Pro), blew it up to 4X size, then picked off points for every 50W up to 750 watts, so I had x(speed) and y(power) values from about 0-30 mph, and 0-750W. I then plotted these points into MATLAB, a mathematical software package, which has a tool that will tell you what the cubic polynomial is for the curve you plot. For the JF Pro, the polynomial happens to be: -0.46095+2.4455x+0.2232x^2+0.01844x^3, where x is speed.

    I then imported my trainer ride into GoldenCheetah, and copied the speed column from the "Edit" section to an Excel spreadsheet. Then, in the next column entered in the polynomial equation, with the first column being "x". I then copied the new "power" column I just created back into GoldenCheetah (you'll need to add an additional column), and voila! It gave me all of the power graphs.

    So then I compared what Garmin Connect and GoldenCheetah gave as a total power result. For a 35 minute ride (just for this experiment) Golden Cheetah says my total work was 940kJ, or 224.42 kcal, while Garmin Connect (using my age, heart rate, weight, age, etc.) says that the workout was worth 553kcal. Note: the Garmin was set to use the infamous "220-age" method for max HR I am sure. That would be 180 bpm, but actually my max HR is around 200 bpm.

    While all of that is great, I have not been able to successfully export the GoldenCheetah data to GarminConnect or Strava, as I get some kind of error. If I figure it out, I will let you know.

    Posted by Joe Meier, 29/01/2013 7:05pm (2 years ago)

  • Hi,

    I was interested to read this as I have been thinking about doing something similar to add the turbo trainer that I use (tacx satori) to golden cheetah. I have worked out the polynomial equation to relate speed to power, but have no idea how to add this into golden cheetah.

    Any chance of a guide on how to do this? I think a lot of golden cheetah users would be interested.

    Posted by jim, 08/01/2013 9:50pm (2 years ago)

RSS feed for comments on this page | RSS feed for all comments