W5_programowanie_sym_morskich_Wczytywanie danych z odbiornika GPS w standardzie NMEA-0183 biblioteki geodezyjne.pptx

khann1 12 views 11 slides May 11, 2024
Slide 1
Slide 1 of 11
Slide 1
1
Slide 2
2
Slide 3
3
Slide 4
4
Slide 5
5
Slide 6
6
Slide 7
7
Slide 8
8
Slide 9
9
Slide 10
10
Slide 11
11

About This Presentation

Simulators lectures


Slide Content

Programowanie Symulatorów Morskich Wykład 5 Wczytywanie danych z odbiornika GPS w standardzie NMEA-0183 biblioteki geod Marek Duczkowski Projekt współfinansowany ze środków Unii Europejskiej w ramach Europejskiego Funduszu Społecznego

Klasa Public Class NmeaInterpreter ' Processes information from the GPS receiver Public Function Parse( ByVal sentence As String) As Boolean ' Divide the sentence into words Dim Words() As String = GetWords (sentence) ' Look at the first word to decide where to go next Select Case Words(0) Case "$GPRMC" ' A "Recommended Minimum" sentence was found! ' Indicate that the sentence was recognized Return True Case Else ' Indicate that the sentence was not recognized Return False End Select End Function ' Divides a sentence into individual words Public Function GetWords ( ByVal sentence As String) As String() Return sentence.Split (","c) End Function End Class

Szukamy… $GPGSA,A,3,11,29,07,08,5,17,24,,,,,,2.3,1.2,2.0*30 2.3, 1.2, and 2.0, representing mean, horizontal and vertical DOP, respectively. This sentence represents a high-precision environment

C# using System; using System.Globalization ; public class NmeaInterpreter { // Represents the EN-US culture , used for numers in NMEA sentences public static CultureInfo NmeaCultureInfo = new CultureInfo (" en-US "); // Used to convert knots into miles per hour public static double MPHPerKnot = double.Parse ("1.150779", NmeaCultureInfo ); #region Delegates public delegate void PositionReceivedEventHandler ( string latitude , string longitude ); public delegate void DateTimeChangedEventHandler ( System.DateTime dateTime ); public delegate void BearingReceivedEventHandler (double bearing ); public delegate void SpeedReceivedEventHandler (double speed ); public delegate void SpeedLimitReachedEventHandler (); public delegate void FixObtainedEventHandler (); public delegate void FixLostEventHandler (); public delegate void SatelliteReceivedEventHandler ( int pseudoRandomCode , int azimuth , int elevation , int signalToNoiseRatio ); public delegate void HDOPReceivedEventHandler (double value ); public delegate void VDOPReceivedEventHandler (double value ); public delegate void PDOPReceivedEventHandler (double value ); # endregion #region Events public event PositionReceivedEventHandler PositionReceived ; public event DateTimeChangedEventHandler DateTimeChanged ; public event BearingReceivedEventHandler BearingReceived ; public event SpeedReceivedEventHandler SpeedReceived ; public event SpeedLimitReachedEventHandler SpeedLimitReached ; public event FixObtainedEventHandler FixObtained ; public event FixLostEventHandler FixLost ; public event SatelliteReceivedEventHandler SatelliteReceived ; public event HDOPReceivedEventHandler HDOPReceived ; public event VDOPReceivedEventHandler VDOPReceived ; public event PDOPReceivedEventHandler PDOPReceived ; # endregion

Obsługa przychodzących komunikatów // Processes information from the GPS receiver public bool Parse(string sentence) { // Discard the sentence if its checksum does not match our // calculated checksum if (! IsValid (sentence)) return false; // Look at the first word to decide where to go next switch ( GetWords (sentence)[0]) { case "$GPRMC": // A "Recommended Minimum" sentence was found! return ParseGPRMC (sentence); case "$GPGSV": // A "Satellites in View" sentence was received return ParseGPGSV (sentence); case "$GPGSA": return ParseGPGSA (sentence); default: // Indicate that the sentence was not recognized return false; } } // Divides a sentence into individual words public string[] GetWords (string sentence) { return sentence.Split (','); } // Interprets a $GPRMC message public bool ParseGPRMC (string sentence) { // Divide the sentence into words string[] Words = GetWords (sentence); // Do we have enough values to describe our location? if (Words[3] != "" && Words[4] != "" && Words[5] != "" && Words[6] != "") { // Yes. Extract latitude and longitude // Append hours string Latitude = Words[3].Substring(0, 2) + "°"; // Append minutes Latitude = Latitude + Words[3].Substring(2) + "\""; // Append hours Latitude = Latitude + Words[4]; // Append the hemisphere string Longitude = Words[5].Substring(0, 3) + "°"; // Append minutes Longitude = Longitude + Words[5].Substring(3) + "\""; // Append the hemisphere Longitude = Longitude + Words[6]; // Notify the calling application of the change if( PositionReceived != null) PositionReceived (Latitude, Longitude); }

Czas, data, kurs, pozycja // Do we have enough values to parse satellite-derived time? if (Words[1] != "") { // Yes. Extract hours, minutes, seconds and milliseconds int UtcHours = Convert.ToInt32(Words[1].Substring(0, 2)); int UtcMinutes = Convert.ToInt32(Words[1].Substring(2, 2)); int UtcSeconds = Convert.ToInt32(Words[1].Substring(4, 2)); int UtcMilliseconds = 0; // Extract milliseconds if it is available if (Words[1].Length > 7) { UtcMilliseconds = Convert.ToInt32( float.Parse (Words[1].Substring(6), NmeaCultureInfo ) * 1000); } // Now build a DateTime object with all values System.DateTime Today = System.DateTime.Now.ToUniversalTime (); System.DateTime SatelliteTime = new System.DateTime ( Today.Year , Today.Month , Today.Day , UtcHours , UtcMinutes , UtcSeconds , UtcMilliseconds ); // Notify of the new time, adjusted to the local time zone if( DateTimeChanged != null) DateTimeChanged ( SatelliteTime.ToLocalTime ()); } // Do we have enough information to extract the current speed? if (Words[7] != "") { // Yes. Parse the speed and convert it to MPH double Speed = double.Parse (Words[7], NmeaCultureInfo ) * MPHPerKnot ; // Notify of the new speed if( SpeedReceived != null) SpeedReceived (Speed);

cd // Are we over the highway speed limit? if (Speed > 55) if( SpeedLimitReached != null) SpeedLimitReached (); } // Do we have enough information to extract bearing? if (Words[8] != "") { // Indicate that the sentence was recognized double Bearing = double.Parse (Words[8], NmeaCultureInfo ); if( BearingReceived != null) BearingReceived (Bearing); } // Does the device currently have a satellite fix? if (Words[2] != "") { switch (Words[2]) { case "A": if( FixObtained != null) FixObtained (); break; case "V": if( FixLost != null) FixLost (); break; } } // Indicate that the sentence was recognized return true; }

Sat in view // Interprets a " Satellites in View " NMEA sentence public bool ParseGPGSV ( string sentence ) { int PseudoRandomCode = 0; int Azimuth = 0; int Elevation = 0; int SignalToNoiseRatio = 0; // Divide the sentence into words string [] Words = GetWords ( sentence ); // Each sentence contains four blocks of satellite information . // Read each block and report each satellite's information int Count = 0; for ( Count = 1; Count <= 4; Count ++) { // Does the sentence have enough words to analyze ? if (( Words.Length - 1) >= ( Count * 4 + 3)) { // Yes . Proceed with analyzing the block . // Does it contain any information ? if ( Words [ Count * 4] != "" && Words [ Count * 4 + 1] != "" && Words [ Count * 4 + 2] != "" && Words [ Count * 4 + 3] != "") { // Yes . Extract satellite information and report it PseudoRandomCode = System.Convert.ToInt32( Words [ Count * 4]); Elevation = Convert.ToInt32( Words [ Count * 4 + 1]); Azimuth = Convert.ToInt32( Words [ Count * 4 + 2]); SignalToNoiseRatio = Convert.ToInt32( Words [ Count * 4 + 3]); // Notify of this satellite's information if ( SatelliteReceived != null ) SatelliteReceived ( PseudoRandomCode , Azimuth , Elevation , SignalToNoiseRatio ); } } } // Indicate that the sentence was recognized return true ; }

interpreter // Interprets a " Fixed Satellites and DOP" NMEA sentence public bool ParseGPGSA ( string sentence ) { // Divide the sentence into words string [] Words = GetWords ( sentence ); // Update the DOP values if ( Words [15] != "") { if ( PDOPReceived != null ) PDOPReceived ( double.Parse ( Words [15], NmeaCultureInfo )); } if ( Words [16] != "") { if ( HDOPReceived != null ) HDOPReceived ( double.Parse ( Words [16], NmeaCultureInfo )); } if ( Words [17] != "") { if ( VDOPReceived != null ) VDOPReceived ( double.Parse ( Words [17], NmeaCultureInfo )); } return true ; } // Returns True if a sentence's checksum matches the // calculated checksum public bool IsValid ( string sentence ) { // Compare the characters after the asterisk to the calculation return sentence.Substring ( sentence.IndexOf ("*") + 1) == GetChecksum ( sentence ); } // Calculates the checksum for a sentence

walidator public string GetChecksum ( string sentence ) { // Loop through all chars to get a checksum int Checksum = 0; foreach (char Character in sentence ) { if ( Character == '$') { // Ignore the dollar sign } else if ( Character == '*') { // Stop processing before the asterisk break; } else { // Is this the first value for the checksum ? if ( Checksum == 0) { // Yes . Set the checksum to the value Checksum = Convert.ToByte ( Character ); } else { // No. XOR the checksum with this character's value Checksum = Checksum ^ Convert.ToByte ( Character ); } } } // Return the checksum formatted as a two-character hexadecimal return Checksum.ToString ("X2"); } }

Aplikacja wykonawcza public class HighPrecisionTest { private NmeaInterpreter MyInterpreter = new NmeaInterpreter (); private int MaximumDOPAllowed = 6; private double CurrentHDOP ; public HighPrecisionTest () { // Bind events for dilution of position MyInterpreter.HDOPReceived += new System.EventHandler ( OnHDOPReceived ); MyInterpreter.PositionReceived += new System.EventHandler ( OnPositionReceived ); } public void Test() { // Parse satellite information (HDOP is 50.0) MyInterpreter.Parse ( "$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05"); // Parse the current position MyInterpreter.Parse ( "$GPRMC,225233.990,V,3939.4000,N,10506.4000,W,0.00,51.40,280804,,*35"); // Parse satellite information (HDOP is 1.2) MyInterpreter.Parse ( "$GPGSA,A,3,11,29,07,08,19,28,26,,,,,,2.3,1.2,2.0*30"); // Parse the current position again MyInterpreter.Parse ( "$GPRMC,012558.584,A,3939.7000,N,10506.7000,W,0.00,198.07,290804,,*11"); } private void OnHDOPReceived (double value ) { // Remember the current HDOP value CurrentHDOP = value ; } private void OnPositionReceived ( string latitude , string longitude ) { // Is the HDOP at least six ? if ( CurrentHDOP <= MaximumDOPAllowed ) { // Yes . Display the current position Debug.WriteLine (" You are here : " + latitude + ", " + longitude ); } else { // No. Discard this positional measurement Debug.WriteLine (" The received location is not precise enough to use ."); } } }