L5 Metrics Addition:

Added L5 metrics to determine if L5 should be enabled or not.

Test: On device

adb shell dumpsys location

Output:
  Number of CN0 reports: 149
  Top 4 Avg CN0 mean (dB-Hz): 26.100838872410307
  Top 4 Avg CN0 standard deviation (dB-Hz): 1.7702387090734562
  Total number of sv status messages processed: 4202
  Total number of L5 sv status messages processed: 703
  Total number of sv status messages processed, where sv is used in fix: 1979
  Total number of L5 sv status messages processed, where sv is used in fix: 46
  Number of L5 CN0 reports: 97
  L5 Top 4 Avg CN0 mean (dB-Hz): 20.273711379041377
  L5 Top 4 Avg CN0 standard deviation (dB-Hz): 2.632911219511556
  Used-in-fix constellation types: GPS GLONASS GALILEO

Output Logs: https://drive.google.com/drive/folders/1tGEolHWtF92UkJ8lxgFihIzfWLl8ChZK?usp=sharing
Bug: 137575988
Change-Id: Id306d7cc27c9410a5ad73f5a0940c25f8d795686
This commit is contained in:
Blake Kragten
2019-08-28 16:21:35 -07:00
parent 0bd4a945c8
commit bb613600fc
3 changed files with 160 additions and 2 deletions

View File

@@ -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
@@ -63,9 +65,16 @@ public class GnssMetrics {
/* The time since boot when logging started */
private String mLogStartInElapsedRealTime;
/** The number of hertz in one MHz */
private static final double HZ_PER_MHZ = 1e6;
/* 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;
/** Location failure statistics */
@@ -76,6 +85,16 @@ public class GnssMetrics {
private Statistics mPositionAccuracyMeterStatistics;
/** Top 4 average CN0 statistics */
private Statistics mTopFourAverageCn0Statistics;
/** 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;
public GnssMetrics(IBatteryStats stats) {
mGnssPowerMetrics = new GnssPowerMetrics(stats);
@@ -83,6 +102,11 @@ public class GnssMetrics {
mTimeToFirstFixSecStatistics = new Statistics();
mPositionAccuracyMeterStatistics = new Statistics();
mTopFourAverageCn0Statistics = new Statistics();
mTopFourAverageCn0StatisticsL5 = new Statistics();
mNumSvStatus = 0;
mNumL5SvStatus = 0;
mNumSvStatusUsedInFix = 0;
mNumL5SvStatusUsedInFix = 0;
reset();
}
@@ -127,8 +151,14 @@ public class GnssMetrics {
/**
* 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);
@@ -150,6 +180,75 @@ public class GnssMetrics {
mTopFourAverageCn0Statistics.addItem(top4AvgCn0);
}
}
/* 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.
@@ -189,6 +288,24 @@ public class GnssMetrics {
msg.standardDeviationTopFourAverageCn0DbHz =
mTopFourAverageCn0Statistics.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);
@@ -238,6 +355,24 @@ public class GnssMetrics {
s.append(" Top 4 Avg CN0 standard deviation (dB-Hz): ").append(
mTopFourAverageCn0Statistics.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]) {

View File

@@ -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

View File

@@ -1458,7 +1458,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);
@@ -1509,6 +1509,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