Fed up of Phoebe

I’m giving up on Phoebe and adding new sensors using the IMU FIFO code.  The final nail in the coffin was I spotted I2C errors while I was trying to diagnose the squid problems.  I2C errors rule out using the IMU FIFO as the code then gets out of sync with what data it’s getting from the FIFO.  That means Phoebe has to switch back to using the data ready interrupt code, which in turn means she can’t periodically do something else like read other sensors because she can’t afford to miss the next interrupt and hence the next batch of data.

I’ve never been able to find the source of these I2C errors but I guess it’s the PCB, and I’m not going to get a revised version designed any time soon based on speculation alone.

Zoe on the other hand is still working perfectly – no I2C errors with identical code perhaps because she’s the daughter of Johnny Ball, a science presenter from my era, who also has cartoon appearances on the Raspberry Pi site.  But more likely is that she’s a Zero not an A+ and running a different PCB design as result (both mine and A+/Zero).  Unfortunately Zoe would need a new PCB to add the URF for vertical motion tracking, and she could never have a camera for the horizontal motion tracking – PiZero’s don’t have the camera socket.  So Zoe’s is essentially finished other than fine tuning.

So this project is grinding to a terminal halt for the moment until either an A2 appears on the market allowing me to split the DRI code from the motion processing and connect them with an OS FIFO, or I get a new PCB done for an A+ where there’s no guarantee this will fix anything.


A couple of photos of Phoebe resembling (to me at least) a dead octopus.  On the top left of the PCB, you can see the new regulator – she’ll no longer run off a battery bank; instead the regulator is fed directly from the LiPo.  On the bottom-right of the PCB, the additional I2C wires heading underneath. Oh, and the camera wire…



…With the demise of the battery bank, as you can see from this underside shot, there’s now somewhere to put the ultrasonic range finder and camera for vertical and horizontal motion tracking respectively.



These updates were due to be for Chloe with her 4-core B2, but due to a total lack of forethought, it can’t be done: the B2 is too big to fit between the top and bottom plates so it needs to go on top;  the LiPo is also too big to fit between the top and bottom plates, so it needs to go underneath.  Which leaves nowhere to put the new sensors. D’oh.  Chloe is packed away again, pending the arrival of the A2.

The future’s bright; the future’s orange!

Well, tangerine actually!

With the IMU FIFO code taking the pressure off critical timings for reading the IMU, a huge range of options have opened up for what to do next with the spare time the FIFO has created:

  • A simple keyboard remote control is tempting where the QC code polls stdin periodically during a hover phase and amends the flight plan dynamically; ultimately, I’d like to do this via a touch screen app on my Raspberry Pi providing joystick buttons.  However for this to work well, I really need to add further sensor input providing feedback on longer-term horizontal and vertical motion…
  • A downward facing Ultrasonic Range Finder (URF) would provide the vertical motion tracking when combined with angles from the IMU.  I’d looked at this a long time ago but it stalled as I’d read the sensors could only run at up to 100kbps I2C baudrate which would prevent use of the higher 400kbps required for reading the FIFO.  However a quick test just now shows the URF working perfectly at 400kbps.
  • A downward facing RPi camera when combined with the URF would provide horizontal motion tracking.  Again I’d written this off due to the URF, but now it’s worth progressing with.  This is the Kitty++ code I started looking at during the summer and abandoned almost immediately due both to the lack of spare time in the code, and also the need for extra CPU cores to do the camera motion processing; Chloe with her Raspberry Pi B2 and her tangerine PiBow case more than satisfy that requirement now.
  • The magnetometer / compass on the IMU can provide longer term yaw stability which currently relies on just the integrated Z-axis gyro.

I do also have barometer and GPS sensors ‘in-stock’ but their application is primarily for long distance flights over variable terrain at heights above the range of the URF.  This is well out of scope for my current aims, so for the moment then, I’ll leave the parts shelved.

I have a lot of work to do, so I’d better get on with it.


Blind, deaf, disorientated, lost and scared of heights…

and yet, amazing.

So in that last video of a ~10s flight, Phoebe drifted about 1m when she shouldn’t have.  To me, that’s amazing; to you, that may be underwhelming.  So here’s why you should be amazed.  Basic school math(s):

distance = ½ x acceleration x time² ⇒ plugging in the numbers above says she was accelerating at 0.02m/s² (2cm/s²) instead of zero to travel 1 meter in 10 seconds.

Gravity is roughly 10m/s².  The accelerometer is set to read up to ±4g.  So that’s a range of 8g or roughly 80m/s²

So 0.02/80 * 100 = 0.025% error or a ±8 error value in the sensor range of ±32768.

Now the critical part – the sensors are only rated at 2% (±655) accuracy, and yet I’m getting 0.025% or 80 times that degree of accuracy.

And that’s why I don’t think I can get things very much better, whatever I do.

There is a slight chance that when the A2 is released (sounds like that’s shifted to next year now), I may be able to run the sampling rate at 1kHz without missing samples (I’ve had to drop to 500Hz to ensure I don’t miss samples at the moment).

Other than that though, she needs more sensors:

  • camera for motion tracking (!blind)
  • ultrasonic sensors for range finding (!deaf)
  • compass (!disorientated)
  • GPS (!lost)
  • altimeter (!scared of heights).

but they’ll also need an A2 for the extra processing.  So this is most definitely it for now.

Accelerometer drift proof and solutions

These are readings direct from the 3 accelerometers with virtually zero code tinkering – specifically no subtraction of gravity; the only code modifying the sensor data values is fixed calibration values, fixed unit conversion and averaging. None of these three should cause the decline in the Z-axis (yellow) line against the right-hand axis.

Z-axis drift

Z-axis drift

So I need to do something about this, in particular the Z axis which is the cause of my ever climbing flights.  3 approaches:

  1. give in and add an altimeter – but I’m waiting for the next revision of the DroTek board that has the pin spacing I needs – however this wouldn’t be ideal for indoor flights due to air pressure changes as people open doors etc
  2. give in and add ultrasonic range finders – again not perfect for a variety of reasons – firstly it’s I2C is only 100kHz rather than the 400kHz for the MPU6050 so could slow things down without some very careful coding;  secondly it’s tracking distance to ground where as the accelerometer is tracking from takeoff point – so in a lecture theatre, takeoff from a table would give horizontal flight from the accelerometer, but a rapid descent as the quad passes over the edge of the table, also possible causing two of the arms to clip the table; third and finally, I’m not sure how well a URF will perform on grassy rather than hard surfaces.
  3. filter the accelerometer output to smooth the acceleration (the spike at one second in the graph above) but trace the steady drift downwards; simplest would be yet another complementary filter, merging in fractions of latest accelerometer readings into the initial value in the earth axis; better though would probably be a Kalman filter where the prediction it provides may well be able to remove the spikes completely – it’s also easier as there’s just a single source of the data being filtered, unlike the current complementary filters which are used to merge angles from gyro and accelerometer.

So option 3 it is, though as always, I’ll chicken out on the Kalman unless the complementary doesn’t work well!

Code updated on GitHub

I’ve reworked the code so the bulk is a python import library (Quadcopter.py), and qc.py is now just a shim header to import the bulk of the code.  Imported libraries are pre-interpreted and the results stored in bitcode (Quadcopter.pyc).  If the .py code hasn’t changed since the previous run, then the interpreter picks up the .pyc file instead; the .pyc file is automatically generated if the .py and .pyc don’t match.

Why bother?  I thought I’d see what sort of performance improvement it would yield.  The answer is minimal – perhaps 2% – not really a surprise as the bulk of the processing is reading the sensors, and that happens at a fixed period that the code can never go faster than, but it was worth a try, and now it’s done, I’ll leave it in place on GitHub.

In passing, you may have noticed that Phoebe’s new built is not using the URF; that’s because I’m missing a connector that Farnell have on back order, but in the meantime I need to test the physical rebuild.  A Cube Calibration of gravity seems to have sorted her consistent forward drift, and now I have the same sort of sluggish self-correcting drift I had previously.

Next step is to do a double check on horizontal velocity tuning, as I think I may not be putting enough P gain into the PID.  Weather looks good this weekend, so I’ll let you know how it goes.


I took Phoebe out for a flight yesterday to test a fix for the URF, but she couldn’t get the thermostat to warm up enough towards the calibration temperature for the flight to proceed.

In contrast, I took Chloe (see below) out for her maiden voyage this morning, and she reached calibration temperature in seconds, and flew better than Phoebe has ever done consistently.  That didn’t surprise me; the location of LiPo and A+ have swapped – center of gravity is now only just below the props, Chloe’s sensors are below but nearer the COG and they are protected much better from prop noise as a result.

She ain't heavy, she's my sister.

She ain’t heavy, she’s my sister.

The cause of Phoebe’s heater problem (I think) is the difference in power consumption between the A and A+.  Phoebe is an A possibly drawing 750mA; combined with the heater, drawing 500mA, I suspect that’s breached the battery bank limit of 1A, and it engaged the current limiter.

With Chloe, power convertion of the A+ is much more efficient, and I suspect that means that even with the heater, the battery bank remains happy.

So I’m in the process of converting Phoebe to an A+ and Beret – at the same time, in putting Chloe together yesterday, I found her beret PCB layout I used for her B+ wasn’t good for the A+ – it made it hard to plug in the ESC and heater wires.  So Phoebe is going to get a revised Beret layout.

Chloe and Phoebe will remain functionally different: I’ll continue playing primarily with Phoebe and her URF, while I’ll leave Chloe on the side-lines still pending a new IMU with compass and barometer.

What do you get if you cross an accelerometer with an ultrasonic range finder?


Pink is the range finder distance differentiated against time giving velocity in the quad Z axis – note how spikey it is.

Green is the accelerometer output integrated over time giving velocity in the quad Z axis – note that it’s drifting downwards between 6 and 10 seconds when the quad is actually hovering – I know because I’m holding it in my hands.

Orange is what you get when you fuse these together with a complementary filter – note it doesn’t drift downwards, and much of the spikiness is gone.

Velocity fusion

Velocity fusion

Time for real test flight tomorrow – weather is looking good too.

Time to compromise

My aim with this project was to make a quadcopter with Python and a Raspberry Pi and as little else as I could get away with.  As the project slowly progressed, this aim refined to include autonomous control and use of only accelerometer and gyroscope as the sensors.

It’s clear now that the variability in the accelerometer Z axis (despite tuning) is messing up most flights, and I need something else to help it.  I’d hoped to use a barometer / altimeter on the same breakout as the existing IMU but I need to wait for the next revision of the breakout from DroTek, and that won’t happen until their current stock sells out – perhaps not until Easter next year apparently.

So plan B in the meantime is to use one of the ultrasonic range finders I bought strapped to Phoebe’s underside to read vertical height and differentiate over time to get vertical speed, and then mix that with the integrated (accelerometer Z axis – gravity) speed with a complementary filter.

This shouldn’t be hard – I already have built a prototype that works well.  The hardest part it working out where on Phoebe’s underside I can attach the sensor without it getting mauled on landing!