1 /* 2 * Copyright (C) 2018 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.FloatRange; 20 import android.annotation.IntRange; 21 import android.annotation.NonNull; 22 import android.annotation.Nullable; 23 import android.annotation.SystemApi; 24 import android.os.Parcel; 25 import android.os.Parcelable; 26 27 import com.android.internal.util.Preconditions; 28 29 /** 30 * A container with measurement corrections for a single visible satellite 31 * 32 * @hide 33 */ 34 @SystemApi 35 public final class GnssSingleSatCorrection implements Parcelable { 36 37 /** 38 * Bit mask for {@link #mSingleSatCorrectionFlags} indicating the presence of {@link 39 * #mProbSatIsLos}. 40 * 41 * @hide 42 */ 43 public static final int HAS_PROB_SAT_IS_LOS_MASK = 1 << 0; 44 45 /** 46 * Bit mask for {@link #mSingleSatCorrectionFlags} indicating the presence of {@link 47 * #mExcessPathLengthMeters}. 48 * 49 * @hide 50 */ 51 public static final int HAS_EXCESS_PATH_LENGTH_MASK = 1 << 1; 52 53 /** 54 * Bit mask for {@link #mSingleSatCorrectionFlags} indicating the presence of {@link 55 * #mExcessPathLengthUncertaintyMeters}. 56 * 57 * @hide 58 */ 59 public static final int HAS_EXCESS_PATH_LENGTH_UNC_MASK = 1 << 2; 60 61 /** 62 * Bit mask for {@link #mSingleSatCorrectionFlags} indicating the presence of {@link 63 * #mReflectingPlane}. 64 * 65 * @hide 66 */ 67 public static final int HAS_REFLECTING_PLANE_MASK = 1 << 3; 68 69 /** A bitmask of fields present in this object (see HAS_* constants defined above) */ 70 private final int mSingleSatCorrectionFlags; 71 72 /** Defines the constellation of the given satellite as defined in {@link GnssStatus}. */ 73 @GnssStatus.ConstellationType 74 private final int mConstellationType; 75 76 /** 77 * Satellite vehicle ID number 78 * 79 * <p>Interpretation depends on {@link GnssStatus#getSvid(int)}. 80 */ 81 @IntRange(from = 0) 82 private final int mSatId; 83 84 /** 85 * Carrier frequency of the signal to be corrected, for example it can be the GPS center 86 * frequency for L1 = 1,575,420,000 Hz, varying GLO channels, etc. 87 * 88 * <p>For an L1, L5 receiver tracking a satellite on L1 and L5 at the same time, two correction 89 * objects will be reported for this same satellite, in one of the correction objects, all the 90 * values related to L1 will be filled, and in the other all of the values related to L5 will be 91 * filled. 92 */ 93 @FloatRange(from = 0.0f, fromInclusive = false) 94 private final float mCarrierFrequencyHz; 95 96 /** 97 * The probability that the satellite is estimated to be in Line-of-Sight condition at the given 98 * location. 99 */ 100 @FloatRange(from = 0.0f, to = 1.0f) 101 private final float mProbSatIsLos; 102 103 /** 104 * Excess path length to be subtracted from pseudorange before using it in calculating location. 105 */ 106 @FloatRange(from = 0.0f) 107 private final float mExcessPathLengthMeters; 108 109 /** Error estimate (1-sigma) for the Excess path length estimate */ 110 @FloatRange(from = 0.0f) 111 private final float mExcessPathLengthUncertaintyMeters; 112 113 /** 114 * Defines the reflecting plane location and azimuth information 115 * 116 * <p>The flag HAS_REFLECTING_PLANE will be used to set this value to invalid if the satellite 117 * signal goes through multiple reflections or if reflection plane serving is not supported. 118 */ 119 @Nullable 120 private final GnssReflectingPlane mReflectingPlane; 121 GnssSingleSatCorrection(Builder builder)122 private GnssSingleSatCorrection(Builder builder) { 123 mSingleSatCorrectionFlags = builder.mSingleSatCorrectionFlags; 124 mSatId = builder.mSatId; 125 mConstellationType = builder.mConstellationType; 126 mCarrierFrequencyHz = builder.mCarrierFrequencyHz; 127 mProbSatIsLos = builder.mProbSatIsLos; 128 mExcessPathLengthMeters = builder.mExcessPathLengthMeters; 129 mExcessPathLengthUncertaintyMeters = builder.mExcessPathLengthUncertaintyMeters; 130 mReflectingPlane = builder.mReflectingPlane; 131 } 132 133 /** 134 * Gets a bitmask of fields present in this object 135 * 136 * @hide 137 */ getSingleSatelliteCorrectionFlags()138 public int getSingleSatelliteCorrectionFlags() { 139 return mSingleSatCorrectionFlags; 140 } 141 142 /** 143 * Gets the constellation type. 144 * 145 * <p>The return value is one of those constants with {@code CONSTELLATION_} prefix in {@link 146 * GnssStatus}. 147 */ 148 @GnssStatus.ConstellationType getConstellationType()149 public int getConstellationType() { 150 return mConstellationType; 151 } 152 153 /** 154 * Gets the satellite ID. 155 * 156 * <p>Interpretation depends on {@link #getConstellationType()}. See {@link 157 * GnssStatus#getSvid(int)}. 158 */ 159 @IntRange(from = 0) getSatelliteId()160 public int getSatelliteId() { 161 return mSatId; 162 } 163 164 /** 165 * Gets the carrier frequency of the tracked signal. 166 * 167 * <p>For example it can be the GPS central frequency for L1 = 1575.45 MHz, or L2 = 1227.60 MHz, 168 * L5 = 1176.45 MHz, varying GLO channels, etc. 169 * 170 * <p>For an L1, L5 receiver tracking a satellite on L1 and L5 at the same time, two correction 171 * objects will be reported for this same satellite, in one of the correction objects, all the 172 * values related to L1 will be filled, and in the other all of the values related to L5 will be 173 * filled. 174 * 175 * @return the carrier frequency of the signal tracked in Hz. 176 */ 177 @FloatRange(from = 0.0f, fromInclusive = false) getCarrierFrequencyHz()178 public float getCarrierFrequencyHz() { 179 return mCarrierFrequencyHz; 180 } 181 182 /** 183 * Returns the probability that the satellite is in line-of-sight condition at the given 184 * location. 185 */ 186 @FloatRange(from = 0.0f, to = 1.0f) getProbabilityLineOfSight()187 public float getProbabilityLineOfSight() { 188 return mProbSatIsLos; 189 } 190 191 /** 192 * Returns the Excess path length to be subtracted from pseudorange before using it in 193 * calculating location. 194 */ 195 @FloatRange(from = 0.0f) getExcessPathLengthMeters()196 public float getExcessPathLengthMeters() { 197 return mExcessPathLengthMeters; 198 } 199 200 /** Returns the error estimate (1-sigma) for the Excess path length estimate */ 201 @FloatRange(from = 0.0f) getExcessPathLengthUncertaintyMeters()202 public float getExcessPathLengthUncertaintyMeters() { 203 return mExcessPathLengthUncertaintyMeters; 204 } 205 206 /** 207 * Returns the reflecting plane characteristics at which the signal has bounced 208 * 209 * <p>The flag HAS_REFLECTING_PLANE will be used to set this value to invalid if the satellite 210 * signal goes through multiple reflections or if reflection plane serving is not supported 211 */ 212 @Nullable getReflectingPlane()213 public GnssReflectingPlane getReflectingPlane() { 214 return mReflectingPlane; 215 } 216 217 /** Returns {@code true} if {@link #getProbabilityLineOfSight()} is valid. */ hasValidSatelliteLineOfSight()218 public boolean hasValidSatelliteLineOfSight() { 219 return (mSingleSatCorrectionFlags & HAS_PROB_SAT_IS_LOS_MASK) != 0; 220 } 221 222 /** Returns {@code true} if {@link #getExcessPathLengthMeters()} is valid. */ hasExcessPathLength()223 public boolean hasExcessPathLength() { 224 return (mSingleSatCorrectionFlags & HAS_EXCESS_PATH_LENGTH_MASK) != 0; 225 } 226 227 /** Returns {@code true} if {@link #getExcessPathLengthUncertaintyMeters()} is valid. */ hasExcessPathLengthUncertainty()228 public boolean hasExcessPathLengthUncertainty() { 229 return (mSingleSatCorrectionFlags & HAS_EXCESS_PATH_LENGTH_UNC_MASK) != 0; 230 } 231 232 /** Returns {@code true} if {@link #getReflectingPlane()} is valid. */ hasReflectingPlane()233 public boolean hasReflectingPlane() { 234 return (mSingleSatCorrectionFlags & HAS_REFLECTING_PLANE_MASK) != 0; 235 } 236 237 @Override describeContents()238 public int describeContents() { 239 return 0; 240 } 241 242 public static final Creator<GnssSingleSatCorrection> CREATOR = 243 new Creator<GnssSingleSatCorrection>() { 244 @Override 245 @NonNull 246 public GnssSingleSatCorrection createFromParcel(@NonNull Parcel parcel) { 247 int mSingleSatCorrectionFlags = parcel.readInt(); 248 boolean hasReflectingPlane = 249 (mSingleSatCorrectionFlags & HAS_REFLECTING_PLANE_MASK) != 0; 250 final GnssSingleSatCorrection.Builder singleSatCorrectionBuilder = 251 new Builder() 252 .setConstellationType(parcel.readInt()) 253 .setSatelliteId(parcel.readInt()) 254 .setCarrierFrequencyHz(parcel.readFloat()) 255 .setProbabilityLineOfSight(parcel.readFloat()) 256 .setExcessPathLengthMeters(parcel.readFloat()) 257 .setExcessPathLengthUncertaintyMeters(parcel.readFloat()); 258 if (hasReflectingPlane) { 259 singleSatCorrectionBuilder.setReflectingPlane( 260 GnssReflectingPlane.CREATOR.createFromParcel(parcel)); 261 } 262 return singleSatCorrectionBuilder.build(); 263 } 264 265 @Override 266 public GnssSingleSatCorrection[] newArray(int i) { 267 return new GnssSingleSatCorrection[i]; 268 } 269 }; 270 271 @Override toString()272 public String toString() { 273 final String format = " %-29s = %s\n"; 274 StringBuilder builder = new StringBuilder("GnssSingleSatCorrection:\n"); 275 builder.append( 276 String.format(format, "SingleSatCorrectionFlags = ", mSingleSatCorrectionFlags)); 277 builder.append(String.format(format, "ConstellationType = ", mConstellationType)); 278 builder.append(String.format(format, "SatId = ", mSatId)); 279 builder.append(String.format(format, "CarrierFrequencyHz = ", mCarrierFrequencyHz)); 280 builder.append(String.format(format, "ProbSatIsLos = ", mProbSatIsLos)); 281 builder.append(String.format(format, "ExcessPathLengthMeters = ", mExcessPathLengthMeters)); 282 builder.append( 283 String.format( 284 format, 285 "ExcessPathLengthUncertaintyMeters = ", 286 mExcessPathLengthUncertaintyMeters)); 287 if (hasReflectingPlane()) { 288 builder.append(String.format(format, "ReflectingPlane = ", mReflectingPlane)); 289 } 290 return builder.toString(); 291 } 292 293 @Override writeToParcel(@onNull Parcel parcel, int flags)294 public void writeToParcel(@NonNull Parcel parcel, int flags) { 295 parcel.writeInt(mSingleSatCorrectionFlags); 296 parcel.writeInt(mConstellationType); 297 parcel.writeInt(mSatId); 298 parcel.writeFloat(mCarrierFrequencyHz); 299 parcel.writeFloat(mProbSatIsLos); 300 parcel.writeFloat(mExcessPathLengthMeters); 301 parcel.writeFloat(mExcessPathLengthUncertaintyMeters); 302 if (hasReflectingPlane()) { 303 mReflectingPlane.writeToParcel(parcel, flags); 304 } 305 } 306 307 /** Builder for {@link GnssSingleSatCorrection} */ 308 public static final class Builder { 309 310 /** 311 * For documentation of below fields, see corresponding fields in {@link 312 * GnssSingleSatCorrection}. 313 */ 314 private int mSingleSatCorrectionFlags; 315 316 private int mConstellationType; 317 private int mSatId; 318 private float mCarrierFrequencyHz; 319 private float mProbSatIsLos; 320 private float mExcessPathLengthMeters; 321 private float mExcessPathLengthUncertaintyMeters; 322 @Nullable 323 private GnssReflectingPlane mReflectingPlane; 324 325 /** Sets the constellation type. */ setConstellationType( @nssStatus.ConstellationType int constellationType)326 @NonNull public Builder setConstellationType( 327 @GnssStatus.ConstellationType int constellationType) { 328 mConstellationType = constellationType; 329 return this; 330 } 331 332 /** Sets the Satellite ID defined in the ICD of the given constellation. */ setSatelliteId(@ntRangefrom = 0) int satId)333 @NonNull public Builder setSatelliteId(@IntRange(from = 0) int satId) { 334 mSatId = satId; 335 return this; 336 } 337 338 /** Sets the Carrier frequency in Hz. */ setCarrierFrequencyHz( @loatRangefrom = 0.0f, fromInclusive = false) float carrierFrequencyHz)339 @NonNull public Builder setCarrierFrequencyHz( 340 @FloatRange(from = 0.0f, fromInclusive = false) float carrierFrequencyHz) { 341 mCarrierFrequencyHz = carrierFrequencyHz; 342 return this; 343 } 344 345 /** 346 * Sets the line-of-sight probability of the satellite at the given location in the range 347 * between 0 and 1. 348 */ setProbabilityLineOfSight( @loatRangefrom = 0.0f, to = 1.0f) float probSatIsLos)349 @NonNull public Builder setProbabilityLineOfSight( 350 @FloatRange(from = 0.0f, to = 1.0f) float probSatIsLos) { 351 Preconditions.checkArgumentInRange( 352 probSatIsLos, 0, 1, "probSatIsLos should be between 0 and 1."); 353 mProbSatIsLos = probSatIsLos; 354 mSingleSatCorrectionFlags = 355 (byte) (mSingleSatCorrectionFlags | HAS_PROB_SAT_IS_LOS_MASK); 356 return this; 357 } 358 359 /** 360 * Sets the Excess path length to be subtracted from pseudorange before using it in 361 * calculating location. 362 */ setExcessPathLengthMeters( @loatRangefrom = 0.0f) float excessPathLengthMeters)363 @NonNull public Builder setExcessPathLengthMeters( 364 @FloatRange(from = 0.0f) float excessPathLengthMeters) { 365 mExcessPathLengthMeters = excessPathLengthMeters; 366 mSingleSatCorrectionFlags = 367 (byte) (mSingleSatCorrectionFlags | HAS_EXCESS_PATH_LENGTH_MASK); 368 return this; 369 } 370 371 /** Sets the error estimate (1-sigma) for the Excess path length estimate */ setExcessPathLengthUncertaintyMeters( @loatRangefrom = 0.0f) float excessPathLengthUncertaintyMeters)372 @NonNull public Builder setExcessPathLengthUncertaintyMeters( 373 @FloatRange(from = 0.0f) float excessPathLengthUncertaintyMeters) { 374 mExcessPathLengthUncertaintyMeters = excessPathLengthUncertaintyMeters; 375 mSingleSatCorrectionFlags = 376 (byte) (mSingleSatCorrectionFlags | HAS_EXCESS_PATH_LENGTH_UNC_MASK); 377 return this; 378 } 379 380 /** Sets the reflecting plane information */ setReflectingPlane(@ullable GnssReflectingPlane reflectingPlane)381 @NonNull public Builder setReflectingPlane(@Nullable GnssReflectingPlane reflectingPlane) { 382 mReflectingPlane = reflectingPlane; 383 if (reflectingPlane != null) { 384 mSingleSatCorrectionFlags = 385 (byte) (mSingleSatCorrectionFlags | HAS_REFLECTING_PLANE_MASK); 386 } else { 387 mSingleSatCorrectionFlags = 388 (byte) (mSingleSatCorrectionFlags & ~HAS_REFLECTING_PLANE_MASK); 389 } 390 return this; 391 } 392 393 /** Builds a {@link GnssSingleSatCorrection} instance as specified by this builder. */ build()394 @NonNull public GnssSingleSatCorrection build() { 395 return new GnssSingleSatCorrection(this); 396 } 397 } 398 } 399