| /* |
| * Copyright (C) 2024 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.FlaggedApi; |
| import android.annotation.FloatRange; |
| import android.annotation.NonNull; |
| import android.annotation.SystemApi; |
| import android.location.flags.Flags; |
| import android.os.Parcel; |
| import android.os.Parcelable; |
| |
| import com.android.internal.util.Preconditions; |
| |
| /** |
| * Contains Keplerian orbit model parameters for GPS/Galileo/QZSS/Beidou. |
| * <p>For GPS, this is defined in IS-GPS-200 Table 20-II. |
| * <p>For Galileo, this is defined in Galileo-OS-SIS-ICD-v2.1 section 5.1.1. |
| * <p>For QZSS, this is defined in IS-QZSS-PNT section 4.1.2. |
| * <p>For Baidou, this is defined in BDS-SIS-ICD-B1I-3.0 section 5.2.4.12. |
| * |
| * @hide |
| */ |
| @FlaggedApi(Flags.FLAG_GNSS_ASSISTANCE_INTERFACE) |
| @SystemApi |
| public final class KeplerianOrbitModel implements Parcelable { |
| /** Square root of the semi-major axis in square root of meters. */ |
| private final double mRootA; |
| |
| /** Eccentricity. */ |
| private final double mEccentricity; |
| |
| /** Inclination angle at reference time in radians. */ |
| private final double mI0; |
| |
| /** Rate of change of inclination angle in radians per second. */ |
| private final double mIDot; |
| |
| /** Argument of perigee in radians. */ |
| private final double mOmega; |
| |
| /** Longitude of ascending node of orbit plane at beginning of week in radians. */ |
| private final double mOmega0; |
| |
| /** Rate of right ascension in radians per second. */ |
| private final double mOmegaDot; |
| |
| /** Mean anomaly at reference time in radians. */ |
| private final double mM0; |
| |
| /** Mean motion difference from computed value in radians per second. */ |
| private final double mDeltaN; |
| |
| /** Second-order harmonic perturbations. */ |
| SecondOrderHarmonicPerturbation mSecondOrderHarmonicPerturbation; |
| |
| private KeplerianOrbitModel(Builder builder) { |
| Preconditions.checkArgumentInRange(builder.mRootA, 0.0f, 8192.0f, "RootA"); |
| Preconditions.checkArgumentInRange(builder.mEccentricity, 0.0f, 0.5f, "Eccentricity"); |
| Preconditions.checkArgumentInRange(builder.mI0, -3.15f, 3.15f, "I0"); |
| Preconditions.checkArgumentInRange(builder.mIDot, -2.94e-9f, 2.94e-9f, "IDot"); |
| Preconditions.checkArgumentInRange(builder.mOmega, -3.15f, 3.15f, "Omega"); |
| Preconditions.checkArgumentInRange(builder.mOmega0, -3.15f, 3.15f, "Omega0"); |
| Preconditions.checkArgumentInRange(builder.mOmegaDot, -3.1e-6f, 3.1e-6f, "OmegaDot"); |
| Preconditions.checkArgumentInRange(builder.mM0, -3.15f, 3.15f, "M0"); |
| Preconditions.checkArgumentInRange(builder.mDeltaN, -1.18e-8f, 1.18e-8f, "DeltaN"); |
| mRootA = builder.mRootA; |
| mEccentricity = builder.mEccentricity; |
| mI0 = builder.mI0; |
| mIDot = builder.mIDot; |
| mOmega = builder.mOmega; |
| mOmega0 = builder.mOmega0; |
| mOmegaDot = builder.mOmegaDot; |
| mM0 = builder.mM0; |
| mDeltaN = builder.mDeltaN; |
| mSecondOrderHarmonicPerturbation = builder.mSecondOrderHarmonicPerturbation; |
| } |
| |
| /** Get the square root of the semi-major axis in square root of meters. */ |
| @FloatRange(from = 0.0f, to = 8192.0f) |
| public double getRootA() { |
| return mRootA; |
| } |
| |
| /** Get the eccentricity. */ |
| @FloatRange(from = 0.0f, to = 0.5f) |
| public double getEccentricity() { |
| return mEccentricity; |
| } |
| |
| /** Get the inclination angle at reference time in radians. */ |
| @FloatRange(from = -3.15f, to = 3.15f) |
| public double getI0() { |
| return mI0; |
| } |
| |
| /** Get the rate of change of inclination angle in radians per second. */ |
| @FloatRange(from = -2.94e-9f, to = 2.94e-9f) |
| public double getIDot() { |
| return mIDot; |
| } |
| |
| /** Get the argument of perigee in radians. */ |
| @FloatRange(from = -3.15f, to = 3.15f) |
| public double getOmega() { |
| return mOmega; |
| } |
| |
| /** Get the longitude of ascending node of orbit plane at beginning of week in radians. */ |
| @FloatRange(from = -3.15f, to = 3.15f) |
| public double getOmega0() { |
| return mOmega0; |
| } |
| |
| /** Get the rate of right ascension in radians per second. */ |
| @FloatRange(from = -3.1e-6f, to = 3.1e-6f) |
| public double getOmegaDot() { |
| return mOmegaDot; |
| } |
| |
| /** Get the mean anomaly at reference time in radians. */ |
| @FloatRange(from = -3.15f, to = 3.15f) |
| public double getM0() { |
| return mM0; |
| } |
| |
| /** Get the mean motion difference from computed value in radians per second. */ |
| @FloatRange(from = -1.18e-8f, to = 1.18e-8f) |
| public double getDeltaN() { |
| return mDeltaN; |
| } |
| |
| /** Get the second-order harmonic perturbations. */ |
| @NonNull |
| public SecondOrderHarmonicPerturbation getSecondOrderHarmonicPerturbation() { |
| return mSecondOrderHarmonicPerturbation; |
| } |
| |
| public static final @NonNull Creator<KeplerianOrbitModel> CREATOR = |
| new Creator<KeplerianOrbitModel>() { |
| @Override |
| @NonNull |
| public KeplerianOrbitModel createFromParcel(Parcel in) { |
| final KeplerianOrbitModel.Builder keplerianOrbitModel = |
| new Builder() |
| .setRootA(in.readDouble()) |
| .setEccentricity(in.readDouble()) |
| .setI0(in.readDouble()) |
| .setIDot(in.readDouble()) |
| .setOmega(in.readDouble()) |
| .setOmega0(in.readDouble()) |
| .setOmegaDot(in.readDouble()) |
| .setM0(in.readDouble()) |
| .setDeltaN(in.readDouble()) |
| .setSecondOrderHarmonicPerturbation( |
| in.readTypedObject( |
| SecondOrderHarmonicPerturbation.CREATOR)); |
| return keplerianOrbitModel.build(); |
| } |
| |
| @Override |
| public KeplerianOrbitModel[] newArray(int size) { |
| return new KeplerianOrbitModel[size]; |
| } |
| }; |
| |
| @Override |
| public int describeContents() { |
| return 0; |
| } |
| |
| @Override |
| public void writeToParcel(@NonNull Parcel parcel, int flags) { |
| parcel.writeDouble(mRootA); |
| parcel.writeDouble(mEccentricity); |
| parcel.writeDouble(mI0); |
| parcel.writeDouble(mIDot); |
| parcel.writeDouble(mOmega); |
| parcel.writeDouble(mOmega0); |
| parcel.writeDouble(mOmegaDot); |
| parcel.writeDouble(mM0); |
| parcel.writeDouble(mDeltaN); |
| parcel.writeTypedObject(mSecondOrderHarmonicPerturbation, flags); |
| } |
| |
| @Override |
| @NonNull |
| public String toString() { |
| StringBuilder builder = new StringBuilder("KeplerianOrbitModel["); |
| builder.append("rootA = ").append(mRootA); |
| builder.append(", eccentricity = ").append(mEccentricity); |
| builder.append(", i0 = ").append(mI0); |
| builder.append(", iDot = ").append(mIDot); |
| builder.append(", omega = ").append(mOmega); |
| builder.append(", omega0 = ").append(mOmega0); |
| builder.append(", omegaDot = ").append(mOmegaDot); |
| builder.append(", m0 = ").append(mM0); |
| builder.append(", deltaN = ").append(mDeltaN); |
| builder.append(", secondOrderHarmonicPerturbation = ") |
| .append(mSecondOrderHarmonicPerturbation); |
| builder.append("]"); |
| return builder.toString(); |
| } |
| |
| /** Builder for {@link KeplerianOrbitModel} */ |
| public static final class Builder { |
| private double mRootA; |
| private double mEccentricity; |
| private double mI0; |
| private double mIDot; |
| private double mOmega; |
| private double mOmega0; |
| private double mOmegaDot; |
| private double mM0; |
| private double mDeltaN; |
| private SecondOrderHarmonicPerturbation mSecondOrderHarmonicPerturbation; |
| |
| /** Sets the square root of the semi-major axis in square root of meters. */ |
| @NonNull |
| public Builder setRootA(@FloatRange(from = 0.0f, to = 8192.0f) double rootA) { |
| mRootA = rootA; |
| return this; |
| } |
| |
| /** Sets the eccentricity. */ |
| @NonNull |
| public Builder setEccentricity(@FloatRange(from = 0.0f, to = 0.5f) double eccentricity) { |
| mEccentricity = eccentricity; |
| return this; |
| } |
| |
| /** Sets the inclination angle at reference time in radians. */ |
| @NonNull |
| public Builder setI0(@FloatRange(from = -3.15f, to = 3.15f) double i0) { |
| mI0 = i0; |
| return this; |
| } |
| |
| /** Sets the rate of change of inclination angle in radians per second. */ |
| @NonNull |
| public Builder setIDot(@FloatRange(from = -2.94e-9f, to = 2.94e-9f) double iDot) { |
| mIDot = iDot; |
| return this; |
| } |
| |
| /** Sets the argument of perigee in radians. */ |
| @NonNull |
| public Builder setOmega(@FloatRange(from = -3.15f, to = 3.15f) double omega) { |
| mOmega = omega; |
| return this; |
| } |
| |
| /** |
| * Sets the longitude of ascending node of orbit plane at beginning of week in radians. |
| */ |
| @NonNull |
| public Builder setOmega0(@FloatRange(from = -3.15f, to = 3.15f) double omega0) { |
| mOmega0 = omega0; |
| return this; |
| } |
| |
| /** Sets the rate of right ascension in radians per second. */ |
| @NonNull |
| public Builder setOmegaDot(@FloatRange(from = -3.1e-6f, to = 3.1e-6f) double omegaDot) { |
| mOmegaDot = omegaDot; |
| return this; |
| } |
| |
| /** Sets the mean anomaly at reference time in radians. */ |
| @NonNull |
| public Builder setM0(@FloatRange(from = -3.15f, to = 3.15f) double m0) { |
| mM0 = m0; |
| return this; |
| } |
| |
| /** Sets the mean motion difference from computed value in radians per second. */ |
| @NonNull |
| public Builder setDeltaN(@FloatRange(from = -1.18e-8f, to = 1.18e-8f) double deltaN) { |
| mDeltaN = deltaN; |
| return this; |
| } |
| |
| /** Sets the second-order harmonic perturbations. */ |
| @NonNull |
| public Builder setSecondOrderHarmonicPerturbation( |
| @NonNull SecondOrderHarmonicPerturbation secondOrderHarmonicPerturbation) { |
| mSecondOrderHarmonicPerturbation = secondOrderHarmonicPerturbation; |
| return this; |
| } |
| |
| /** Builds a {@link KeplerianOrbitModel} instance as specified by this builder. */ |
| @NonNull |
| public KeplerianOrbitModel build() { |
| return new KeplerianOrbitModel(this); |
| } |
| } |
| |
| /** A class contains second-order harmonic perturbations. */ |
| public static final class SecondOrderHarmonicPerturbation implements Parcelable { |
| /** Amplitude of cosine harmonic correction term to angle of inclination in radians. */ |
| private final double mCic; |
| |
| /** Amplitude of sine harmonic correction term to angle of inclination in radians. */ |
| private final double mCis; |
| |
| /** Amplitude of cosine harmonic correction term to the orbit in meters. */ |
| private final double mCrc; |
| |
| /** Amplitude of sine harmonic correction term to the orbit in meters. */ |
| private final double mCrs; |
| |
| /** Amplitude of cosine harmonic correction term to the argument of latitude in radians. */ |
| private final double mCuc; |
| |
| /** Amplitude of sine harmonic correction term to the argument of latitude in radians. */ |
| private final double mCus; |
| |
| private SecondOrderHarmonicPerturbation(Builder builder) { |
| Preconditions.checkArgumentInRange(builder.mCic, -6.11e-5f, 6.11e-5f, "Cic"); |
| Preconditions.checkArgumentInRange(builder.mCis, -6.11e-5f, 6.11e-5f, "Cis"); |
| Preconditions.checkArgumentInRange(builder.mCrc, -2048.0f, 2048.0f, "Crc"); |
| Preconditions.checkArgumentInRange(builder.mCrs, -2048.0f, 2048.0f, "Crs"); |
| Preconditions.checkArgumentInRange(builder.mCuc, -6.11e-5f, 6.11e-5f, "Cuc"); |
| Preconditions.checkArgumentInRange(builder.mCus, -6.11e-5f, 6.11e-5f, "Cus"); |
| mCic = builder.mCic; |
| mCrc = builder.mCrc; |
| mCis = builder.mCis; |
| mCrs = builder.mCrs; |
| mCuc = builder.mCuc; |
| mCus = builder.mCus; |
| } |
| |
| /** |
| * Get the amplitude of cosine harmonic correction term to angle of inclination in radians. |
| */ |
| @FloatRange(from = -6.11e-5f, to = 6.11e-5f) |
| public double getCic() { |
| return mCic; |
| } |
| |
| /** |
| * Get the amplitude of sine harmonic correction term to angle of inclination in radians. |
| */ |
| @FloatRange(from = -6.11e-5f, to = 6.11e-5f) |
| public double getCis() { |
| return mCis; |
| } |
| |
| /** Get the amplitude of cosine harmonic correction term to the orbit in meters. */ |
| @FloatRange(from = -2048.0f, to = 2048.0f) |
| public double getCrc() { |
| return mCrc; |
| } |
| |
| /** Get the amplitude of sine harmonic correction term to the orbit in meters. */ |
| @FloatRange(from = -2048.0f, to = 2048.0f) |
| public double getCrs() { |
| return mCrs; |
| } |
| |
| /** |
| * Get the amplitude of cosine harmonic correction term to the argument of latitude in |
| * radians. |
| */ |
| @FloatRange(from = -6.11e-5f, to = 6.11e-5f) |
| public double getCuc() { |
| return mCuc; |
| } |
| |
| /** |
| * Get the amplitude of sine harmonic correction term to the argument of latitude in |
| * radians. |
| */ |
| @FloatRange(from = -6.11e-5f, to = 6.11e-5f) |
| public double getCus() { |
| return mCus; |
| } |
| |
| public static final @NonNull Creator<SecondOrderHarmonicPerturbation> CREATOR = |
| new Creator<SecondOrderHarmonicPerturbation>() { |
| @Override |
| @NonNull |
| public SecondOrderHarmonicPerturbation createFromParcel(Parcel in) { |
| final SecondOrderHarmonicPerturbation.Builder |
| secondOrderHarmonicPerturbation = |
| new Builder() |
| .setCic(in.readDouble()) |
| .setCis(in.readDouble()) |
| .setCrc(in.readDouble()) |
| .setCrs(in.readDouble()) |
| .setCuc(in.readDouble()) |
| .setCus(in.readDouble()); |
| return secondOrderHarmonicPerturbation.build(); |
| } |
| |
| @Override |
| public SecondOrderHarmonicPerturbation[] newArray(int size) { |
| return new SecondOrderHarmonicPerturbation[size]; |
| } |
| }; |
| |
| @Override |
| public int describeContents() { |
| return 0; |
| } |
| |
| @Override |
| public void writeToParcel(@NonNull Parcel parcel, int flags) { |
| parcel.writeDouble(mCic); |
| parcel.writeDouble(mCis); |
| parcel.writeDouble(mCrc); |
| parcel.writeDouble(mCrs); |
| parcel.writeDouble(mCuc); |
| parcel.writeDouble(mCus); |
| } |
| |
| @Override |
| @NonNull |
| public String toString() { |
| StringBuilder builder = new StringBuilder("SecondOrderHarmonicPerturbation["); |
| builder.append("cic = ").append(mCic); |
| builder.append(", cis = ").append(mCis); |
| builder.append(", crc = ").append(mCrc); |
| builder.append(", crs = ").append(mCrs); |
| builder.append(", cuc = ").append(mCuc); |
| builder.append(", cus = ").append(mCus); |
| builder.append("]"); |
| return builder.toString(); |
| } |
| |
| /** Builder for {@link SecondOrderHarmonicPerturbation} */ |
| public static final class Builder { |
| private double mCic; |
| private double mCis; |
| private double mCrc; |
| private double mCrs; |
| private double mCuc; |
| private double mCus; |
| |
| /** |
| * Sets the amplitude of cosine harmonic correction term to angle of inclination in |
| * radians. |
| */ |
| @NonNull |
| public Builder setCic(@FloatRange(from = -6.11e-5f, to = 6.11e-5f) double cic) { |
| mCic = cic; |
| return this; |
| } |
| |
| /** |
| * Sets the amplitude of sine harmonic correction term to angle of inclination in |
| * radians. |
| */ |
| @NonNull |
| public Builder setCis(@FloatRange(from = -6.11e-5f, to = 6.11e-5f) double cis) { |
| mCis = cis; |
| return this; |
| } |
| |
| /** Sets the amplitude of cosine harmonic correction term to the orbit in meters. */ |
| @NonNull |
| public Builder setCrc(@FloatRange(from = -2048.0f, to = 2048.0f) double crc) { |
| mCrc = crc; |
| return this; |
| } |
| |
| /** Sets the amplitude of sine harmonic correction term to the orbit in meters. */ |
| @NonNull |
| public Builder setCrs(@FloatRange(from = -2048.0f, to = 2048.0f) double crs) { |
| mCrs = crs; |
| return this; |
| } |
| |
| /** |
| * Sets the amplitude of cosine harmonic correction term to the argument of latitude in |
| * radians. |
| */ |
| @NonNull |
| public Builder setCuc(@FloatRange(from = -6.11e-5f, to = 6.11e-5f) double cuc) { |
| mCuc = cuc; |
| return this; |
| } |
| |
| /** |
| * Sets the amplitude of sine harmonic correction term to the argument of latitude in |
| * radians. |
| */ |
| @NonNull |
| public Builder setCus(@FloatRange(from = -6.11e-5f, to = 6.11e-5f) double cus) { |
| mCus = cus; |
| return this; |
| } |
| |
| /** |
| * Builds a {@link SecondOrderHarmonicPerturbation} instance as specified by this |
| * builder. |
| */ |
| @NonNull |
| public SecondOrderHarmonicPerturbation build() { |
| return new SecondOrderHarmonicPerturbation(this); |
| } |
| } |
| } |
| } |