Same shᴉt, different day.

I went to the neighbouring field that the farmer isn’t using because they are digging for gravel in 90% of it, still leaving a sizeable 10% right next to my house; again tried GPS tracking, and again overshat (overshotted? overshooted? overshot?) significantly.  She started 13 meters away from the orange frisbee based on the GPS position of both, correlating nicely with the video.  She’s facing almost exactly away from the target as passed from the autopilot and logged by the motion process:

 GPS TARGET 13m 173o

The target is in a NNE direction by gut feel and confirmed by the GPS log stats:

GPS tracking

GPS tracking

GPS thought it had travelled about 5.3 meters when in fact this was more than 16 meters, based both on the video and on the GPS itself showing 33 samples at 1Hz with ‘H’ programmed to fly at 0.5 m/s.

Now what’s interesting here are the spacing between the dots on the graph. Since each dot is one second apart, this give the speed the GPS thought it was moving:

GPS speed

GPS speed

As already mentioned, ‘H’ is flying at a constant and stable 0.5m/s, confirmed by the video, but GPS ‘speed’ climbed and has not yet reached the stable 0.5m/s.

As a result of all the above, I finally I have a clue of why ‘H’ keeps overshooting her GPS target: it’s like the NEO-M8T algorithm uses some form of low pass filter, which gives brilliant accuracy for a stable location (i.e. the waypoints and at takeoff), but when moving, each new reading is fused with historic readings, causing significant lag.

The NEO-M8T has a vast amount of config parameters accessible via its u-center app.  Time for me to explore the options.

P.S. A post to the u-blox forum quickly yielded the solution: the UBX-CFG-NAV5 can be set via the u-center app (or other means, I’m sure).  By default, the NEO-M8T algorithm uses a “stationary” model, but there are many other options:



I’ll try “portable” model first based on their descriptions of the different models in their NEO-M8T spec, section 7, followed by “pedestrian” and finally “Automotive”.

P.P.S. The “portable” model worked perfectly as shown by the next post.  There was one additional config change to make which is in the “CFG” section: changes need to be saved in all possible options so the update to “portable” survived after reboot.

Winter wonderland?

Yes, based upon my walk to the next village shop along a bridleway this morning:

Winter wonderland 1

Winter wonderland 1

Winter wonderland 2

Winter wonderland 2

Sadly no, based on flying Hermione in the park shortly after I got back from my walk:

GPS gave 15 samples corresponding well with the lateral flight time.  However the stats showed it still had 4 meters to reach the first waypoint when I aborted the flight.  I’m not clear as to the cause of this; perhaps how GPS prerecorded the waypoints verses how it then flew towards them?

On the plus point, she

  • flew well at 1m/s despite the reduced contrast for the down-facing video
  • was heading in the right direction.

On the downside, due to weather, start of kids’ school holidays, and Christmas, this may turn out to be my last flight in 2017!

Best lawn mower ever!

Note, best watched full screen:

Hermione starts to the right of the video; the yellow frisbee (upper left) identifies the first GPS waypoint she is to reach, the red one (lower left) the second and last where she should land. And she was doing so well right until she reached the first waypoint and flipped over, left mowing the park grass!

Best guess, main battery was running low, she clipped the ground, and flipped.  No real damage done; she’s just outside at the moment drying, so I can brush the grass cuttings off her!

Park life

Hermione and I went to the play park to test the GPS against a preconfigured 5m square flight.

Video isn’t so great due to looking directly into the low midday sun.  Only real thing of note was that despite the grass having been recently mown (and hence featureless), Hermione did the square beautifully, landing just a few centimetres from where she took off.

More interesting to me was that the ublox NEO-M8T ran through the flight and produced this:

NEO-M8T live tracking

NEO-M8T live tracking

This is well within the bounds of GPS accuracy needed for flight control even though the number of satellites was only 8 at best; 2 samples showed 7 in the 121s flight.

It’s 2pm now and the sun is already setting, but from the above results, I have no choice tomorrow but to do a complete GPS driven flight i.e. a flight which tracks through a set of predefined waypoints.

P.S. I forgot to mention Hermione was pointing roughly south on take off.

P.P.S. It’s now “tomorrow” I referred to above, and the breeze has increased to about 15mph; this is fine in a sheltered area like my garden or drive, but not in the exposed park area required for the GPS tracking flight; also, it’s sub-zero outside, and although the batteries have heaters to keep their chemical ions flowing freely, I don’t.  Testing will resume when the breeze drops and the temperature rises.

2m square

While waiting for half-decent weather, I’ve been tinkering and tweaking to make sure everything is as good as possible before moving on to the GPS tracking code. This is the result: a 2m square.

As a result, I’ve updated the code on GitHub.

Encroaching Hermione’s personal space

With Scanse Sweep installed underneath (yes, she has blind spots from her legs and the WiFi antenna), any object detected between 50cm (the distance to tip of her props) and 1m (her personal space boundary) now triggers a controlled landing.  The same thing would happen if the obstacle wasn’t me approaching her, but instead, her approaching a brick wall: a vertical controlled descent to ground.

There’s a lot more that can be built on this; the Sweep is rotating at 1Hz (it can do up to 10Hz), and its taking about 115 samples per loop, each reporting both the rotation position (azimuth) and distance to the nearest object at that rotation.  Currently the code only collects the shortest distance per loop, and if under 1m, the standard file-based flight plan is replaced with a dynamically created descent flight plan based upon the height that Hermione should have reached at that point with the file-based flight plan.

Here’s the layout of communication between the 5 processes involved:

          +—————+     +—————————+
          +—————+     +—————————+     |
                         +———+     +——————+
                         +———+     +——————+
                          +—————+     |

The latest code updates are on GitHub.

Next step is to move GPS to also feed into Autopilot.  The move is easy, just a couple of minutes to move who starts the GPS process; the difficult bit is how the autopilot should handle that extra information.  Currently the plan is that before a flight, Hermione is taken to the desired end-point of the flight, and she captures the GPS coordinates.  Then she’s moved to somewhere else, and pointing in any direction; on take-off, she finds her current GPS position, and the autopilot builds a dynamic flight plan to the end-point; all the constituent parts of the code are already in place.  It’s just the plumbing that needs careful creation.

P.S. That was the first live test flight, hence the slightly nervous look on my face, and my step backwards once she’d detected my intrusions!

P.P.S: Proof that the abort was triggered courtesy of the logs:

[CRITICAL] (MainThread) fly 3467, ASCENT
[CRITICAL] (MainThread) fly 3467, HOVER
[CRITICAL] (MainThread) fly 3467, ABORT (0.88m)
[CRITICAL] (MainThread) fly 3467, STOP
[CRITICAL] (MainThread) fly 4087, Flight time 16.627974

An uninterrupted flight would have run for 22s where descent would have started at 18s.

Resistance is futile…

Given her previous hover flight was so good, I couldn’t resist a 10m flight directly away from me. She overshot the 10m target significantly, probably due to being unable to track the ground motion in the dust storm section.  I killed the flight before she hit the wall. Nevertheless, this confirms that she’s good to go with GPS tracking, firstly where she’s going, and next, actually defining where she should be going, based on a preset waypoint collected prior to a flight.

As a result, I’ve updated the code on GitHub.

Surprise Surprise…

the unexpected hits you between the eyes* (no, not literally!).

She’s sans chapeau as this was just a quick test. However, the flight was quite surprising so I thought I’d share: I’ve been tinkering with the scheduling of video processing, GPS, autopilot and the main sensor processing; I’d spotted these were getting out of sync, the primary reason being reading the autopilot and GPS OS FIFO shared memory data streams often enough for them to stay in sync, yet not too often that the read() blocked. The trivial drift over this 23s hover proved this is working – double integrated acceleration can only hold back drift for a second or two. What surprised me though is that this level of stability took place over gravel, and on checking the config, it became even more of a surprise: the video was running 320 x 320 pixels at 10Hz at 50% contrast levels and it worked brilliantly. I’d assumed higher resolution was needed and that she’d been flying at 640 x 640 (i.e. 4 times the resolution) and at that level she was both drifting, and struggling to process the video frames fast enough. I’m finally at a confident place that I can now move GPS to feed the autopilot such that the autopilot can direct the core motion processing where to go.

*courtesy of Cilla Black


Flight plan processing has now been moved to a new autopilot process ultimately with the aim of feeding Sweep object detection into the autopilot, which in turn swaps from the current flight plan to an ’emergency landing’ flight plan, updating the main process to hover and descend to ground. This flight proves the autopilot feed works, though does raise other problems, primarily the drift over the course of a 3 second takeoff, 5 second hover and 4 second land.

I suspect the drift is caused by video processing: it was processing the 10Hz output at 7Hz, leading to lag.  This reduced processing speed may be caused by overheating of the RPi CPU, causing it to throttle back.

I’d set


in /boot/config.txt to make sure the CPU runs at fully speed always, rather than when it ‘thinks’ it’s busy.  This, combined with the fact the temperature today is 24° in the shade may well be enough for the CPU to throttle back due to overheating instead.  Certainly just a few days ago when the outdoor temperature was in the mid-teens and a cool breeze was blowing, there was no drift.  The CPU has a heatsink, but it is a case.  I may have to either remove the case (exposing it to the elements) or add a cooling fan to the case.  If possible, the latter would be better as the case is there to provide a constant temperature to IMU temperature drift.  I’ve found this one which might just fit in.

Note the kids’ pétanque kit is deliberately on the ground to provide weighty contrasting areas that the grass no longer supplies to the video.  Off to mow the lawn now.