Freesteel Blog » GPS Timing Anomalies

GPS Timing Anomalies

Tuesday, April 5th, 2016 at 1:04 pm Written by:

On this second day of heavy rain in the Pyrenees I think I might have the time to catch up some ancient history from all of last week. We waited five hours on El Bosque for the wind to come right, and were then rewarded with this flight with vultures.
These birds came much closer than they ever showed up in the pictures. They fly with hunched shoulders.

Unfortunately the GPS for that flight is inexplicably jagged, so here’s a flight above Teba from a day later where the data is cleaner.



The yellow cube is 1000m on each side for scale from a flight that took off at the point on the frontmost vertical cube edge

Here’s a zoomed in section of the left most section of the path, shown looking down, with 100m XY axes in yellow. The track comes in from the bottom right goes to the top left (against the wind direction), then turns left to make four anticlockwise loops that drift back with the wind

Here’s the track but with points drawn on to show how frequent the samples are (ten times a second). Note that the spacing is tighter when flying upwind towards the left.

The GPS doesn’t come out as very smooth, even though the flight trajectory must have been smooth because the wings are only pushing off air. Sometimes you can get really sharp corners where the GPS suddenly seems to correct itself as if making a phase jump. However, the samples are continuous, which is not something you would get if this was an honest sensor that was actually reporting its raw noise. I therefore suspect that there is a smoothing process going on.

The most common smoothing process is an exponential filter like: yn+1 = yn*0.9 + xn+1*0.1, which has the tendency to delay the signal so that the peaks and troughs occur later than they do in the original measurements.

Let’s see what we can do about detecting this.

The GPS velocity setting
As above, but with the GPS forward velocity vectors drawn in from the positions on the trajectory corresponding to the recorded timestamp.

To get this ability to take velocities and positions at the rate of 10 times a second, the commands I send to the GPS device are as follows:


The first line sets it to a 0.1second cycle, and the second is interpreted as “please send me a GPRMC record every 50*0.1 seconds (ie five seconds), a GPVTG and a GPGGA every 0.1 seconds, and a GPGSA every second.”

These record types hold various overlapping sets of data, none of which are exactly right, which is why I am requesting four different types.

In particular, the velocity record:


decodes to a speed of 0.53kph in the direction of 62.47deg, and the position record:

$GPGGA,064306.590,5323.7234,N,00258.3325,W, 2, 10, 1.00,38.3,M,49.4,M,0000,0000*4A

decodes to the time hours=06 minutes=43 seconds=06.590 at location 53deg23.7234’N 002deg58.3325’W.

Note that the actual date is missing from this record, which is why I’m having to grab the occasional GPRMC record to get it. The GPGSA holds the dilution of precision, which doesn’t seem to relate to the accuracy of the position to be of any use (check this on the El Bosque day).

The velocity is supposed to use the doppler shift to the GPS satelites to get an instantaneous measurement, and so doesn’t depend on measuring the positions and subtracting their differences. This would be more useful for a slower sample rate of, say, once every five seconds. However, at this sample rate we can derive the velocity from the position in the following way:

Dvelocityt = (positiont+d – positiont-d)/(2*d)

The plot is here:
Yellow is the velocity derived from the position, which appears time shifted forwards slightly. Note the big velocity measurement discontinuity on the first loop on the left.

We can quantify this shift by plotting the sum of the square distances between the derived velocity and the measured velocity:

k1 = ziptvsG(DerivedVelocity, [(t+dt, v) for t, v in MeasuredVelocity])
difference = sum((dv – mv).Lensq() for t, dv, mv in k1)/len(k1)
plotpoint(dt, v)

From the graph:
(where the white vertical line is zero) it looks like the measured velocity is a quarter of a second (2.5 units) behind the derived the velocity. If my theory is correct, then it’s subject to more smoothing than the position records, although this is contradicted by the way that the velocity vector has that sharp corner on the second loop.

In all ways, this is the wrong way round, especially when they could be using the velocity vector to direct the position to a more consistent point, in which case it would be ahead.

Just to check this isn’t to do with the data transmission, I’ve looked at the raw data records in the log file, and they come out like this:


ie the velocity records V get logged immediately after the position record Q at a time difference of 0x00874B2D – 0x00874B03 = 42milliseconds, so to be fair the true lag (if the measurements are made simultaneously from the same satellite observation) is more like 200ms, or two GPS sample points.

One would expect, with a hefty calculation and data transmission issue, there to be about a one sample point time shift from reality (whatever reality is) at the maximum cycle speed. However I can’t imagine there would be a buffer of two or four measurements deliberately queuing the outputs systematically.

I reckon that reality comes from the BNO055 absolute orientation accelerometer, which is sensitive enough to encode vibrations. It’s like a microphone where it’s near instantaneous and there can’t be a lag of more than a fraction of a wavelength. No lightspeed to satellites in high orbits to contend with. We can plot the acceleration positions against the GPS signal, like so:

(I’m plotting less than a third of the vectors sampled.) Remember the travel is anticlockwise through the loops, and the accelerations should be pointing in from the trajectory, so there is an even bigger time-lag.

Here is the plot of accelerations derived from the GPS position:

There is plenty of noise here, but we can still try to plot the average square distance error for each timeshift, like so:
This says one should shift the acceleration vectors 0.4seconds forward in time to best match the GPS positions (and their implied acceleration).

We can do the same with the velocity records, which only needs to be differentiated once:

The velocity time shift (in green) is best at 0.6ms, which is consistent to an acceptable error with what we had between the velocity and the position.

Still, about a half second time lag is quite sizeable. My glider is going to move 6 metres in that time period, and if I’m trying to relate this to the edge boundary of a thermal from one of the other sensors, I will need to take account of this.

Speaking of other sensors, what about the barometer?

Funny you should mention that. I hadn’t thought about it until now. It’s probably going to take the rest of the day to code this up, so let’s make a start.

The snippet of flight about with the four loops takes 145 seconds. This is the graph of the barometer (in green) against the GPS altitude (in yellow).

Pressure goes up as altitude goes down. The reason I start making those horizontal loops is because I am in rising air, and this is the only way to stay in it when the alternative is to keep going down until I eventually have to land.

On trying to align the two by factoring linear interpolation to get a scale of alt = (102028.010949 – millibars)/11.172943 produces not a great fit as follows:

Vertical lines are one second intervals. Maybe there is a slippage forward of half a second between those readings and the GPS altitude, but it’ll be hard to quantify unless I get a better match. I ought to also compare it to the vertical acceleration.

The barometer system sure needs some debugging and error checking as its non-standard communication protocol is a bit flaky. It will also require some smoothing and discounting of rogue readings. I wonder if also the presence and orientation of the wing will change the pressure below.

This one is pretty darn hard, so I’ll put it off till later after I’ve caught up on my logbook writeups of more recent flights. Which involves disclosing this brief and terrifying incident:

Leave a comment

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <blockquote cite=""> <code> <em> <strong>