Settle down…

Settling Time

Settling Time

It looks at first glance at this test that simply allowing some settling time would significantly reduce the level of sensor drift. X and Y aren’t 0 due to some very small angle of tilt during the test; what’s looking promising though is that throughout several similar tests, the Z axis measure of g always stabilizes significantly around 10s.  I don’t know whether that’s related to temperature, but I plotted it just in case.

So for indoor flights where the temperature environment is stable, the fix may well be to just allow more time for the temperature and sensors to settle down.

Clearly for outdoor flights mid-winter with cold winds, the sensors are going to need to be wrapped up nice and cosy warm in their own onesie.

You put your right prop on..

your right prop off.
on, off, on, off
and smash into a wall.
You do the hokey cokey and you turn around.
That’s what it’s all about!

Why do all my crashes break a right hand, ACW / CCW rotating prop?  I have so many spare lefts it’s getting embarrassing!

Though it wouldn’t help that sometime (I think yesterday) I fitted 10″ instead of my normal 11″ props to Phoebe’s left hand side.  Oopsy – it least that explains the increasing negative (ACW) rotation, eventually leading to the left wall collision.

On the plus side, with the correct props fitted on the left hand side, I got stability matching the take-off angle with the attitude only PIDs (i.e. completely as expected), and zero-drift once the motion PIDs were included too (again, completely as expected).  In other words, absolutely perfect…

…except for the fact she kept climbing; nevertheless still worth videoing.  Two reasons why I didn’t video the flights – they’re called Jacob and Milly; I’m the parent in charge until mid-afternoon so my time for test flights today is very limited!

So back to the Z-axis velocity PIDs, it seems.  I wonder whether the dlpf of 3 (44Hz, 4.9ms lag) could be the cause – either too high or too low – I can speculate on the cause of either way, so I’ll try both dlpf 4 (20Hz, 8.3ms lag) and dlpf 2 (90Hz and 3.0ms lag).


Lightbulb moment…

How many PIDs does it take to change a lightbulb?

None, if the quadcopter can’t get off the ground to break the bulb that’s currently working perfectly.

I’m trying to get Phoebe safe to test indoors (aka. complete autonomous stability and accurate flight plan conformance)

In doing so, some of the changes have introduced a serious downgrade in behaviour and bank-balance; I’ve been tinkering with PID gains but nothing seems to work well.  So it’s now time to understand PID operation properly.  The easiest way to solidify my thinking is to blog it.  So here goes:

QF* X|Y axis difference in desired and real velocity => desired change in QF X|Y axis acceleration to correct that error.  That’s what X|Y velocity PID ‘P’ output does – it produced the required change.

The desired change in QF X|Y acceleration => desired change in QF pitch|roll angle. That’s just some arbitrary mapping to convert the change in acceleration to a change in angle

QF Z axis difference in desired and real velocity => desired change in QF Z-axis acceleration to correct that error.  That what the Z velocity PID ‘P’ output does – it produces the required change.

Now what’s finally(!) becoming clear to me is that it is the ‘P’ in PID that’s responsible to manage the change at a fixed rate, perhaps with some ‘D’ to accelerate / brake the effect of the ‘P’.

But note all the changes above?  Who’s managing the absolute value rather than just the changes?

For example, imaging a constant wind; the quadcopter tilts down at a fixed angle and the horizontal acceleration that produces cancels out the force of the wind, and the quadcopter doesn’t move.  The rotation rate is zero, and there is a fixed angle that’s fighting the wind.

But then the strength of the wind changes.  The increased force it applies is detected by the accelerometers, and compared to the previous stable settings, out comes the change in acceleration and hence the change in the angle the quadcopter is tilting at.  The QF X|Y axis ‘P’ can handle the change, but what if the wind speed stays this high?  The ‘P’ gain could be made high enough to cope, but then it would be awfully juddery to minor changes.  Someone needs to step in to maintain a longer term stability (i.e. absolute values) to which ‘P’ can apply the changes?  Quite clearly the PIDs’ ‘I’ factor.

OK, so what?  Well that’s clarified in my mind who’s responsible for short term changes (the ‘P’) and longer term absolutes (the ‘I’) and hence I can use some intelligence in my tuning rather than just guessing.  I also need to back-out the recently-introduced absolute angle PID (this didn’t make it to GitHub, so no worries there), and return back to using an angular rotation PID with an ‘I’ gain to maintain any absolute angle.

*QF = quad-frame orientation

P.S. I nearly couldn’t bring myself to post this – it’s embarrassing quite how far into this project I’ve got without bothering to really understand how PIDs work.


PIDs model a linear system without having to know all the factors which may affect the system, nor what effect they may have, as long as the affect is linear.

But there’s a non-linearity in the code at the moment (and a bug actually that became cler as I gave the none linearity some thought:

The velocity PIDs’ output is essentially a number representing the desired corrective acceleration.  The bigger the velocity error, the bigger the acceleration required to fix it; they are proportional.

For constant acceleration:

v = a * t

Or if the acceleration is not constant:

v = ∫ a dt

Similarly the rotation PID’s input is essentially representing the desired change in angle, and the output is the desired rotation rate applied to the ESCs / motors to carry out that change; again they are proportional.

For a fixed rotation rate, R:

θ = R * t

Or if the rotation rate is not constant:

θ = ∫ R dt

But there’s a problem turning the corrective acceleration (the output from the velocity PID) into the desired angle (the input to the rotation rate PID).  Here’s the current code.

 pr_target = qvx_out
 rr_target = -qvy_out

There’s two problems with the code above.  It’s mapping the qv*_out accelerations to a rotation rate.  But the acceleration in the quad X and Y axes is not proportional to the angle (for examply 0º change gives 0 change in acceleration; 45° gives 1/√2 acceleration change and 90° gives full power acceleration change.  Notice the underlined above – they don’t match and that’s the bug.  To add to the complexity, it’s not actually known what the angle change actually is – it’s not an absolute angle wrt the earth gravity; it’s the change in angle since last time so an integration of the gyro output or the gyro change since the last set of motion processing. But currently that’s not what is fed into that PID – it’s a rotation rate.

So once more, I have a rewrite of the code shown above to allow for the non-linearity, and the result is fed into the inner PID as a desired angle change and compared to the integrated gyro angle change to come up with the rotation rate.

A good thing then that the weather has gone lousy again, so I have plenty of time to think it through properly and implement the changes.

P.S I’m going to apply these changes to the thread + signal code as although its use of threads provided no performance improvement in data collection rate, the code is a lot cleaner / tidier both in allocation / ownership and freeing of variables, and has a nice clean split between locally owned and global variables.

All good things come in 3’s

3 flights this morning – all identical – and good.  Vertical take-off, and no drift.  Sadly then a cold breeze took the sensors outside of the calibration range, and she shuts down mid-air.  No damage though.

I hope I can resolve the temperature calibration by adding a bit of d gain to the thermostat PID, but if that fails, then the only option is to encase her which is hard as there’s not much space between the top and bottom plates where she now lives.

Fingers crossed for the D-gain.

Hot is the new cool!

After a very useful conversation on the Raspberry Pi Forum, it turns out all I need to temperature manage the MPU-6050 is a resistor.  Instead of using the Peltier to heat or cool the IMU to a mid-range arbitrary temperature, you use a resistor to heat the IMU to a safe above-ambient temperature – say 40°C (104°F, 313K).

Many SMD resistors will sit on the 4mm x 4mm top plate of the MPU-6050.  They tend to be rated at up to 1W max power rating and roughly 70°C at max power.

Taking power direct from the 5V battery means the current to supply max power to the resistor is (P = VI)

1W/5v = 0.2A

That’s a resistor of the order of (V = IR)

5V/0.2A = 25Ω

With that, PWM will prevent the resistor melting, and the MPU-6050 temperature sensor will provide feedback to maintain the chip at 40°C

Then all I need is a mosfet to switch 5V through the 25Ω resistor based on the GPIO pin 3.3v PWM.

Google “crystal oven” – this uses an op-amp, thermistor and resistor to do analogue temperature control of oscillator crystals which also drift with temperature.  In my case, the op-amp is replaced by a PID driving PWM output, the thermistor by the MPU-6050 temperature sensor, and the resistor stays the same.


Countdown to CamJam: 6 days to go

A day spent inconclusively tuning horizontal PIDs’ gains, with some integration tweaks to get better accuracy of velocities from the accelerometer, as yet untested, due to a bad beer last night (just 1 pint, guv) which left me after lunch today, staring down a toilet bowl, with undigested lunch staring back up at me.

The PID tuning goes loosely along these lines:

  • the P gain is there to maintain a fixed target velocity
  • the I gain is there to return Phoebe back to any point she drifts away from
  • the D gain is there to apply additional acceleration / braking to stop drift.

It’s visible working, but it is very sensitive – change one gain, and the effect on the others’ change radically – to some extent you can use some structure, but ultimately it’s also a lot of guess work and gut-feel which doesn’t sit well, the way my gut is currently feeling.


Countdown to CamJam: 7 days to go


  • one bug fix to integrated the gyros rather than just using the last sample
  • one deletion of redundant conversion from horizontal velocity to required angle whose PID is ancient history
  • retune the horizontal PIDs’ gains
  • test flight leading to a number of literally flipping crashes as my guestimate PID gains were way too high
  • fix resultant Phoebe who wouldn’t boot after crashes – SD card socket damaged irreparably – new model A (reserved for the now unnecessary radio control)
  • retune again with much reduced PID gains resulting in…
  • final test flight of the day: she takes off at the angle she was tilted on the ground resulting in rapid backward movements which then slows, stops, and she then returns to the point she took off from.

Net: probably the best motion tracking flight yet, but the day would have been much more satisfying had I not had been forced to rebuild her mid-way through.  Still on track for CamJam in 1 week.

Haven or Hell?

Just back from just over a week’s camping in Minty, our VW Camper Van in the River Dart Country Park: a fantastic place for kids and grown ups – and great value too – go there! After that, off to Burnham-on-Sea Haven holidays camp-ground – a very different experience but the kids loved it – and if the kids are happy, so are their parents!

Anyway, with no internet and no Raspberry Pi’s, I had to engage my brain in isolation; the net results of which are

  • A while ago I’d achieved the level of code / calibration equivalent to an off-the-shelf quadcopter – these generally have 2 PIDs in the X and Y axes controlling stability and absolute angle – trouble is I didn’t realize that back then when Phoebe also had that PID structure; my target was (and still is) autonomous control, whereas this PID layout also requires “the nut behind the wheel” – i.e. a human being with Radio Control.
  • I still have a couple of lines of code left from the days when I did have the absolute angle PID (as opposed to the motion PID now controlling things), and these are probably causing trouble; first job tomorrow is to take them out.