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