/// <summary> /// Set any possible values for the given NMEA data. /// It will continue to replace /// the values so the last value is used as the final value. /// </summary> /// <param name="sentence">NMEA sentence containing data.</param> private void SetValues(NmeaSentence sentence) { /* * NMEA specification states that the first two letters of * a sentence may change. For example, for "$GPGSV" there may be variations such as * "$__GSV" where the first two letters change. As a result, we need only test the last three * characters. */ try { if (sentence.CommandWord.EndsWith("GGA", StringComparison.Ordinal)) { // Yes. Convert it using the fast pre-parseed constructor GPGGA = new GpggaSentence(sentence.Sentence); // Set the Lat and Lon and time } if (sentence.CommandWord.EndsWith("VTG", StringComparison.Ordinal)) { // Yes. Convert it using the fast pre-parseed constructor GPVTG = new GpvtgSentence(sentence.Sentence); } if (sentence.CommandWord.EndsWith("RMC", StringComparison.Ordinal)) { // Yes. Convert it using the fast pre-parseed constructor GPRMC = new GprmcSentence(sentence.Sentence); } if (sentence.CommandWord.EndsWith("RMF", StringComparison.Ordinal)) { // Yes. Convert it using the fast pre-parseed constructor PGRMF = new PgrmfSentence(sentence.Sentence); } if (sentence.CommandWord.EndsWith("GLL", StringComparison.Ordinal)) { // Yes. Convert it using the fast pre-parseed constructor GPGLL = new GpgllSentence(sentence.Sentence); } if (sentence.CommandWord.EndsWith("GSV", StringComparison.Ordinal)) { // Yes. Convert it using the fast pre-parseed constructor GPGSV = new GpgsvSentence(sentence.Sentence); } if (sentence.CommandWord.EndsWith("GSA", StringComparison.Ordinal)) { // Yes. Convert it using the fast pre-parseed constructor GPGSA = new GpgsaSentence(sentence.Sentence); } if (sentence.CommandWord.EndsWith("HDT", StringComparison.Ordinal)) { // Yes. Convert it using the fast pre-parseed constructor GPHDT = new GphdtSentence(sentence.Sentence); } } catch (Exception e) { log.Error("Error decoding a NMEA sentance.", e); } }
public void GpgsvSentenceFromString() { List <Satellite> sats = new List <Satellite> { new Satellite(2, new Azimuth(282.00), new Elevation(59.00), new SignalToNoiseRatio(0)), new Satellite(3, new Azimuth(287.00), new Elevation(42.00), new SignalToNoiseRatio(0)), new Satellite(6, new Azimuth(94.00), new Elevation(16.00), new SignalToNoiseRatio(0)), new Satellite(15, new Azimuth(90.00), new Elevation(80.00), new SignalToNoiseRatio(48)) }; GpgsvSentence sentence = new GpgsvSentence("$GPGSV,2,1,08,02,59,282,00,03,42,287,00,06,16,094,00,15,80,090,48*79"); Assert.AreEqual("$GPGSV,2,1,08,02,59,282,00,03,42,287,00,06,16,094,00,15,80,090,48*79", sentence.Sentence); Assert.AreEqual(2, sentence.TotalMessageCount); Assert.AreEqual(1, sentence.CurrentMessageNumber); Assert.AreEqual(8, sentence.SatellitesInView); Assert.AreEqual(sats.Count, sentence.Satellites.Count); for (int i = 0; i < sats.Count; i++) { Assert.AreEqual(sats[i], sentence.Satellites[i]); } }
/// <summary> /// Set any possible values for the given NMEA data. /// It will continue to replace /// the values so the last value is used as the final value. /// </summary> /// <param name="sentence">NMEA sentence containing data.</param> private void SetValues(NmeaSentence sentence) { /* * NMEA specification states that the first two letters of * a sentence may change. For example, for "$GPGSV" there may be variations such as * "$__GSV" where the first two letters change. As a result, we need only test the last three * characters. */ if (sentence.CommandWord.EndsWith("GGA", StringComparison.Ordinal)) { // Yes. Convert it using the fast pre-parseed constructor GPGGA = new GpggaSentence(sentence.Sentence); // Set the Lat and Lon and time } if (sentence.CommandWord.EndsWith("VTG", StringComparison.Ordinal)) { // Yes. Convert it using the fast pre-parseed constructor GPVTG = new GpvtgSentence(sentence.Sentence); } if (sentence.CommandWord.EndsWith("RMC", StringComparison.Ordinal)) { // Yes. Convert it using the fast pre-parseed constructor GPRMC = new GprmcSentence(sentence.Sentence); } if (sentence.CommandWord.EndsWith("RMF", StringComparison.Ordinal)) { // Yes. Convert it using the fast pre-parseed constructor PGRMF = new PgrmfSentence(sentence.Sentence); } if (sentence.CommandWord.EndsWith("GLL", StringComparison.Ordinal)) { // Yes. Convert it using the fast pre-parseed constructor GPGLL = new GpgllSentence(sentence.Sentence); } if (sentence.CommandWord.EndsWith("GSV", StringComparison.Ordinal)) { // Yes. Convert it using the fast pre-parseed constructor GPGSV = new GpgsvSentence(sentence.Sentence); } if (sentence.CommandWord.EndsWith("GSA", StringComparison.Ordinal)) { // Yes. Convert it using the fast pre-parseed constructor GPGSA = new GpgsaSentence(sentence.Sentence); } if (sentence.CommandWord.EndsWith("HDT", StringComparison.Ordinal)) { // Yes. Convert it using the fast pre-parseed constructor GPHDT = new GphdtSentence(sentence.Sentence); } }
/// <summary> /// Generates actual data to send to the client. /// </summary> /// <remarks>Data is sent according to the behavior of a typical GPS device: $GPGGA, /// $GPGSA, $GPRMC, $GPGSV sentences are sent every second, and a $GPGSV sentence /// is sent every five seconds. /// Developers who want to emulate a specific model of GPS device should override this /// method and generate the sentences specific to that device.</remarks> protected override void OnEmulation() { // Update real-time position, speed, bearing, etc. base.OnEmulation(); if (Route.Count == 0) { CurrentPosition = EmulateError(CurrentPosition); } /* NMEA devices will transmit "bursts" of NMEA sentences, followed by a one-second pause. * Other sentences (usually $GPGSV) are transmitted once every few seconds. This emulator, * by default, will transmit the most common NMEA sentences. */ // $GPGGA if (!_GpggaInterval.Equals(TimeSpan.Zero) // Has enough time elapsed to send the sentence? && UtcDateTime.Subtract(_GpggaLastSent) > _GpggaInterval) { // Get the tracked satellite count int trackedCount = 0; foreach (Satellite item in Satellites) { if (item.SignalToNoiseRatio.Value > 0) { trackedCount++; } } // Yes _GpggaLastSent = UtcDateTime; // Queue the sentence to the read buffer WriteSentenceToClient(new GpggaSentence(UtcDateTime.TimeOfDay, CurrentPosition, _FixQuality, trackedCount, _HorizontalDOP, Altitude, Distance.Empty, TimeSpan.Zero, -1)); } // $GPRMC if (!_GprmcInterval.Equals(TimeSpan.Zero) // Has enough time elapsed to send the sentence? && UtcDateTime.Subtract(_GprmcLastSent) > _GprmcInterval) { // Yes _GprmcLastSent = UtcDateTime; // Queue the sentence to the read buffer WriteSentenceToClient(new GprmcSentence(UtcDateTime, _FixStatus == FixStatus.Fix, CurrentPosition, Speed, Bearing, _MagneticVariation)); } // $GPGLL if (!_GpgllInterval.Equals(TimeSpan.Zero) // Has enough time elapsed to send the sentence? && UtcDateTime.Subtract(_GpgllLastSent) > _GpgllInterval) { // Yes _GpgllLastSent = UtcDateTime; // Write a $GPGLL to the client WriteSentenceToClient(new GpgllSentence(CurrentPosition, UtcDateTime.TimeOfDay, _FixStatus)); } // $GPGSA if (!_GpgsaInterval.Equals(TimeSpan.Zero) // Has enough time elapsed to send the sentence? && UtcDateTime.Subtract(_GpgsaLastSent) > _GpgsaInterval) { // Yes _GpgsaLastSent = UtcDateTime; // Queue the sentence to the read buffer WriteSentenceToClient(new GpgsaSentence(_FixMode, _FixMethod, Satellites, _MeanDOP, _HorizontalDOP, _VerticalDOP)); } // $GPGSV if (!_GpgsvInterval.Equals(TimeSpan.Zero) // Has enough time elapsed to send the sentence? && UtcDateTime.Subtract(_GpgsvLastSent) > _GpgsvInterval) { // Build a list of sentences from our satellites IList <GpgsvSentence> sentences = GpgsvSentence.FromSatellites(Satellites); // Yes _GpgsvLastSent = UtcDateTime; // Write each sentence to the read buffer foreach (GpgsvSentence gpgsv in sentences) { WriteSentenceToClient(gpgsv); } } // And signal that we have data (or not) if (ReadBuffer.Count == 0) { ReadDataAvailableWaitHandle.Reset(); } else { ReadDataAvailableWaitHandle.Set(); } }