In the last blog post we did a literature review on what information is required to enable cm-level positioning with a mobile device. Now we’ll get into the Android API to understand how to access the necessary information to construct the pseudorange and carrier-phase measurements for precise positioning. Access to the GNSS measurements in the android devices were added in API level 24 and can be referenced here. The API includes several interesting elements that we’ll discuss in future blog posts. You can visit the Android documentation for the original defintion of these terms but we found them a bit cryptic. We tried to describe them a bit simpler. It is important to note all units provided by android are in units of nanoseconds which can be a bit cumbersome, because getFullBiasNanos has at least 20 digits. |
For this post, we’ll need:
getTimeNanos – Length of time android device has been powered on
getTimeOffsetNanos – Typically 0 but can be used to express time sub-nanosecond precision
getFullBiasNanos – GPS time expressed in nanoseconds. GPS time was zero at 0h 6-Jan-1980. If GNSS time was computed with a non-GPS satellite, an offset will be required to align to GPS time
getBiasNanos - Typically 0 but can be used to express time sub-nanosecond precision.
getReceivedSvTimeNanos – Estimated time of transmission of the pseudorange
getAccumulatedDeltaRangeMeters – Counts the number of carrier-phase cycles since powered on (assuming no duty cycles). The cycles are converted to range in unit of meters.
getCarrierFrequencyHz – The carrier-phase frequency being tracked. It can be L1 or L2 and if empty, the default is L1.
getTimeNanos – Length of time android device has been powered on
getTimeOffsetNanos – Typically 0 but can be used to express time sub-nanosecond precision
getFullBiasNanos – GPS time expressed in nanoseconds. GPS time was zero at 0h 6-Jan-1980. If GNSS time was computed with a non-GPS satellite, an offset will be required to align to GPS time
getBiasNanos - Typically 0 but can be used to express time sub-nanosecond precision.
getReceivedSvTimeNanos – Estimated time of transmission of the pseudorange
getAccumulatedDeltaRangeMeters – Counts the number of carrier-phase cycles since powered on (assuming no duty cycles). The cycles are converted to range in unit of meters.
getCarrierFrequencyHz – The carrier-phase frequency being tracked. It can be L1 or L2 and if empty, the default is L1.
Pseudoranges?
Interestingly, the Android API does not construct the pseudoranges for you. I can imagine this feature being implemented in future iterations, as it is a bit ad hoc. Pseudo…ranges represent the approximate (pseudo) distance (range) between the satellite and the receiver.
Highlighted in the flowchart below, how the different components of the API come together.
Highlighted in the flowchart below, how the different components of the API come together.
The following steps are required to compute the pseudorange. Note, we converted the input data to seconds to have more meaningful values.
Code Editor
Show me the carrier-phase!
The carrier-phase measurements are currently bitter-sweet. They are very easy to access in the API using getAccumulatedDeltaRangeMeters() , but most GNSS chip manufactures aren’t required to allow access to the carrier-phase data until 2017.