FIFO overflow

The IMU FIFO has a fixed size, so it can fill up if not read frequently; it’s then configurable whether the IMU stops adding to the FIFO or overwrite what’s there already.  Either way, this results in data corruption.  I’d heard, and a quick test confirmed that the FIFO size  is 512 bytes.  The same test also revealed it takes 0.064s to empty a full FIFO byte-by-byte or 0.000125s (1/8000)s to read a single byte or 1.5ms to read the 12 bytes that are a full set of sensor data.

For the FIFO code to work, I need to read the FIFO and update the ESCs often enough in comparison to the sensor sampling rate to ensure the FIFO never overflows.  The rate for updating the ESCs is arbitrary; experience say about 100Hz is a good value.

The other factor is how long the motion processing takes; again experience with the hardware interrupt code suggests this is around 2ms.

A flight loop looks like this:  sleep, empty FIFO, motion_processing.

The question is how long to sleep in order to get the 100Hz ESC update frequency and not allow the FIFO to overflow?

esc_period = 100Hz = 0.01s
read_period = 0.0015s
motion_period = 0.002s
num_samples = sampling_rate * dt

esc_period ≈ sleep_period + n_samples x read_period + motion_period
0.01 ≈ sleep_period + sampling_rate x dt x 0.0015 + 0.002
sleep_period ≈ 0.01 - 0.002 - sampling_rate x dt x 0.0015

I’ve updated the code, and then collapsed it to a simplified version which is now on GitHub.  With some basic PID tuning, flights are back to the equivalent quality Phoebe could do although I need to keep testing for finer tuning and confidence building.


Zoe the Zero – Appendix – Testing and Tuning

I did very little testing before I let Zoe loose – just two pieces:

With the LiPo not plugged in, I ran a flight; this checks that the sensors are working and  tuning data sampling rate to ensure all samples are caught.  Simply run

cd ~/Quadcopter
sudo ./ -f fp.csv

As a result you should see a 20s countdown, a 1.5 second warm-up, ascent (2s), hover (2s), and descent (2s).  Then the length of the flight is shown on screen.  The key here is that the internal timing for the steps through the flight plan is based only on the number of samples captured, and the data ready interrupt frequency; the total time printed at the end is the difference between calls time.time() before and after the flight.  It should read 7.5s with accuracy of 1% or less based upon the above flight plan.  If it is significantly more, then samples are being missed and you need to reduce the dri_frequency.  If it is significantly less, then the data ready interrupt is not working – have you installed the customized GPIO code?

With that passed, the other step is to check the PWM is working, and that the props, motors and ESCs are installed correctly:  the front left and back right props should spin anti-clockwise to match the code’s expectation.  Run

sudo python ./ --tc 1 -h 150

Each prop should spin in turn (front left, front right, back left, back right) for 10s.  Feel the down draft underneath each.  If the props are not turning the right way, swap any two wires on the ESC.  -h specified the PWM pulse size minus 1000 i.e. 150 is 1150us pulse.  This should be enough to get the props spinning but well below the takeoff speed of around 400+.

With those two tests done, she’s ready for a trial flight.  With the motors still powered up run

sudo python ./ -f fp.csv

Be ready with control-C to kill the flight, and I’d strongly recommend running this flight outside on a soft surface (grass).  It should all be fine, but it’s very demoralising to trash your quad in a violent crash on the first flight!

BYOAQ-BAT IX: Testing and tuning

If you haven’t already, please read the previous BYOAQ-BAT articles first – just search for the BYOAQ-BAT tag.

Only one very simple test is required before HoG takes to the air.  With your quad on the ground, and motors and HoG powered up, simply type

sudo python ./ --tc 1 -h 200

Each blade props should spin in turn in the order of front left, front right, back left and back right.  The front left and back right props should spin anti- / counter-clockwise, the front right and back left props clockwise.  If the props don’t spin, increase -h slowly (in tens) until they do.  If any of the props spin the wrong way, swap any pair of the three wires driving the ESC.  If each props is rotating in the right direction, check that each prop is producing a down-draft, not an up-draft.  If there’s an up-draft, then swap the props.

For PID tuning, I’m not going into the details of how to do it from scratch, but here are some guidelines of how you can take my PID gains and tweak them to fit your quad.

First, only the inner PIDs which control stability need proper tuning specific to your quad.  The are the pitch, roll and yaw rate PIDs.  The rest are almost certainly fine for any quad.

In the code, look in CheckCLI at the various i_am_phoebe, i_am_chloe, i_am_zoe and i_am_hog settings:

  • cli_hover_target is not strictly necessary – it’s just used to slowly spin up the motors to roughly hover speed before takeoff.  I general have it set to 500 for 12″ props, 550 for 11″ props and 600 for 10″ props.  This value is the size of the PWM pulse width from the HoG to ESCs in microseconds
  • cli_pr*_gain, cli_rr*_gain and cli_yr*_gain vary with length of arms and power of motors, and the weight distribution of the quad.  The ratio of 2:1:0 for P:I:D seems to work well.  Phoebe has short arms and small props, Zoe had larger props, and HoG has long arms and large props – compare the setting for each to see the effect.  In addition, all my batteries face front to back, so it takes more power to pitch rather than roll, hence the difference between cli_pr*_gains and cli_rr*_gains.
  • finally, cli_vv*_gains are for vertical acceleration, but if you compare Phoebe to Zoe and HoG, you’ll see the setting is inconsistent.  Because of gravity, the only real tuning required is “enough” power; hence small props have larger PID values.

S’no drift!

Found my bravery, so I took this new code outside and flew it.  And it worked!  Vertical take-off and none of the rapid horizontal ‘drift’ into walls or railings.  Sadly it showed I needed some more PID tuning, as she was see-sawing on the X axis, and then exceeded her temperature limit, so died midair, still rotating.  She hit the ground on her side at pretty much the point she took off from (!), stuck a blade in the ground and then continued rotating until she was horizontal.  That was the last of my 11 x 3.7 blades broken, but I have another two sets on order already, but with the state of the postal service at this time of the year, there’s no guarantee they won’t arrive until 2015!

Flight path

Flight path from above – note the scale is in meters!

Distance vs Time

Distance vs Time (vertical units in meters, horizontal in seconds)


Sorry it’s been a bit quiet here – I’ve been working on lots of little bits, none of which individually were worth a blog, but the whole is worth more that the sum of its parts…

  • a complete recalibration of the accelerometer as carefully as possible across 3 axes against temperature
  • some code tidying to sharpen up transition between velocity PID targets – I’d softened these out previously to stop mid-flight reboots due to power surges, the down side being that during a soft transition between state, there’s prolonged acceleration, and that acceleration skews the angles leading to drift – without the softening, acceleration is a short burst, and the angles remain more accurate as a result
  • some tidy up of other commented out bit of code that had historical value that now has depreciated to zero
  • a general spit and polish.

And as a result, I’ve just had a perfect flight.

Flight Track

Flight Track

The units of the graph are meters.  Phoebe drifted only around by 0.25m and self correct according to the plot, and what’s critical is that matches my perception of the flight.

Sadly, because it was just a test flight, I wasn’t rigged up for video – I’ll try and get one done later this week.

On the plus side, I’ll be updating the code on GitHub shortly.  Be aware though that the code is now dependent of VERY accurate accelerometer calibration – use it as is at your own peril.  I’ll blog again how to do the best possible calibration.

Countdown to CamJam: 2 days left

I’m off to London tomorrow morning, and up to Cambridge after work, so I’m packing her up ready for her journey.

She’s probably doing the best she can given the inaccuracy of the sensors, but I’m still not quite confident she’s good enough for an indoor demo, based upon a few tuning test flights this morning.

So fingers crossed for a safe journey and a good day on Saturday, and I’ll update you on the results.

Wish us luck!

P.S. Just cheated and run her through the calibration cube again with the aim of getting the best possible set of sensor readings for the show.

Countdown to CamJam: 3 days left

Today’s aim was to work out how to sort out correct vertical take-off speed / height, combined with reduced drift with a sloped take-off surface.

She’s taking off vertically now, but her vertical scale is out, she rose to 2m+ before attaining hover.  Then I had to kill the flight as she drifted slowly towards the kids’ paddling pool!

The stats show she thinks risen to 1m, suggesting that I’m integrating accelerometer readings incorrectly or rotating the earth axis targets to quad frame wrongly.  Very hard to judge which of these or another issue is the cause.

I’d dearly like to understand this before the CamJam, but time is very much running out.


Phoebe’s perceived flight path

Top down view from above the lawn.

Phoebe's perceived flight path

Phoebe’s perceived flight path

She thinks she drifted consistently to the right by 0.6m and backwards by 0.35m before recovering back to 0m.

My view of the flight

My view of the flight

But that’s not how I saw it!  I’m sure she drifted slowly towards me – in fact, a lot like if I flipped the graph thus →

So I need to do one or more of the following…

  • static sensor tuning as well as the dynamic she does per flight to correct her perception
  • find the bug in the diagnostics which swapped the X and Y axis
  • find the bug in the code which flipped the X and Y axes.

Not sure which yet – I think I need to watch a few more test flights to be really confident of the difference between mine and Phoebe’s point of view.


Bugger stats and logic, use the Force

Having had a quick look over my matrix code last night, and a re-review of the stats, I’m pretty sure that code is good.

So today, I decided to take a different approach: just cram in as many flights as possible, and look for common behaviour.

Each flight took off from my favourite patch of daisies in the lawn, and used identical configuration.  Each flight drifted, but the fore-aft drift seemed entirely random; the port-starboard drift seemed more consistently to starboard, notably in complete contrast to the wall-collision on the port side yesterday.

So absolutely no conclusions can be drawn as yet, but I plan to proceed along the same lines later once Phoebe’s batteries have charged in the hope that some consistency of behaviour starts to emerge.