blob: a118274dc9a35427640f5efbee642bfd2a389a00 [file]
/*
* 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);
}
}
}
}