Пример #1
0
        public void Parse(NmeaSentence sentence)
        {
            /* NMEA data is parsed in a specific order to maximize data quality and also to reduce latency
             * problems.  The date/time is processed first to minimize latency.  Then, dilution of precision
             * values are processed.  Finally, if precision is good enough to work with, remaining values are 
             * processed.
             */

            // Is this a fix method message?
            IFixMethodSentence fixMethodSentence = sentence as IFixMethodSentence;
            if (fixMethodSentence != null)
                SetFixMethod(fixMethodSentence.FixMethod);

            // Is this a fix quality message?
            IFixQualitySentence fixQualitySentence = sentence as IFixQualitySentence;
            if (fixQualitySentence != null)
                SetFixQuality(fixQualitySentence.FixQuality);

            #region Process common GPS information

            // If a fix is required, don't process time
            if (!IsFixRequired || (IsFixRequired && IsFixed))
            {
                // Does this sentence support the UTC date and time?
                IUtcDateTimeSentence dateTimeSentence = sentence as IUtcDateTimeSentence;
                if (dateTimeSentence != null)
                    SetDateTimes(dateTimeSentence.UtcDateTime);

                /* Some NMEA sentences provide UTC time information, but no date!  To make this work,
                 * we must combine the time report with the current UTC date.
                 */
                IUtcTimeSentence timeSentence = sentence as IUtcTimeSentence;
                if (timeSentence != null && !timeSentence.UtcTime.Equals(TimeSpan.MinValue) && !timeSentence.UtcTime.Equals(TimeSpan.Zero))
                    SetDateTimes(new DateTime(DateTime.UtcNow.Year, DateTime.UtcNow.Month, DateTime.UtcNow.Day,
                                        timeSentence.UtcTime.Hours, timeSentence.UtcTime.Minutes, timeSentence.UtcTime.Seconds, timeSentence.UtcTime.Milliseconds,
                                        DateTimeKind.Utc));
            }

            // Does this sentence support horizontal DOP?
            IHorizontalDilutionOfPrecisionSentence hdopSentence = sentence as IHorizontalDilutionOfPrecisionSentence;
            if (hdopSentence != null)
                SetHorizontalDilutionOfPrecision(hdopSentence.HorizontalDilutionOfPrecision);

            // Does the sentence support vertical DOP?
            IVerticalDilutionOfPrecisionSentence vdopSentence = sentence as IVerticalDilutionOfPrecisionSentence;
            if (vdopSentence != null)
                SetVerticalDilutionOfPrecision(vdopSentence.VerticalDilutionOfPrecision);

            // Does the sentence support mean DOP?
            IPositionDilutionOfPrecisionSentence mdopSentence = sentence as IPositionDilutionOfPrecisionSentence;
            if (mdopSentence != null)
                SetMeanDilutionOfPrecision(mdopSentence.PositionDilutionOfPrecision);

            #endregion

            // If a fix is required, don't process time
            if (!IsFixRequired || (IsFixRequired && IsFixed))
            {
                // Is precision good enough to work with?
                if (this.HorizontalDilutionOfPrecision.Value <= this.MaximumHorizontalDilutionOfPrecision.Value)
                {
                    #region Process real-time positional data

                    // Does this sentence support lat/long info?
                    IPositionSentence positionSentence = sentence as IPositionSentence;
                    if (positionSentence != null)
                        SetPosition(positionSentence.Position);

                    // Does this sentence support bearing?
                    IBearingSentence bearingSentence = sentence as IBearingSentence;
                    if (bearingSentence != null)
                        SetBearing(bearingSentence.Bearing);

                    // Does this sentence support speed?
                    ISpeedSentence speedSentence = sentence as ISpeedSentence;
                    if (speedSentence != null)
                        SetSpeed(speedSentence.Speed);

                    #endregion
                }

                // Is the vertical DOP low enough to be worth processing?
                if (this.VerticalDilutionOfPrecision.Value <= this.MaximumVerticalDilutionOfPrecision.Value)
                {
                    #region Process altitude data

                    // Does this sentence support altitude?
                    IAltitudeSentence altitudeSentence = sentence as IAltitudeSentence;
                    if (altitudeSentence != null)
                        SetAltitude(altitudeSentence.Altitude);

                    // Does this sentence support altitude?
                    IAltitudeAboveEllipsoidSentence altitudeAboveEllipsoidSentence = sentence as IAltitudeAboveEllipsoidSentence;
                    if (altitudeAboveEllipsoidSentence != null)
                        SetAltitude(altitudeAboveEllipsoidSentence.AltitudeAboveEllipsoid);

                    // Does this sentence support geoidal separation?
                    IGeoidalSeparationSentence geoidSeparationSentence = sentence as IGeoidalSeparationSentence;
                    if (geoidSeparationSentence != null)
                        SetGeoidalSeparation(geoidSeparationSentence.GeoidalSeparation);

                    #endregion
                }
            }

            #region Lower-priority information

            // Is this a fix mode sentence?
            IFixModeSentence fixModeSentence = sentence as IFixModeSentence;
            if (fixModeSentence != null)
                SetFixMode(fixModeSentence.FixMode);

            // Does this sentence have fix status?
            IFixStatusSentence fixedSentence = sentence as IFixStatusSentence;
            if (fixedSentence != null)
                SetFixStatus(fixedSentence.FixStatus);

            // Does this sentence support magnetic variation?
            IMagneticVariationSentence magVarSentence = sentence as IMagneticVariationSentence;
            if (magVarSentence != null)
                SetMagneticVariation(magVarSentence.MagneticVariation);

            // Process satellite data
            ISatelliteCollectionSentence satelliteSentence = sentence as ISatelliteCollectionSentence;
            if (satelliteSentence != null)
            {
                /* GPS.NET 2.0 performed thorough comparison of satellites in order to update
                 * an *existing* instance of Satellite objects.  I think now that this was overkill.
                 * For performance and limited memory use, satellites are just overwritten.
                 */
                AppendSatellites(satelliteSentence.Satellites);
            }

            // Fixed satellite count
            IFixedSatelliteCountSentence fixedCountSentence = sentence as IFixedSatelliteCountSentence;
            if (fixedCountSentence != null)
                SetFixedSatelliteCount(fixedCountSentence.FixedSatelliteCount);

            // Process fixed satellites
            IFixedSatellitesSentence fixedSatellitesSentence = sentence as IFixedSatellitesSentence;
            if (fixedSatellitesSentence != null)
            {
                SetFixedSatellites(fixedSatellitesSentence.FixedSatellites);
            }

            #endregion
        }
Пример #2
0
        protected void WriteSentenceToClient(NmeaSentence sentence)
        {
            // Get a byte array of the sentence
            byte[] sentenceBytes = sentence.ToByteArray();

            /* Some customers were found to make an emulator, but then not actually read from it. 
             * To prevent huge buffers, we will only write a sentence if the buffer can handle it.
             * Otherwise, we'll ignore it completely.
             */
            if (ReadBuffer.Count + sentenceBytes.Length + 2 > ReadBuffer.Capacity)
                return;

            // Add the bytes
            ReadBuffer.AddRange(sentenceBytes);

            // Add a CrLf
            ReadBuffer.Add(13);
            ReadBuffer.Add(10);
        }
Пример #3
0
        /// <summary>
        /// Process the valid NMEA sentence.  Check which 
        /// type of DVL message it is and create the data set.
        /// Then send the data set to the CurrentDataSetManager.
        /// </summary>
        /// <param name="sentence">Sentence to process.</param>
        private void ProcessSentence(NmeaSentence sentence)
        {
            // Check for PRTI01
            if (sentence.CommandWord.EndsWith(RTI.Prti01Sentence.CMD_WORD_PRTI01, StringComparison.Ordinal))
            {
                // Check if the previous PRTI01 was used
                // If it was not used, send the data
                if (_prti01 != null)
                {
                    SendData(_prti01);
                    _prti01 = null;
                }

                // Store the sentence to be combined with PRTI02
                _prti01 = new Prti01Sentence(sentence.Sentence, sentence.CommandWord, sentence.Words, sentence.ExistingChecksum);

            }
            // Check for PRTI02
            else if (sentence.CommandWord.EndsWith(RTI.Prti02Sentence.CMD_WORD_PRTI02, StringComparison.Ordinal))
            {
                Prti02Sentence prti02 = new Prti02Sentence(sentence.Sentence, sentence.CommandWord, sentence.Words, sentence.ExistingChecksum);

                // Check if the PRTI01 and PRTI02 match
                // If they match, combine and send
                // If they do not match, send PRTI02
                if (_prti01 != null && _prti01.SampleNumber == prti02.SampleNumber)
                {
                    SendData(_prti01, prti02, _prti30, _prti31);
                    _prti01 = null;
                }
                else
                {
                    SendData(prti02);
                }
            }
            // Check for PRTI03
            else if (sentence.CommandWord.EndsWith(RTI.Prti03Sentence.CMD_WORD_PRTI03, StringComparison.Ordinal))
            {
                // Store the sentence to be combined with PRTI02
                Prti03Sentence prti03 = new Prti03Sentence(sentence.Sentence, sentence.CommandWord, sentence.Words, sentence.ExistingChecksum);
                SendData(prti03);
            }
            // Check for PRTI30
            else if (sentence.CommandWord.EndsWith(RTI.Prti30Sentence.CMD_WORD_PRTI30, StringComparison.Ordinal))
            {
                // Store the sentence to be combined with PRTI01 and PRTI02
                _prti30 = new Prti30Sentence(sentence.Sentence, sentence.CommandWord, sentence.Words, sentence.ExistingChecksum);
            }
            // Check for PRTI31
            else if (sentence.CommandWord.EndsWith(RTI.Prti31Sentence.CMD_WORD_PRTI31, StringComparison.Ordinal))
            {
                // Store the sentence to be combined with PRTI01 and PRTI02
                _prti31 = new Prti31Sentence(sentence.Sentence, sentence.CommandWord, sentence.Words, sentence.ExistingChecksum);
            }
            else
            {
                // If the data was nether PRTI01 or PRTI02, then it must be GPS NMEA data and add it
                // to the NMEA buffer to be processed with a complete dataset
                AddNmeaData(sentence.Sentence + NMEA_END);
            }
        }
Пример #4
0
 protected void OnSentenceRecorded(NmeaSentence sentence)
 {
     if (SentenceRecorded != null)
         SentenceRecorded(this, new NmeaSentenceEventArgs(sentence));
 }
Пример #5
0
 /// <summary>
 /// Creates a new instance of the Nmea Sentence Resolver Event arguments class
 /// </summary>
 /// <param name="sentence">The sentence.</param>
 public NmeaSentenceResolverEventArgs(NmeaSentence sentence)
 {
     _sentence = sentence;
 }
Пример #6
0
        /// <summary>
        /// Find the first $. Then find the first start
        /// of a checksum.  Remove the string of a complete
        /// NMEA sentence and check if its a valid sentence.
        /// If it is valid, process the sentence.
        /// </summary>
        private void ProcessDataThread( )
        {
            while (_continue)
            {
                try
                {
                    // Block until awoken when data is received
                    // Timeout every 60 seconds to see if shutdown occured
                    _eventWaitData.WaitOne();

                    // If wakeup was called to kill thread
                    if (!_continue)
                    {
                        return;
                    }

                    // Ensure the data can contain NMEA sentences
                    while (_buffer.Length > 0 && _buffer.Contains("$") && _buffer.Contains("*"))
                    {

                        // Find a sentence in the buffer
                        string nmea = FindSentence();

                        // If one is found, process the data
                        if (nmea.Length > 0)
                        {
                            // Create a NMEA sentence and verify its valid
                            NmeaSentence sentence = new NmeaSentence(nmea);
                            if (sentence.IsValid)
                            {
                                // Process sentence
                                ProcessSentence(sentence);
                            }
                        }

                        // If wakeup was called to kill thread
                        if (!_continue)
                        {
                            return;
                        }
                    }
                }
                catch (ThreadAbortException)
                {
                    // Thread is aborted to stop processing
                    return;
                }
                catch (Exception e)
                {
                    log.Error("Error processing binary codec data.", e);
                    return;
                }

                // Send an event that processing is complete
                if (ProcessDataCompleteEvent != null)
                {
                    ProcessDataCompleteEvent();
                }
            }
        }
Пример #7
0
            /// <summary>
            /// Parse the string of all valid NMEA sentences.
            /// Store them to the array.
            /// </summary>
            /// <param name="nmeaStrings">String containing NMEA sentences.</param>
            private void SetNmeaStringArray(string nmeaStrings)
            {
                LinkedList<NmeaSentence> list = new LinkedList<NmeaSentence>();

                // Find the first $
                while(nmeaStrings.Contains("$") && nmeaStrings.Contains("*"))
                {
                    int start = nmeaStrings.IndexOf("$");
                    nmeaStrings = nmeaStrings.Substring(start);

                    // Check if a checksum exist in the data
                    // If so, being parsing
                    int checksumLoc = nmeaStrings.IndexOf("*");

                    string nmea = "";
                    // Find the start of the checksum
                    // Add NMEA_CHECKSUM_SIZE to include the * and checksum value
                    if (checksumLoc >= 0)
                    {
                        if (nmeaStrings.Length >= checksumLoc + NMEA_CHECKSUM_SIZE)
                        {
                            // Check if the checksum is good
                            if (!nmeaStrings.Substring(checksumLoc, NMEA_CHECKSUM_SIZE).Contains("$"))
                            {
                                // Get the NMEA string and remove it from the buffer.
                                nmea = nmeaStrings.Substring(0, checksumLoc + NMEA_CHECKSUM_SIZE);
                                nmeaStrings = nmeaStrings.Remove(0, nmea.Length);

                                // Remove any trailing new lines
                                nmea = nmea.TrimEnd(REMOVE_END);
                            }
                            else
                            {
                                // Bad Nmea string, $ within checksum
                                // Remove the bad string
                                nmeaStrings = nmeaStrings.Remove(0, checksumLoc);
                            }
                        }
                        else
                        {
                            nmeaStrings = nmeaStrings.Remove(0, checksumLoc);
                        }
                    }

                    if (nmea.Length > 0)
                    {
                        // Create a NMEA sentence and verify its valid
                        NmeaSentence sentence = new NmeaSentence(nmea);
                        if (sentence.IsValid)
                        {
                            // Add the nmea data to list
                            NmeaStrings.Add(sentence.Sentence);

                            // Set values from the NMEA data
                            SetValues(sentence);
                        }
                    }
                }

                // Store the Nmea data
                //NmeaStrings = new NmeaSentence[list.Count];
                //list.CopyTo(NmeaStrings, 0);
            }
Пример #8
0
            /// <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);
                }
            }
Пример #9
0
            /// <summary>
            /// Decode the NMEA sentence from the array.  Then add
            /// it to the list of NMEA sentences.  Set value will try
            /// to update the NMEA data with the latest information.
            /// </summary>
            /// <param name="nmeaSentences">All the NMEA setences.</param>
            private void DecodeNmeaData(List<string> nmeaSentences)
            {
                // Create a list of all the NMEA setences
                LinkedList<string> list = new LinkedList<string>();

                if (nmeaSentences != null)
                {
                    for (int x = 0; x < nmeaSentences.Count; x++)
                    {
                        // Create a NMEA sentence and verify its valid
                        NmeaSentence sentence = new NmeaSentence(nmeaSentences[x]);
                        if (sentence.IsValid)
                        {
                            // Set values from the NMEA data
                            SetValues(sentence);
                        }
                    }
                }
            }
Пример #10
0
            /// <summary>
            /// Decode the NMEA sentence from the array.  Then add
            /// it to the list of NMEA sentences.  Set value will try
            /// to update the NMEA data with the latest information.
            /// </summary>
            /// <param name="nmeaSentences">All the NMEA setences.</param>
            private void DecodeNmeaData(string[] nmeaSentences)
            {
                // Create a list of all the NMEA setences
                LinkedList<string> list = new LinkedList<string>();

                if (nmeaSentences != null)
                {
                    for (int x = 0; x < nmeaSentences.Length; x++)
                    {
                        // Create a NMEA sentence and verify its valid
                        NmeaSentence sentence = new NmeaSentence(nmeaSentences[x]);
                        if (sentence.IsValid)
                        {
                            // Add to the list
                            NmeaStrings.Add(sentence.Sentence);

                            // Set values from the NMEA data
                            SetValues(sentence);
                        }
                    }
                }

                // Copy the list to the NmeaStrings
                //NmeaStrings = new string[list.Count];
                //list.CopyTo(NmeaStrings, 0);
            }
Пример #11
0
 private void OnSentenceReceivedFromClient(NmeaSinkAndSource source, NmeaSentence sentence)
 {
     DispatchSentenceEvents(sentence);
 }
Пример #12
0
 private void ForwardDecoded(NmeaSinkAndSource source, NmeaSentence sentence)
 {
     DispatchSentenceEvents(sentence);
 }
Пример #13
0
 /// <inheritdoc />
 public override void SendSentence(NmeaSinkAndSource source, NmeaSentence sentence)
 {
 }