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 @NonNull 272 @Override toString()273 public String toString() { 274 final String format = " %-29s = %s\n"; 275 StringBuilder builder = new StringBuilder("GnssSingleSatCorrection:\n"); 276 builder.append( 277 String.format(format, "SingleSatCorrectionFlags = ", mSingleSatCorrectionFlags)); 278 builder.append(String.format(format, "ConstellationType = ", mConstellationType)); 279 builder.append(String.format(format, "SatId = ", mSatId)); 280 builder.append(String.format(format, "CarrierFrequencyHz = ", mCarrierFrequencyHz)); 281 builder.append(String.format(format, "ProbSatIsLos = ", mProbSatIsLos)); 282 builder.append(String.format(format, "ExcessPathLengthMeters = ", mExcessPathLengthMeters)); 283 builder.append( 284 String.format( 285 format, 286 "ExcessPathLengthUncertaintyMeters = ", 287 mExcessPathLengthUncertaintyMeters)); 288 if (hasReflectingPlane()) { 289 builder.append(String.format(format, "ReflectingPlane = ", mReflectingPlane)); 290 } 291 return builder.toString(); 292 } 293 294 @Override writeToParcel(@onNull Parcel parcel, int flags)295 public void writeToParcel(@NonNull Parcel parcel, int flags) { 296 parcel.writeInt(mSingleSatCorrectionFlags); 297 parcel.writeInt(mConstellationType); 298 parcel.writeInt(mSatId); 299 parcel.writeFloat(mCarrierFrequencyHz); 300 parcel.writeFloat(mProbSatIsLos); 301 parcel.writeFloat(mExcessPathLengthMeters); 302 parcel.writeFloat(mExcessPathLengthUncertaintyMeters); 303 if (hasReflectingPlane()) { 304 mReflectingPlane.writeToParcel(parcel, flags); 305 } 306 } 307 308 /** Builder for {@link GnssSingleSatCorrection} */ 309 public static final class Builder { 310 311 /** 312 * For documentation of below fields, see corresponding fields in {@link 313 * GnssSingleSatCorrection}. 314 */ 315 private int mSingleSatCorrectionFlags; 316 317 private int mConstellationType; 318 private int mSatId; 319 private float mCarrierFrequencyHz; 320 private float mProbSatIsLos; 321 private float mExcessPathLengthMeters; 322 private float mExcessPathLengthUncertaintyMeters; 323 @Nullable 324 private GnssReflectingPlane mReflectingPlane; 325 326 /** Sets the constellation type. */ setConstellationType( @nssStatus.ConstellationType int constellationType)327 @NonNull public Builder setConstellationType( 328 @GnssStatus.ConstellationType int constellationType) { 329 mConstellationType = constellationType; 330 return this; 331 } 332 333 /** Sets the Satellite ID defined in the ICD of the given constellation. */ setSatelliteId(@ntRangefrom = 0) int satId)334 @NonNull public Builder setSatelliteId(@IntRange(from = 0) int satId) { 335 mSatId = satId; 336 return this; 337 } 338 339 /** Sets the Carrier frequency in Hz. */ setCarrierFrequencyHz( @loatRangefrom = 0.0f, fromInclusive = false) float carrierFrequencyHz)340 @NonNull public Builder setCarrierFrequencyHz( 341 @FloatRange(from = 0.0f, fromInclusive = false) float carrierFrequencyHz) { 342 mCarrierFrequencyHz = carrierFrequencyHz; 343 return this; 344 } 345 346 /** 347 * Sets the line-of-sight probability of the satellite at the given location in the range 348 * between 0 and 1. 349 */ setProbabilityLineOfSight( @loatRangefrom = 0.0f, to = 1.0f) float probSatIsLos)350 @NonNull public Builder setProbabilityLineOfSight( 351 @FloatRange(from = 0.0f, to = 1.0f) float probSatIsLos) { 352 Preconditions.checkArgumentInRange( 353 probSatIsLos, 0, 1, "probSatIsLos should be between 0 and 1."); 354 mProbSatIsLos = probSatIsLos; 355 mSingleSatCorrectionFlags = 356 (byte) (mSingleSatCorrectionFlags | HAS_PROB_SAT_IS_LOS_MASK); 357 return this; 358 } 359 360 /** 361 * Sets the Excess path length to be subtracted from pseudorange before using it in 362 * calculating location. 363 */ setExcessPathLengthMeters( @loatRangefrom = 0.0f) float excessPathLengthMeters)364 @NonNull public Builder setExcessPathLengthMeters( 365 @FloatRange(from = 0.0f) float excessPathLengthMeters) { 366 mExcessPathLengthMeters = excessPathLengthMeters; 367 mSingleSatCorrectionFlags = 368 (byte) (mSingleSatCorrectionFlags | HAS_EXCESS_PATH_LENGTH_MASK); 369 return this; 370 } 371 372 /** Sets the error estimate (1-sigma) for the Excess path length estimate */ setExcessPathLengthUncertaintyMeters( @loatRangefrom = 0.0f) float excessPathLengthUncertaintyMeters)373 @NonNull public Builder setExcessPathLengthUncertaintyMeters( 374 @FloatRange(from = 0.0f) float excessPathLengthUncertaintyMeters) { 375 mExcessPathLengthUncertaintyMeters = excessPathLengthUncertaintyMeters; 376 mSingleSatCorrectionFlags = 377 (byte) (mSingleSatCorrectionFlags | HAS_EXCESS_PATH_LENGTH_UNC_MASK); 378 return this; 379 } 380 381 /** Sets the reflecting plane information */ setReflectingPlane(@ullable GnssReflectingPlane reflectingPlane)382 @NonNull public Builder setReflectingPlane(@Nullable GnssReflectingPlane reflectingPlane) { 383 mReflectingPlane = reflectingPlane; 384 if (reflectingPlane != null) { 385 mSingleSatCorrectionFlags = 386 (byte) (mSingleSatCorrectionFlags | HAS_REFLECTING_PLANE_MASK); 387 } else { 388 mSingleSatCorrectionFlags = 389 (byte) (mSingleSatCorrectionFlags & ~HAS_REFLECTING_PLANE_MASK); 390 } 391 return this; 392 } 393 394 /** Builds a {@link GnssSingleSatCorrection} instance as specified by this builder. */ build()395 @NonNull public GnssSingleSatCorrection build() { 396 return new GnssSingleSatCorrection(this); 397 } 398 } 399 } 400