@Override public void onGnssMeasurementsReceived(GnssMeasurementsEvent event) { synchronized (mFileLock) { if (mFileWriter == null) { return; } GnssClock gnssClock = event.getClock(); for (GnssMeasurement measurement : event.getMeasurements()) { try { writeGnssMeasurementToFile(gnssClock, measurement); } catch (IOException e) { logException(ERROR_WRITING_FILE, e); } } } }
@RequiresApi(Build.VERSION_CODES.N) @Override protected void configureSensorSubscribeAndUnsubscribeBehaviors(FlowableEmitter<SensorRecord> subscriber) { final GnssMeasurementsEvent.Callback callback = initializeGnssMeasurementsCallbackFor(subscriber); startListeningGnssMeasurementsEventsChanges(callback); addUnsubscribeCallbackFor(subscriber, callback); }
@RequiresApi(Build.VERSION_CODES.N) private GnssMeasurementsEvent.Callback initializeGnssMeasurementsCallbackFor(final FlowableEmitter<SensorRecord> subscriber) { return new GnssMeasurementsEvent.Callback() { @Override public void onGnssMeasurementsReceived(GnssMeasurementsEvent event) { subscriber.onNext(new RawGPSMeasurementsRecord(event)); } }; }
@SuppressWarnings("MissingPermission") @RequiresApi(Build.VERSION_CODES.N) private void startListeningGnssMeasurementsEventsChanges(final GnssMeasurementsEvent.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.registerGnssMeasurementsCallback(callback)); } }) .subscribeOn(AndroidSchedulers.mainThread()) .subscribe(); }
@RequiresApi(Build.VERSION_CODES.N) private void addUnsubscribeCallbackFor(FlowableEmitter<SensorRecord> subscriber, final GnssMeasurementsEvent.Callback callback) { subscriber.setCancellable(new Cancellable() { @Override public void cancel() throws Exception { locationManager.unregisterGnssMeasurementsCallback(callback); } }); }
@Override public void onGnssMeasurementsReceived(GnssMeasurementsEvent event) { if (mLogMeasurements) { for (GnssListener logger : mLoggers) { logger.onGnssMeasurementsReceived(event); } } }
@Override public void onGnssMeasurementsReceived(GnssMeasurementsEvent event) { StringBuilder builder = new StringBuilder("[ GnssMeasurementsEvent:\n\n"); builder.append(toStringClock(event.getClock())); builder.append("\n"); for (GnssMeasurement measurement : event.getMeasurements()) { builder.append(toStringMeasurement(measurement)); builder.append("\n"); } builder.append("]"); logMeasurementEvent("onGnsssMeasurementsReceived: " + builder.toString()); }
private String gnssMeasurementsStatusToString(int status) { switch (status) { case GnssMeasurementsEvent.Callback.STATUS_NOT_SUPPORTED: return "NOT_SUPPORTED"; case GnssMeasurementsEvent.Callback.STATUS_READY: return "READY"; case GnssMeasurementsEvent.Callback.STATUS_LOCATION_DISABLED: return "GNSS_LOCATION_DISABLED"; default: return "<Unknown>"; } }
@RequiresApi(api = Build.VERSION_CODES.N) public RawGPSMeasurementsRecord(GnssMeasurementsEvent event) { super(new RecordInfo(event.getClock().getTimeNanos())); Collection<GnssMeasurement> measurements = event.getMeasurements(); this.satelliteCount = measurements.size(); this.svids = new int[satelliteCount]; this.constellations = new int[satelliteCount]; this.timeOffsets = new double[satelliteCount]; this.stateCodes = new int[satelliteCount]; this.svTimes = new long[satelliteCount]; this.svTimeUncerts = new long[satelliteCount]; this.cn0DbHzs = new double[satelliteCount]; this.pseudoranges = new double[satelliteCount]; this.pseudorangeUncerts = new double[satelliteCount]; this.deltaStates = new int[satelliteCount]; this.deltas = new double[satelliteCount]; this.deltaUncerts = new double[satelliteCount]; this.multipaths = new int[satelliteCount]; Iterator<GnssMeasurement> it = measurements.iterator(); int i = 0; while (it.hasNext()) { GnssMeasurement measurement = it.next(); svids[i] = measurement.getSvid(); constellations[i] = measurement.getConstellationType(); timeOffsets[i] = measurement.getTimeOffsetNanos(); stateCodes[i] = measurement.getState(); svTimes[i] = measurement.getReceivedSvTimeNanos(); svTimeUncerts[i] = measurement.getReceivedSvTimeUncertaintyNanos(); cn0DbHzs[i] = measurement.getCn0DbHz(); pseudoranges[i] = measurement.getPseudorangeRateMetersPerSecond(); pseudorangeUncerts[i] = measurement.getPseudorangeRateUncertaintyMetersPerSecond(); deltaStates[i] = measurement.getAccumulatedDeltaRangeState(); deltas[i] = measurement.getAccumulatedDeltaRangeMeters(); deltaUncerts[i] = measurement.getAccumulatedDeltaRangeUncertaintyMeters(); multipaths[i] = measurement.getMultipathIndicator(); i++; } }
@Override public void onGnssMeasurementsReceived(GnssMeasurementsEvent event) {}
/** * 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(); }
@Override public void onGnssMeasurementsReceived(final GnssMeasurementsEvent event) { mAllowShowingRawResults = true; final Runnable r = new Runnable() { @Override public void run() { mMainActivity.runOnUiThread( new Runnable() { @Override public void run() { mPlotFragment.updateCnoTab(event); } }); if (mPseudorangePositionVelocityFromRealTimeEvents == null) { return; } try { if (mResidualPlotStatus != RESIDUAL_MODE_DISABLED && mResidualPlotStatus != RESIDUAL_MODE_AT_INPUT_LOCATION) { // The position at last epoch is used for the residual analysis. // This is happening by updating the ground truth for pseudorange before using the // new arriving pseudoranges to compute a new position. mPseudorangePositionVelocityFromRealTimeEvents .setCorrectedResidualComputationTruthLocationLla(mGroundTruth); } mPseudorangePositionVelocityFromRealTimeEvents .computePositionVelocitySolutionsFromRawMeas(event); // Running on main thread instead of in parallel will improve the thread safety if (mResidualPlotStatus != RESIDUAL_MODE_DISABLED) { mMainActivity.runOnUiThread( new Runnable() { @Override public void run() { mPlotFragment.updatePseudorangeResidualTab( mPseudorangePositionVelocityFromRealTimeEvents .getPseudorangeResidualsMeters(), TimeUnit.NANOSECONDS.toSeconds( event.getClock().getTimeNanos())); } } ); } else { mMainActivity.runOnUiThread( new Runnable() { @Override public void run() { // Here we create gaps when the residual plot is disabled mPlotFragment.updatePseudorangeResidualTab( GpsMathOperations.createAndFillArray( GpsNavigationMessageStore.MAX_NUMBER_OF_SATELLITES, Double.NaN), TimeUnit.NANOSECONDS.toSeconds( event.getClock().getTimeNanos())); } } ); } } catch (Exception e) { e.printStackTrace(); } } }; mMyPositionVelocityCalculationHandler.post(r); }
/** * @see GnssMeasurementsEvent.Callback# * onGnssMeasurementsReceived(GnssMeasurementsEvent) */ void onGnssMeasurementsReceived(GnssMeasurementsEvent event);