diff options
author | Blake Kragten <kragtenb@google.com> | 2019-09-16 18:19:54 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2019-09-16 18:19:54 +0000 |
commit | 9c16632a2401c379330d8aa5ee960a9f7b4f4692 (patch) | |
tree | cee5d7964eaa4a1ee6be960da60690d129669670 | |
parent | 4d959eeba9010fddfd71f2e44bcccad413f2d8d6 (diff) | |
parent | 025aabe693ad4e823dfb613ad9adc740418247e4 (diff) |
Merge "L5 Metrics Addition:" into qt-qpr1-dev
3 files changed, 170 insertions, 4 deletions
diff --git a/location/java/com/android/internal/location/gnssmetrics/GnssMetrics.java b/location/java/com/android/internal/location/gnssmetrics/GnssMetrics.java index 78239714ca3b..b6a24e41d958 100644 --- a/location/java/com/android/internal/location/gnssmetrics/GnssMetrics.java +++ b/location/java/com/android/internal/location/gnssmetrics/GnssMetrics.java @@ -31,7 +31,9 @@ import com.android.internal.app.IBatteryStats; import com.android.internal.location.nano.GnssLogsProto.GnssLog; import com.android.internal.location.nano.GnssLogsProto.PowerMetrics; +import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; /** * GnssMetrics: Is used for logging GNSS metrics @@ -60,13 +62,20 @@ public class GnssMetrics { /** Default time between location fixes (in millisecs) */ private static final int DEFAULT_TIME_BETWEEN_FIXES_MILLISECS = 1000; + /** The number of hertz in one MHz */ + private static final double HZ_PER_MHZ = 1e6; + /* The time since boot when logging started */ private String logStartInElapsedRealTime; /* GNSS power metrics */ private GnssPowerMetrics mGnssPowerMetrics; - /** + /** Frequency range of GPS L5, Galileo E5a, QZSS J5 frequency band */ + private static final double L5_CARRIER_FREQ_RANGE_LOW_HZ = 1164 * HZ_PER_MHZ; + private static final double L5_CARRIER_FREQ_RANGE_HIGH_HZ = 1189 * HZ_PER_MHZ; + + /** * A boolean array indicating whether the constellation types have been used in fix. */ private boolean[] mConstellationTypes; @@ -78,6 +87,11 @@ public class GnssMetrics { timeToFirstFixSecStatistics = new Statistics(); positionAccuracyMeterStatistics = new Statistics(); topFourAverageCn0Statistics = new Statistics(); + mTopFourAverageCn0StatisticsL5 = new Statistics(); + mNumSvStatus = 0; + mNumL5SvStatus = 0; + mNumSvStatusUsedInFix = 0; + mNumL5SvStatusUsedInFix = 0; reset(); } @@ -133,11 +147,16 @@ public class GnssMetrics { return; } - /* + /** * Logs CN0 when at least 4 SVs are available * + * @param cn0s + * @param numSv + * @param svCarrierFreqs */ - public void logCn0(float[] cn0s, int numSv) { + public void logCn0(float[] cn0s, int numSv, float[] svCarrierFreqs) { + // Calculate L5 Cn0 + logCn0L5(numSv, cn0s, svCarrierFreqs); if (numSv == 0 || cn0s == null || cn0s.length == 0 || cn0s.length < numSv) { if (numSv == 0) { mGnssPowerMetrics.reportSignalQuality(null, 0); @@ -161,6 +180,76 @@ public class GnssMetrics { return; } + /* Helper function to check if a SV is L5 */ + private static boolean isL5Sv(float carrierFreq) { + return (carrierFreq >= L5_CARRIER_FREQ_RANGE_LOW_HZ + && carrierFreq <= L5_CARRIER_FREQ_RANGE_HIGH_HZ); + } + + /** + * Logs sv status data + * + * @param svCount + * @param svidWithFlags + * @param svCarrierFreqs + */ + public void logSvStatus(int svCount, int[] svidWithFlags, float[] svCarrierFreqs) { + boolean isL5 = false; + // Calculate SvStatus Information + for (int i = 0; i < svCount; i++) { + if ((svidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_HAS_CARRIER_FREQUENCY) != 0) { + mNumSvStatus++; + isL5 = isL5Sv(svCarrierFreqs[i]); + if (isL5) { + mNumL5SvStatus++; + } + if ((svidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_USED_IN_FIX) != 0) { + mNumSvStatusUsedInFix++; + if (isL5) { + mNumL5SvStatusUsedInFix++; + } + } + } + } + return; + } + + /** + * Logs CN0 when at least 4 SVs are available L5 Only + * + * @param svCount + * @param cn0s + * @param svCarrierFreqs + */ + private void logCn0L5(int svCount, float[] cn0s, float[] svCarrierFreqs) { + if (svCount == 0 || cn0s == null || cn0s.length == 0 || cn0s.length < svCount + || svCarrierFreqs == null || svCarrierFreqs.length == 0 + || svCarrierFreqs.length < svCount) { + return; + } + // Create array list of all L5 satellites in report. + ArrayList<Float> CnoL5Array = new ArrayList(); + for (int i = 0; i < svCount; i++) { + if (isL5Sv(svCarrierFreqs[i])) { + CnoL5Array.add(cn0s[i]); + } + } + if (CnoL5Array.size() == 0 || CnoL5Array.size() < 4) { + return; + } + int numSvL5 = CnoL5Array.size(); + Collections.sort(CnoL5Array); + if (CnoL5Array.get(numSvL5 - 4) > 0.0) { + double top4AvgCn0 = 0.0; + for (int i = numSvL5 - 4; i < numSvL5; i++) { + top4AvgCn0 += (double) CnoL5Array.get(i); + } + top4AvgCn0 /= 4; + mTopFourAverageCn0StatisticsL5.addItem(top4AvgCn0); + } + return; + } + /** * Logs that a constellation type has been observed. @@ -201,6 +290,24 @@ public class GnssMetrics { msg.standardDeviationTopFourAverageCn0DbHz = topFourAverageCn0Statistics.getStandardDeviation(); } + if (mNumSvStatus > 0) { + msg.numSvStatusProcessed = mNumSvStatus; + } + if (mNumL5SvStatus > 0) { + msg.numL5SvStatusProcessed = mNumL5SvStatus; + } + if (mNumSvStatusUsedInFix > 0) { + msg.numSvStatusUsedInFix = mNumSvStatusUsedInFix; + } + if (mNumL5SvStatusUsedInFix > 0) { + msg.numL5SvStatusUsedInFix = mNumL5SvStatusUsedInFix; + } + if (mTopFourAverageCn0StatisticsL5.getCount() > 0) { + msg.numL5TopFourAverageCn0Processed = mTopFourAverageCn0StatisticsL5.getCount(); + msg.meanL5TopFourAverageCn0DbHz = mTopFourAverageCn0StatisticsL5.getMean(); + msg.standardDeviationL5TopFourAverageCn0DbHz = + mTopFourAverageCn0StatisticsL5.getStandardDeviation(); + } msg.powerMetrics = mGnssPowerMetrics.buildProto(); msg.hardwareRevision = SystemProperties.get("ro.boot.revision", ""); String s = Base64.encodeToString(GnssLog.toByteArray(msg), Base64.DEFAULT); @@ -249,6 +356,22 @@ public class GnssMetrics { s.append(" Top 4 Avg CN0 standard deviation (dB-Hz): ").append( topFourAverageCn0Statistics.getStandardDeviation()).append("\n"); } + s.append(" Total number of sv status messages processed: ").append( + mNumSvStatus).append("\n"); + s.append(" Total number of L5 sv status messages processed: ").append( + mNumL5SvStatus).append("\n"); + s.append(" Total number of sv status messages processed, where sv is used in fix: ").append( + mNumSvStatusUsedInFix).append("\n"); + s.append(" Total number of L5 sv status messages processed, where sv is used in fix: ").append( + mNumL5SvStatusUsedInFix).append("\n"); + s.append(" Number of L5 CN0 reports: ").append( + mTopFourAverageCn0StatisticsL5.getCount()).append("\n"); + if (mTopFourAverageCn0StatisticsL5.getCount() > 0) { + s.append(" L5 Top 4 Avg CN0 mean (dB-Hz): ").append( + mTopFourAverageCn0StatisticsL5.getMean()).append("\n"); + s.append(" L5 Top 4 Avg CN0 standard deviation (dB-Hz): ").append( + mTopFourAverageCn0StatisticsL5.getStandardDeviation()).append("\n"); + } s.append(" Used-in-fix constellation types: "); for (int i = 0; i < mConstellationTypes.length; i++) { if (mConstellationTypes[i]) { @@ -333,6 +456,21 @@ public class GnssMetrics { /** Top 4 average CN0 statistics */ private Statistics topFourAverageCn0Statistics; + /** Top 4 average CN0 statistics L5 */ + private Statistics mTopFourAverageCn0StatisticsL5; + + /** Total number of sv status messages processed */ + private int mNumSvStatus; + + /** Total number of L5 sv status messages processed */ + private int mNumL5SvStatus; + + /** Total number of sv status messages processed, where sv is used in fix */ + private int mNumSvStatusUsedInFix; + + /** Total number of L5 sv status messages processed, where sv is used in fix */ + private int mNumL5SvStatusUsedInFix; + /** * Resets GNSS metrics */ @@ -344,6 +482,11 @@ public class GnssMetrics { timeToFirstFixSecStatistics.reset(); positionAccuracyMeterStatistics.reset(); topFourAverageCn0Statistics.reset(); + mTopFourAverageCn0StatisticsL5.reset(); + mNumSvStatus = 0; + mNumL5SvStatus = 0; + mNumSvStatusUsedInFix = 0; + mNumL5SvStatusUsedInFix = 0; resetConstellationTypes(); return; } diff --git a/proto/src/gnss.proto b/proto/src/gnss.proto index 1509fc00fb1d..33dbb26c3958 100644 --- a/proto/src/gnss.proto +++ b/proto/src/gnss.proto @@ -48,6 +48,27 @@ message GnssLog { // Hardware revision (EVT, DVT, PVT etc.) optional string hardware_revision = 13; + + // Total number of sv status messages processed + optional int32 num_sv_status_processed = 14; + + // Total number of L5 sv status messages processed + optional int32 num_l5_sv_status_processed = 15; + + // Total number of sv status messages processed, where sv is used in fix + optional int32 num_sv_status_used_in_fix = 16; + + // Total number of L5 sv status messages processed, where sv is used in fix + optional int32 num_l5_sv_status_used_in_fix = 17; + + // Number of l5 top 4 average CN0 processed + optional int32 num_l5_top_four_average_cn0_processed = 18; + + // Mean of l5 top 4 average CN0 (dB-Hz) + optional double mean_l5_top_four_average_cn0_db_hz = 19; + + // Standard deviation of l5 top 4 average CN0 (dB-Hz) + optional double standard_deviation_l5_top_four_average_cn0_db_hz = 20; } // Power metrics diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java index c312b76cc463..181a43549313 100644 --- a/services/core/java/com/android/server/location/GnssLocationProvider.java +++ b/services/core/java/com/android/server/location/GnssLocationProvider.java @@ -1459,7 +1459,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements info.mSvCarrierFreqs); // Log CN0 as part of GNSS metrics - mGnssMetrics.logCn0(info.mCn0s, info.mSvCount); + mGnssMetrics.logCn0(info.mCn0s, info.mSvCount, info.mSvCarrierFreqs); if (VERBOSE) { Log.v(TAG, "SV count: " + info.mSvCount); @@ -1510,6 +1510,8 @@ public class GnssLocationProvider extends AbstractLocationProvider implements SystemClock.elapsedRealtime() - mLastFixTime > RECENT_FIX_TIMEOUT) { updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE); } + + mGnssMetrics.logSvStatus(info.mSvCount, info.mSvidWithFlags, info.mSvCarrierFreqs); } @NativeEntryPoint |