Files
frameworks_base/location/java/android/location/GpsMeasurement.java
destradaa c91ac68829 Update handling of enum/flag fields in GPS data structures.
It fixes cases when flags where filtered in the platform, because they were
checked as enums.
It also simplies handling of future values in enums/flags.

Change-Id: I83a0f82cc4562749081bf7e279ea52e2d5ba1f7c
2015-02-11 13:16:28 -08:00

1374 lines
44 KiB
Java

/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License
*/
package android.location;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
/**
* A class representing a GPS satellite measurement, containing raw and computed information.
*
* @hide
*/
@SystemApi
public class GpsMeasurement implements Parcelable {
private int mFlags;
private byte mPrn;
private double mTimeOffsetInNs;
private short mState;
private long mReceivedGpsTowInNs;
private long mReceivedGpsTowUncertaintyInNs;
private double mCn0InDbHz;
private double mPseudorangeRateInMetersPerSec;
private double mPseudorangeRateUncertaintyInMetersPerSec;
private short mAccumulatedDeltaRangeState;
private double mAccumulatedDeltaRangeInMeters;
private double mAccumulatedDeltaRangeUncertaintyInMeters;
private double mPseudorangeInMeters;
private double mPseudorangeUncertaintyInMeters;
private double mCodePhaseInChips;
private double mCodePhaseUncertaintyInChips;
private float mCarrierFrequencyInHz;
private long mCarrierCycles;
private double mCarrierPhase;
private double mCarrierPhaseUncertainty;
private byte mLossOfLock;
private int mBitNumber;
private short mTimeFromLastBitInMs;
private double mDopplerShiftInHz;
private double mDopplerShiftUncertaintyInHz;
private byte mMultipathIndicator;
private double mSnrInDb;
private double mElevationInDeg;
private double mElevationUncertaintyInDeg;
private double mAzimuthInDeg;
private double mAzimuthUncertaintyInDeg;
private boolean mUsedInFix;
// The following enumerations must be in sync with the values declared in gps.h
private static final int HAS_NO_FLAGS = 0;
private static final int HAS_SNR = (1<<0);
private static final int HAS_ELEVATION = (1<<1);
private static final int HAS_ELEVATION_UNCERTAINTY = (1<<2);
private static final int HAS_AZIMUTH = (1<<3);
private static final int HAS_AZIMUTH_UNCERTAINTY = (1<<4);
private static final int HAS_PSEUDORANGE = (1<<5);
private static final int HAS_PSEUDORANGE_UNCERTAINTY = (1<<6);
private static final int HAS_CODE_PHASE = (1<<7);
private static final int HAS_CODE_PHASE_UNCERTAINTY = (1<<8);
private static final int HAS_CARRIER_FREQUENCY = (1<<9);
private static final int HAS_CARRIER_CYCLES = (1<<10);
private static final int HAS_CARRIER_PHASE = (1<<11);
private static final int HAS_CARRIER_PHASE_UNCERTAINTY = (1<<12);
private static final int HAS_BIT_NUMBER = (1<<13);
private static final int HAS_TIME_FROM_LAST_BIT = (1<<14);
private static final int HAS_DOPPLER_SHIFT = (1<<15);
private static final int HAS_DOPPLER_SHIFT_UNCERTAINTY = (1<<16);
/**
* The indicator is not available or it is unknown.
*/
public static final byte LOSS_OF_LOCK_UNKNOWN = 0;
/**
* The measurement does not present any indication of 'loss of lock'.
*/
public static final byte LOSS_OF_LOCK_OK = 1;
/**
* 'Loss of lock' detected between the previous and current observation: cycle slip possible.
*/
public static final byte LOSS_OF_LOCK_CYCLE_SLIP = 2;
/**
* The indicator is not available or it is unknown.
*/
public static final byte MULTIPATH_INDICATOR_UNKNOWN = 0;
/**
* The measurement has been indicated to use multi-path.
*/
public static final byte MULTIPATH_INDICATOR_DETECTED = 1;
/**
* The measurement has been indicated not tu use multi-path.
*/
public static final byte MULTIPATH_INDICATOR_NOT_USED = 2;
/**
* The state of GPS receiver the measurement is invalid or unknown.
*/
public static final short STATE_UNKNOWN = 0;
/**
* The state of the GPS receiver is ranging code lock.
*/
public static final short STATE_CODE_LOCK = (1<<0);
/**
* The state of the GPS receiver is in bit sync.
*/
public static final short STATE_BIT_SYNC = (1<<1);
/**
*The state of the GPS receiver is in sub-frame sync.
*/
public static final short STATE_SUBFRAME_SYNC = (1<<2);
/**
* The state of the GPS receiver has TOW decoded.
*/
public static final short STATE_TOW_DECODED = (1<<3);
/**
* All the GPS receiver state flags.
*/
private static final short STATE_ALL =
STATE_CODE_LOCK | STATE_BIT_SYNC | STATE_SUBFRAME_SYNC | STATE_TOW_DECODED;
/**
* The state of the 'Accumulated Delta Range' is invalid or unknown.
*/
public static final short ADR_STATE_UNKNOWN = 0;
/**
* The state of the 'Accumulated Delta Range' is valid.
*/
public static final short ADR_STATE_VALID = (1<<0);
/**
* The state of the 'Accumulated Delta Range' has detected a reset.
*/
public static final short ADR_STATE_RESET = (1<<1);
/**
* The state of the 'Accumulated Delta Range' has a cycle slip detected.
*/
public static final short ADR_STATE_CYCLE_SLIP = (1<<2);
/**
* All the 'Accumulated Delta Range' flags.
*/
private static final short ADR_ALL = ADR_STATE_VALID | ADR_STATE_RESET | ADR_STATE_CYCLE_SLIP;
// End enumerations in sync with gps.h
GpsMeasurement() {
initialize();
}
/**
* Sets all contents to the values stored in the provided object.
*/
public void set(GpsMeasurement measurement) {
mFlags = measurement.mFlags;
mPrn = measurement.mPrn;
mTimeOffsetInNs = measurement.mTimeOffsetInNs;
mState = measurement.mState;
mReceivedGpsTowInNs = measurement.mReceivedGpsTowInNs;
mReceivedGpsTowUncertaintyInNs = measurement.mReceivedGpsTowUncertaintyInNs;
mCn0InDbHz = measurement.mCn0InDbHz;
mPseudorangeRateInMetersPerSec = measurement.mPseudorangeRateInMetersPerSec;
mPseudorangeRateUncertaintyInMetersPerSec =
measurement.mPseudorangeRateUncertaintyInMetersPerSec;
mAccumulatedDeltaRangeState = measurement.mAccumulatedDeltaRangeState;
mAccumulatedDeltaRangeInMeters = measurement.mAccumulatedDeltaRangeInMeters;
mAccumulatedDeltaRangeUncertaintyInMeters =
measurement.mAccumulatedDeltaRangeUncertaintyInMeters;
mPseudorangeInMeters = measurement.mPseudorangeInMeters;
mPseudorangeUncertaintyInMeters = measurement.mPseudorangeUncertaintyInMeters;
mCodePhaseInChips = measurement.mCodePhaseInChips;
mCodePhaseUncertaintyInChips = measurement.mCodePhaseUncertaintyInChips;
mCarrierFrequencyInHz = measurement.mCarrierFrequencyInHz;
mCarrierCycles = measurement.mCarrierCycles;
mCarrierPhase = measurement.mCarrierPhase;
mCarrierPhaseUncertainty = measurement.mCarrierPhaseUncertainty;
mLossOfLock = measurement.mLossOfLock;
mBitNumber = measurement.mBitNumber;
mTimeFromLastBitInMs = measurement.mTimeFromLastBitInMs;
mDopplerShiftInHz = measurement.mDopplerShiftInHz;
mDopplerShiftUncertaintyInHz = measurement.mDopplerShiftUncertaintyInHz;
mMultipathIndicator = measurement.mMultipathIndicator;
mSnrInDb = measurement.mSnrInDb;
mElevationInDeg = measurement.mElevationInDeg;
mElevationUncertaintyInDeg = measurement.mElevationUncertaintyInDeg;
mAzimuthInDeg = measurement.mAzimuthInDeg;
mAzimuthUncertaintyInDeg = measurement.mAzimuthUncertaintyInDeg;
mUsedInFix = measurement.mUsedInFix;
}
/**
* Resets all the contents to its original state.
*/
public void reset() {
initialize();
}
/**
* Gets the Pseudo-random number (PRN).
* Range: [1, 32]
*/
public byte getPrn() {
return mPrn;
}
/**
* Sets the Pseud-random number (PRN).
*/
public void setPrn(byte value) {
mPrn = value;
}
/**
* Gets the time offset at which the measurement was taken in nanoseconds.
* The reference receiver's time is specified by {@link GpsClock#getTimeInNs()} and should be
* interpreted in the same way as indicated by {@link GpsClock#getType()}.
*
* The sign of this value is given by the following equation:
* measurement time = time_ns + time_offset_ns
*
* The value provides an individual time-stamp for the measurement, and allows sub-nanosecond
* accuracy.
*/
public double getTimeOffsetInNs() {
return mTimeOffsetInNs;
}
/**
* Sets the time offset at which the measurement was taken in nanoseconds.
*/
public void setTimeOffsetInNs(double value) {
mTimeOffsetInNs = value;
}
/**
* Gets per-satellite sync state.
* It represents the current sync state for the associated satellite.
*
* This value helps interpret {@link #getReceivedGpsTowInNs()}.
*/
public short getState() {
return mState;
}
/**
* Sets the sync state.
*/
public void setState(short value) {
mState = value;
}
/**
* Gets a string representation of the 'sync state'.
* For internal and logging use only.
*/
private String getStateString() {
if (mState == STATE_UNKNOWN) {
return "Unknown";
}
StringBuilder builder = new StringBuilder();
if ((mState & STATE_CODE_LOCK) == STATE_CODE_LOCK) {
builder.append("CodeLock|");
}
if ((mState & STATE_BIT_SYNC) == STATE_BIT_SYNC) {
builder.append("BitSync|");
}
if ((mState & STATE_SUBFRAME_SYNC) == STATE_SUBFRAME_SYNC) {
builder.append("SubframeSync|");
}
if ((mState & STATE_TOW_DECODED) == STATE_TOW_DECODED) {
builder.append("TowDecoded|");
}
int remainingStates = mState & ~STATE_ALL;
if (remainingStates > 0) {
builder.append("Other(");
builder.append(Integer.toBinaryString(remainingStates));
builder.append(")|");
}
builder.deleteCharAt(builder.length() - 1);
return builder.toString();
}
/**
* Gets the received GPS Time-of-Week at the measurement time, in nanoseconds.
* The value is relative to the beginning of the current GPS week.
*
* Given {@link #getState()} of the GPS receiver, the range of this field can be:
* Searching : [ 0 ] : {@link #STATE_UNKNOWN} is set
* Ranging code lock : [ 0 1 ms ] : {@link #STATE_CODE_LOCK} is set
* Bit sync : [ 0 20 ms ] : {@link #STATE_BIT_SYNC} is set
* Subframe sync : [ 0 6 ms ] : {@link #STATE_SUBFRAME_SYNC} is set
* TOW decoded : [ 0 1 week ] : {@link #STATE_TOW_DECODED} is set
*/
public long getReceivedGpsTowInNs() {
return mReceivedGpsTowInNs;
}
/**
* Sets the received GPS time-of-week in nanoseconds.
*/
public void setReceivedGpsTowInNs(long value) {
mReceivedGpsTowInNs = value;
}
/**
* Gets the received GPS time-of-week's uncertainty (1-Sigma) in nanoseconds.
*/
public long getReceivedGpsTowUncertaintyInNs() {
return mReceivedGpsTowUncertaintyInNs;
}
/**
* Sets the received GPS time-of-week's uncertainty (1-Sigma) in nanoseconds.
*/
public void setReceivedGpsTowUncertaintyInNs(long value) {
mReceivedGpsTowUncertaintyInNs = value;
}
/**
* Gets the Carrier-to-noise density in dB-Hz.
* Range: [0, 63].
*
* The value contains the measured C/N0 for the signal at the antenna input.
*/
public double getCn0InDbHz() {
return mCn0InDbHz;
}
/**
* Sets the carrier-to-noise density in dB-Hz.
*/
public void setCn0InDbHz(double value) {
mCn0InDbHz = value;
}
/**
* Gets the Pseudorange rate at the timestamp in m/s.
* The reported value includes {@link #getPseudorangeRateUncertaintyInMetersPerSec()}.
*/
public double getPseudorangeRateInMetersPerSec() {
return mPseudorangeRateInMetersPerSec;
}
/**
* Sets the pseudorange rate at the timestamp in m/s.
*/
public void setPseudorangeRateInMetersPerSec(double value) {
mPseudorangeRateInMetersPerSec = value;
}
/**
* Gets the pseudorange's rate uncertainty (1-Sigma) in m/s.
* The uncertainty is represented as an absolute (single sided) value.
*/
public double getPseudorangeRateUncertaintyInMetersPerSec() {
return mPseudorangeRateUncertaintyInMetersPerSec;
}
/**
* Sets the pseudorange's rate uncertainty (1-Sigma) in m/s.
*/
public void setPseudorangeRateUncertaintyInMetersPerSec(double value) {
mPseudorangeRateUncertaintyInMetersPerSec = value;
}
/**
* Gets 'Accumulated Delta Range' state.
* It indicates whether {@link #getAccumulatedDeltaRangeInMeters()} is reset or there is a
* cycle slip (indicating 'loss of lock').
*/
public short getAccumulatedDeltaRangeState() {
return mAccumulatedDeltaRangeState;
}
/**
* Sets the 'Accumulated Delta Range' state.
*/
public void setAccumulatedDeltaRangeState(short value) {
mAccumulatedDeltaRangeState = value;
}
/**
* Gets a string representation of the 'Accumulated Delta Range state'.
* For internal and logging use only.
*/
private String getAccumulatedDeltaRangeStateString() {
if (mAccumulatedDeltaRangeState == ADR_STATE_UNKNOWN) {
return "Unknown";
}
StringBuilder builder = new StringBuilder();
if ((mAccumulatedDeltaRangeState & ADR_STATE_VALID) == ADR_STATE_VALID) {
builder.append("Valid|");
}
if ((mAccumulatedDeltaRangeState & ADR_STATE_RESET) == ADR_STATE_RESET) {
builder.append("Reset|");
}
if ((mAccumulatedDeltaRangeState & ADR_STATE_CYCLE_SLIP) == ADR_STATE_CYCLE_SLIP) {
builder.append("CycleSlip|");
}
int remainingStates = mAccumulatedDeltaRangeState & ~ADR_ALL;
if (remainingStates > 0) {
builder.append("Other(");
builder.append(Integer.toBinaryString(remainingStates));
builder.append(")|");
}
builder.deleteCharAt(builder.length() - 1);
return builder.toString();
}
/**
* Gets the accumulated delta range since the last channel reset, in meters.
* The reported value includes {@link #getAccumulatedDeltaRangeUncertaintyInMeters()}.
*
* The availability of the value is represented by {@link #getAccumulatedDeltaRangeState()}.
*/
public double getAccumulatedDeltaRangeInMeters() {
return mAccumulatedDeltaRangeInMeters;
}
/**
* Sets the accumulated delta range in meters.
*/
public void setAccumulatedDeltaRangeInMeters(double value) {
mAccumulatedDeltaRangeInMeters = value;
}
/**
* Gets the accumulated delta range's uncertainty (1-Sigma) in meters.
* The uncertainty is represented as an absolute (single sided) value.
*/
public double getAccumulatedDeltaRangeUncertaintyInMeters() {
return mAccumulatedDeltaRangeUncertaintyInMeters;
}
/**
* Sets the accumulated delta range's uncertainty (1-sigma) in meters.
*
* The availability of the value is represented by {@link #getAccumulatedDeltaRangeState()}.
*/
public void setAccumulatedDeltaRangeUncertaintyInMeters(double value) {
mAccumulatedDeltaRangeUncertaintyInMeters = value;
}
/**
* Returns true if {@link #getPseudorangeInMeters()} is available, false otherwise.
*/
public boolean hasPseudorangeInMeters() {
return isFlagSet(HAS_PSEUDORANGE);
}
/**
* Gets the best derived pseudorange by the chipset, in meters.
* The reported pseudorange includes {@link #getPseudorangeUncertaintyInMeters()}.
*
* The value is only available if {@link #hasPseudorangeInMeters()} is true.
*/
public double getPseudorangeInMeters() {
return mPseudorangeInMeters;
}
/**
* Sets the Pseudo-range in meters.
*/
public void setPseudorangeInMeters(double value) {
setFlag(HAS_PSEUDORANGE);
mPseudorangeInMeters = value;
}
/**
* Resets the Pseudo-range in meters.
*/
public void resetPseudorangeInMeters() {
resetFlag(HAS_PSEUDORANGE);
mPseudorangeInMeters = Double.NaN;
}
/**
* Returns true if {@link #getPseudorangeUncertaintyInMeters()} is available, false otherwise.
*/
public boolean hasPseudorangeUncertaintyInMeters() {
return isFlagSet(HAS_PSEUDORANGE_UNCERTAINTY);
}
/**
* Gets the pseudorange's uncertainty (1-Sigma) in meters.
* The value contains the 'pseudorange' and 'clock' uncertainty in it.
* The uncertainty is represented as an absolute (single sided) value.
*
* The value is only available if {@link #hasPseudorangeUncertaintyInMeters()} is true.
*/
public double getPseudorangeUncertaintyInMeters() {
return mPseudorangeUncertaintyInMeters;
}
/**
* Sets the pseudo-range's uncertainty (1-Sigma) in meters.
*/
public void setPseudorangeUncertaintyInMeters(double value) {
setFlag(HAS_PSEUDORANGE_UNCERTAINTY);
mPseudorangeUncertaintyInMeters = value;
}
/**
* Resets the pseudo-range's uncertainty (1-Sigma) in meters.
*/
public void resetPseudorangeUncertaintyInMeters() {
resetFlag(HAS_PSEUDORANGE_UNCERTAINTY);
mPseudorangeUncertaintyInMeters = Double.NaN;
}
/**
* Returns true if {@link #getCodePhaseInChips()} is available, false otherwise.
*/
public boolean hasCodePhaseInChips() {
return isFlagSet(HAS_CODE_PHASE);
}
/**
* Gets the fraction of the current C/A code cycle.
* Range: [0, 1023]
* The reference frequency is given by the value of {@link #getCarrierFrequencyInHz()}.
* The reported code-phase includes {@link #getCodePhaseUncertaintyInChips()}.
*
* The value is only available if {@link #hasCodePhaseInChips()} is true.
*/
public double getCodePhaseInChips() {
return mCodePhaseInChips;
}
/**
* Sets the Code-phase in chips.
*/
public void setCodePhaseInChips(double value) {
setFlag(HAS_CODE_PHASE);
mCodePhaseInChips = value;
}
/**
* Resets the Code-phase in chips.
*/
public void resetCodePhaseInChips() {
resetFlag(HAS_CODE_PHASE);
mCodePhaseInChips = Double.NaN;
}
/**
* Returns true if {@link #getCodePhaseUncertaintyInChips()} is available, false otherwise.
*/
public boolean hasCodePhaseUncertaintyInChips() {
return isFlagSet(HAS_CODE_PHASE_UNCERTAINTY);
}
/**
* Gets the code-phase's uncertainty (1-Sigma) as a fraction of chips.
* The uncertainty is represented as an absolute (single sided) value.
*
* The value is only available if {@link #hasCodePhaseUncertaintyInChips()} is true.
*/
public double getCodePhaseUncertaintyInChips() {
return mCodePhaseUncertaintyInChips;
}
/**
* Sets the Code-phase's uncertainty (1-Sigma) in fractions of chips.
*/
public void setCodePhaseUncertaintyInChips(double value) {
setFlag(HAS_CODE_PHASE_UNCERTAINTY);
mCodePhaseUncertaintyInChips = value;
}
/**
* Resets the Code-phase's uncertainty (1-Sigma) in fractions of chips.
*/
public void resetCodePhaseUncertaintyInChips() {
resetFlag(HAS_CODE_PHASE_UNCERTAINTY);
mCodePhaseUncertaintyInChips = Double.NaN;
}
/**
* Returns true if {@link #getCarrierFrequencyInHz()} is available, false otherwise.
*/
public boolean hasCarrierFrequencyInHz() {
return isFlagSet(HAS_CARRIER_FREQUENCY);
}
/**
* Gets the carrier frequency at which codes and messages are modulated, it can be L1 or L2.
* If the field is not set, the carrier frequency corresponds to L1.
*
* The value is only available if {@link #hasCarrierFrequencyInHz()} is true.
*/
public float getCarrierFrequencyInHz() {
return mCarrierFrequencyInHz;
}
/**
* Sets the Carrier frequency (L1 or L2) in Hz.
*/
public void setCarrierFrequencyInHz(float carrierFrequencyInHz) {
setFlag(HAS_CARRIER_FREQUENCY);
mCarrierFrequencyInHz = carrierFrequencyInHz;
}
/**
* Resets the Carrier frequency (L1 or L2) in Hz.
*/
public void resetCarrierFrequencyInHz() {
resetFlag(HAS_CARRIER_FREQUENCY);
mCarrierFrequencyInHz = Float.NaN;
}
/**
* Returns true if {@link #getCarrierCycles()} is available, false otherwise.
*/
public boolean hasCarrierCycles() {
return isFlagSet(HAS_CARRIER_CYCLES);
}
/**
* The number of full carrier cycles between the satellite and the receiver.
* The reference frequency is given by the value of {@link #getCarrierFrequencyInHz()}.
*
* The value is only available if {@link #hasCarrierCycles()} is true.
*/
public long getCarrierCycles() {
return mCarrierCycles;
}
/**
* Sets the number of full carrier cycles between the satellite and the receiver.
*/
public void setCarrierCycles(long value) {
setFlag(HAS_CARRIER_CYCLES);
mCarrierCycles = value;
}
/**
* Resets the number of full carrier cycles between the satellite and the receiver.
*/
public void resetCarrierCycles() {
resetFlag(HAS_CARRIER_CYCLES);
mCarrierCycles = Long.MIN_VALUE;
}
/**
* Returns true if {@link #getCarrierPhase()} is available, false otherwise.
*/
public boolean hasCarrierPhase() {
return isFlagSet(HAS_CARRIER_PHASE);
}
/**
* Gets the RF phase detected by the receiver.
* Range: [0.0, 1.0].
* This is usually the fractional part of the complete carrier phase measurement.
*
* The reference frequency is given by the value of {@link #getCarrierFrequencyInHz()}.
* The reported carrier-phase includes {@link #getCarrierPhaseUncertainty()}.
*
* The value is only available if {@link #hasCarrierPhase()} is true.
*/
public double getCarrierPhase() {
return mCarrierPhase;
}
/**
* Sets the RF phase detected by the receiver.
*/
public void setCarrierPhase(double value) {
setFlag(HAS_CARRIER_PHASE);
mCarrierPhase = value;
}
/**
* Resets the RF phase detected by the receiver.
*/
public void resetCarrierPhase() {
resetFlag(HAS_CARRIER_PHASE);
mCarrierPhase = Double.NaN;
}
/**
* Returns true if {@link #getCarrierPhaseUncertainty()} is available, false otherwise.
*/
public boolean hasCarrierPhaseUncertainty() {
return isFlagSet(HAS_CARRIER_PHASE_UNCERTAINTY);
}
/**
* Gets the carrier-phase's uncertainty (1-Sigma).
* The uncertainty is represented as an absolute (single sided) value.
*
* The value is only available if {@link #hasCarrierPhaseUncertainty()} is true.
*/
public double getCarrierPhaseUncertainty() {
return mCarrierPhaseUncertainty;
}
/**
* Sets the Carrier-phase's uncertainty (1-Sigma) in cycles.
*/
public void setCarrierPhaseUncertainty(double value) {
setFlag(HAS_CARRIER_PHASE_UNCERTAINTY);
mCarrierPhaseUncertainty = value;
}
/**
* Resets the Carrier-phase's uncertainty (1-Sigma) in cycles.
*/
public void resetCarrierPhaseUncertainty() {
resetFlag(HAS_CARRIER_PHASE_UNCERTAINTY);
mCarrierPhaseUncertainty = Double.NaN;
}
/**
* Gets a value indicating the 'loss of lock' state of the event.
*/
public byte getLossOfLock() {
return mLossOfLock;
}
/**
* Sets the 'loss of lock' status.
*/
public void setLossOfLock(byte value) {
mLossOfLock = value;
}
/**
* Gets a string representation of the 'loss of lock'.
* For internal and logging use only.
*/
private String getLossOfLockString() {
switch (mLossOfLock) {
case LOSS_OF_LOCK_UNKNOWN:
return "Unknown";
case LOSS_OF_LOCK_OK:
return "Ok";
case LOSS_OF_LOCK_CYCLE_SLIP:
return "CycleSlip";
default:
return "<Invalid:" + mLossOfLock + ">";
}
}
/**
* Returns true if {@link #getBitNumber()} is available, false otherwise.
*/
public boolean hasBitNumber() {
return isFlagSet(HAS_BIT_NUMBER);
}
/**
* Gets the number of GPS bits transmitted since Sat-Sun midnight (GPS week).
*
* The value is only available if {@link #hasBitNumber()} is true.
*/
public int getBitNumber() {
return mBitNumber;
}
/**
* Sets the bit number within the broadcast frame.
*/
public void setBitNumber(int bitNumber) {
setFlag(HAS_BIT_NUMBER);
mBitNumber = bitNumber;
}
/**
* Resets the bit number within the broadcast frame.
*/
public void resetBitNumber() {
resetFlag(HAS_BIT_NUMBER);
mBitNumber = Integer.MIN_VALUE;
}
/**
* Returns true if {@link #getTimeFromLastBitInMs()} is available, false otherwise.
*/
public boolean hasTimeFromLastBitInMs() {
return isFlagSet(HAS_TIME_FROM_LAST_BIT);
}
/**
* Gets the elapsed time since the last received bit in milliseconds.
* Range: [0, 20].
*
* The value is only available if {@link #hasTimeFromLastBitInMs()} is true.
*/
public short getTimeFromLastBitInMs() {
return mTimeFromLastBitInMs;
}
/**
* Sets the elapsed time since the last received bit in milliseconds.
*/
public void setTimeFromLastBitInMs(short value) {
setFlag(HAS_TIME_FROM_LAST_BIT);
mTimeFromLastBitInMs = value;
}
/**
* Resets the elapsed time since the last received bit in milliseconds.
*/
public void resetTimeFromLastBitInMs() {
resetFlag(HAS_TIME_FROM_LAST_BIT);
mTimeFromLastBitInMs = Short.MIN_VALUE;
}
/**
* Returns true if {@link #getDopplerShiftInHz()} is available, false otherwise.
*/
public boolean hasDopplerShiftInHz() {
return isFlagSet(HAS_DOPPLER_SHIFT);
}
/**
* Gets the Doppler Shift in Hz.
* A positive value indicates that the SV is moving toward the receiver.
*
* The reference frequency is given by the value of {@link #getCarrierFrequencyInHz()}.
* The reported doppler shift includes {@link #getDopplerShiftUncertaintyInHz()}.
*
* The value is only available if {@link #hasDopplerShiftInHz()} is true.
*/
public double getDopplerShiftInHz() {
return mDopplerShiftInHz;
}
/**
* Sets the Doppler shift in Hz.
*/
public void setDopplerShiftInHz(double value) {
setFlag(HAS_DOPPLER_SHIFT);
mDopplerShiftInHz = value;
}
/**
* Resets the Doppler shift in Hz.
*/
public void resetDopplerShiftInHz() {
resetFlag(HAS_DOPPLER_SHIFT);
mDopplerShiftInHz = Double.NaN;
}
/**
* Returns true if {@link #getDopplerShiftUncertaintyInHz()} is available, false otherwise.
*/
public boolean hasDopplerShiftUncertaintyInHz() {
return isFlagSet(HAS_DOPPLER_SHIFT_UNCERTAINTY);
}
/**
* Gets the Doppler's Shift uncertainty (1-Sigma) in Hz.
* The uncertainty is represented as an absolute (single sided) value.
*
* The value is only available if {@link #hasDopplerShiftUncertaintyInHz()} is true.
*/
public double getDopplerShiftUncertaintyInHz() {
return mDopplerShiftUncertaintyInHz;
}
/**
* Sets the Doppler's shift uncertainty (1-Sigma) in Hz.
*/
public void setDopplerShiftUncertaintyInHz(double value) {
setFlag(HAS_DOPPLER_SHIFT_UNCERTAINTY);
mDopplerShiftUncertaintyInHz = value;
}
/**
* Resets the Doppler's shift uncertainty (1-Sigma) in Hz.
*/
public void resetDopplerShiftUncertaintyInHz() {
resetFlag(HAS_DOPPLER_SHIFT_UNCERTAINTY);
mDopplerShiftUncertaintyInHz = Double.NaN;
}
/**
* Gets a value indicating the 'multipath' state of the event.
*/
public byte getMultipathIndicator() {
return mMultipathIndicator;
}
/**
* Sets the 'multi-path' indicator.
*/
public void setMultipathIndicator(byte value) {
mMultipathIndicator = value;
}
/**
* Gets a string representation of the 'multi-path indicator'.
* For internal and logging use only.
*/
private String getMultipathIndicatorString() {
switch(mMultipathIndicator) {
case MULTIPATH_INDICATOR_UNKNOWN:
return "Unknown";
case MULTIPATH_INDICATOR_DETECTED:
return "Detected";
case MULTIPATH_INDICATOR_NOT_USED:
return "NotUsed";
default:
return "<Invalid:" + mMultipathIndicator + ">";
}
}
/**
* Returns true if {@link #getSnrInDb()} is available, false otherwise.
*/
public boolean hasSnrInDb() {
return isFlagSet(HAS_SNR);
}
/**
* Gets the Signal-to-Noise ratio (SNR) in dB.
*
* The value is only available if {@link #hasSnrInDb()} is true.
*/
public double getSnrInDb() {
return mSnrInDb;
}
/**
* Sets the Signal-to-noise ratio (SNR) in dB.
*/
public void setSnrInDb(double snrInDb) {
setFlag(HAS_SNR);
mSnrInDb = snrInDb;
}
/**
* Resets the Signal-to-noise ratio (SNR) in dB.
*/
public void resetSnrInDb() {
resetFlag(HAS_SNR);
mSnrInDb = Double.NaN;
}
/**
* Returns true if {@link #getElevationInDeg()} is available, false otherwise.
*/
public boolean hasElevationInDeg() {
return isFlagSet(HAS_ELEVATION);
}
/**
* Gets the Elevation in degrees.
* Range: [-90, 90]
* The reported elevation includes {@link #getElevationUncertaintyInDeg()}.
*
* The value is only available if {@link #hasElevationInDeg()} is true.
*/
public double getElevationInDeg() {
return mElevationInDeg;
}
/**
* Sets the Elevation in degrees.
*/
public void setElevationInDeg(double elevationInDeg) {
setFlag(HAS_ELEVATION);
mElevationInDeg = elevationInDeg;
}
/**
* Resets the Elevation in degrees.
*/
public void resetElevationInDeg() {
resetFlag(HAS_ELEVATION);
mElevationInDeg = Double.NaN;
}
/**
* Returns true if {@link #getElevationUncertaintyInDeg()} is available, false otherwise.
*/
public boolean hasElevationUncertaintyInDeg() {
return isFlagSet(HAS_ELEVATION_UNCERTAINTY);
}
/**
* Gets the elevation's uncertainty (1-Sigma) in degrees.
* Range: [0, 90]
*
* The uncertainty is represented as an absolute (single sided) value.
*
* The value is only available if {@link #hasElevationUncertaintyInDeg()} is true.
*/
public double getElevationUncertaintyInDeg() {
return mElevationUncertaintyInDeg;
}
/**
* Sets the elevation's uncertainty (1-Sigma) in degrees.
*/
public void setElevationUncertaintyInDeg(double value) {
setFlag(HAS_ELEVATION_UNCERTAINTY);
mElevationUncertaintyInDeg = value;
}
/**
* Resets the elevation's uncertainty (1-Sigma) in degrees.
*/
public void resetElevationUncertaintyInDeg() {
resetFlag(HAS_ELEVATION_UNCERTAINTY);
mElevationUncertaintyInDeg = Double.NaN;
}
/**
* Returns true if {@link #getAzimuthInDeg()} is available, false otherwise.
*/
public boolean hasAzimuthInDeg() {
return isFlagSet(HAS_AZIMUTH);
}
/**
* Gets the azimuth in degrees.
* Range: [0, 360).
*
* The reported azimuth includes {@link #getAzimuthUncertaintyInDeg()}.
*
* The value is only available if {@link #hasAzimuthInDeg()} is true.
*/
public double getAzimuthInDeg() {
return mAzimuthInDeg;
}
/**
* Sets the Azimuth in degrees.
*/
public void setAzimuthInDeg(double value) {
setFlag(HAS_AZIMUTH);
mAzimuthInDeg = value;
}
/**
* Resets the Azimuth in degrees.
*/
public void resetAzimuthInDeg() {
resetFlag(HAS_AZIMUTH);
mAzimuthInDeg = Double.NaN;
}
/**
* Returns true if {@link #getAzimuthUncertaintyInDeg()} is available, false otherwise.
*/
public boolean hasAzimuthUncertaintyInDeg() {
return isFlagSet(HAS_AZIMUTH_UNCERTAINTY);
}
/**
* Gets the azimuth's uncertainty (1-Sigma) in degrees.
* Range: [0, 180].
*
* The uncertainty is represented as an absolute (single sided) value.
*
* The value is only available if {@link #hasAzimuthUncertaintyInDeg()} is true.
*/
public double getAzimuthUncertaintyInDeg() {
return mAzimuthUncertaintyInDeg;
}
/**
* Sets the Azimuth's uncertainty (1-Sigma) in degrees.
*/
public void setAzimuthUncertaintyInDeg(double value) {
setFlag(HAS_AZIMUTH_UNCERTAINTY);
mAzimuthUncertaintyInDeg = value;
}
/**
* Resets the Azimuth's uncertainty (1-Sigma) in degrees.
*/
public void resetAzimuthUncertaintyInDeg() {
resetFlag(HAS_AZIMUTH_UNCERTAINTY);
mAzimuthUncertaintyInDeg = Double.NaN;
}
/**
* Gets a flag indicating whether the GPS represented by the measurement was used for computing
* the most recent fix.
*
* @return A non-null value if the data is available, null otherwise.
*/
public boolean isUsedInFix() {
return mUsedInFix;
}
/**
* Sets the Used-in-Fix flag.
*/
public void setUsedInFix(boolean value) {
mUsedInFix = value;
}
public static final Creator<GpsMeasurement> CREATOR = new Creator<GpsMeasurement>() {
@Override
public GpsMeasurement createFromParcel(Parcel parcel) {
GpsMeasurement gpsMeasurement = new GpsMeasurement();
gpsMeasurement.mFlags = parcel.readInt();
gpsMeasurement.mPrn = parcel.readByte();
gpsMeasurement.mTimeOffsetInNs = parcel.readDouble();
gpsMeasurement.mState = (short) parcel.readInt();
gpsMeasurement.mReceivedGpsTowInNs = parcel.readLong();
gpsMeasurement.mReceivedGpsTowUncertaintyInNs = parcel.readLong();
gpsMeasurement.mCn0InDbHz = parcel.readDouble();
gpsMeasurement.mPseudorangeRateInMetersPerSec = parcel.readDouble();
gpsMeasurement.mPseudorangeRateUncertaintyInMetersPerSec = parcel.readDouble();
gpsMeasurement.mAccumulatedDeltaRangeState = (short) parcel.readInt();
gpsMeasurement.mAccumulatedDeltaRangeInMeters = parcel.readDouble();
gpsMeasurement.mAccumulatedDeltaRangeUncertaintyInMeters = parcel.readDouble();
gpsMeasurement.mPseudorangeInMeters = parcel.readDouble();
gpsMeasurement.mPseudorangeUncertaintyInMeters = parcel.readDouble();
gpsMeasurement.mCodePhaseInChips = parcel.readDouble();
gpsMeasurement.mCodePhaseUncertaintyInChips = parcel.readDouble();
gpsMeasurement.mCarrierFrequencyInHz = parcel.readFloat();
gpsMeasurement.mCarrierCycles = parcel.readLong();
gpsMeasurement.mCarrierPhase = parcel.readDouble();
gpsMeasurement.mCarrierPhaseUncertainty = parcel.readDouble();
gpsMeasurement.mLossOfLock = parcel.readByte();
gpsMeasurement.mBitNumber = parcel.readInt();
gpsMeasurement.mTimeFromLastBitInMs = (short) parcel.readInt();
gpsMeasurement.mDopplerShiftInHz = parcel.readDouble();
gpsMeasurement.mDopplerShiftUncertaintyInHz = parcel.readDouble();
gpsMeasurement.mMultipathIndicator = parcel.readByte();
gpsMeasurement.mSnrInDb = parcel.readDouble();
gpsMeasurement.mElevationInDeg = parcel.readDouble();
gpsMeasurement.mElevationUncertaintyInDeg = parcel.readDouble();
gpsMeasurement.mAzimuthInDeg = parcel.readDouble();
gpsMeasurement.mAzimuthUncertaintyInDeg = parcel.readDouble();
gpsMeasurement.mUsedInFix = parcel.readInt() != 0;
return gpsMeasurement;
}
@Override
public GpsMeasurement[] newArray(int i) {
return new GpsMeasurement[i];
}
};
public void writeToParcel(Parcel parcel, int flags) {
parcel.writeInt(mFlags);
parcel.writeByte(mPrn);
parcel.writeDouble(mTimeOffsetInNs);
parcel.writeInt(mState);
parcel.writeLong(mReceivedGpsTowInNs);
parcel.writeLong(mReceivedGpsTowUncertaintyInNs);
parcel.writeDouble(mCn0InDbHz);
parcel.writeDouble(mPseudorangeRateInMetersPerSec);
parcel.writeDouble(mPseudorangeRateUncertaintyInMetersPerSec);
parcel.writeInt(mAccumulatedDeltaRangeState);
parcel.writeDouble(mAccumulatedDeltaRangeInMeters);
parcel.writeDouble(mAccumulatedDeltaRangeUncertaintyInMeters);
parcel.writeDouble(mPseudorangeInMeters);
parcel.writeDouble(mPseudorangeUncertaintyInMeters);
parcel.writeDouble(mCodePhaseInChips);
parcel.writeDouble(mCodePhaseUncertaintyInChips);
parcel.writeFloat(mCarrierFrequencyInHz);
parcel.writeLong(mCarrierCycles);
parcel.writeDouble(mCarrierPhase);
parcel.writeDouble(mCarrierPhaseUncertainty);
parcel.writeByte(mLossOfLock);
parcel.writeInt(mBitNumber);
parcel.writeInt(mTimeFromLastBitInMs);
parcel.writeDouble(mDopplerShiftInHz);
parcel.writeDouble(mDopplerShiftUncertaintyInHz);
parcel.writeByte(mMultipathIndicator);
parcel.writeDouble(mSnrInDb);
parcel.writeDouble(mElevationInDeg);
parcel.writeDouble(mElevationUncertaintyInDeg);
parcel.writeDouble(mAzimuthInDeg);
parcel.writeDouble(mAzimuthUncertaintyInDeg);
parcel.writeInt(mUsedInFix ? 1 : 0);
}
@Override
public int describeContents() {
return 0;
}
@Override
public String toString() {
final String format = " %-29s = %s\n";
final String formatWithUncertainty = " %-29s = %-25s %-40s = %s\n";
StringBuilder builder = new StringBuilder("GpsMeasurement:\n");
builder.append(String.format(format, "Prn", mPrn));
builder.append(String.format(format, "TimeOffsetInNs", mTimeOffsetInNs));
builder.append(String.format(format, "State", getStateString()));
builder.append(String.format(
formatWithUncertainty,
"ReceivedGpsTowInNs",
mReceivedGpsTowInNs,
"ReceivedGpsTowUncertaintyInNs",
mReceivedGpsTowUncertaintyInNs));
builder.append(String.format(format, "Cn0InDbHz", mCn0InDbHz));
builder.append(String.format(
formatWithUncertainty,
"PseudorangeRateInMetersPerSec",
mPseudorangeRateInMetersPerSec,
"PseudorangeRateUncertaintyInMetersPerSec",
mPseudorangeRateUncertaintyInMetersPerSec));
builder.append(String.format(
format,
"AccumulatedDeltaRangeState",
getAccumulatedDeltaRangeStateString()));
builder.append(String.format(
formatWithUncertainty,
"AccumulatedDeltaRangeInMeters",
mAccumulatedDeltaRangeInMeters,
"AccumulatedDeltaRangeUncertaintyInMeters",
mAccumulatedDeltaRangeUncertaintyInMeters));
builder.append(String.format(
formatWithUncertainty,
"PseudorangeInMeters",
hasPseudorangeInMeters() ? mPseudorangeInMeters : null,
"PseudorangeUncertaintyInMeters",
hasPseudorangeUncertaintyInMeters() ? mPseudorangeUncertaintyInMeters : null));
builder.append(String.format(
formatWithUncertainty,
"CodePhaseInChips",
hasCodePhaseInChips() ? mCodePhaseInChips : null,
"CodePhaseUncertaintyInChips",
hasCodePhaseUncertaintyInChips() ? mCodePhaseUncertaintyInChips : null));
builder.append(String.format(
format,
"CarrierFrequencyInHz",
hasCarrierFrequencyInHz() ? mCarrierFrequencyInHz : null));
builder.append(String.format(
format,
"CarrierCycles",
hasCarrierCycles() ? mCarrierCycles : null));
builder.append(String.format(
formatWithUncertainty,
"CarrierPhase",
hasCarrierPhase() ? mCarrierPhase : null,
"CarrierPhaseUncertainty",
hasCarrierPhaseUncertainty() ? mCarrierPhaseUncertainty : null));
builder.append(String.format(format, "LossOfLock", getLossOfLockString()));
builder.append(String.format(
format,
"BitNumber",
hasBitNumber() ? mBitNumber : null));
builder.append(String.format(
format,
"TimeFromLastBitInMs",
hasTimeFromLastBitInMs() ? mTimeFromLastBitInMs : null));
builder.append(String.format(
formatWithUncertainty,
"DopplerShiftInHz",
hasDopplerShiftInHz() ? mDopplerShiftInHz : null,
"DopplerShiftUncertaintyInHz",
hasDopplerShiftUncertaintyInHz() ? mDopplerShiftUncertaintyInHz : null));
builder.append(String.format(format, "MultipathIndicator", getMultipathIndicatorString()));
builder.append(String.format(
format,
"SnrInDb",
hasSnrInDb() ? mSnrInDb : null));
builder.append(String.format(
formatWithUncertainty,
"ElevationInDeg",
hasElevationInDeg() ? mElevationInDeg : null,
"ElevationUncertaintyInDeg",
hasElevationUncertaintyInDeg() ? mElevationUncertaintyInDeg : null));
builder.append(String.format(
formatWithUncertainty,
"AzimuthInDeg",
hasAzimuthInDeg() ? mAzimuthInDeg : null,
"AzimuthUncertaintyInDeg",
hasAzimuthUncertaintyInDeg() ? mAzimuthUncertaintyInDeg : null));
builder.append(String.format(format, "UsedInFix", mUsedInFix));
return builder.toString();
}
private void initialize() {
mFlags = HAS_NO_FLAGS;
setPrn(Byte.MIN_VALUE);
setTimeOffsetInNs(Long.MIN_VALUE);
setState(STATE_UNKNOWN);
setReceivedGpsTowInNs(Long.MIN_VALUE);
setReceivedGpsTowUncertaintyInNs(Long.MAX_VALUE);
setCn0InDbHz(Double.MIN_VALUE);
setPseudorangeRateInMetersPerSec(Double.MIN_VALUE);
setPseudorangeRateUncertaintyInMetersPerSec(Double.MIN_VALUE);
setAccumulatedDeltaRangeState(ADR_STATE_UNKNOWN);
setAccumulatedDeltaRangeInMeters(Double.MIN_VALUE);
setAccumulatedDeltaRangeUncertaintyInMeters(Double.MIN_VALUE);
resetPseudorangeInMeters();
resetPseudorangeUncertaintyInMeters();
resetCodePhaseInChips();
resetCodePhaseUncertaintyInChips();
resetCarrierFrequencyInHz();
resetCarrierCycles();
resetCarrierPhase();
resetCarrierPhaseUncertainty();
setLossOfLock(LOSS_OF_LOCK_UNKNOWN);
resetBitNumber();
resetTimeFromLastBitInMs();
resetDopplerShiftInHz();
resetDopplerShiftUncertaintyInHz();
setMultipathIndicator(MULTIPATH_INDICATOR_UNKNOWN);
resetSnrInDb();
resetElevationInDeg();
resetElevationUncertaintyInDeg();
resetAzimuthInDeg();
resetAzimuthUncertaintyInDeg();
setUsedInFix(false);
}
private void setFlag(int flag) {
mFlags |= flag;
}
private void resetFlag(int flag) {
mFlags &= ~flag;
}
private boolean isFlagSet(int flag) {
return (mFlags & flag) == flag;
}
}