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 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 & 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