@RequiresApi(api = Build.VERSION_CODES.N) public RawGPSStatusRecord(GnssStatus status) { super(new RecordInfo(System.currentTimeMillis())); this.satelliteCount = status.getSatelliteCount(); this.azimuths = new float[satelliteCount]; this.cn0DHzs = new float[satelliteCount]; this.constellationTypes = new int[satelliteCount]; this.elevations = new float[satelliteCount]; this.svids = new int[satelliteCount]; for (int i = 0; i < satelliteCount; i++) { azimuths[i] = status.getAzimuthDegrees(i); cn0DHzs[i] = status.getCn0DbHz(i); constellationTypes[i] = status.getConstellationType(i); elevations[i] = status.getElevationDegrees(i); svids[i] = status.getSvid(i); } }
private String gnssStatusToString(GnssStatus gnssStatus) { StringBuilder builder = new StringBuilder("SATELLITE_STATUS | [Satellites:\n"); for (int i = 0; i < gnssStatus.getSatelliteCount(); i++) { builder .append("Constellation = ") .append(getConstellationName(gnssStatus.getConstellationType(i))) .append(", "); builder.append("Svid = ").append(gnssStatus.getSvid(i)).append(", "); builder.append("Cn0DbHz = ").append(gnssStatus.getCn0DbHz(i)).append(", "); builder.append("Elevation = ").append(gnssStatus.getElevationDegrees(i)).append(", "); builder.append("Azimuth = ").append(gnssStatus.getAzimuthDegrees(i)).append(", "); builder.append("hasEphemeris = ").append(gnssStatus.hasEphemerisData(i)).append(", "); builder.append("hasAlmanac = ").append(gnssStatus.hasAlmanacData(i)).append(", "); builder.append("usedInFix = ").append(gnssStatus.usedInFix(i)).append("\n"); } builder.append("]"); return builder.toString(); }
@RequiresApi(Build.VERSION_CODES.N) @Override protected void configureSensorSubscribeAndUnsubscribeBehaviors(FlowableEmitter<SensorRecord> subscriber) { final GnssStatus.Callback callback = initializeGnssStatusCallbackFor(subscriber); startListeningGnssStatusChanges(callback); addUnsubscribeCallbackFor(subscriber, callback); }
@RequiresApi(Build.VERSION_CODES.N) private GnssStatus.Callback initializeGnssStatusCallbackFor(final FlowableEmitter<SensorRecord> subscriber) { return new GnssStatus.Callback() { @Override public void onSatelliteStatusChanged(GnssStatus status) { subscriber.onNext(new RawGPSStatusRecord(status)); } }; }
@SuppressWarnings("MissingPermission") @RequiresApi(Build.VERSION_CODES.N) private void startListeningGnssStatusChanges(final GnssStatus.Callback callback) { // This is needed because location manager location updates need a looper Completable.create(new CompletableOnSubscribe() { @Override public void subscribe(CompletableEmitter e) throws Exception { checkRegistrationSuccess(locationManager.registerGnssStatusCallback(callback)); } }) .subscribeOn(AndroidSchedulers.mainThread()) .subscribe(); }
@RequiresApi(Build.VERSION_CODES.N) private void addUnsubscribeCallbackFor(FlowableEmitter<SensorRecord> subscriber, final GnssStatus.Callback callback) { subscriber.setCancellable(new Cancellable() { @Override public void cancel() throws Exception { locationManager.unregisterGnssStatusCallback(callback); } }); }
@Override public void onGnssStatusChanged(GnssStatus gnssStatus) {}
/** * Updates the pseudorange residual plot from residual results calculated by * {@link RealTimePositionVelocityCalculator} * * @param residuals An array of MAX_NUMBER_OF_SATELLITES elements where indexes of satellites was * not seen are fixed with {@code Double.NaN} and indexes of satellites what were seen * are filled with pseudorange residual in meters * @param timeInSeconds the time at which measurements are received */ protected void updatePseudorangeResidualTab(double[] residuals, double timeInSeconds) { double timeSinceLastMeasurement = timeInSeconds - mInitialTimeSeconds; for (int i = 1; i <= GpsNavigationMessageStore.MAX_NUMBER_OF_SATELLITES; i++) { if (!Double.isNaN(residuals[i - 1])) { mDataSetManager.addValue( PR_RESIDUAL_TAB, GnssStatus.CONSTELLATION_GPS, i, timeSinceLastMeasurement, residuals[i - 1]); } } mDataSetManager.fillInDiscontinuity(PR_RESIDUAL_TAB, timeSinceLastMeasurement); }
private String getConstellationPrefix(int constellationType) { if (constellationType <= GnssStatus.CONSTELLATION_UNKNOWN || constellationType > NUMBER_OF_CONSTELLATIONS) { return ""; } return CONSTELLATION_PREFIX[constellationType - 1]; }
@Override public void onSatelliteStatusChanged(GnssStatus status) { for (GnssListener logger : mLoggers) { logger.onGnssStatusChanged(status); } }
/** * Updates the CN0 versus Time plot data from a {@link GnssMeasurement} */ protected void updateCnoTab(GnssMeasurementsEvent event) { long timeInSeconds = TimeUnit.NANOSECONDS.toSeconds(event.getClock().getTimeNanos()); if (mInitialTimeSeconds < 0) { mInitialTimeSeconds = timeInSeconds; } // Building the texts message in analysis text view List<GnssMeasurement> measurements = sortByCarrierToNoiseRatio(new ArrayList<>(event.getMeasurements())); SpannableStringBuilder builder = new SpannableStringBuilder(); double currentAverage = 0; if (measurements.size() >= NUMBER_OF_STRONGEST_SATELLITES) { mAverageCn0 = (mAverageCn0 * mMeasurementCount + (measurements.get(0).getCn0DbHz() + measurements.get(1).getCn0DbHz() + measurements.get(2).getCn0DbHz() + measurements.get(3).getCn0DbHz()) / NUMBER_OF_STRONGEST_SATELLITES) / (++mMeasurementCount); currentAverage = (measurements.get(0).getCn0DbHz() + measurements.get(1).getCn0DbHz() + measurements.get(2).getCn0DbHz() + measurements.get(3).getCn0DbHz()) / NUMBER_OF_STRONGEST_SATELLITES; } builder.append(getString(R.string.history_average_hint, sDataFormat.format(mAverageCn0) + "\n")); builder.append(getString(R.string.current_average_hint, sDataFormat.format(currentAverage) + "\n")); for (int i = 0; i < NUMBER_OF_STRONGEST_SATELLITES && i < measurements.size(); i++) { int start = builder.length(); builder.append( mDataSetManager.getConstellationPrefix(measurements.get(i).getConstellationType()) + measurements.get(i).getSvid() + ": " + sDataFormat.format(measurements.get(i).getCn0DbHz()) + "\n"); int end = builder.length(); builder.setSpan( new ForegroundColorSpan( mColorMap.getColor( measurements.get(i).getSvid(), measurements.get(i).getConstellationType())), start, end, Spannable.SPAN_INCLUSIVE_EXCLUSIVE); } builder.append(getString(R.string.satellite_number_sum_hint, measurements.size())); mAnalysisView.setText(builder); // Adding incoming data into Dataset mLastTimeReceivedSeconds = timeInSeconds - mInitialTimeSeconds; for (GnssMeasurement measurement : measurements) { int constellationType = measurement.getConstellationType(); int svID = measurement.getSvid(); if (constellationType != GnssStatus.CONSTELLATION_UNKNOWN) { mDataSetManager.addValue( CN0_TAB, constellationType, svID, mLastTimeReceivedSeconds, measurement.getCn0DbHz()); } } mDataSetManager.fillInDiscontinuity(CN0_TAB, mLastTimeReceivedSeconds); // Checks if the plot has reached the end of frame and resize if (mLastTimeReceivedSeconds > mCurrentRenderer.getXAxisMax()) { mCurrentRenderer.setXAxisMax(mLastTimeReceivedSeconds); mCurrentRenderer.setXAxisMin(mLastTimeReceivedSeconds - TIME_INTERVAL_SECONDS); } mChartView.invalidate(); }
/** @see GnssStatus.Callback#onSatelliteStatusChanged(GnssStatus) */ void onGnssStatusChanged(GnssStatus gnssStatus);
@Override public void onGnssStatusChanged(GnssStatus gnssStatus) { logStatusEvent("onGnssStatusChanged: " + gnssStatusToString(gnssStatus)); }