Here’s what I’ve tried for gravity calibration so far:

Sit Phoebe on the flattest platform you can find. Sensors should read (0, 0, 1)g. Save the actual values to file and use each flight. Take-off OK, but drift terrible suggesting angle errors – suggesting not just sensor offsets but gain errors too (hindsight applied liberally). This ‘solution’ was the default for many months until I really started trying to actively attack drift.

Next try the same, but with temperature compensation – convert multiple readings of “(0, 0, 1)” like above against temperature, and use excel to produce a trend-line linear equation for any temperature. Good, but still no effect on drift, because I was ignoring the possibility of gain as well as offset.

Then the mathematical approach, but still ignoring gain: if the accelerometer was perfect, and not accelerating, then the combination of all 3 dimension sensors must read 1g regardless of surface tilt.

√(a_{x}^{2}+ a_{y}^{2}+ a_{z}^{2}) = 1

where sensor values = real values + offset. Trouble here is too few equations with too many variables to find (or perhaps not, read on…)

So I went back to the experimental side, and ran 4 tests, with Phoebe tilted towards each leg in turn, trying to guess the equation that might find a fixed offset for each dimension. No luck, but again hindsight reveals I was tilting in 3 axes not two so all my guessed equations could not be right. But I hadn’t spotted that.

I had considered all this in the past, buying a perspex cube inside which I could strap the unchristened Phoebe, measure g in 6 directions, and work out both offset and gain. Sadly even duct tape isn’t strong enough to strap her down well enough, and I had much bigger problems back then

But today is a new day and after a good night’s sleep with my thinking cap on, with it comes a new plan to allow for gain as well as offset. Start with a test platform tilted at an angle. Sit Phoebe on that platform, both nose down and nose up, and read those values.

Then

a = g * (s + o)

where a is expected value for gravity, g is the gain, s is the sensor reading and o is the offset.

Nose down ‘a’ and nose up ‘a’ should be the same value with opposite signs leading to

g * (s + o) = - g * (s' + o) g * (s + s') = g * 2 * o

So

o = (s + s') / 2

Then knowing the angle of tilt from my spirit level combined with the fact that the perfect sensor reading for the angle would be sin θ (with units of g) leads to

a = sin θ g * (s + o) = sin θ g = sin θ / (s + o)

I suspect that just an approximate value for θ will suffice, as the equation right at the top could be used to fine tune all the gains equally to ensure 1g at any angle of tilt.

Time to stop talking and get on with it. Here’s the raw data I got:

Raw Temp X accel Y accel Z accel X gyro Y gyro Z gyro FD -4011, 24.732941, -0.142926, 0.012745, 1.050931, -0.053121, 0.025203, -0.000613 -4003, 24.756471, -0.142944, 0.012847, 1.050797, -0.053175, 0.025116, -0.000586 -4007, 24.744706, -0.143027, 0.012854, 1.050942, -0.053439, 0.025573, -0.000224 AD -4269, 23.974118, 0.158685, 0.007537, 1.050188, -0.051737, 0.025540, -0.000832 -4280, 23.941765, 0.158802, 0.007494, 1.050043, -0.051684, 0.025404, -0.000848 -4269, 23.974118, 0.158779, 0.007461, 1.050281, -0.052030, 0.025653, -0.000663 LD -4119, 24.415294, 0.005269, -0.140297, 1.050463, -0.052647, 0.025136, -0.000694 -4105, 24.456471, 0.005559, -0.139865, 1.050735, -0.052635, 0.025112, -0.000635 -4117, 24.421176, 0.005273, -0.140439, 1.050992, -0.052608, 0.025244, -0.000740 RD -4057, 24.597647, 0.010099, 0.160093, 1.050826, -0.052801, 0.025332, -0.000706 -4046, 24.630000, 0.009812, 0.160029, 1.050554, -0.053320, 0.025580, -0.000406 -4055, 24.603529, 0.009934, 0.160293, 1.051040, -0.053330, 0.025560, -0.000511

where FD = fore down, AD = aft down, LD = left down and RD = right down by 10°.

That results in the following

x_offset = 0.007894833 x_gain = 1.28560825 y_offset = 0.009969 y_gain = 1.333382476

Same thing can be done with the z axis using the same data slightly differently:

o_{z}= (s_{z}- s'_{z}) / 2 a_{z}= cos θ g_{z}* (s_{z}+ o_{z}) = cos θ g_{z}= cos θ / (s_{z}+ o_{z})

Resulting in the following – you get two sets of possible sets of offsets / gains depending on whether the tilt is fore / aft or port / starboard.

z_{fa}_offset = 0.000359667 z_{fa}_gain = 0.936797208 z_{ps}_offset = 0.0000383333 z_{ps}_gain = 0.937294721

Although the offsets are quite different between both samples, they are an order of magnitude smaller than the X and Y axis offsets so I’m not bothered – the gains match nicely which is reassuring. Because I didn’t turn Phoebe on her head, it’s not possible to find the offsets, so essentially, the offsets are 0, and the gain is covering the discrepancy.

And finally, some sanity checking (not with the wife this time) that everything I’ve done here matches the equation I showed at the start based upon the 12 samples I took.

√(a_{x}^{2}+ a_{y}^{2}+ a_{z}^{2}) = 1

There’s actually 24 sanity checks as the z axis gain and offsets could be calculated from both the fore / aft (pitch) tilt values or the left / right (roll) values:

1.006204657 1.007968538 1.005967585 1.007731109 1.006276408 1.008040318 1.004816622 1.006578528 1.004608175 1.006369695 1.005035531 1.006797684 1.007888677 1.009651313 1.008157198 1.009920557 1.008939806 1.010703849 1.008478641 1.010242242 1.007941093 1.009703971 1.008978921 1.010743092

And actually, I’m really pleased with that – errors are primarily going to be due to the rather course measurement of 10° of tilt. Next steps:

- test the values above to see what happens live
- refine the test rig for accurate angles
- re-run the test at multiple temperatures and throw the gains / offsets into excel for adding temperature related trend lines.

On a roll again!

Pingback: Math(s) help please! | PiStuffing