blob: e9019097e32772329e46ba0d95cb081a585164d7 [file] [log] [blame]
/*
* Copyright (C) 2018 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.FloatRange;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
import com.android.internal.util.Preconditions;
/**
* A container with measurement corrections for a single visible satellite
*
* @hide
*/
@SystemApi
public final class GnssSingleSatCorrection implements Parcelable {
/**
* Bit mask for {@link #mSingleSatCorrectionFlags} indicating the presence of {@link
* #mProbSatIsLos}.
*
* @hide
*/
public static final int HAS_PROB_SAT_IS_LOS_MASK = 1 << 0;
/**
* Bit mask for {@link #mSingleSatCorrectionFlags} indicating the presence of {@link
* #mExcessPathLengthMeters}.
*
* @hide
*/
public static final int HAS_EXCESS_PATH_LENGTH_MASK = 1 << 1;
/**
* Bit mask for {@link #mSingleSatCorrectionFlags} indicating the presence of {@link
* #mExcessPathLengthUncertaintyMeters}.
*
* @hide
*/
public static final int HAS_EXCESS_PATH_LENGTH_UNC_MASK = 1 << 2;
/**
* Bit mask for {@link #mSingleSatCorrectionFlags} indicating the presence of {@link
* #mReflectingPlane}.
*
* @hide
*/
public static final int HAS_REFLECTING_PLANE_MASK = 1 << 3;
/** A bitmask of fields present in this object (see HAS_* constants defined above) */
private final int mSingleSatCorrectionFlags;
/** Defines the constellation of the given satellite as defined in {@link GnssStatus}. */
@GnssStatus.ConstellationType
private final int mConstellationType;
/**
* Satellite vehicle ID number
*
* <p>Interpretation depends on {@link GnssStatus#getSvid(int)}.
*/
@IntRange(from = 0)
private final int mSatId;
/**
* Carrier frequency of the signal to be corrected, for example it can be the GPS center
* frequency for L1 = 1,575,420,000 Hz, varying GLO channels, etc.
*
* <p>For an L1, L5 receiver tracking a satellite on L1 and L5 at the same time, two correction
* objects will be reported for this same satellite, in one of the correction objects, all the
* values related to L1 will be filled, and in the other all of the values related to L5 will be
* filled.
*/
@FloatRange(from = 0.0f, fromInclusive = false)
private final float mCarrierFrequencyHz;
/**
* The probability that the satellite is estimated to be in Line-of-Sight condition at the given
* location.
*/
@FloatRange(from = 0.0f, to = 1.0f)
private final float mProbSatIsLos;
/**
* Excess path length to be subtracted from pseudorange before using it in calculating location.
*/
@FloatRange(from = 0.0f)
private final float mExcessPathLengthMeters;
/** Error estimate (1-sigma) for the Excess path length estimate */
@FloatRange(from = 0.0f)
private final float mExcessPathLengthUncertaintyMeters;
/**
* Defines the reflecting plane location and azimuth information
*
* <p>The flag HAS_REFLECTING_PLANE will be used to set this value to invalid if the satellite
* signal goes through multiple reflections or if reflection plane serving is not supported.
*/
@Nullable
private final GnssReflectingPlane mReflectingPlane;
private GnssSingleSatCorrection(Builder builder) {
mSingleSatCorrectionFlags = builder.mSingleSatCorrectionFlags;
mSatId = builder.mSatId;
mConstellationType = builder.mConstellationType;
mCarrierFrequencyHz = builder.mCarrierFrequencyHz;
mProbSatIsLos = builder.mProbSatIsLos;
mExcessPathLengthMeters = builder.mExcessPathLengthMeters;
mExcessPathLengthUncertaintyMeters = builder.mExcessPathLengthUncertaintyMeters;
mReflectingPlane = builder.mReflectingPlane;
}
/**
* Gets a bitmask of fields present in this object
*
* @hide
*/
public int getSingleSatelliteCorrectionFlags() {
return mSingleSatCorrectionFlags;
}
/**
* Gets the constellation type.
*
* <p>The return value is one of those constants with {@code CONSTELLATION_} prefix in {@link
* GnssStatus}.
*/
@GnssStatus.ConstellationType
public int getConstellationType() {
return mConstellationType;
}
/**
* Gets the satellite ID.
*
* <p>Interpretation depends on {@link #getConstellationType()}. See {@link
* GnssStatus#getSvid(int)}.
*/
@IntRange(from = 0)
public int getSatelliteId() {
return mSatId;
}
/**
* Gets the carrier frequency of the tracked signal.
*
* <p>For example it can be the GPS central frequency for L1 = 1575.45 MHz, or L2 = 1227.60 MHz,
* L5 = 1176.45 MHz, varying GLO channels, etc.
*
* <p>For an L1, L5 receiver tracking a satellite on L1 and L5 at the same time, two correction
* objects will be reported for this same satellite, in one of the correction objects, all the
* values related to L1 will be filled, and in the other all of the values related to L5 will be
* filled.
*
* @return the carrier frequency of the signal tracked in Hz.
*/
@FloatRange(from = 0.0f, fromInclusive = false)
public float getCarrierFrequencyHz() {
return mCarrierFrequencyHz;
}
/**
* Returns the probability that the satellite is in line-of-sight condition at the given
* location.
*/
@FloatRange(from = 0.0f, to = 1.0f)
public float getProbabilityLineOfSight() {
return mProbSatIsLos;
}
/**
* Returns the Excess path length to be subtracted from pseudorange before using it in
* calculating location.
*/
@FloatRange(from = 0.0f)
public float getExcessPathLengthMeters() {
return mExcessPathLengthMeters;
}
/** Returns the error estimate (1-sigma) for the Excess path length estimate */
@FloatRange(from = 0.0f)
public float getExcessPathLengthUncertaintyMeters() {
return mExcessPathLengthUncertaintyMeters;
}
/**
* Returns the reflecting plane characteristics at which the signal has bounced
*
* <p>The flag HAS_REFLECTING_PLANE will be used to set this value to invalid if the satellite
* signal goes through multiple reflections or if reflection plane serving is not supported
*/
@Nullable
public GnssReflectingPlane getReflectingPlane() {
return mReflectingPlane;
}
/** Returns {@code true} if {@link #getProbabilityLineOfSight()} is valid. */
public boolean hasValidSatelliteLineOfSight() {
return (mSingleSatCorrectionFlags & HAS_PROB_SAT_IS_LOS_MASK) != 0;
}
/** Returns {@code true} if {@link #getExcessPathLengthMeters()} is valid. */
public boolean hasExcessPathLength() {
return (mSingleSatCorrectionFlags & HAS_EXCESS_PATH_LENGTH_MASK) != 0;
}
/** Returns {@code true} if {@link #getExcessPathLengthUncertaintyMeters()} is valid. */
public boolean hasExcessPathLengthUncertainty() {
return (mSingleSatCorrectionFlags & HAS_EXCESS_PATH_LENGTH_UNC_MASK) != 0;
}
/** Returns {@code true} if {@link #getReflectingPlane()} is valid. */
public boolean hasReflectingPlane() {
return (mSingleSatCorrectionFlags & HAS_REFLECTING_PLANE_MASK) != 0;
}
@Override
public int describeContents() {
return 0;
}
public static final Creator<GnssSingleSatCorrection> CREATOR =
new Creator<GnssSingleSatCorrection>() {
@Override
@NonNull
public GnssSingleSatCorrection createFromParcel(@NonNull Parcel parcel) {
int mSingleSatCorrectionFlags = parcel.readInt();
boolean hasReflectingPlane =
(mSingleSatCorrectionFlags & HAS_REFLECTING_PLANE_MASK) != 0;
final GnssSingleSatCorrection.Builder singleSatCorrectionBuilder =
new Builder()
.setConstellationType(parcel.readInt())
.setSatelliteId(parcel.readInt())
.setCarrierFrequencyHz(parcel.readFloat())
.setProbabilityLineOfSight(parcel.readFloat())
.setExcessPathLengthMeters(parcel.readFloat())
.setExcessPathLengthUncertaintyMeters(parcel.readFloat());
if (hasReflectingPlane) {
singleSatCorrectionBuilder.setReflectingPlane(
GnssReflectingPlane.CREATOR.createFromParcel(parcel));
}
return singleSatCorrectionBuilder.build();
}
@Override
public GnssSingleSatCorrection[] newArray(int i) {
return new GnssSingleSatCorrection[i];
}
};
@Override
public String toString() {
final String format = " %-29s = %s\n";
StringBuilder builder = new StringBuilder("GnssSingleSatCorrection:\n");
builder.append(
String.format(format, "SingleSatCorrectionFlags = ", mSingleSatCorrectionFlags));
builder.append(String.format(format, "ConstellationType = ", mConstellationType));
builder.append(String.format(format, "SatId = ", mSatId));
builder.append(String.format(format, "CarrierFrequencyHz = ", mCarrierFrequencyHz));
builder.append(String.format(format, "ProbSatIsLos = ", mProbSatIsLos));
builder.append(String.format(format, "ExcessPathLengthMeters = ", mExcessPathLengthMeters));
builder.append(
String.format(
format,
"ExcessPathLengthUncertaintyMeters = ",
mExcessPathLengthUncertaintyMeters));
if (hasReflectingPlane()) {
builder.append(String.format(format, "ReflectingPlane = ", mReflectingPlane));
}
return builder.toString();
}
@Override
public void writeToParcel(@NonNull Parcel parcel, int flags) {
parcel.writeInt(mSingleSatCorrectionFlags);
parcel.writeInt(mConstellationType);
parcel.writeInt(mSatId);
parcel.writeFloat(mCarrierFrequencyHz);
parcel.writeFloat(mProbSatIsLos);
parcel.writeFloat(mExcessPathLengthMeters);
parcel.writeFloat(mExcessPathLengthUncertaintyMeters);
if (hasReflectingPlane()) {
mReflectingPlane.writeToParcel(parcel, flags);
}
}
/** Builder for {@link GnssSingleSatCorrection} */
public static final class Builder {
/**
* For documentation of below fields, see corresponding fields in {@link
* GnssSingleSatCorrection}.
*/
private int mSingleSatCorrectionFlags;
private int mConstellationType;
private int mSatId;
private float mCarrierFrequencyHz;
private float mProbSatIsLos;
private float mExcessPathLengthMeters;
private float mExcessPathLengthUncertaintyMeters;
@Nullable
private GnssReflectingPlane mReflectingPlane;
/** Sets the constellation type. */
@NonNull public Builder setConstellationType(
@GnssStatus.ConstellationType int constellationType) {
mConstellationType = constellationType;
return this;
}
/** Sets the Satellite ID defined in the ICD of the given constellation. */
@NonNull public Builder setSatelliteId(@IntRange(from = 0) int satId) {
mSatId = satId;
return this;
}
/** Sets the Carrier frequency in Hz. */
@NonNull public Builder setCarrierFrequencyHz(
@FloatRange(from = 0.0f, fromInclusive = false) float carrierFrequencyHz) {
mCarrierFrequencyHz = carrierFrequencyHz;
return this;
}
/**
* Sets the line-of-sight probability of the satellite at the given location in the range
* between 0 and 1.
*/
@NonNull public Builder setProbabilityLineOfSight(
@FloatRange(from = 0.0f, to = 1.0f) float probSatIsLos) {
Preconditions.checkArgumentInRange(
probSatIsLos, 0, 1, "probSatIsLos should be between 0 and 1.");
mProbSatIsLos = probSatIsLos;
mSingleSatCorrectionFlags =
(byte) (mSingleSatCorrectionFlags | HAS_PROB_SAT_IS_LOS_MASK);
return this;
}
/**
* Sets the Excess path length to be subtracted from pseudorange before using it in
* calculating location.
*/
@NonNull public Builder setExcessPathLengthMeters(
@FloatRange(from = 0.0f) float excessPathLengthMeters) {
mExcessPathLengthMeters = excessPathLengthMeters;
mSingleSatCorrectionFlags =
(byte) (mSingleSatCorrectionFlags | HAS_EXCESS_PATH_LENGTH_MASK);
return this;
}
/** Sets the error estimate (1-sigma) for the Excess path length estimate */
@NonNull public Builder setExcessPathLengthUncertaintyMeters(
@FloatRange(from = 0.0f) float excessPathLengthUncertaintyMeters) {
mExcessPathLengthUncertaintyMeters = excessPathLengthUncertaintyMeters;
mSingleSatCorrectionFlags =
(byte) (mSingleSatCorrectionFlags | HAS_EXCESS_PATH_LENGTH_UNC_MASK);
return this;
}
/** Sets the reflecting plane information */
@NonNull public Builder setReflectingPlane(@Nullable GnssReflectingPlane reflectingPlane) {
mReflectingPlane = reflectingPlane;
if (reflectingPlane != null) {
mSingleSatCorrectionFlags =
(byte) (mSingleSatCorrectionFlags | HAS_REFLECTING_PLANE_MASK);
} else {
mSingleSatCorrectionFlags =
(byte) (mSingleSatCorrectionFlags & ~HAS_REFLECTING_PLANE_MASK);
}
return this;
}
/** Builds a {@link GnssSingleSatCorrection} instance as specified by this builder. */
@NonNull public GnssSingleSatCorrection build() {
return new GnssSingleSatCorrection(this);
}
}
}