GnssMeasurement.java revision 0e342e1fdb892529b9fbc073dbe18c8704af0355
1/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
15 */
16
17package android.location;
18
19import android.annotation.TestApi;
20import android.annotation.IntDef;
21import android.os.Parcel;
22import android.os.Parcelable;
23
24import java.lang.annotation.Retention;
25import java.lang.annotation.RetentionPolicy;
26
27/**
28 * A class representing a GNSS satellite measurement, containing raw and computed information.
29 */
30public final class GnssMeasurement implements Parcelable {
31    private int mFlags;
32    private int mSvid;
33    private int mConstellationType;
34    private double mTimeOffsetNanos;
35    private int mState;
36    private long mReceivedSvTimeNanos;
37    private long mReceivedSvTimeUncertaintyNanos;
38    private double mCn0DbHz;
39    private double mPseudorangeRateMetersPerSecond;
40    private double mPseudorangeRateUncertaintyMetersPerSecond;
41    private int mAccumulatedDeltaRangeState;
42    private double mAccumulatedDeltaRangeMeters;
43    private double mAccumulatedDeltaRangeUncertaintyMeters;
44    private float mCarrierFrequencyHz;
45    private long mCarrierCycles;
46    private double mCarrierPhase;
47    private double mCarrierPhaseUncertainty;
48    private int mMultipathIndicator;
49    private double mSnrInDb;
50    private double mAutomaticGainControlLevelInDb;
51
52    // The following enumerations must be in sync with the values declared in gps.h
53
54    private static final int HAS_NO_FLAGS = 0;
55    private static final int HAS_SNR = (1<<0);
56    private static final int HAS_CARRIER_FREQUENCY = (1<<9);
57    private static final int HAS_CARRIER_CYCLES = (1<<10);
58    private static final int HAS_CARRIER_PHASE = (1<<11);
59    private static final int HAS_CARRIER_PHASE_UNCERTAINTY = (1<<12);
60    private static final int HAS_AUTOMATIC_GAIN_CONTROL = (1<<13);
61
62    /**
63     * The status of the multipath indicator.
64     * @hide
65     */
66    @Retention(RetentionPolicy.SOURCE)
67    @IntDef({MULTIPATH_INDICATOR_UNKNOWN, MULTIPATH_INDICATOR_DETECTED,
68            MULTIPATH_INDICATOR_NOT_DETECTED})
69    public @interface MultipathIndicator {}
70
71    /**
72     * The indicator is not available or the presence or absence of multipath is unknown.
73     */
74    public static final int MULTIPATH_INDICATOR_UNKNOWN = 0;
75
76    /**
77     * The measurement shows signs of multi-path.
78     */
79    public static final int MULTIPATH_INDICATOR_DETECTED = 1;
80
81    /**
82     * The measurement shows no signs of multi-path.
83     */
84    public static final int MULTIPATH_INDICATOR_NOT_DETECTED = 2;
85
86    /** This GNSS measurement's tracking state is invalid or unknown. */
87    public static final int STATE_UNKNOWN = 0;
88    /** This GNSS measurement's tracking state has code lock. */
89    public static final int STATE_CODE_LOCK = (1<<0);
90    /** This GNSS measurement's tracking state has bit sync. */
91    public static final int STATE_BIT_SYNC = (1<<1);
92    /** This GNSS measurement's tracking state has sub-frame sync. */
93    public static final int STATE_SUBFRAME_SYNC = (1<<2);
94    /** This GNSS measurement's tracking state has time-of-week decoded. */
95    public static final int STATE_TOW_DECODED = (1<<3);
96    /** This GNSS measurement's tracking state contains millisecond ambiguity. */
97    public static final int STATE_MSEC_AMBIGUOUS = (1<<4);
98    /** This GNSS measurement's tracking state has symbol sync. */
99    public static final int STATE_SYMBOL_SYNC = (1<<5);
100    /** This Glonass measurement's tracking state has string sync. */
101    public static final int STATE_GLO_STRING_SYNC = (1<<6);
102    /** This Glonass measurement's tracking state has time-of-day decoded. */
103    public static final int STATE_GLO_TOD_DECODED = (1<<7);
104    /** This Beidou measurement's tracking state has D2 bit sync. */
105    public static final int STATE_BDS_D2_BIT_SYNC = (1<<8);
106    /** This Beidou measurement's tracking state has D2 sub-frame sync. */
107    public static final int STATE_BDS_D2_SUBFRAME_SYNC = (1<<9);
108    /** This Galileo measurement's tracking state has E1B/C code lock. */
109    public static final int STATE_GAL_E1BC_CODE_LOCK = (1<<10);
110    /** This Galileo measurement's tracking state has E1C secondary code lock. */
111    public static final int STATE_GAL_E1C_2ND_CODE_LOCK = (1<<11);
112    /** This Galileo measurement's tracking state has E1B page sync. */
113    public static final int STATE_GAL_E1B_PAGE_SYNC = (1<<12);
114    /** This SBAS measurement's tracking state has whole second level sync. */
115    public static final int STATE_SBAS_SYNC = (1<<13);
116    /**
117     * This GNSS measurement's tracking state has time-of-week known, possibly not decoded
118     * over the air but has been determined from other sources. If TOW decoded is set then TOW Known
119     * will also be set.
120     */
121    public static final int STATE_TOW_KNOWN = (1<<14);
122    /**
123     * This Glonass measurement's tracking state has time-of-day known, possibly not decoded
124     * over the air but has been determined from other sources. If TOD decoded is set then TOD Known
125     * will also be set.
126     */
127    public static final int STATE_GLO_TOD_KNOWN = (1<<15);
128
129    /**
130     * All the GNSS receiver state flags, for bit masking purposes (not a sensible state for any
131     * individual measurement.)
132     */
133    private static final int STATE_ALL = 0x3fff;  // 2 bits + 4 bits + 4 bits + 4 bits = 14 bits
134
135    /**
136     * The state of the 'Accumulated Delta Range' is invalid or unknown.
137     */
138    public static final int ADR_STATE_UNKNOWN = 0;
139
140    /**
141     * The state of the 'Accumulated Delta Range' is valid.
142     */
143    public static final int ADR_STATE_VALID = (1<<0);
144
145    /**
146     * The state of the 'Accumulated Delta Range' has detected a reset.
147     */
148    public static final int ADR_STATE_RESET = (1<<1);
149
150    /**
151     * The state of the 'Accumulated Delta Range' has a cycle slip detected.
152     */
153    public static final int ADR_STATE_CYCLE_SLIP = (1<<2);
154
155    /**
156     * All the 'Accumulated Delta Range' flags.
157     */
158    private static final int ADR_ALL = ADR_STATE_VALID | ADR_STATE_RESET | ADR_STATE_CYCLE_SLIP;
159
160    // End enumerations in sync with gps.h
161
162    /**
163     * @hide
164     */
165    @TestApi
166    public GnssMeasurement() {
167        initialize();
168    }
169
170    /**
171     * Sets all contents to the values stored in the provided object.
172     * @hide
173     */
174    @TestApi
175    public void set(GnssMeasurement measurement) {
176        mFlags = measurement.mFlags;
177        mSvid = measurement.mSvid;
178        mConstellationType = measurement.mConstellationType;
179        mTimeOffsetNanos = measurement.mTimeOffsetNanos;
180        mState = measurement.mState;
181        mReceivedSvTimeNanos = measurement.mReceivedSvTimeNanos;
182        mReceivedSvTimeUncertaintyNanos = measurement.mReceivedSvTimeUncertaintyNanos;
183        mCn0DbHz = measurement.mCn0DbHz;
184        mPseudorangeRateMetersPerSecond = measurement.mPseudorangeRateMetersPerSecond;
185        mPseudorangeRateUncertaintyMetersPerSecond =
186                measurement.mPseudorangeRateUncertaintyMetersPerSecond;
187        mAccumulatedDeltaRangeState = measurement.mAccumulatedDeltaRangeState;
188        mAccumulatedDeltaRangeMeters = measurement.mAccumulatedDeltaRangeMeters;
189        mAccumulatedDeltaRangeUncertaintyMeters =
190                measurement.mAccumulatedDeltaRangeUncertaintyMeters;
191        mCarrierFrequencyHz = measurement.mCarrierFrequencyHz;
192        mCarrierCycles = measurement.mCarrierCycles;
193        mCarrierPhase = measurement.mCarrierPhase;
194        mCarrierPhaseUncertainty = measurement.mCarrierPhaseUncertainty;
195        mMultipathIndicator = measurement.mMultipathIndicator;
196        mSnrInDb = measurement.mSnrInDb;
197        mAutomaticGainControlLevelInDb = measurement.mAutomaticGainControlLevelInDb;
198    }
199
200    /**
201     * Resets all the contents to its original state.
202     * @hide
203     */
204    @TestApi
205    public void reset() {
206        initialize();
207    }
208
209    /**
210     * Gets the satellite ID.
211     *
212     * <p>Interpretation depends on {@link #getConstellationType()}.
213     * See {@link GnssStatus#getSvid(int)}.
214     */
215    public int getSvid() {
216        return mSvid;
217    }
218
219    /**
220     * Sets the Satellite ID.
221     * @hide
222     */
223    @TestApi
224    public void setSvid(int value) {
225        mSvid = value;
226    }
227
228    /**
229     * Gets the constellation type.
230     *
231     * <p>The return value is one of those constants with {@code CONSTELLATION_} prefix in
232     * {@link GnssStatus}.
233     */
234    @GnssStatus.ConstellationType
235    public int getConstellationType() {
236        return mConstellationType;
237    }
238
239    /**
240     * Sets the constellation type.
241     * @hide
242     */
243    @TestApi
244    public void setConstellationType(@GnssStatus.ConstellationType int value) {
245        mConstellationType = value;
246    }
247
248    /**
249     * Gets the time offset at which the measurement was taken in nanoseconds.
250     *
251     * <p>The reference receiver's time from which this is offset is specified by
252     * {@link GnssClock#getTimeNanos()}.
253     *
254     * <p>The sign of this value is given by the following equation:
255     * <pre>
256     *      measurement time = TimeNanos + TimeOffsetNanos</pre>
257     *
258     * <p>The value provides an individual time-stamp for the measurement, and allows sub-nanosecond
259     * accuracy.
260     */
261    public double getTimeOffsetNanos() {
262        return mTimeOffsetNanos;
263    }
264
265    /**
266     * Sets the time offset at which the measurement was taken in nanoseconds.
267     * @hide
268     */
269    @TestApi
270    public void setTimeOffsetNanos(double value) {
271        mTimeOffsetNanos = value;
272    }
273
274    /**
275     * Gets per-satellite sync state.
276     *
277     * <p>It represents the current sync state for the associated satellite.
278     *
279     * <p>This value helps interpret {@link #getReceivedSvTimeNanos()}.
280     */
281    public int getState() {
282        return mState;
283    }
284
285    /**
286     * Sets the sync state.
287     * @hide
288     */
289    @TestApi
290    public void setState(int value) {
291        mState = value;
292    }
293
294    /**
295     * Gets a string representation of the 'sync state'.
296     *
297     * <p>For internal and logging use only.
298     */
299    private String getStateString() {
300        if (mState == STATE_UNKNOWN) {
301            return "Unknown";
302        }
303
304        StringBuilder builder = new StringBuilder();
305        if ((mState & STATE_CODE_LOCK) != 0) {
306            builder.append("CodeLock|");
307        }
308        if ((mState & STATE_BIT_SYNC) != 0) {
309            builder.append("BitSync|");
310        }
311        if ((mState & STATE_SUBFRAME_SYNC) != 0) {
312            builder.append("SubframeSync|");
313        }
314        if ((mState & STATE_TOW_DECODED) != 0) {
315            builder.append("TowDecoded|");
316        }
317        if ((mState & STATE_TOW_KNOWN) != 0) {
318          builder.append("TowKnown|");
319        }
320        if ((mState & STATE_MSEC_AMBIGUOUS) != 0) {
321            builder.append("MsecAmbiguous|");
322        }
323        if ((mState & STATE_SYMBOL_SYNC) != 0) {
324            builder.append("SymbolSync|");
325        }
326        if ((mState & STATE_GLO_STRING_SYNC) != 0) {
327            builder.append("GloStringSync|");
328        }
329        if ((mState & STATE_GLO_TOD_DECODED) != 0) {
330            builder.append("GloTodDecoded|");
331        }
332        if ((mState & STATE_GLO_TOD_KNOWN) != 0) {
333          builder.append("GloTodKnown|");
334        }
335        if ((mState & STATE_BDS_D2_BIT_SYNC) != 0) {
336            builder.append("BdsD2BitSync|");
337        }
338        if ((mState & STATE_BDS_D2_SUBFRAME_SYNC) != 0) {
339            builder.append("BdsD2SubframeSync|");
340        }
341        if ((mState & STATE_GAL_E1BC_CODE_LOCK) != 0) {
342            builder.append("GalE1bcCodeLock|");
343        }
344        if ((mState & STATE_GAL_E1C_2ND_CODE_LOCK) != 0) {
345            builder.append("E1c2ndCodeLock|");
346        }
347        if ((mState & STATE_GAL_E1B_PAGE_SYNC) != 0) {
348            builder.append("GalE1bPageSync|");
349        }
350        if ((mState & STATE_SBAS_SYNC) != 0) {
351            builder.append("SbasSync|");
352        }
353
354        int remainingStates = mState & ~STATE_ALL;
355        if (remainingStates > 0) {
356            builder.append("Other(");
357            builder.append(Integer.toBinaryString(remainingStates));
358            builder.append(")|");
359        }
360        builder.setLength(builder.length() - 1);
361        return builder.toString();
362    }
363
364    /**
365     * Gets the received GNSS satellite time, at the measurement time, in nanoseconds.
366     *
367     * <p>For GPS &amp; QZSS, this is:
368     * <ul>
369     * <li>Received GPS Time-of-Week at the measurement time, in nanoseconds.</li>
370     * <li>The value is relative to the beginning of the current GPS week.</li>
371     * </ul>
372     *
373     * <p>Given the highest sync state that can be achieved, per each satellite, valid range
374     * for this field can be:
375     * <pre>
376     *     Searching       : [ 0       ]   : STATE_UNKNOWN
377     *     C/A code lock   : [ 0   1ms ]   : STATE_CODE_LOCK is set
378     *     Bit sync        : [ 0  20ms ]   : STATE_BIT_SYNC is set
379     *     Subframe sync   : [ 0    6s ]   : STATE_SUBFRAME_SYNC is set
380     *     TOW decoded     : [ 0 1week ]   : STATE_TOW_DECODED is set
381     *     TOW Known       : [ 0 1week ]   : STATE_TOW_KNOWN set</pre>
382     *
383     * Note: TOW Known refers to the case where TOW is possibly not decoded over the air but has
384     * been determined from other sources. If TOW decoded is set then TOW Known must also be set.
385     *
386     * <p>Note well: if there is any ambiguity in integer millisecond, {@code STATE_MSEC_AMBIGUOUS}
387     * must be set accordingly, in the 'state' field.
388     *
389     * <p>This value must be populated if 'state' != {@code STATE_UNKNOWN}.
390     *
391     * <p>For Glonass, this is:
392     * <ul>
393     * <li>Received Glonass time of day, at the measurement time in nanoseconds.</li>
394     * </ul>
395     *
396     * <p>Given the highest sync state that can be achieved, per each satellite, valid range for
397     * this field can be:
398     * <pre>
399     *     Searching           : [ 0       ]   : STATE_UNKNOWN
400     *     C/A code lock       : [ 0   1ms ]   : STATE_CODE_LOCK is set
401     *     Symbol sync         : [ 0  10ms ]   : STATE_SYMBOL_SYNC is set
402     *     Bit sync            : [ 0  20ms ]   : STATE_BIT_SYNC is set
403     *     String sync         : [ 0    2s ]   : STATE_GLO_STRING_SYNC is set
404     *     Time of day decoded : [ 0  1day ]   : STATE_GLO_TOD_DECODED is set
405     *     Time of day known   : [ 0  1day ]   : STATE_GLO_TOD_KNOWN set</pre>
406     *
407     * Note: Time of day known refers to the case where it is possibly not decoded over the air but
408     * has been determined from other sources. If Time of day decoded is set then Time of day known
409     * must also be set.
410     *
411     * <p>For Beidou, this is:
412     * <ul>
413     * <li>Received Beidou time of week, at the measurement time in nanoseconds.</li>
414     * </ul>
415     *
416     * <p>Given the highest sync state that can be achieved, per each satellite, valid range for
417     * this field can be:
418     * <pre>
419     *     Searching              : [ 0       ]   : STATE_UNKNOWN
420     *     C/A code lock          : [ 0   1ms ]   : STATE_CODE_LOCK is set
421     *     Bit sync (D2)          : [ 0   2ms ]   : STATE_BDS_D2_BIT_SYNC is set
422     *     Bit sync (D1)          : [ 0  20ms ]   : STATE_BIT_SYNC is set
423     *     Subframe (D2)          : [ 0  0.6s ]   : STATE_BDS_D2_SUBFRAME_SYNC is set
424     *     Subframe (D1)          : [ 0    6s ]   : STATE_SUBFRAME_SYNC is set
425     *     Time of week decoded   : [ 0 1week ]   : STATE_TOW_DECODED is set
426     *     Time of week known     : [ 0 1week ]   : STATE_TOW_KNOWN set</pre>
427     *
428     * Note: TOW Known refers to the case where TOW is possibly not decoded over the air but has
429     * been determined from other sources. If TOW decoded is set then TOW Known must also be set.
430     *
431     * <p>For Galileo, this is:
432     * <ul>
433     * <li>Received Galileo time of week, at the measurement time in nanoseconds.</li>
434     * </ul>
435     * <pre>
436     *     E1BC code lock       : [ 0   4ms ]  : STATE_GAL_E1BC_CODE_LOCK is set
437     *     E1C 2nd code lock    : [ 0 100ms ]  : STATE_GAL_E1C_2ND_CODE_LOCK is set
438     *     E1B page             : [ 0    2s ]  : STATE_GAL_E1B_PAGE_SYNC is set
439     *     Time of week decoded : [ 0 1week ]  : STATE_GAL_TOW_DECODED is set
440     *     Time of week known   : [ 0 1week ]  : STATE_GAL_TOW_KNOWN set</pre>
441     *
442     * Note: TOW Known refers to the case where TOW is possibly not decoded over the air but has
443     * been determined from other sources. If TOW decoded is set then TOW Known must also be set.
444     *
445     * <p>For SBAS, this is:
446     * <ul>
447     * <li>Received SBAS time, at the measurement time in nanoseconds.</li>
448     * </ul>
449     *
450     * <p>Given the highest sync state that can be achieved, per each satellite, valid range for
451     * this field can be:
452     * <pre>
453     *     Searching       : [ 0       ]   : STATE_UNKNOWN
454     *     C/A code lock   : [ 0   1ms ]   : STATE_CODE_LOCK is set
455     *     Symbol sync     : [ 0   2ms ]   : STATE_SYMBOL_SYNC is set
456     *     Message         : [ 0    1s ]   : STATE_SBAS_SYNC is set</pre>
457     */
458    public long getReceivedSvTimeNanos() {
459        return mReceivedSvTimeNanos;
460    }
461
462    /**
463     * Sets the received GNSS time in nanoseconds.
464     * @hide
465     */
466    @TestApi
467    public void setReceivedSvTimeNanos(long value) {
468        mReceivedSvTimeNanos = value;
469    }
470
471    /**
472     * Gets the error estimate (1-sigma) for the received GNSS time, in nanoseconds.
473     */
474    public long getReceivedSvTimeUncertaintyNanos() {
475        return mReceivedSvTimeUncertaintyNanos;
476    }
477
478    /**
479     * Sets the received GNSS time uncertainty (1-Sigma) in nanoseconds.
480     * @hide
481     */
482    @TestApi
483    public void setReceivedSvTimeUncertaintyNanos(long value) {
484        mReceivedSvTimeUncertaintyNanos = value;
485    }
486
487    /**
488     * Gets the Carrier-to-noise density in dB-Hz.
489     *
490     * <p>Typical range: 10-50 db-Hz.
491     *
492     * <p>The value contains the measured C/N0 for the signal at the antenna input.
493     */
494    public double getCn0DbHz() {
495        return mCn0DbHz;
496    }
497
498    /**
499     * Sets the carrier-to-noise density in dB-Hz.
500     * @hide
501     */
502    @TestApi
503    public void setCn0DbHz(double value) {
504        mCn0DbHz = value;
505    }
506
507    /**
508     * Gets the Pseudorange rate at the timestamp in m/s.
509     *
510     * <p>The error estimate for this value is
511     * {@link #getPseudorangeRateUncertaintyMetersPerSecond()}.
512     *
513     * <p>The value is uncorrected, i.e. corrections for receiver and satellite clock frequency
514     * errors are not included.
515     *
516     * <p>A positive 'uncorrected' value indicates that the SV is moving away from the receiver. The
517     * sign of the 'uncorrected' 'pseudorange rate' and its relation to the sign of 'doppler shift'
518     * is given by the equation:
519     *
520     * <pre>
521     *      pseudorange rate = -k * doppler shift   (where k is a constant)</pre>
522     */
523    public double getPseudorangeRateMetersPerSecond() {
524        return mPseudorangeRateMetersPerSecond;
525    }
526
527    /**
528     * Sets the pseudorange rate at the timestamp in m/s.
529     * @hide
530     */
531    @TestApi
532    public void setPseudorangeRateMetersPerSecond(double value) {
533        mPseudorangeRateMetersPerSecond = value;
534    }
535
536    /**
537     * Gets the pseudorange's rate uncertainty (1-Sigma) in m/s.
538     *
539     * <p>The uncertainty is represented as an absolute (single sided) value.
540     */
541    public double getPseudorangeRateUncertaintyMetersPerSecond() {
542        return mPseudorangeRateUncertaintyMetersPerSecond;
543    }
544
545    /**
546     * Sets the pseudorange's rate uncertainty (1-Sigma) in m/s.
547     * @hide
548     */
549    @TestApi
550    public void setPseudorangeRateUncertaintyMetersPerSecond(double value) {
551        mPseudorangeRateUncertaintyMetersPerSecond = value;
552    }
553
554    /**
555     * Gets 'Accumulated Delta Range' state.
556     *
557     * <p>It indicates whether {@link #getAccumulatedDeltaRangeMeters()} is reset or there is a
558     * cycle slip (indicating 'loss of lock').
559     */
560    public int getAccumulatedDeltaRangeState() {
561        return mAccumulatedDeltaRangeState;
562    }
563
564    /**
565     * Sets the 'Accumulated Delta Range' state.
566     * @hide
567     */
568    @TestApi
569    public void setAccumulatedDeltaRangeState(int value) {
570        mAccumulatedDeltaRangeState = value;
571    }
572
573    /**
574     * Gets a string representation of the 'Accumulated Delta Range state'.
575     *
576     * <p>For internal and logging use only.
577     */
578    private String getAccumulatedDeltaRangeStateString() {
579        if (mAccumulatedDeltaRangeState == ADR_STATE_UNKNOWN) {
580            return "Unknown";
581        }
582        StringBuilder builder = new StringBuilder();
583        if ((mAccumulatedDeltaRangeState & ADR_STATE_VALID) == ADR_STATE_VALID) {
584            builder.append("Valid|");
585        }
586        if ((mAccumulatedDeltaRangeState & ADR_STATE_RESET) == ADR_STATE_RESET) {
587            builder.append("Reset|");
588        }
589        if ((mAccumulatedDeltaRangeState & ADR_STATE_CYCLE_SLIP) == ADR_STATE_CYCLE_SLIP) {
590            builder.append("CycleSlip|");
591        }
592        int remainingStates = mAccumulatedDeltaRangeState & ~ADR_ALL;
593        if (remainingStates > 0) {
594            builder.append("Other(");
595            builder.append(Integer.toBinaryString(remainingStates));
596            builder.append(")|");
597        }
598        builder.deleteCharAt(builder.length() - 1);
599        return builder.toString();
600    }
601
602    /**
603     * Gets the accumulated delta range since the last channel reset, in meters.
604     *
605     * <p>The error estimate for this value is {@link #getAccumulatedDeltaRangeUncertaintyMeters()}.
606     *
607     * <p>The availability of the value is represented by {@link #getAccumulatedDeltaRangeState()}.
608     *
609     * <p>A positive value indicates that the SV is moving away from the receiver.
610     * The sign of {@link #getAccumulatedDeltaRangeMeters()} and its relation to the sign of
611     * {@link #getCarrierPhase()} is given by the equation:
612     *
613     * <pre>
614     *          accumulated delta range = -k * carrier phase    (where k is a constant)</pre>
615     */
616    public double getAccumulatedDeltaRangeMeters() {
617        return mAccumulatedDeltaRangeMeters;
618    }
619
620    /**
621     * Sets the accumulated delta range in meters.
622     * @hide
623     */
624    @TestApi
625    public void setAccumulatedDeltaRangeMeters(double value) {
626        mAccumulatedDeltaRangeMeters = value;
627    }
628
629    /**
630     * Gets the accumulated delta range's uncertainty (1-Sigma) in meters.
631     *
632     * <p>The uncertainty is represented as an absolute (single sided) value.
633     *
634     * <p>The status of the value is represented by {@link #getAccumulatedDeltaRangeState()}.
635     */
636    public double getAccumulatedDeltaRangeUncertaintyMeters() {
637        return mAccumulatedDeltaRangeUncertaintyMeters;
638    }
639
640    /**
641     * Sets the accumulated delta range's uncertainty (1-sigma) in meters.
642     *
643     * <p>The status of the value is represented by {@link #getAccumulatedDeltaRangeState()}.
644     *
645     * @hide
646     */
647    @TestApi
648    public void setAccumulatedDeltaRangeUncertaintyMeters(double value) {
649        mAccumulatedDeltaRangeUncertaintyMeters = value;
650    }
651
652    /**
653     * Returns {@code true} if {@link #getCarrierFrequencyHz()} is available, {@code false}
654     * otherwise.
655     */
656    public boolean hasCarrierFrequencyHz() {
657        return isFlagSet(HAS_CARRIER_FREQUENCY);
658    }
659
660    /**
661     * Gets the carrier frequency of the tracked signal.
662     *
663     * <p>For example it can be the GPS central frequency for L1 = 1575.45 MHz, or L2 = 1227.60 MHz,
664     * L5 = 1176.45 MHz, varying GLO channels, etc. If the field is not set, it is the primary
665     * common use central frequency, e.g. L1 = 1575.45 MHz for GPS.
666     *
667     * For an L1, L5 receiver tracking a satellite on L1 and L5 at the same time, two raw
668     * measurement objects will be reported for this same satellite, in one of the measurement
669     * objects, all the values related to L1 will be filled, and in the other all of the values
670     * related to L5 will be filled.
671     *
672     * <p>The value is only available if {@link #hasCarrierFrequencyHz()} is {@code true}.
673     *
674     * @return the carrier frequency of the signal tracked in Hz.
675     */
676    public float getCarrierFrequencyHz() {
677        return mCarrierFrequencyHz;
678    }
679
680    /**
681     * Sets the Carrier frequency in Hz.
682     * @hide
683     */
684    @TestApi
685    public void setCarrierFrequencyHz(float carrierFrequencyHz) {
686        setFlag(HAS_CARRIER_FREQUENCY);
687        mCarrierFrequencyHz = carrierFrequencyHz;
688    }
689
690    /**
691     * Resets the Carrier frequency in Hz.
692     * @hide
693     */
694    @TestApi
695    public void resetCarrierFrequencyHz() {
696        resetFlag(HAS_CARRIER_FREQUENCY);
697        mCarrierFrequencyHz = Float.NaN;
698    }
699
700    /**
701     * Returns {@code true} if {@link #getCarrierCycles()} is available, {@code false} otherwise.
702     */
703    public boolean hasCarrierCycles() {
704        return isFlagSet(HAS_CARRIER_CYCLES);
705    }
706
707    /**
708     * The number of full carrier cycles between the satellite and the receiver.
709     *
710     * <p>The reference frequency is given by the value of {@link #getCarrierFrequencyHz()}.
711     *
712     * <p>The value is only available if {@link #hasCarrierCycles()} is {@code true}.
713     */
714    public long getCarrierCycles() {
715        return mCarrierCycles;
716    }
717
718    /**
719     * Sets the number of full carrier cycles between the satellite and the receiver.
720     * @hide
721     */
722    @TestApi
723    public void setCarrierCycles(long value) {
724        setFlag(HAS_CARRIER_CYCLES);
725        mCarrierCycles = value;
726    }
727
728    /**
729     * Resets the number of full carrier cycles between the satellite and the receiver.
730     * @hide
731     */
732    @TestApi
733    public void resetCarrierCycles() {
734        resetFlag(HAS_CARRIER_CYCLES);
735        mCarrierCycles = Long.MIN_VALUE;
736    }
737
738    /**
739     * Returns {@code true} if {@link #getCarrierPhase()} is available, {@code false} otherwise.
740     */
741    public boolean hasCarrierPhase() {
742        return isFlagSet(HAS_CARRIER_PHASE);
743    }
744
745    /**
746     * Gets the RF phase detected by the receiver.
747     *
748     * <p>Range: [0.0, 1.0].
749     *
750     * <p>This is the fractional part of the complete carrier phase measurement.
751     *
752     * <p>The reference frequency is given by the value of {@link #getCarrierFrequencyHz()}.
753     *
754     * <p>The error estimate for this value is {@link #getCarrierPhaseUncertainty()}.
755     *
756     * <p>The value is only available if {@link #hasCarrierPhase()} is {@code true}.
757     */
758    public double getCarrierPhase() {
759        return mCarrierPhase;
760    }
761
762    /**
763     * Sets the RF phase detected by the receiver.
764     * @hide
765     */
766    @TestApi
767    public void setCarrierPhase(double value) {
768        setFlag(HAS_CARRIER_PHASE);
769        mCarrierPhase = value;
770    }
771
772    /**
773     * Resets the RF phase detected by the receiver.
774     * @hide
775     */
776    @TestApi
777    public void resetCarrierPhase() {
778        resetFlag(HAS_CARRIER_PHASE);
779        mCarrierPhase = Double.NaN;
780    }
781
782    /**
783     * Returns {@code true} if {@link #getCarrierPhaseUncertainty()} is available, {@code false}
784     * otherwise.
785     */
786    public boolean hasCarrierPhaseUncertainty() {
787        return isFlagSet(HAS_CARRIER_PHASE_UNCERTAINTY);
788    }
789
790    /**
791     * Gets the carrier-phase's uncertainty (1-Sigma).
792     *
793     * <p>The uncertainty is represented as an absolute (single sided) value.
794     *
795     * <p>The value is only available if {@link #hasCarrierPhaseUncertainty()} is {@code true}.
796     */
797    public double getCarrierPhaseUncertainty() {
798        return mCarrierPhaseUncertainty;
799    }
800
801    /**
802     * Sets the Carrier-phase's uncertainty (1-Sigma) in cycles.
803     * @hide
804     */
805    @TestApi
806    public void setCarrierPhaseUncertainty(double value) {
807        setFlag(HAS_CARRIER_PHASE_UNCERTAINTY);
808        mCarrierPhaseUncertainty = value;
809    }
810
811    /**
812     * Resets the Carrier-phase's uncertainty (1-Sigma) in cycles.
813     * @hide
814     */
815    @TestApi
816    public void resetCarrierPhaseUncertainty() {
817        resetFlag(HAS_CARRIER_PHASE_UNCERTAINTY);
818        mCarrierPhaseUncertainty = Double.NaN;
819    }
820
821    /**
822     * Gets a value indicating the 'multipath' state of the event.
823     */
824    @MultipathIndicator
825    public int getMultipathIndicator() {
826        return mMultipathIndicator;
827    }
828
829    /**
830     * Sets the 'multi-path' indicator.
831     * @hide
832     */
833    @TestApi
834    public void setMultipathIndicator(@MultipathIndicator int value) {
835        mMultipathIndicator = value;
836    }
837
838    /**
839     * Gets a string representation of the 'multi-path indicator'.
840     *
841     * <p>For internal and logging use only.
842     */
843    private String getMultipathIndicatorString() {
844        switch(mMultipathIndicator) {
845            case MULTIPATH_INDICATOR_UNKNOWN:
846                return "Unknown";
847            case MULTIPATH_INDICATOR_DETECTED:
848                return "Detected";
849            case MULTIPATH_INDICATOR_NOT_DETECTED:
850                return "NotDetected";
851            default:
852                return "<Invalid:" + mMultipathIndicator + ">";
853        }
854    }
855
856    /**
857     * Returns {@code true} if {@link #getSnrInDb()} is available, {@code false} otherwise.
858     */
859    public boolean hasSnrInDb() {
860        return isFlagSet(HAS_SNR);
861    }
862
863    /**
864     * Gets the Signal-to-Noise ratio (SNR) in dB.
865     *
866     * <p>The value is only available if {@link #hasSnrInDb()} is {@code true}.
867     */
868    public double getSnrInDb() {
869        return mSnrInDb;
870    }
871
872    /**
873     * Sets the Signal-to-noise ratio (SNR) in dB.
874     * @hide
875     */
876    @TestApi
877    public void setSnrInDb(double snrInDb) {
878        setFlag(HAS_SNR);
879        mSnrInDb = snrInDb;
880    }
881
882    /**
883     * Resets the Signal-to-noise ratio (SNR) in dB.
884     * @hide
885     */
886    @TestApi
887    public void resetSnrInDb() {
888        resetFlag(HAS_SNR);
889        mSnrInDb = Double.NaN;
890    }
891
892    /**
893     * Returns {@code true} if {@link #getAutomaticGainControlLevelDb()} is available,
894     * {@code false} otherwise.
895     */
896    public boolean hasAutomaticGainControlLevelDb() {
897        return isFlagSet(HAS_AUTOMATIC_GAIN_CONTROL);
898    }
899
900    /**
901     * Gets the Automatic Gain Control level in dB.
902     *
903     * <p> AGC acts as a variable gain amplifier adjusting the power of the incoming signal. The AGC
904     * level may be used to indicate potential interference. When AGC is at a nominal level, this
905     * value must be set as 0. Higher gain (and/or lower input power) shall be output as a positive
906     * number. Hence in cases of strong jamming, in the band of this signal, this value will go more
907     * negative.
908     *
909     * <p>Note: Different hardware designs (e.g. antenna, pre-amplification, or other RF HW
910     * components) may also affect the typical output of of this value on any given hardware design
911     * in an open sky test - the important aspect of this output is that changes in this value are
912     * indicative of changes on input signal power in the frequency band for this measurement.
913     * <p>The value is only available if {@link #hasAutomaticGainControlLevelDb()} is {@code true}
914     */
915    public double getAutomaticGainControlLevelDb() {
916        return mAutomaticGainControlLevelInDb;
917    }
918
919    /**
920     * Sets the Automatic Gain Control level in dB.
921     * @hide
922     */
923    @TestApi
924    public void setAutomaticGainControlLevelInDb(double agcLevelDb) {
925        setFlag(HAS_AUTOMATIC_GAIN_CONTROL);
926        mAutomaticGainControlLevelInDb = agcLevelDb;
927    }
928
929    /**
930     * Resets the Automatic Gain Control level.
931     * @hide
932     */
933    @TestApi
934    public void resetAutomaticGainControlLevel() {
935        resetFlag(HAS_AUTOMATIC_GAIN_CONTROL);
936        mAutomaticGainControlLevelInDb = Double.NaN;
937    }
938
939    public static final Creator<GnssMeasurement> CREATOR = new Creator<GnssMeasurement>() {
940        @Override
941        public GnssMeasurement createFromParcel(Parcel parcel) {
942            GnssMeasurement gnssMeasurement = new GnssMeasurement();
943
944            gnssMeasurement.mFlags = parcel.readInt();
945            gnssMeasurement.mSvid = parcel.readInt();
946            gnssMeasurement.mConstellationType = parcel.readInt();
947            gnssMeasurement.mTimeOffsetNanos = parcel.readDouble();
948            gnssMeasurement.mState = parcel.readInt();
949            gnssMeasurement.mReceivedSvTimeNanos = parcel.readLong();
950            gnssMeasurement.mReceivedSvTimeUncertaintyNanos = parcel.readLong();
951            gnssMeasurement.mCn0DbHz = parcel.readDouble();
952            gnssMeasurement.mPseudorangeRateMetersPerSecond = parcel.readDouble();
953            gnssMeasurement.mPseudorangeRateUncertaintyMetersPerSecond = parcel.readDouble();
954            gnssMeasurement.mAccumulatedDeltaRangeState = parcel.readInt();
955            gnssMeasurement.mAccumulatedDeltaRangeMeters = parcel.readDouble();
956            gnssMeasurement.mAccumulatedDeltaRangeUncertaintyMeters = parcel.readDouble();
957            gnssMeasurement.mCarrierFrequencyHz = parcel.readFloat();
958            gnssMeasurement.mCarrierCycles = parcel.readLong();
959            gnssMeasurement.mCarrierPhase = parcel.readDouble();
960            gnssMeasurement.mCarrierPhaseUncertainty = parcel.readDouble();
961            gnssMeasurement.mMultipathIndicator = parcel.readInt();
962            gnssMeasurement.mSnrInDb = parcel.readDouble();
963            gnssMeasurement.mAutomaticGainControlLevelInDb = parcel.readDouble();
964
965            return gnssMeasurement;
966        }
967
968        @Override
969        public GnssMeasurement[] newArray(int i) {
970            return new GnssMeasurement[i];
971        }
972    };
973
974    @Override
975    public void writeToParcel(Parcel parcel, int flags) {
976        parcel.writeInt(mFlags);
977        parcel.writeInt(mSvid);
978        parcel.writeInt(mConstellationType);
979        parcel.writeDouble(mTimeOffsetNanos);
980        parcel.writeInt(mState);
981        parcel.writeLong(mReceivedSvTimeNanos);
982        parcel.writeLong(mReceivedSvTimeUncertaintyNanos);
983        parcel.writeDouble(mCn0DbHz);
984        parcel.writeDouble(mPseudorangeRateMetersPerSecond);
985        parcel.writeDouble(mPseudorangeRateUncertaintyMetersPerSecond);
986        parcel.writeInt(mAccumulatedDeltaRangeState);
987        parcel.writeDouble(mAccumulatedDeltaRangeMeters);
988        parcel.writeDouble(mAccumulatedDeltaRangeUncertaintyMeters);
989        parcel.writeFloat(mCarrierFrequencyHz);
990        parcel.writeLong(mCarrierCycles);
991        parcel.writeDouble(mCarrierPhase);
992        parcel.writeDouble(mCarrierPhaseUncertainty);
993        parcel.writeInt(mMultipathIndicator);
994        parcel.writeDouble(mSnrInDb);
995        parcel.writeDouble(mAutomaticGainControlLevelInDb);
996    }
997
998    @Override
999    public int describeContents() {
1000        return 0;
1001    }
1002
1003    @Override
1004    public String toString() {
1005        final String format = "   %-29s = %s\n";
1006        final String formatWithUncertainty = "   %-29s = %-25s   %-40s = %s\n";
1007        StringBuilder builder = new StringBuilder("GnssMeasurement:\n");
1008
1009        builder.append(String.format(format, "Svid", mSvid));
1010        builder.append(String.format(format, "ConstellationType", mConstellationType));
1011        builder.append(String.format(format, "TimeOffsetNanos", mTimeOffsetNanos));
1012
1013        builder.append(String.format(format, "State", getStateString()));
1014
1015        builder.append(String.format(
1016                formatWithUncertainty,
1017                "ReceivedSvTimeNanos",
1018                mReceivedSvTimeNanos,
1019                "ReceivedSvTimeUncertaintyNanos",
1020                mReceivedSvTimeUncertaintyNanos));
1021
1022        builder.append(String.format(format, "Cn0DbHz", mCn0DbHz));
1023
1024        builder.append(String.format(
1025                formatWithUncertainty,
1026                "PseudorangeRateMetersPerSecond",
1027                mPseudorangeRateMetersPerSecond,
1028                "PseudorangeRateUncertaintyMetersPerSecond",
1029                mPseudorangeRateUncertaintyMetersPerSecond));
1030
1031        builder.append(String.format(
1032                format,
1033                "AccumulatedDeltaRangeState",
1034                getAccumulatedDeltaRangeStateString()));
1035
1036        builder.append(String.format(
1037                formatWithUncertainty,
1038                "AccumulatedDeltaRangeMeters",
1039                mAccumulatedDeltaRangeMeters,
1040                "AccumulatedDeltaRangeUncertaintyMeters",
1041                mAccumulatedDeltaRangeUncertaintyMeters));
1042
1043        builder.append(String.format(
1044                format,
1045                "CarrierFrequencyHz",
1046                hasCarrierFrequencyHz() ? mCarrierFrequencyHz : null));
1047
1048        builder.append(String.format(
1049                format,
1050                "CarrierCycles",
1051                hasCarrierCycles() ? mCarrierCycles : null));
1052
1053        builder.append(String.format(
1054                formatWithUncertainty,
1055                "CarrierPhase",
1056                hasCarrierPhase() ? mCarrierPhase : null,
1057                "CarrierPhaseUncertainty",
1058                hasCarrierPhaseUncertainty() ? mCarrierPhaseUncertainty : null));
1059
1060        builder.append(String.format(format, "MultipathIndicator", getMultipathIndicatorString()));
1061
1062        builder.append(String.format(
1063                format,
1064                "SnrInDb",
1065                hasSnrInDb() ? mSnrInDb : null));
1066        builder.append(String.format(
1067            format,
1068            "AgcLevelDb",
1069            hasAutomaticGainControlLevelDb() ? mAutomaticGainControlLevelInDb : null));
1070
1071        return builder.toString();
1072    }
1073
1074    private void initialize() {
1075        mFlags = HAS_NO_FLAGS;
1076        setSvid(0);
1077        setTimeOffsetNanos(Long.MIN_VALUE);
1078        setState(STATE_UNKNOWN);
1079        setReceivedSvTimeNanos(Long.MIN_VALUE);
1080        setReceivedSvTimeUncertaintyNanos(Long.MAX_VALUE);
1081        setCn0DbHz(Double.MIN_VALUE);
1082        setPseudorangeRateMetersPerSecond(Double.MIN_VALUE);
1083        setPseudorangeRateUncertaintyMetersPerSecond(Double.MIN_VALUE);
1084        setAccumulatedDeltaRangeState(ADR_STATE_UNKNOWN);
1085        setAccumulatedDeltaRangeMeters(Double.MIN_VALUE);
1086        setAccumulatedDeltaRangeUncertaintyMeters(Double.MIN_VALUE);
1087        resetCarrierFrequencyHz();
1088        resetCarrierCycles();
1089        resetCarrierPhase();
1090        resetCarrierPhaseUncertainty();
1091        setMultipathIndicator(MULTIPATH_INDICATOR_UNKNOWN);
1092        resetSnrInDb();
1093        resetAutomaticGainControlLevel();
1094    }
1095
1096    private void setFlag(int flag) {
1097        mFlags |= flag;
1098    }
1099
1100    private void resetFlag(int flag) {
1101        mFlags &= ~flag;
1102    }
1103
1104    private boolean isFlagSet(int flag) {
1105        return (mFlags & flag) == flag;
1106    }
1107}
1108