public static Decoded Parse(Sentence sentence) { // $GPVTG,<1>,T,<3>,M,<5>,N,<7>,K*<CS><CR><LF> // 0) Sentence Id // 1) True course over ground, 000 to 359 degrees. // 2) T for true course // 3) Magnetic course over ground, 000 to 359 degrees. // 4) M for magnetic course // 5) horizontal speed over ground, 00.0 to 999.9 knots. // 6) N for knots // 7) Speed over ground, 00.0 to 1851.8 ko/hr. // 8) K for km/p // *<CS>) Checksum. // <CR><LF>) Sentence terminator if (sentence.Id != "$GPVTG") { return null; } if (sentence.Parts.Length != 9) { return null; } double trueCourse; if (!double.TryParse(sentence.Parts[1], out trueCourse)) { trueCourse = double.NaN; } double magneticCourse; double.TryParse(sentence.Parts[3], out magneticCourse); double speedInKnots; double.TryParse(sentence.Parts[5], out speedInKnots); return new Decoded(trueCourse, magneticCourse, new Speed(speedInKnots, SpeedUnit.NauticalMilesPerHour)); }
public Message Parse(Sentence sentence) { if (sentence == null) { return null; } int decoderIndex = 0; object decoded = null; for (; decoderIndex < _decoders.Count; decoderIndex++) { var decoder = _decoders[decoderIndex]; decoded = decoder(sentence); if (decoded != null) { //automatically reorder decoders so that the most used decoders are first in the list for (int i = decoderIndex; i > 0; i--) { _decoders[i] = _decoders[i - 1]; } _decoders[0] = decoder; break; } } if (decoded == null) { //decode failed? // Debugger.Break(); return null; } return new Message(sentence, decoded); }
public static Decoded Parse(Sentence sentence) { // $GPGLL,<1>,<2>,<3>,<4>,<5>,<6>,<7>*<CS><CR><LF> // 0) Sentence Id // 1) Latitude, ddmm.mmmm format. // 2) Latitude hemisphere, N or S. // 3) Longitude, dddmT1.mmmm format. // 4) Longitude hemisphere, E or W. // 5) UTC time of position fix, hhmmss format. // 6) Status, A = data active or V = data void. // *<CS>) Checksum. // <CR><LF>) Sentence terminator if (sentence.Id != "$GPGLL") { return null; } if (sentence.Parts.Length != 6) { return null; } if (sentence.Parts[6] != "A") { return null; } var latitude = SentenceHelper.ParseLatitude(sentence.Parts[1], sentence.Parts[2]); var longitude = SentenceHelper.ParseLongitude(sentence.Parts[3], sentence.Parts[4]); var fixTime = NmeaClock.GetTime() .Date; fixTime += SentenceHelper.ParseUtcTime(sentence.Parts[5]); return new Decoded(new GeoPosition(latitude, longitude), fixTime); }
// DeviceInfoRequest - "$PLTIT,RQ,ID\r\n" // DeviceInfoResponse - "$PLTIT,ID,{model},{version}*{check}\r\n" // $ID,{model},{version},{date}*{check}\r\n public static DeviceInfo Parse(Sentence sentence) { if (sentence.Parts[0] == "$PLTIT" && sentence.Parts[1] == "ID") { return new DeviceInfo(sentence.Parts[2], sentence.Parts[3]); } if (sentence.Parts[0] == "$ID") { return new DeviceInfo(sentence.Parts[1], sentence.Parts[2], sentence.Parts[3]); } return null; }
// there will be 2 HV sentences then the ML sentence // "$PLTIT,ML,{hValue},{hUnits: F,Y,M},{azValue},{azUnits: D},{incValue},{incUnits: D},{sdValue},{sdUnits: F,Y,M}*{check}" // 0 1 2 3 public static MissingLine ParseMissing(Sentence sentence) { if (sentence.Parts[0] != "$PLTIT") { return null; } if (sentence.Parts[1] != "ML") { return null; } GeoVector missing = ParseVector(sentence); return new MissingLine(null, null, missing); }
// "$PLTIT,HV,{hValue},{hUnits: F,Y,M},{azValue},{azUnits: D},{incValue},{incUnits: D},{sdValue},{sdUnits: F,Y,M}*{check}" // 0 1 2 3 4 5 6 7 8 9 public static GeoVector ParseDirect(Sentence sentence) { if (sentence.Parts[0] != "$PLTIT") { return null; } if (sentence.Parts[1] != "HV") { return null; } GeoVector direct = ParseVector(sentence); return direct; }
// "$PLTIT,HT,{htValue},{htUnits: F,Y,M},*{check}" public static Length Parse(Sentence sentence) { if (sentence.Parts[0] != "$PLTIT") { return null; } if (sentence.Parts[1] != "HT") { return null; } // todo high-res check Length height = new Length(double.Parse(sentence.Parts[2]), LengthUnit.Foot); return height; }
public static Decoded Parse(Sentence sentence) { // $GPRMC,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,<10>,<11>*<CS><CR><LF> // 0) Sentence Id // 1) UTC time of position fix, hhmmss.sss format. // 2) Status, A = data valid, V = data not valid. // 3) Latitude, ddmm.mmmm format. // 4) Latitude hemisphere, N or S. // 5) Longitude, dddmmm.mmmm format. // 6) Longitude hemisphere, E or W. // 7) Speed over ground, 0.0 to 1851.8 knots. // 8) Course over ground, 000.0 to 359.9 degrees, true. // 9) UTC Date, ddmmyy format. // 10) Magnetic variation, 000.0 to 180.O degrees // 11) Magnetic variation, E = East, W = West // 12) (Optional) Fix mode indicator , A=autonomous, D=differential, E=Estimated, N=not valid, S=Simulator // *<CS>) Checksum. // <CR><LF>) Sentence terminator if (sentence.Id != "$GPRMC") { return null; } if (sentence.Parts.Length != 12 && sentence.Parts.Length != 13) { return null; } if (sentence.Parts[2] != "A") { return null; } DateTime fixTime = SentenceHelper.ParseUtcDate(sentence.Parts[9]) + SentenceHelper.ParseUtcTime(sentence.Parts[1]); Latitude latitude = SentenceHelper.ParseLatitude(sentence.Parts[3], sentence.Parts[4]); Longitude longitude = SentenceHelper.ParseLongitude(sentence.Parts[5], sentence.Parts[6]); double speed, heading; double.TryParse(sentence.Parts[7], out speed); if (!double.TryParse(sentence.Parts[8], out heading)) { heading = double.NaN; } //todo: magnetic variation if (sentence.Parts.Length == 13) { if (sentence.Parts[12] != "A" && sentence.Parts[12] != "D") { return null; } } return new Decoded(new GeoPosition(latitude, longitude), fixTime, heading, new Speed(speed, SpeedUnit.NauticalMilesPerHour)); }
public static Decoded Parse(Sentence sentence) { // $GPGSV,<1>,<2>,<3>,<4>,<5>,<6>,<7>, ... ,<4>,<5>,<6>,<7>*<CS><CR><LF> // 0) Sentence Id // 1) Total number of GSV sentences to be transmitted, 1-3. // 2) Sequence number of message, 1-3. // 3) Total number of satellites in view, 00 to 12. // 4) Satellite PRN number, 01 to 32. // 5) Satellite elevation, 00 to 90 degrees. // 6) Satellite azimuth, 000 to 359 degrees, true. // 7) Signal to noise ration in dBHZ (0-99), null when not tracking. // *<CS>) Checksum. // <CR><LF>) Sentence terminator // // NOTE: Items <4>,<5>,<6> and <7> repeat for each satellite in view to a maximum // of four (4) satellites per sentence. Additional satellites in view information // must be sent in subsequent sentences. These fields will be null if unused. if (sentence.Id != "$GPGSV") { return null; } if (sentence.Parts.Length != 20) { return null; } int sequenceCount, sequenceId, numberOfSatellites; int.TryParse(sentence.Parts[1], out sequenceCount); int.TryParse(sentence.Parts[2], out sequenceId); int.TryParse(sentence.Parts[3], out numberOfSatellites); SatelliteInfo[] satelliteInfos = new SatelliteInfo[4]; for (int i = 0; i < 4; i++) { int prn, elevation, azimuth; double signalToNoise; int.TryParse(sentence.Parts[4 * i + 4], out prn); int.TryParse(sentence.Parts[4 * i + 5], out elevation); int.TryParse(sentence.Parts[4 * i + 6], out azimuth); double.TryParse(sentence.Parts[4 * i + 7], out signalToNoise); //todo use sequence id for start offset satelliteInfos[i] = new SatelliteInfo(prn, elevation, azimuth, signalToNoise); } return new Decoded(satelliteInfos); }
private static GeoVector ParseVector(Sentence sentence) { bool highQuality = true; //horizontal distance Length horizontal = null; string measurement = sentence.Parts[2]; if (!string.IsNullOrEmpty(measurement)) { highQuality = measurement.EndsWith("0"); measurement = measurement.Substring(0, measurement.Length - 1); LengthUnit units = GetLengthUnit(sentence.Parts[3]); horizontal = new Length(double.Parse(measurement), units); } //azimuth angle Angle azimuth = null; measurement = sentence.Parts[4]; if (!string.IsNullOrEmpty(measurement)) { measurement = measurement.Substring(0, measurement.Length - 1); AngleUnit units = GetAngleUnit(sentence.Parts[5]); azimuth = new Angle(double.Parse(measurement), units); } //inclination angle Angle inclination = null; measurement = sentence.Parts[6]; if (!string.IsNullOrEmpty(measurement)) { measurement = measurement.Substring(0, measurement.Length - 1); AngleUnit units = GetAngleUnit(sentence.Parts[7]); inclination = new Angle(double.Parse(measurement), units); } //slope distance Length slope = null; measurement = sentence.Parts[8]; if (!string.IsNullOrEmpty(measurement)) { measurement = measurement.Substring(0, measurement.Length - 1); LengthUnit units = GetLengthUnit(sentence.Parts[9]); slope = new Length(double.Parse(measurement), units); } return new GeoVector(horizontal, azimuth, inclination, slope, highQuality); }
public static Decoded Parse(Sentence sentence) { // $GPGGA,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,M,<11>,M,<13>,<14>*<CS><CR><LF> // 0) Sentence Id // 1) UTC time of position fix, hhmmss.sss format // 2) Latitude, ddmm.mmmm format. // 3) Latitude hemisphere, N or S. // 4) Longitude, dddmm.mmmm format. // 5) Longitude hemisphere, E or W. // 6) Position Fix Indicator, // 0 = Invalid fix. // 1 = GPS fix (SPS) // 2 = DGPS fix // 3 = PPS fix // 4 = Real Time Kinematic // 5 = Float RTK // 6 = estimated (dead reckoning) (2.3 feature) // 7 = Manual input mode // 8 = Simulation mode // 7) Number of sate1lites in use, 00 to 12. // 8) Horizontal Dilution of Precision, 0.5 to 99.9. // 9) MSL Altitude, -9999.9 to 99999.9 meters. // 10) Altitude units - M for meters // 11) Geoid separation in meters according to WGS-84 ellipsoid, -999.9 to 9999.9 meters. // 12) Separation units - M for meters // 13) Differential GPS (RTCM SC-104) data age, number of seconds since last valid RTCM transmission (nu1l if non-DGPS). // 14) Differential Reference Station ID, 0000 to 1023. (null if non-DGPS) // *<CS>) Checksum. // <CR><LF>) Sentence terminator if (sentence.Id != "$GPGGA") { return null; } if (sentence.Parts.Length != 15) { return null; } int fixIndicator; int.TryParse(sentence.Parts[6], out fixIndicator); if (fixIndicator == 0) { return null; } DateTime fixTime = NmeaClock.GetTime() .Date; fixTime += SentenceHelper.ParseUtcTime(sentence.Parts[1]); Latitude latitude = SentenceHelper.ParseLatitude(sentence.Parts[2], sentence.Parts[3]); Longitude longitude = SentenceHelper.ParseLongitude(sentence.Parts[4], sentence.Parts[5]); int numberOfSatellites; int.TryParse(sentence.Parts[7], out numberOfSatellites); double horizontalDop; double.TryParse(sentence.Parts[8], out horizontalDop); Length altitude = SentenceHelper.ParseLength(sentence.Parts[9], sentence.Parts[10]); Length heightOfGeoid = SentenceHelper.ParseLength(sentence.Parts[11], sentence.Parts[12]); int dgpsAge; int.TryParse(sentence.Parts[13], out dgpsAge); string dgpsStationId = sentence.Parts[14]; return new Decoded(new GeoPosition(latitude, longitude, altitude), fixTime); }
public static Decoded Parse(Sentence sentence) { // $GPGSA,<1>,<2>,<3>,<4>, ... ,<13>,<14>,<15>,<16>,<17>*<CS><CR><LF> // 0) Sentence Id // 1) Mode 1, M = manual, A = automatic. // 2) Mode 2, Fix type, 1 = no fix, 2 = 2D, 3 = 3D. // 3) PRN number, 01 to 32, of satellite used on channel 1 // 4) PRN number, 01 to 32, of satellite used on channel 2 // 5) PRN number, 01 to 32, of satellite used on channel 3 // 6) PRN number, 01 to 32, of satellite used on channel 4 // 7) PRN number, 01 to 32, of satellite used on channel 5 // 8) PRN number, 01 to 32, of satellite used on channel 6 // 9) PRN number, 01 to 32, of satellite used on channel 7 // 10) PRN number, 01 to 32, of satellite used on channel 8 // 11) PRN number, 01 to 32, of satellite used on channel 9 // 12) PRN number, 01 to 32, of satellite used on channel 10 // 13) PRN number, 01 to 32, of satellite used on channel 11 // 14) PRN number, 01 to 32, of satellite used on channel 12 // 15) PDOP-Position dilution of precision, 0.5 to 99.9. // 16) HDOP-Horizontal dilution of precision, 0.5 to 99.9. // 17) VDOP-Vertical di1ution of precision, 0.5 to 99.9. // *<CS>) Checksum. // <CR><LF>) Sentence terminator if (sentence.Id != "$GPGSA") { return null; } if (sentence.Parts.Length != 18) { return null; } GpsFixType fixType; switch (sentence.Parts[2]) { case "3": fixType = GpsFixType.ThreeD; break; case "2": fixType = GpsFixType.TwoD; break; default: fixType = GpsFixType.None; break; } int[] satellites = new int[12]; for (int i = 0; i < 12; i++) { int satId; if (int.TryParse(sentence.Parts[i + 3], out satId)) { satellites[i] = satId; } } double positionDop, horizontalDop, verticalDop; double.TryParse(sentence.Parts[15], out positionDop); double.TryParse(sentence.Parts[16], out horizontalDop); double.TryParse(sentence.Parts[17], out verticalDop); return new Decoded(fixType, satellites, positionDop, horizontalDop, verticalDop); }
private void PublishSentence(Sentence sentence) { var handler = SentenceReceived; if (handler != null) { handler(sentence); } }