From BudgetTrainer to BeagleTrainer

As mentioned in the previous update, until recently I’d been sending a serial data stream to a laptop for processing.

This was primarily due to the curve fitting & floating point maths that I’m using in the spindown calibration process. While this code could likely be replaced in the long term, as it stands now it’s a poor fit for a resource constrained 8-bit micro with no hardware floating point support!

So now I’ve switched development to a BeagleBone Black. This is a small development board capable of running Linux on a 1GHz ARM Cortex A8 processor.


One great thing about the TI Sitara processor on this board is that it includes a pair of Programmable Realtime Units (or PRUs). These run independently of the main processor, with a 200MHz clock speed (5ns per instruction), and are perfect for guaranteed real-time tasks. They are programmed in their own assembly language, but there is also a C compiler (currently in beta) available from TI.

For my purposes, I’ll be using PRU assembly for the timing sensitive hardware interaction (frequency measurement, PWM etc), with the main C code running in Linux userspace on the ARM processor, and using an ANT2 USB stick for the comms.

I’ve already written some initial test code for speed measurement, spindown processing, curve fitting, power calculation, and the ANT+ transmission. The individual pieces are all working separately, now I just need to tie them together under a single control program. Once it’s all been tidied up a bit, I’ll post a link to a new github repo for this code.

When that’s done, I’ll be getting back to some metalwork & preparing new electromagnets for the adjustable resistance control.

Period vs frequency

In my previous post, I was struggling a bit with accuracy on the acceleration component of the power tracking.

I’d originally been calculating instantaneous roller speed from the period between the last two sensor pulses, but I think this was suffering with a bit of jitter in the measurements. For the next attempt, I started to calculate the speed from the pulse count over a set period.

These frequency based results (based on pulses per second) were somewhat smoother, but in order to remain responsive to speed changes, I needed to make the period shorter. The data in the graph below was generated at 4hz, but still smoothed over 4 samples.


To maintain accuracy, with a reasonable number of pulses per period, I’ve also needed to increase the pulse rate. For the above test, I just stuck another three magnets onto the roller, but have since ordered an optical sensor. This should allow very easy adjustments of the pulse rate, just by printing up new encoder disks.


Until now, I’ve been sending the raw speed data over a serial link to a PC, where it’s saved and then post-processed in a spreadsheet. Next post I’ll cover a new development platform, where I’m able to do the curve fitting and power calculations in real time.

Summer slowdown

In a fairly predictable turn of events, my development efforts pretty much ground to halt over summer. But a recent touch of autumnal chill in the air has shuffled the trainer project a couple of notches back up the todo list..

So, progress since the last post? Not much – just the addition of a micro and hall effect sensor to the prototype for some more accurate speed measurement.


This is presently just dumping a serial datastream to the PC for post-processing, while I wrestle with the maths for the un-braked roller assembly. There is obviously work to do, but the very first attempts at calculating speed & power weren’t entirely terrible.



The trainer power consists of the steady state power derived from a spindown test, plus an estimate for acceleration/deceleration (see shonky graph above).

While the steady state power is tracking pretty well already, it’s fair to say the acceleration component needs some work! I think this is primarily down to a very slack update rate from the initial firmware. I’m only sending speed updates to the PC every second, which is then averaging the acceleration over a 2 second window, so it’s this area that I’m aiming to improve on next..

Wheel inertia and a quick sanity check

Rear wheel inertia

After previously calculating the moment of inertia for the roller assembly, the next step was to get a more accurate figure for the rear wheel.

For this, I used the approach given at I’d be the first to confess I don’t quite follow the maths involved, but am happy enough to trust the answer it spat out – 0.079619 kg m².

Just for the record, the complete wheel (excluding skewer) weighed in at 1669 grams on my trusty kitchen scales – and consists of a 2012 PowerTap Pro hub, 11-32 SRAM cassette, 32 hole Kinlin XR300 rim, Sapim laser spokes with alloy nipples, 23mm GP4000S clincher, a random inner tube, plus a light smattering of road grime ;)

Rotational kinetic energy

Now I have a moment of inertia for both the roller assembly and the rear wheel, it’s possible to calculate the kinetic energy of both at any given speed.

The first step is obtaining the angular velocity for both the wheel and the roller. To get this, we convert the road speed in kilometres per hour into metres per second, and from there into angular velocity (radians per second);

ω = (road speed * 0.27777777777778) * circumference * 2π

Then, from the moment of inertia and the angular velocity, can we obtain the rotational kinetic energy;

KE = ½ I ω²

Rolldown test

Prior to building up the speed sensor, I thought I’d perform a quick sanity check of my calculations (and my assumptions) based on some ANT+ data. So, with GC running in training mode on my laptop & collecting data via a USB ANT+ stick, I performed a number of steady speed efforts, along with couple of roll down tests.

The roll down test gives speed against time, but more usefully (thanks to the equations above) kinetic energy against time. From this data I can generate a polynomial expression for the curve, and then differentiate to get the rate of change of kinetic energy at any given speed.

That last sentence is actually the key point of this whole weighing and measuring exercise on the un-braked roller assembly. We have calculated the kinetic energy (in joules per second) that is being lost through rolling resistance at any speed, and by extension the wattage (1 watt = 1 joule per second) we would need to put back in to overcome this resistance and hold a steady state.

The final sanity check against the training mode ANT+ data consists of comparing the actual wattage required for the steady speed efforts against the expected rate of change obtained from our calculations.


At this point, I’ll call that a win! Next step is to build up the speed sensor to get some more accurate data..


Moments of inertia


In order to calculate an overall moment of inertia for the roller assembly, it helps to break it down into a series of simpler geometric shapes. For each of these shapes, the moment of inertia can be calculated independently, and once complete, the results for each section can be added (or subtracted) to produce a total for the entire roller assembly.

As an example, here is the process I followed for the brake disk assembly.

Brake disk

The brake assembly has a thinner (4mm) disk that ends up sandwiched between the electromagnets, and a larger central cylindrical section that fits onto the tapered roller, with both a truncated cone and a cylinder removed from the centre. In these pictures, this is turned onto it’s side, rotating around a central vertical axis. Apart from fitting the page layout better, this orientation makes more sense of the radius and height elements of the equations.


The first step is to calculate the volume of each ‘feature’ from the measured dimensions. From this we can determine the mass, and then use these figures to find the moment of inertia.


There are a couple of equations needed for calculating the volume;

volume of a cylinder:

V = π r² h

volume of a truncated cone:

V = 1/3 π (r1² + r1+r2 + r2²) h

Starting with the thinner section of the disk – the first step is to calculate the volume of a cylinder representing the entire width of the disk (r = 66.5mm, h = 4mm).

We can then calculate the volume of a smaller cylinder, representing everything inside the central section (r = 25mm, h = 4mm). Then if we subtract one from the other, we are left with the volume of just the thin external section. Hopefully the image below makes sense of these three steps;


Then we can perform a very similar process for the thicker central section. First we calculate the volume of the solid cylinder (r = 25mm, h = 26mm), then the volume of the features removed from the centre – in this instance a smaller cylinder (r = 10mm, h = 7mm) and a  truncated cone (r1 = 10mm, r2 = 12mm, h = 19mm). We then subtract the volume of both these features from the starting cylinder, leaving just the remaining material.



Now we know the volume of all the features (and therefore the volume of the entire assembly), we can simply calculate the mass of each feature as a proportion of the overall weight of the brake assembly.

Moment of Inertia

The next step is to calculate the moment of inertia for each feature, just as we did for the volume calculations. The equations needed for this are;

moment of inertia of a solid cylinder:

I = 1/2 m r²

moment of inertia of a cone:

I = 3/10 m r²

You may notice this last equation is for a full cone, so in order to calculate the moment of inertia for our truncated cone, we need to perform one additional step. We calculate the volume, mass, and moment of inertia of both a full cone, and a smaller cone representing the portion that is removed. Subtracting one from the other will then leave us with the value we want for the remaining truncated portion. Again, hopefully the image below makes more sense of these steps;


Once we have the moment of inertia for each individual feature, we can calculate the overall moment of inertia for the brake assembly. This is done by following exactly the same steps of adding and subtracting features that we used for the volume calculations above (i.e. large thin cylinder minus small thin cylinder, large central cylinder minus small central cylinder and small truncated cone).

Roller and flywheel

The same approach was then taken for both the main roller and the flywheel.

For the threaded sections of the roller, I cheated a little and treated them as cylinders with a diameter somewhere in-between the minor and major thread diameters.

Nuts and bearings

For the hex nuts, I cheated a lot and treated them as having an outer diameter  somewhere in-between the flats and the points. At this stage I’ve ignored the mass/inertia of the bearings completely.

I think all this cheating is an acceptable nod to reality, as these aspects only account for a tiny fraction of the overall moment of inertia.

Putting it all together

Finally we can sum the moment of inertia of each part (brake, roller, flywheel, nuts) to come up with an overall figure for the roller assembly,  which by my current reckoning is 0.005418 kg m² (allowing for howlers in my calculations/spreadsheet which I may yet uncover!).

There are elements outside of the roller assembly that will need to be considered, primarily the moment of inertia of the rear wheel. It is notable that my calculated moment of inertia for the roller assembly is considerably smaller than a very rough estimate of the moment of inertia for a rear wheel (~ 0.1 kg m²) .

Of course the roller is rotating a lot faster than the wheel, which greatly increases the angular momentum, but even so – my gut feel is that I ought to double check my figures. Either way, any gross errors should become apparent once I start performing some spin down and power testing…

Next steps

Next up will be measuring the moment of inertia of my powertap wheel, and then putting together a speed sensor to feed the roller data back to the PC for processing.

A quick recap

I thought before getting too far into the next steps of the build, I’d quickly describe what I’m aiming for..

As mentioned in a previous post here, the v1 build has been pretty successful – I’ve been using it now for the best part of a year with no real issues. Still, the nagging feeling remains that I’d like something with sufficient accuracy that I don’t need to rely on an external power meter, which is where the v2 build comes in.

Looking at the unit as a whole, I think it’s helpful to break the overall resistance into two separate areas. Firstly, there is the resistance of the un-braked roller assembly (rolling resistance of the tire, bearing drag etc). Secondly, there is the deliberately induced resistance from the eddy current brake.

Modelling the un-braked rolling resistance

I am assuming that it won’t be sufficient to simply take a series of measurements from test rides and use them as a basis for the power requirements. The rolling resistance is liable to change with temperature, tyre pressure, and clamping pressure (or rider weight, depending on the design of the trainer frame). Therefore, I believe I’ll need to add an element of dynamic calibration through a spin-down process.

I think the following steps are required;

  • Establish the moment of inertia for the roller assembly
  • Instrument the roller for speed (using a hall effect sensor)
  • Measure the deceleration through a series of spin down tests

From knowing the speed and the moment of inertia, I can derive the stored kinetic energy in the roller assembly. Measuring the rate of deceleration should then allow me to obtain the rolling resistance in watts, and calculate a speed/resistance curve.

Another limitation with the v1 trainer was that the resistance maps assumed a steady speed. By measuring the speed more accurately at the roller, I should also be able to factor any acceleration/deceleration into the power model.

Measuring the braking force

With the above (hopefully) taken care of, the next stage will be accurately measuring the braking force applied through the eddy current brake.

This would once again be susceptible to changes in temperature during operation. As well as affecting the electrical resistance & the current flow in the electromagnet coils, it would also alter the electrical resistance of the aluminium disk & therefore the strength of the induced eddy currents.

I think in this case, the best approach would be to actually measure the force applied through the use of a strain gauge on the electromagnet assembly – and yes, this would also be temperature dependant, but at least it’s only in one place.

Next steps

That’s the plan anyway, as with all these things, it generally becomes clearer to me as I’m working through the process!

Next post will cover calculating the moment of inertia..

Brake disk

The new aluminium eddy current brake disk is machined and mounted on the roller.


Just for a change, the next step will be some maths instead of machining! I want to model the power curve for the un-braked roller, which I think I can do by calculating the moment of inertia, and performing some spin down tests..