Discussion:
Time precision of gpsd with u-blox GPS receiver
Benedikt Kleinmeier
2014-09-11 07:56:07 UTC
Permalink
Hi,

I use a u-blox NEO-7 GPS receiver as stratum 1 source and gpsd/ntpd to set the time of a connected PC very precisely.

I used the following HOWTO:

http://www.catb.org/gpsd/gpsd-time-service-howto.html

Now, I'm interested in the accuracy of this solution.

Default, u-blox GPS receiver only sends NMEA 0183 Version 2.3 sentences. According to NMEA specification, in NMEA messages, time is always reported rounded to the nearest hundredth of a second (i.e. at least 10 ms). This is not very accurate for a stratum 1 source.

On the other hand, u-blox GPS receiver supports the binary UBX protocol. According to protocol specification [1], some UBX messages provide a field, called "nano", to allow nano precision. When analyzing logs, I only can recognize second precision:

gpsd:DATA: TIMEGPS: time=1410420630.000000 mask={TIME}
gpsd:DATA: TIMEGPS: time=1410420631.000000 mask={TIME}
gpsd:DATA: TIMEGPS: time=1410420632.000000 mask={TIME}
gpsd:DATA: TIMEGPS: time=1410420633.000000 mask={TIME}
gpsd:DATA: TIMEGPS: time=1410420634.000000 mask={TIME}

Where are the fractions of a seconds?

Note: logs where generated by

gpsctl -b /dev/ttyACM0 # Switch to binary UBX protocol.
gpsd -b -N -n -D 6 /dev/ttyACM0 # Use log level 6 to make "gpsd:DATA" messages visible.

Looking at the code in "drivers_ubx.c", reveals that only "tow" field is read (time of GPS week in milliseconds) but the millisecond digits are always zero and "ftow" field (which provides "nano" precision" is completely ignored. See the following log of a slightly modified version of "drivers_ubx.c". Look at the "tow=" strings:

gpsd:DATA: TIMEGPS: gw=1809 tow=372408000 ftow=-262153 tow_with_fractional_part=372407.999738
gpsd:DATA: TIMEGPS: time=1410420391.999738 mask={TIME}
gpsd:DATA: TIMEGPS: gw=1809 tow=372409000 ftow=-261526 tow_with_fractional_part=372408.999738
gpsd:DATA: TIMEGPS: time=1410420392.999738 mask={TIME}
gpsd:DATA: TIMEGPS: gw=1809 tow=372410000 ftow=-260899 tow_with_fractional_part=372409.999739
gpsd:DATA: TIMEGPS: time=1410420393.999739 mask={TIME}
gpsd:DATA: TIMEGPS: gw=1809 tow=372411000 ftow=-260276 tow_with_fractional_part=372410.999740
gpsd:DATA: TIMEGPS: time=1410420394.999740 mask={TIME}
gpsd:DATA: TIMEGPS: gw=1809 tow=372412000 ftow=-259652 tow_with_fractional_part=372411.999740
gpsd:DATA: TIMEGPS: time=1410420395.999740 mask={TIME}

Is it only possible to get second precision with this setup (u-blox UBX/gpsd/ntpd)?

Thanks for your help,
Benedikt

[1] http://www.u-blox.com/images/downloads/Product_Docs/u-blox7-V14_ReceiverDescriptionProtocolSpec_Public_%28GPS.G7-SW-12001%29.pdf
[2] http://git.savannah.gnu.org/cgit/gpsd.git/tree/driver_ubx.c#n213
Robert Calhoun
2014-09-11 15:33:32 UTC
Permalink
On 9/11/14 3:56 AM, "Benedikt Kleinmeier"
Post by Benedikt Kleinmeier
Hi,
I use a u-blox NEO-7 GPS receiver as stratum 1 source and gpsd/ntpd to
set the time of a connected PC very precisely.
http://www.catb.org/gpsd/gpsd-time-service-howto.html
Now, I'm interested in the accuracy of this solution.
Default, u-blox GPS receiver only sends NMEA 0183 Version 2.3 sentences.
According to NMEA specification, in NMEA messages, time is always
reported rounded to the nearest hundredth of a second (i.e. at least 10
ms). This is not very accurate for a stratum 1 source.
All high-precision timing is done with the time pulse signal when working
with GPS. The serial messages, be they NMEA or binary protocol, simply
label the preceding time pulse and have little to do with the accuracy.
See the diagram at the top of page 29 in the uBlox Protocol Spec:

http://www.u-blox.com/images/downloads/Product_Docs/u-blox7-V14_ReceiverDes
criptionProtocolSpec_Public_%28GPS.G7-SW-12001%29.pdf


The accuracy of the time pulse itself is given in the datasheet for the
part. For the uBlox 7 series, the time pulse accuracy is 30 nanoseconds
RMS.

Because GPS parts can provide > 1 Hz updates, the nav/clock messages need
to support resolution better than one second. The NMEA protocol specifies
time rounded to the nearest hundredths of a second, as text. The uBlox
protocol, on the other hand, uses (binary) fixed-point representation and
can (theoretically) support higher nav rates and timing precision of 1
msec. (The binary protocol is also more compact, an issue as serial
bandwidth is limited.)

For example with uBlox the GPS "time of week" field is an unsigned 32 bit
int in milliseconds; that is how it outputs "GPS time". The nanosecond
field is part of the (redundant) UTC time structure, which incorporates
the Gregorian calendar and leap seconds. See the manual (uBlox has very
good manuals) for how iTOW / UTC / NMEA conversion is done, and how the
messages should be interpreted given the different precision of the NMEA
and uBlox messages and the inconsistent rounding that can result. (That is
what the nano field is about, cleanup of rounding mess.)

But again, the precision of these messages has little to do with the
accuracy of the timing; the messages just label the preceding time pulse.
Almost everybody leaves their GPS at the default one pulse per second, on
the second, so the fractional part is zero.

Now turning to gpsd: under linux, gpsd uses a feature of the linux kernel
called KernelPPS. When appropriately configured, the PPS (pulse per second
a.k.a. time pulse) will generate an interrupt that will be serviced by the
kernel. The kernel can service interrupts faster than a userland process.
I believe the accuracy is on the order of a 1-2 microseconds. Kernel PPS
expects a once per second time pulse; the host's reference clock is used
to measure time between each time pulse. ntpd/chronyd use the time pulse
to derive the actual period of the reference clock and set the system time
appropriately. Getting KernelPPS working is the most important thing you
can do to improve the quality of your time server. See documentation:

http://www.catb.org/gpsd/gpsd-time-service-howto.html

The uBlox-7 is a very flexible GPS platform. It can give navigation
updates (i.e. a new location fix) at 10 Hz, and the time pulse is
configurable from 1 Hz to 10 MHz. If time pulse rate exceeds nav update
rate, you just interpolate the time between messages. The output at up to
10 MHz is new with the 7-series, and provides a great deal of flexibility
in circuit design. (10 MHz is commonly used as a reference frequency in
high-precision designs, and a GPS chipset is vastly cheaper than a
rubidium oscillator.)


As long as we are talking about the uBlox platform, it is worth noting
that the uBlox supports input of differential GPS data via the RTCM
Protocol. (There was a query to gpsd-users in August about getting
improved relative accuracy when using two GPS devices, one at a known
stationary position and one in motion nearby.) I don't think the uBlox can
generate RTCM, but it be might possible to set up a true differential
system with some work. (I've never used RTCM myself, and I'm too cheap to
shell out $60 for the standard just to satisfy my curiosity.)

Rob Calhoun
Benedikt Kleinmeier
2014-09-12 13:58:39 UTC
Permalink
Hi Rob,

thank you very much for your detailed explanations. Now, it is easier for me to understand the complete accuracy/PPS topic.
Post by Robert Calhoun
Almost everybody leaves their GPS at the default one pulse per second,
on the second, so the fractional part is zero.
According to u-blox Receiver description [1] page 129:

The u-blox positioning technology supports navigation update rates higher or lower than 1
update per second. The calculation of the navigation solution will always be aligned to the
top of a second.

I guess because of this aligning, the fractional part of the reported time (in seconds) is always zero. Changing the update rate via a "CFG-RATE" message to 250 ms for example would reveal a fractional part unequal zero.

Thanks,
Benedikt

[1] http://www.u-blox.com/images/downloads/Product_Docs/u-blox7-V14_ReceiverDescriptionProtocolSpec_Public_%28GPS.G7-SW-12001%29.pdf
Loading...