GNSS carrier phase from Nexus 9

GNSS carrier phase from Nexus 9

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.

How to obtain carrier-phase measurements

Even though the Android API seems to have dedicated accessors to the carrier phase (getCarrierPhase() and 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.

Range and phase using instantaneous FullBiasNanos

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)

Using constant FullBiasNanos mitigates the code/phase divergence due to the receiver clock
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:

Horizontal deviation relative to static solution (precise + IONEX)

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).


Post-fit residuals of the carrier-phase measurements

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



Miquel Garcia

  • Miquel Garcia

    Hi Simon, thanks for your reply!

    I agree with your statement of the IONEX and the ionospheric errors, we still have to dig more on the phase residuals to clarify this. Following your suggestion, I prepared a plot showing the range rate computed with different methods (range differences with instantaneous FullBiasNanos, carrierphase differences and Doppler values as reported by the PseudoRangeRateMetersPerSecond getter of the Android API). Both the Doppler and the range rate computed using the carrier phase seem reasonably similar…

    I will keep you posted!

    Range rate measurements from Nexus 9

  • Simon Banville

    If I remember correctly, the tutorial taught by Frank Van Diggelen and his colleagues from Google suggested to use a constant FullBiasNanos as well. The phase residuals still look puzzling to me: the ionospheric errors caused by the IONEX map should vary slowly and not be as noisy. Did you collect Doppler measurements as well? Could you validate the carrier-phase against the Doppler observations? Keep us updated!

    p.s. Thanks for the links to blackdotgnss!

Leave a Reply

Your email address will not be published. Required fields are marked *