Gravity calibration, past and present…

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.

√(ax2 + ay2 + az2) = 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.

Accelerometer calibration test rig

Accelerometer calibration test rig


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


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

-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
-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
-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
-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:

oz = (sz - s'z) / 2
az = cos θ
gz * (sz + oz) = cos θ
gz = cos θ / (sz + oz)

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.

zfa_offset = 0.000359667
zfa_gain = 0.936797208
zps_offset = 0.0000383333
zps_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.

√(ax2 + ay2 + az2) = 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!

Suntan or just a bit grubby?

I coded the trend-line offsets for the accelerometer last night and have just take Phoebe out into the back garden for a quick sanity check test flight.  There was no wind, and very little drift, so the results are a bit inconclusive for the moment (other than no harm was done), but it’s probably worth my while rerunning yesterday’s trend-line tests to get the best values I can.

At the same time, Dave pointed me in the direction of gyro temperature sensitivity too.  I’m less concerned about this since the flights are currently short, the gyro is calibrated per flight, and the gyro is only used short term for rapid detection of changes in tilt – longer term, the accelerometer Euler angles take over via the complementary filter.  Still, probably worth investigating just in case, if only for longer flight drift.

Finally, Jeremy requested some flight sensor data – I’ve attached the .csv file (Excel can turn this into a spreadsheet) corresponding to one of this morning’s flights.  Just leave a comment if you want me to churn out some graphs!

10s flight stats

Attempted Murder Suicide

It’s been a bit quiet here for the past few days as I’ve been testing drift control and until yesterday, there wasn’t a lot to report, so I didn’t bother.

Yesterday’s testing seemed to show progress in the right direction – Phoebe sort of held her own against a 20mph tail wind, before tilting into the wind at an increasing angle towards me.  So I called it a day, knowing the problem was with the ‘matrix’ I was using, and set out to find the problem.

So I went out to the park earlier today with a revised version of the matrix to try.  And that’s when it happened – despite the similar 20mph tail wind, she shot up off the ground, and headed straight for me, directly into the wind.  I had to dive off the stool I was on (she just slashed open the sleeve of my down jacket) and having missed me, she smashed herself into the ground, destroying one propeller and having a really good go at chopping several cables, which luckily they were out of reach.

I have no idea what the lesson is from the software / sensors point of view yet, but I have definitely learned Phoebe is a long way from being trustworthy!

P.S. And do you know what’s worse, Phoebe managed to unplug her power supply, meaning no stats were written (they’re stored in shared memory and dumped to file at the end of each run), meaning I’ve got to do the same thing again tomorrow!

Park Life

I took Phoebe for a play in the village park just now – it was a huge amount of fun for us both!  When the local kids are at school, it’s empty, and there’s a football pitch sized area of just grass.  It’s also just a few meters higher than our garden (we’re at the lowest point in the village), so while our lawn is currently somewhere between a quagmire and a lake, the park just had soft grass to land on, which, it turned out, is a very good thing!

The only downside is our garden has 6 – 10′ stone walls around it shielding it from the worst of any wind; the park is next to an open field, and today a 20mph wind was blowing.  So I sat, back to the wind and let her rip.  Off she flew at probably 20mph and reached the other side of the pitch in no time at all.  Her wind-drift protection wasn’t engaged so that’s actually what I’d expected (which is why I sat where I did), but I was surprised at how effective the wind was!

She did takeoff at a tilt and self corrected as the complementary filter started kicking in.  With dlpf set to 5Hz, I think I should be able to pull in the accelerometer much quicker.  I got it down to 10ms but I suspect I could go lower still.

And best of all, it was fun – there was nobody and nothing other than me that Phoebe could harm, meaning I could just watch the details of the flight and the change of behaviour as I tweak the config – very satisfying!

I’ll definitely be back there next time it’s not raining – Monday’s forecast is looking promising, and the wind is only expected to be just 14mph!

P.S. After reviewing the stats from the final flight, something useful has come from the 20mph flights too:  I’d been tuning the DLPF / complementary filter the wrong way round.  Under the belief that a low DLFP cuts out noise, I’d been reducing the fraction of time that accelerometer Euler angles became dominant.  But as a result, the stats showed I was tuning out the integrated gyro data.  This meant long term stability was fine, but Phoebe lacked the ability to react to the initial tilt she took off with.  So Tuesday’s priority is to see the net effect of the changes I’ve made – to allow more accelerometer data through (DLPF @ 10Hz rather than 5Hz), but then take longer to allow it through the complementary filter (0.2s rather than 0.01s).  Looking forward to seeing the result.

Back on track

Finally, with the new motors, blades, arm and legs, things are back on track.

3 test flights today aiming to find an average ‘hover’ speed.  Only inner most angular rate PID engaged, so there was drift due to the drift of the integrated gyro.  My first flight was once more scary as it also shot up into the sky because the vertical speed PID tried to undo the excessive vertical power applied my guesstimate of the default hover speed (but note not the manic rise that “Scary, very scary” revealed)

The average hover speed is now about 1550us pulse width suggesting these new 1045 carbon props are much more powerful than the 1150’s I had – they are broader and therefore more aerofoil surface area, so it doesn’t surprise me..

The even better news though was no yaw – the stats show no common sharing of power between pairs (front left + back right) and (front right + back left) which is always the sign of the quad trying to compensate for the yaw.  Whether that’s due to motors, props, or frame fixes, I frankly don’t care!  It now means my future flight diagnostics won’t be swamped by yaw.

The only negative was the the integrated gyro drift caused a diagonal drift landing, and once more, another leg died as it stuck a couple of inches in the mud while the quad drifted on!  I’m more than happy to pay that price!

Propeller / motor overshoot

As usual, having a pause for thought has resulted in a plausible cause for the very different tests results between yesterday and today.

Both days I was using the cheaper, lower powered motors with plastic props. The only difference was yesterday the battery was charged to perhaps 11.5V – today nearer to 12.2V.

Imagine that the combination of heavier plastic blades (rather than carbon) combined with higher battery charge level creates sufficient angular momentum in the blades that the motor rotor overshoots the motor stator coils it’s supposed to just reach and instead it continues on to the next set. Depending on the number of coils, that would yield a signifiant increase in RPM and therefore lift.

I’d never had problems with the carbon blades; being so light they simply don’t carry anything like as much angular momentum. And the motors they’re attached to have higher Kv value (980 vs 920) and much stronger magnets meaning they had a tighter grip on these lighter blades. The result: lower angular momentum and closer control leading to much reduced risk of overshoot beyond the expected stator coil.

But in these tests, with heavier props and lower powered motors, it seems the motors simply do not have quite enough oomph to restrain the props angular momentum.

Convincing enough for me; time to move back to the better motors and carbon blades.

Scary, very scary!

She’s undergone a complete change of character this morning.  Same test parameters as before, yet she was climbing at about 1ms-1 – at 3 meters I aborted. Luckily no damage done except to my confidence.

Just look at the graph:

Frantic Phoebe

Frantic Phoebe

  •  very noisy vertical accelerometer results shown by faz (cyan)
  • ever increasing vertical speed maximum at 2.4ms-1 shown by fvz (magenta)
  • height of 2m when I aborted (green)

The target vertical speed was 0.33ms-1, and you can also see in red the desperate attempt the vertical velocity PID was making to turn down the power trying to slow her ascent down, and yet it had no effect. It’s almost as though the ESCs were ignoring the incoming PWM and doing their own thing.

I had changed 2 things overnight:

  • I’d decremented the I gain for vertical speed to 10 from 30
  • I’d charged the battery

Neither of these provide sufficient explanation for the huge increase in motor power and lift.

It’s as though someone had changed the motors overnight, and the 630us pulse I measured and tested yesterday as the perfect hover speed was today ridiculously high, and having reduced the VV PID gains to align with yesterday’s 630 hover speed, they were unable to reduce the motor rotation speed sufficiently to stop her manic climb.

I just don’t get it – how can there be such a radical change in lift produced by the motors after a battery charge – for a given PWM they should rotate at the same speed and therefore produce the same level of lift, regardless of battery power.  I’m flumoxed!

I might have to change back my newer motors – they never did this to me. Before I do though, I will rerun this test with various initial hover speeds to see whether they all converge onto a common hover speed via the VV PID. That won’t explain the difference between yesterday’s and today’s tests, but will help to some extent to rebuild my confidence in these motors.

Back to basics test results

  1. The kids playroom is not a suitable location for testing yet – Phoebe was drifting towards a chair and only stopped due to very short flight times I’d set combined with a panic flurry of ctrl-C’s!
  2. Moving outdoors, in a fight between a climbing rose branch and Phoebe’s blades, the branch was cut off clean – the blade was undamaged until it hit the iron railings supporting the rose – I did say the blades were dangerous, didn’t I!
  3. The inner PID tuning is a beauty to behold – beautiful stable hover with virtually no drift despite only roughly horizontal take-off surface i.e. the flattest piece of lawn I could find.
  4. In contrast, the absolute angle PID flight was a complete ‘mare.  Take-off from lawn or absolute horizontal platform both resulted in drift, generally a combination of forward and right, depending on the slope of the takeoff surface.  The drift would end after a bit and Phoebe would start heading back to where she came from.

Lessons learnt and next steps:

  • the sticky feet for Phoebe’s flight controller, plus the redesigned non-slip padding holding the battery in place worked like a dream – no slippage of either.
  • the drift and slow recovery is most likely due to a combination of 3 factors:
  1. the drift is usually in the same rough direction suggesting mismatched / damaged motors in that direction
  2. the complementary filter may need tuning so that any tilt induced by the mismatched motors gets corrected quicker by filtering a greater proportion of the (noisy) accelerometer earlier – it’s a case of compromise between noise and accuracy
  3. the absolute angle PID might need further tuning to increase P and / or D gain.

I’m going to test option 2 first, then 3 because any mismatch in motors should be compensated for by those two factors.

P.S. Just found option 4 for the cause of drift from a non-horizontal surface: the complementary filter initial values at take off assumed a horizontal take-off and then over time, the input from the Euler angles slowly corrects this, but while the gyro inputs were dominant, if the takeoff surface was not horizontal, drift would occur.  However, it’s possible to read accurate Euler angles (sans noise) prior to take off, and prime the complementary filter with an accurate initial setting to which subsequently the accelerometer can increasingly contribute.  I’ve updated the code (not on GitHub yet until tested) and I’ll also see about upping the fraction of Euler into the overall calculation of absolute tilt. angles.

Once you eliminate the impossible,

whatever remains, no matter how improbable, must be the truth.

Although the video from the other day probably showed the best autonomous flight control for a while, there were pieces I couldn’t explain or was unhappy with my speculative explanation.

So it’s time to move into a completely controlled test environment – my kids’ playroom – and check step by step everything that makes up the quadcopter.

  1. hardware – are the arms aligned – are the top and bottom plates flat? Surprisingly, the answer to the second question is no.  I was adding the new sticky feet onto the flight controller (Raspberry Pi + breadboard) and only 3 feet touched the top plate. Yet all four feet touch the table, kitchen work surface and floor.  Time for a replacement top plate methinks.
  2. gravity calibration – it needs to be done as best as I possibly can to avoid it corrupting further test cases
  3. vertical take-off, hover, and landing from a horizontal platform with only the inner most PID (angular rate with feedback from the gyro) in control to maintain horizontal flight with no drift – this can only be a short flight as gyros are prone to drift
  4. vertical take-off, hover and landing from a slightly non-horizontal platform with the absolute angle PID also engaged to control the angle when the gyro drifts – again a completely vertical take-off with 0 drift regardless of take-off platform should be achieved even over a longer flight
  5. finally, add the horizontal speed PID into the mix to make sure it doesn’t change things when the horizontal speed it set to 0.

Now I was planning to do this tomorrow, but now Phoebe has failed at step one, the testing can’t start until she has her new flat top plate.

Slip sliding away

Went out testing yesterday morning aiming to tune the drift code, but it was a complete mess.  I can’t fully explain why, but certainly one factor was the battery and raspberry pi were slipping around in flight, despite being firmly attached with velcro and either none slip padding (for the battery) or non-slip feet (for the Raspberry Pi).  The problem was the moisture still in the air after the morning mist cleared.

So I’ve improved the velcro, made better fitting non-slip padding for the battery, and added double sided sticky tape to hold the Raspberry Pi down, and I’ll try again later today.

It’s hardly worth blogging about this, other than to point out how well attached to the quad frame all the loose pieces must be if you stand any chance of consistent test flights.