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));
        }
예제 #2
0
 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);
     }
 }