As it is known, there is an active development in using Android ranges for PPP 1 2 and RTK, but these require the phase observables, which, as of the time of writing this post, only few devices provide. Even if they are provided, obtaining the carrier phase might not be as straightforward as in commercial GNSS receivers.
In order to make our first tests with GNSS carrier-phase measurements obtained from an Android device, Rokubun has acquired a non-cellular Nexus 9 tablet. This device is one of the few that has the duty-cycle deactivated, which allows for a continuous tracking of the phase, without a cycle slip at every second.
Header image source: Android Developers Blog
How to obtain carrier-phase measurements
Even though the Android API seems to have dedicated accessors to the carrier phase (
getCarrierCycles()), these methods usually report 0.0. The user has to rely on the
getAccumulatedDeltaRange() method instead, which is defined as a constant (i.e. the wavelength) that multiplies the carrier-phase (expressed in cycles).
A note of caution raised by Google at Innovate UK event “The Future of Mobile Sat Nav” (held in London on July 10th 2017) is that the carrier phase measurements might require a careful processing in order to be reconstructed due to the different implementations of the duty cycling for each manufacturer.
For this work, the Android app
gps-measurements-tool available at GitHub has been used to log GNSS data.
Using the phase
In order to process the phase with GNSS data processing software (such as e.g. RTKlib), we have used a Python script that converts from the GPS logger app to a more standard RINEX format. This script is available here in case you are interested in using it or contributing to it. Please note that this is in active development and the code is very preliminary, use it at your own risk.
In the case of the Nexus 9 tablet, both the time tags of the measurements and the pseudoranges are computed using the smartphone clock and satellite transmission time information and the carrier-phase has been obtained as is (see e.g. this post or the upcoming white paper under preparation by the GSA Task Force on this matter). With this approach, if one plots the pseudorange and the carrier phase against time, for a satellite (see the following example for the GPS satellite “PRN20”), one will see that the pseudorange has a series of periodic jumps that are not present in the phase, which is much more smooth. This leads to a code-phase divergence that increases with time.
These jumps are due to the fact that the clock parameter
FullBiasNanos (used to construct both the time tags and the pseudorange) show a periodic jump of 256 nanoseconds (ca. 77m) each 3 seconds. This jump in the
FullBiasNanos is the culprit of the discontinuities of the pseudoranges shown above because this parameter is also needed to construct the range. Since this is a ‘clock-like’ feature (i.e. is a feature of the receiver that affects all observations), this would not pose a problem if the carrier-phase would show these jumps as well (i.e. the clock parameter when estimating the position would ‘absorb’ these jumps). The problem is that, in this context, the carrier phase is not “consistent” with the pseudorange measurements. The effect of this is that, when processing the data, while the post-fit residuals show a Gaussian distribution for the range, the carrier phase post-fit residuals show regular jumps whose size are around 77meters (the size of the jumps of the
FullBiasNanos, see last plot of this post).
This feature is specially critical if the analyst is interested in using smartphone data for e.g. ionospheric studies, that need the code-minus-phase divergence combination.
As pointed out by several colleagues, a possible means to mitigate this issue would be to assume a constant
FullBiasNanos (taking for instance only the first value), and let the receiver clock (in the estimation process) assume this clock drift. If one does that, the code-phase divergence of the previous plots disappears (see following plot).
Kinematic positioning using phase
In order to test the RINEX converter and check the effect of the
FullBiasNanos in navigation, RTKlib has been used to perform PPP-like processing using precise orbits (rapid IGS orbits and clocks) as well as ionospheric data from IONEX files. Since there was no ground control point to refer the results to, a static solution using precise orbits and IONEX files was computed. This was used as the ground truth to refer the other results. These first results are shown in the following figure:
The horizontal deviations (relative to the ground truth) of the static solution (using broadcast ephemeris) show deviations less than 0.5m at the terminal epoch, while the kinematic solutions show a substantial difference. Using a constant
FullBiasNanos (red dots) seem to improve the solution a bit but the error is still large (6.5 +/- 3.3 m when using constant
FullBiasNanos and 8.7 +/- 5.1m with instantaneous
FullBiasNanos). This is consistent with the post-fit residuals of the phase (see plot below). Note that, as far as the carrier phase post-fit residuals are concerned, despite the fact that the jumps have now disappeared, the residuals are in the range of meters. This large residuals might be in part due to the ionospheric model (IONEX), which has errors on the order of 5 TECU (which is equivalent to ca. 80 cm in GPS L1 frequency).
These results indicate that, on top of the fact that the antenna in smartphone is critical to achieve a good carrier-phase, the smartphone GNSS carrier-phase measurements might not be used as is. Careful attention is required to reconstruct those measurements in order to be used in PPP as well as for ionospheric monitoring applications. This treatment might be even different for each GNSS chipset manufacturer.
Thanks to Moises Navarro (Airbus & GSA) for his valuable contribution on the
FullBiasNanos treatment of the smartphone GNSS receiver clock.