Achieving cm Level GNSS Accuracy Via RTK
Introduction
This is brief practical guide to real-time kinematics (RTK) aimed primarily at users of PyGPSClient and u-blox GNSS receivers.
A common topic on the PyGPSClient Discussion Forums is how to achieve centimeter-level accuracy using an RTK-compatible receiver like the u-blox ZED-F9P.
⚠ The following is by no means a rigorous treatment, but is intended to offer some practical tips and recommendations. YOUR MILEAGE MAY VARY! The focus here is real-time kinematics (RTK), but much the same considerations will apply to post-processing kinematics (PPK) and other differential GPS (DGPS) techniques.
ⓘ If you're relatively new to GNSS and RTK techniques and terminology, you may want to review this wiki and glossary first.
Tips and Recommendations
NB: RTK techniques cannot 'correct' a poor GNSS signal - you need to have a solid 3D fix in the first place to stand any chance of achieving centimeter-level positional accuracy.
1. The importance of Reference Frame
- Navigation or surveying solutions produced by RTK or PPK techniques are only meaningful in relation to a given reference frame or datum. A full discussion of datums is beyond the scope of this article, but in essence a reference frame can be global e.g. WGS84, or local to a particular geographical area e.g. NAD83 (North America) or ETRS89 (Europe). While the differences may be subtle, no two reference frames will yield exactly the same results. All other things being equal, a local reference frame will be more accurate than a global one within its region of coverage. Results based on a mix of disparate reference frames are likely to be spurious.
- GNSS has traditionally been based on the World Geodetic System 1984 or WGS84. WGS84 is an ensemble of geocentric reference frames which were originally accurate to within 1 m. Subsequent revisions have brought this down to around 10 cm.
- When dealing with terrestrial positional accuracy at the centimeter or millimeter level, it is necessary to take into account factors like tectonic plate movement and gravitational/magnetic displacements. This is the function of the International Terrestrial Reference System or ITRS and its associated International Terrestrial Reference Frame ITRF. New ITRF solutions are produced every few years, using the latest mathematical and surveying techniques to attempt to realize the ITRS as precisely as possible. The difference between the latest WGS84 and ITRF2000 frames is of the order of a few centimeters.
- Terrestrial datums can be static ('plate-fixed' i.e. fixed relative to a specific tectonic plate) or dynamic ('earth-fixed' i.e. fixed relative to the earth's centre). The 'earth-fixed' ITRF is typically not regarded as a 'datum' - rather it is the international standard reference framework to which national geocentric datums are aligned.
- In order to achieve meaningful centimeter or millimeter level accuracy, all components in the end-to-end application (including the RTK data source and any maps or geo-referenced imagery) must be using the same ITRF or related 'plate-fixed' reference frame.
2. Use a dual-band RTK-compatible GNSS receiver
- The receiver must be capable of receiving and processing real-time kinematic 'corrections', typically from an NTRIP, MQTT (IP) or L-Band source via the RTCM3 or SPARTN2 protocols.
- The receiver should be capable of receiving GNSS transmissions on both the L1 and L2 (or L5) frequencies (refer to the wiki to understand why this is beneficial to positional accuracy).
- The receiver and/or its antenna should be reasonably robust (ideally IP67 or better), as the best results are likely to be obtained outdoors.
3. Use a suitable L-Band antenna and cable
- A GNSS antenna must be capable of receiving a clear signal on the key GNSS L-Band frequencies - specifically the L1, L2 and (ideally) L5 and L6 frequencies. Depending on your local environment and intended application, a multi-band active patch antenna like the u-blox ANN-MB-00 may suffice, or you may benefit from a 'UFO'style multi-band surveying antenna.
- If weight is at a premium - e.g. for aerial applications - a helical antenna may be more suitable, albeit with some loss of performance.
- Active GNSS antennae typically incorporate low noise amplifiers (LNA) to boost gain, along with bandpass or 'saw' filters to remove extraneous noise and frequencies which are not required for GNSS reception. Note, however, that such filters may render the antenna unsuitable for other RTK applications e.g. reception of L-Band SPARTN data from geostationary Inmarsat satellites using a u-blox NEO-D9S receiver, for which a broad-spectrum active patch antenna, or even a passive directional antenna, may be more suitable. Check the antenna specification to ensure it covers the required frequency spectra.
- Ensure that the antenna cable is a high-quality coaxial cable with minimum attenuation in the L-Band spectrum - RG58 as a bare minimum, preferably RF240 or RF400 for longer runs (> 3m).
- If possible, use a GNSS receiver/breakout board and antenna which support robust TNC, BNC or SMA connectors rather than the much smaller U.FL type, which is not designed for repeated insertion and has limited cable length.
4. Use a suitable ground plane
- Popular active patch antennae like the u-blox ANN-MB-00 are designed to be used with an external ground plane - typically a (steel) car roof or a small steel plate suitable for mounting on a tripod. At a push, a heavy ferrous saucepan lid may suffice.
- The science behind ground planes is beyond the scope of this article but, in essence, a good ground plane under the antenna improves signal strength and reduces noise and interference. Refer to Importance of Ground Planes for a more in-depth discussion.
- Specialised surveying antennae of the 'UFO' type normally have a built-in ground plane.
- Helical antennae do not generally require a ground plane.
5. Ensure you have the best possible view of the sky
- Needless to say, you need to have good unrestricted visibility of the sky (ideally 360°) with
the broadest possible satellite coverage to obtain the most accurate results. This is indicated
by the various Dilution of Precision (DOP) values (
pDOP
,vDOP
,hDOP
). Ideally the indicated pDOP should be <= 1.0. - You should be able to receive signals from at least 10 satellites with a signal strength (CN₀) of 45dB or better.
Poor Satellite Coverage | Good Satellite Coverage |
---|---|
6. Ensure you are using a reliable, local RTK reference station
- In the present context this generally means NTRIP, MQTT (IP) or L-Band sources. NTRIP casters traditionally output data in RTCM format, but there are now proprietary services offering SPARTN format instead.
- The RTK reference station should be no further than 20km from your antenna location, and ideally less than 5km, such that its correction data is representative of local atmospheric conditions. Accuracy decreases the further you are from the reference station.
- NB: While free public domain NTRIP resources exist and can often give perfectly satisfactory results, there is no guarantee as to the quality of the correction data available. Some public domain CORS are essentially amateurs working out of their back yards. The best results for your location may be obtained from proprietary or subscription services which use specialised, carefully calibrated equipment in optimal locations with ITRF or local plate-fixed datums - but it's always worth trying free public domain resources first.
7. Use the highest precision message type(s) available
-
If using a UBX receiver like the ZED-F9P, different NMEA or UBX navigation message types will yield different levels of precision.
Lat/Lon Decimal Places Approx Precision Example Message Type(s) 3 110 m 4 11 m 5 1.1 m 6 11 cm NMEA GGA, GNS in standard precision mode (5dp minutes) 7 1.1 cm UBX NAV-PVT, NAV-POSLLH 8 1.1 mm UBX NAV-HPPOSLLH, NMEA GGA, GNS in high precision mode (7dp minutes) -
8dp (± 1.1 mm) represents the practical limit for RTK and PPK techniques - further decimal places are likely to be spurious (though internal computations may retain them to avoid cumulative rounding errors).
-
NB For the ZED-F9P and other u-blox receivers, the highest precision message types/modes are generally NOT enabled by default - they will need to be enabled via PyGPSClient's UBX Configuration panel:
- NMEA high precision mode can be enabled by setting
CFG_NMEA_HIGHPREC = 1
- UBX NAV-HPPOSLLH can be enabled by setting
CFG_MSGOUT_UBX_NAV_HPPOSLLH_xxxxx = 1
, wherexxxxx
represents the port - 'USB', 'UART1', 'UART2', 'I2C', 'SPI' - If required, these settings can be persisted using PyGPSClient's 'Save configuration to non-volatile memory' preset
- NMEA high precision mode can be enabled by setting
-
A broad indication of available precision can be obtained from the scatterplot widget set to a range of 10 cm or less. If the points appear to be aligned to a coarse grid, this suggests relatively low precision. If the points appear to be scattered more or less randomly, this suggests higher precision.
Lower Precision Higher Precision
8. Check your receiver is successfully receiving and processing RTK data
-
If you're using a UBX receiver like the F9P, you may find it easier to configure it to output UBX messages rather than the default NMEA, as the former are more concise and offer more comprehensive and consistent RTK status information. PyGPSClient provides a range of preset UBX configuration commands to facilitate this.
-
Consider decreasing the navigation solution interval from the default 1000 ms (1Hz) to, say, 250ms (4Hz). This should reduce the time taken to achieve an RTK fix.
-
Set the F9P UART1 and UART2 baud rates to the maximum possible - 115,200 or higher - particularly if you have decreased the solution interval. This will reduce the possibility of rxbuf alloc and txbuf alloc errors, which may impede an RTK fix.
-
Successful receipt and processing of RTK correction data is indicated as follows:
- If using NMEA:
- the RMC or GNS
posMode
attribute will change to 'F' (RTK-FLOAT) or 'R' (RTK-FIXED). - the GGA
quality
attribute will change to '5' (RTK-FLOAT) or '4' (RTK-FIXED) - the GGA or GNS
diffAge
attribute will change to a number between 1 and 60.
- the RMC or GNS
- If using UBX:
- the NAV-PVT or NAV-STATUS
carrSoln
attribute will change to '1' (RTK-FLOAT) or '2' (RTK-FIXED). - the NAV-PVT
lastCorrectionAge
attribute will change to a number between 1 and 8.
- the NAV-PVT or NAV-STATUS
- After a short period (typically a minute or so), the reported horizontal and vertical
accuracy values (
hAcc
andvAcc
) will start to fall to < 1m levels - but note caveats below. - Note that the F9P (in its default configuration) will continue to apply RTK corrections for up to 60 seconds after the last correction message is received.
- If using NMEA:
-
If you're using an F9P or similar, useful additional diagnostics can be obtained by enabling UBX RXM-COR (or, for RTCM only, RXM-RTCM) Receiver Management message types (this can be done using PyGPSClient's UBX Configuration panel). For example, the RXM-COR message includes two data attributes
errStatus
andmsgUsed
;errStatus=1, msgUsed=2
signifies that valid RTK correction data has been received successfully and has been applied to the receiver's navigation solution. For diagnosing L-Band SPARTN reception issues, the UBX INF-DEBUG Information message can also be useful. Refer to the F9P Interface Manual for further details on the meaning of the various UBX NAV, RXM and INF message types and data attributes.- UBX RXM-COR can be enabled by setting
CFG_MSGOUT_UBX_RXM_COR_xxxxx = 1
, wherexxxxx
represents the port ('USB', 'UART1', 'I2C', etc.)
- UBX RXM-COR can be enabled by setting
9. 'FLOAT' vs 'FIXED'
- It is important to understand that these RTK status values are based, in essence, on a statistical analysis (using the principles of Kalman Filtering) of the various errors ('residuals') which affect the calculation of carrier phase pseudorange, and hence the accuracy of the navigation solution.
- The receiver's firmware applies a complex proprietary algorithm to determine if this statistical analysis is within a certain tolerance. If it is, the receiver will report an 'RTK-FIXED' status. If it is outside the designated tolerance, the receiver may report an 'RTK-FLOAT' status. This doesn't necessarily mean that the solution is less accurate - it just means that the confidence level is lower than 'FIXED'.
- An 'RTK-FLOAT' status will therefore generally yield a broader scatter and lower accuracy
estimation (
hAcc
,vAcc
) than 'RTK-FIXED'.
10. Some caveats on 'hAcc' and 'vAcc'
- NB:
hAcc
andvAcc
values are not available from the default cohort of NMEA messages output by most GNSS receivers (including the F9P). In order to receive these values, you will need to enable either proprietary NMEA sentences like u-blox's UBX00, or UBX messages like NAV-PVT. - Much is made of reported horizontal (hAcc) and vertical (vAcc) accuracy figures, but they
are
merely estimates based on a statistical analysis of:
- Number of satellites (
sip
) - Signal strengths (
CN₀
) - Geometric distribution of the satellites (
dop
) - Pseudorange residuals (UERE)
- Number of satellites (
- In the case of the F9P receiver, the analysis itself is proprietary and is performed within the F9P's firmware, rather than in client software.
- Ultimately, the only definitive way of establishing the accuracy of an RTK (or PPK) navigation solution is to compare it with a known fixed reference point whose 3D coordinates have been independently verified via high precision surveying techniques.
Troubleshooting
-
If your fix status does not change or, having enabled RXM-COR or RXM-RTCM diagnostic
message types, you see none in the console, this
may mean the RTK correction data is not making its way through to your receiver. This
could be due to a configuration or connection error of some kind e.g.
- If the RTK service requires client authentication, ensure you are using correct and
current credentials (PyGPSClient will generally report an HTTP 4nn Not Authorized
error in these circumstances).
- Some RTK services are 'geofenced' and will only provide data to clients within a
specified geographical area. Check with the service provider.
- If the NTRIP caster requires NMEA GGA position data (signified by a '1' in the 11th
position of the sourcetable - the one after Longitude), ensure you have this enabled
in the NTRIP client configuration panel.
- If the RTK data is encrypted (as with Thingstream PointPerfect SPARTN MQTT or L-Band
services), ensure that the latest decryption keys have been uploaded to the receiver
via an RXM-SPARTN-KEY message. SPARTN decryption keys are typically only valid for a
4 week period and need to be refreshed regularly.
- If using an internet RTK service (NTRIP or MQTT), ensure you have active internet
connectivity and that the service's IP port (typically 2101, 2102, 443 or 8883) is
not being blocked by a firewall.
- If you're receiving correction data via a direct serial connection (e.g. from a WiFi
or LoRa UART adapter or NEO-D9S receiver), ensure that the port is set to the
correct baud rate.
- Check for rxbuf alloc or txbuf alloc errors in the incoming
datastream - these may indicate that the device's UART1/2 baud rate is insufficient
to support the volume of GNSS or RTK data being processed.
- Ensure that your F9P is configured to allow incoming RTCM3 data on the designated
port - this is the default setting, but it may have been overwritten.
-
If you're receiving RTK correction data and have followed all the recommendations above, but
are
still not seeing the requisite level of accuracy, this may simply be because:
- Your antenna location, equipment and/or environmental conditions are sub-optimal.
- Your RTK data source is too remote and/or not of sufficient quality.
- The connection to your RTK data source is unreliable.
- You haven't waited long enough for a sufficient amount of RTK data to be processed.
It can on rare occasions take half an hour or more to achieve cm-level results
(particularly with SPARTN sources).
If your fix status does not change or, having enabled RXM-COR or RXM-RTCM diagnostic message types, you see none in the console, this may mean the RTK correction data is not making its way through to your receiver. This could be due to a configuration or connection error of some kind e.g.
- If the RTK service requires client authentication, ensure you are using correct and current credentials (PyGPSClient will generally report an HTTP 4nn Not Authorized error in these circumstances).
- Some RTK services are 'geofenced' and will only provide data to clients within a specified geographical area. Check with the service provider.
- If the NTRIP caster requires NMEA GGA position data (signified by a '1' in the 11th position of the sourcetable - the one after Longitude), ensure you have this enabled in the NTRIP client configuration panel.
- If the RTK data is encrypted (as with Thingstream PointPerfect SPARTN MQTT or L-Band services), ensure that the latest decryption keys have been uploaded to the receiver via an RXM-SPARTN-KEY message. SPARTN decryption keys are typically only valid for a 4 week period and need to be refreshed regularly.
- If using an internet RTK service (NTRIP or MQTT), ensure you have active internet connectivity and that the service's IP port (typically 2101, 2102, 443 or 8883) is not being blocked by a firewall.
- If you're receiving correction data via a direct serial connection (e.g. from a WiFi or LoRa UART adapter or NEO-D9S receiver), ensure that the port is set to the correct baud rate.
- Check for rxbuf alloc or txbuf alloc errors in the incoming datastream - these may indicate that the device's UART1/2 baud rate is insufficient to support the volume of GNSS or RTK data being processed.
- Ensure that your F9P is configured to allow incoming RTCM3 data on the designated port - this is the default setting, but it may have been overwritten.
- Your antenna location, equipment and/or environmental conditions are sub-optimal.
- Your RTK data source is too remote and/or not of sufficient quality.
- The connection to your RTK data source is unreliable.
- You haven't waited long enough for a sufficient amount of RTK data to be processed. It can on rare occasions take half an hour or more to achieve cm-level results (particularly with SPARTN sources).
Illustrated Example
The following screen shot illustrates an RTK fix obtained using a SparkFun GPS-RTK-SMA GNSS module and u-blox ANN-MB-00 antenna mounted on a steel car roof (approximately 1.5m high with a base altitude of 66m) at a location with more-or-less 360° unrestricted visibility of the sky, around late afternoon in good weather conditions. The RTK source was a EUREF NTRIP 2.0 reference station (mountpoint) situated some 28km to the west (not ideal, but the closest available). EUREF uses the European Terrestrial Reference System 89 or ETRS89, which at time of writing is coincident with the ITRS at epoch 1989.0. The source had been active for approximately 60 seconds prior to the screenshot being taken.
- The incoming RTCM data may be seen in the console with the tag
NTRIP>>
. - The UBX NAV-PVT messages are reporting
diffSoln=1
('differential corrections were applied'),carrSoln=2
("carrier phase range solution with fixed ambiguities" i.e. 'RTK-FIXED') andlastCorrectionAge=3
("Age between 2 and 5 seconds"). - The UBX RXM-COR messages are reporting
errStatus=1
('Error-free'),msgUsed=2
('Used') andmsgInputHandle=1
('Receiver has input handling support for this message'). - The Satellites widget indicates broad sky visibility, with plenty of satellites with strong signals visible at or near the horizon.
- The Levels widget indicates that we are receiving at least 15 satellites with a CN₀ of 45dB or better.
- The Spectrum widget indicates that the receiver has good reception on both L1 and L2 frequencies.
- The Scatter Plot widget indicates position variability well within the 0.1m radius.
- The Rover Plot widget indicates the relative position of reference station (centre of plot) and receiver antenna (orange vector).
The indicated horizontal accuracy (hacc
) is 1.4cm but note caveats above.
References and Further Reading
See Glossary of GNSS Terms and Abbreviations
- GNSS Positioning - A Reviser
- Differential GPS
- Real-time kinematic positioning
- GNSS Pseudorange Estimation - the 'Integer Ambiguity' Problem
- RTK Fundamentals
- Error analysis for the Global Positioning System
- u-blox GNSS Antennas Paper
- GPS Antenna and Coaxial Cable Specifications
- Importance of Ground Planes
- Ardusimple GNSS Antenna Installation Guide
- RTCM DGNSS standards
- International Terrestial Reference Frame System