예제 #1
0
        private void PublishFix(GPSFix fix, NMEASentenceType fixSource)
        {
            if (fixSource == fixTriggerSentence)
            {
                if (haveGGA && haveRMC)
                {
                    // Output a combined fix if the partial fix is valid.
                    if ((partialFix != null) && (partialFix.UTCFixTime == fix.UTCFixTime) &&
                        (fixSource != partialFixSentenceType))
                    {
                        GPSFix fixRMC = fixSource == NMEASentenceType.RMC ? fix : partialFix;
                        GPSFix fixGGA = fixSource == NMEASentenceType.GGA ? fix : partialFix;

                        m_MostRecentGPSFix = fixGGA;
                        m_MostRecentGPSFix.HeadingRadians = fixRMC.HeadingRadians;
                        m_MostRecentGPSFix.SpeedEast      = fixRMC.SpeedEast;
                        m_MostRecentGPSFix.SpeedNorth     = fixRMC.SpeedNorth;

                        // Still need to calculate vertical speed. Sigh.
                        CalculateSpeedAndHeading(m_MostRecentGPSFix, true);
                    }
                    partialFix             = null;
                    partialFixSentenceType = NMEASentenceType.Unknown;
                }
                else if (fixSource == NMEASentenceType.GGA)
                {
                    // Don't have speed information, so calculate it.
                    m_MostRecentGPSFix = fix;
                    CalculateSpeedAndHeading(m_MostRecentGPSFix, false);
                }
                else if (fixSource == NMEASentenceType.RMC)
                {
                    // Publish the fix as is.
                    m_MostRecentGPSFix = fix;
                }
            }
            else
            {
                // Save the fix until we hit the trigger sentence.
                partialFix             = fix;
                partialFixSentenceType = fixSource;
            }
        }
예제 #2
0
        public void Reset()
        {
            readBuffer = "";

            partialFix             = null;
            partialFixSentenceType = NMEASentenceType.Unknown;
            haveGGA            = false;
            haveRMC            = false;
            lastGGATimestamp   = new DateTime(0);
            lastRMCTimestamp   = new DateTime(0);
            fixTriggerSentence = NMEASentenceType.Unknown;

            savedFix           = null;
            m_MostRecentGPSFix = null;

            gsaData = null;

            partialSatelliteVehicles      = null;
            partialSatelliteVehicleIndex  = 0;
            m_MostRecentSatelliteVehicles = null;

            lastGSVMessageNumber = 0;
        }
		private void PublishFix(GPSFix fix, NMEASentenceType fixSource)
		{
			if (fixSource == fixTriggerSentence) 
			{
				if (haveGGA && haveRMC) 
				{
					// Output a combined fix if the partial fix is valid.
					if ((partialFix != null) && (partialFix.UTCFixTime == fix.UTCFixTime) &&
						(fixSource != partialFixSentenceType))
					{
						GPSFix fixRMC = fixSource == NMEASentenceType.RMC ? fix : partialFix;
						GPSFix fixGGA = fixSource == NMEASentenceType.GGA ? fix : partialFix;

						m_MostRecentGPSFix = fixGGA;
						m_MostRecentGPSFix.HeadingRadians = fixRMC.HeadingRadians;
						m_MostRecentGPSFix.SpeedEast = fixRMC.SpeedEast;
						m_MostRecentGPSFix.SpeedNorth = fixRMC.SpeedNorth;

						// Still need to calculate vertical speed. Sigh.
						CalculateSpeedAndHeading(m_MostRecentGPSFix, true);
					}
					partialFix = null;
					partialFixSentenceType = NMEASentenceType.Unknown;
				}
				else if (fixSource == NMEASentenceType.GGA)
				{
					// Don't have speed information, so calculate it.
					m_MostRecentGPSFix = fix;
					CalculateSpeedAndHeading(m_MostRecentGPSFix, false);
				}
				else if (fixSource == NMEASentenceType.RMC) 
				{
					// Publish the fix as is.
					m_MostRecentGPSFix = fix;
				}
			}
			else
			{
				// Save the fix until we hit the trigger sentence.
				partialFix = fix;
				partialFixSentenceType = fixSource;
			}
		}
		public void ProcessReceivedData(byte[] rawData)
		{
			const string hexChars = "0123456789ABCDEF";

			// Add the data to the read buffer.
			Encoding ascii = Encoding.ASCII; 
			readBuffer += ascii.GetString(rawData, 0, rawData.Length).ToUpper();

			// Process received lines. The last entry in the array (which may be an empty string)
			// is always an incomplete line as it wasn't followed by a "\n". Therefore it needs
			// to go back into the read buffer.
			string[] lines = readBuffer.Split(new char[] {'\n'});
			readBuffer = lines[lines.Length - 1];
			int i;
			for (i = 0; i < lines.Length - 1; i++)
			{
				// Split the checksum off from the line. If we don't find one, ignore the line.
				int hi, lo;
				string[] elements = lines[i].Trim().Split(new char[] {'*'});
				if ((elements.Length == 2) && elements[0].StartsWith("$") && (elements[1].Length == 2) &&
					((hi = hexChars.IndexOf(elements[1][0])) >= 0) &&
					((lo = hexChars.IndexOf(elements[1][1])) >= 0))
				{
					// Verify the checksum.
					byte checksum = (byte)(hi << 4 | lo);
					byte c = 0;
					int j;
					for (j = 1; j < elements[0].Length; j++)
						c ^= (byte)elements[0][j];
					if (c == checksum) 
					{
						// Valid NMEA sentence. Split it into its components and process it after
						// removing the leading '$'. There will always be at least one part, even
						// if it is empty.
						string[] parts = elements[0].Remove(0, 1).Split(new char[] {','});

						// Decide whether to use GGA or RMC sentences, or both.
						if (fixTriggerSentence == NMEASentenceType.Unknown) 
						{
							if (parts[0] == "GPGGA") 
							{
								haveGGA = true;
								if (! haveRMC && (lastGGATimestamp.Ticks != 0)) 
								{
									// This is the second GGA fix we have seen without an intervening RMC fix.
									// Assume no RMC packets.
									fixTriggerSentence = NMEASentenceType.GGA;
								}
								lastGGATimestamp = ParseNMEATimestamp(parts.Length > 0 ? parts[1] : "");
								if (haveRMC)
								{
									if (lastRMCTimestamp == lastGGATimestamp)
										fixTriggerSentence = NMEASentenceType.GGA;
									else
										fixTriggerSentence = NMEASentenceType.RMC;
								}
							}
							else if (parts[0] == "GPRMC")
							{
								haveRMC = true;
								if (! haveGGA && (lastRMCTimestamp.Ticks != 0)) 
								{
									// This is the second RMC fix we have seen without an intervening GGA fix.
									// Assume no GGA packets.
									fixTriggerSentence = NMEASentenceType.RMC;
								}
								lastRMCTimestamp = ParseNMEATimestamp(parts.Length > 0 ? parts[1] : "");
								if (haveGGA)
								{
									if (lastGGATimestamp == lastRMCTimestamp)
										fixTriggerSentence = NMEASentenceType.RMC;
									else
										fixTriggerSentence = NMEASentenceType.GGA;
								}
							}
						}

						// Process specific sentence types.
						switch (parts[0])
						{
							case "GPGGA":
								ProcessGGA(parts);
								break;

							case "GPGSA":
								ProcessGSA(parts);
								break;

							case "GPGSV":
								ProcessGSV(parts);
								break;

							case "GPRMC":
								ProcessRMC(parts);
								break;
						}
					}
				}
			}
		}
		public void Reset()
		{
			readBuffer = "";

			partialFix = null;
			partialFixSentenceType = NMEASentenceType.Unknown;
			haveGGA = false;
			haveRMC = false;
			lastGGATimestamp = new DateTime(0);
			lastRMCTimestamp = new DateTime(0);
			fixTriggerSentence = NMEASentenceType.Unknown;

			savedFix = null;
			m_MostRecentGPSFix = null;

			gsaData = null;

			partialSatelliteVehicles = null;
			partialSatelliteVehicleIndex = 0;
			m_MostRecentSatelliteVehicles = null;

			lastGSVMessageNumber = 0;
		}
예제 #6
0
        public void ProcessReceivedData(byte[] rawData)
        {
            const string hexChars = "0123456789ABCDEF";

            // Add the data to the read buffer.
            Encoding ascii = Encoding.ASCII;

            readBuffer += ascii.GetString(rawData, 0, rawData.Length).ToUpper();

            // Process received lines. The last entry in the array (which may be an empty string)
            // is always an incomplete line as it wasn't followed by a "\n". Therefore it needs
            // to go back into the read buffer.
            string[] lines = readBuffer.Split(new char[] { '\n' });
            readBuffer = lines[lines.Length - 1];
            int i;

            for (i = 0; i < lines.Length - 1; i++)
            {
                // Split the checksum off from the line. If we don't find one, ignore the line.
                int      hi, lo;
                string[] elements = lines[i].Trim().Split(new char[] { '*' });
                if ((elements.Length == 2) && elements[0].StartsWith("$") && (elements[1].Length == 2) &&
                    ((hi = hexChars.IndexOf(elements[1][0])) >= 0) &&
                    ((lo = hexChars.IndexOf(elements[1][1])) >= 0))
                {
                    // Verify the checksum.
                    byte checksum = (byte)(hi << 4 | lo);
                    byte c        = 0;
                    int  j;
                    for (j = 1; j < elements[0].Length; j++)
                    {
                        c ^= (byte)elements[0][j];
                    }
                    if (c == checksum)
                    {
                        // Valid NMEA sentence. Split it into its components and process it after
                        // removing the leading '$'. There will always be at least one part, even
                        // if it is empty.
                        string[] parts = elements[0].Remove(0, 1).Split(new char[] { ',' });

                        // Decide whether to use GGA or RMC sentences, or both.
                        if (fixTriggerSentence == NMEASentenceType.Unknown)
                        {
                            if (parts[0] == "GPGGA")
                            {
                                haveGGA = true;
                                if (!haveRMC && (lastGGATimestamp.Ticks != 0))
                                {
                                    // This is the second GGA fix we have seen without an intervening RMC fix.
                                    // Assume no RMC packets.
                                    fixTriggerSentence = NMEASentenceType.GGA;
                                }
                                lastGGATimestamp = ParseNMEATimestamp(parts.Length > 0 ? parts[1] : "");
                                if (haveRMC)
                                {
                                    if (lastRMCTimestamp == lastGGATimestamp)
                                    {
                                        fixTriggerSentence = NMEASentenceType.GGA;
                                    }
                                    else
                                    {
                                        fixTriggerSentence = NMEASentenceType.RMC;
                                    }
                                }
                            }
                            else if (parts[0] == "GPRMC")
                            {
                                haveRMC = true;
                                if (!haveGGA && (lastRMCTimestamp.Ticks != 0))
                                {
                                    // This is the second RMC fix we have seen without an intervening GGA fix.
                                    // Assume no GGA packets.
                                    fixTriggerSentence = NMEASentenceType.RMC;
                                }
                                lastRMCTimestamp = ParseNMEATimestamp(parts.Length > 0 ? parts[1] : "");
                                if (haveGGA)
                                {
                                    if (lastGGATimestamp == lastRMCTimestamp)
                                    {
                                        fixTriggerSentence = NMEASentenceType.RMC;
                                    }
                                    else
                                    {
                                        fixTriggerSentence = NMEASentenceType.GGA;
                                    }
                                }
                            }
                        }

                        // Process specific sentence types.
                        switch (parts[0])
                        {
                        case "GPGGA":
                            ProcessGGA(parts);
                            break;

                        case "GPGSA":
                            ProcessGSA(parts);
                            break;

                        case "GPGSV":
                            ProcessGSV(parts);
                            break;

                        case "GPRMC":
                            ProcessRMC(parts);
                            break;
                        }
                    }
                }
            }
        }