From d941f2c0f7ee1536fb2de138653172416f625367 Mon Sep 17 00:00:00 2001 From: mort5161 Date: Fri, 25 Jul 2014 16:41:27 -0700 Subject: [PATCH] GPGSA --- src/NmeaParser.Shared/Nmea/Gps/GPGSA.cs | 105 ++++++++++++++++++ src/NmeaParser.Shared/Nmea/NmeaMessage.cs | 2 +- .../NmeaParser.Shared.projitems | 1 + src/NmeaParser.Tests/NmeaMessages.cs | 45 ++++++++ 4 files changed, 152 insertions(+), 1 deletion(-) create mode 100644 src/NmeaParser.Shared/Nmea/Gps/GPGSA.cs diff --git a/src/NmeaParser.Shared/Nmea/Gps/GPGSA.cs b/src/NmeaParser.Shared/Nmea/Gps/GPGSA.cs new file mode 100644 index 0000000..0a4120d --- /dev/null +++ b/src/NmeaParser.Shared/Nmea/Gps/GPGSA.cs @@ -0,0 +1,105 @@ +// +// Copyright (c) 2014 Morten Nielsen +// +// Licensed under the Microsoft Public License (Ms-PL) (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://opensource.org/licenses/Ms-PL.html +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NmeaParser.Nmea.Gps +{ + /// + /// Global Positioning System Fix Data + /// + [NmeaMessageType(Type = "GPGSA")] + public class Gpgsa : NmeaMessage + { + public enum ModeSelection + { + Auto, + Manual, + } + public enum Mode : int + { + NotAvailable = 1, + _2D = 2, + _3D = 3 + } + + protected override void LoadMessage(string[] message) + { + GpsMode = message[0] == "A" ? ModeSelection.Auto : ModeSelection.Manual; + FixMode = (Mode)int.Parse(message[1]); + + List svs = new List(); + for (int i = 2; i < 14; i++) + { + int id = -1; + if (message[i].Length > 0 && int.TryParse(message[i], out id)) + svs.Add(id); + } + SVs = svs.ToArray(); + + double tmp; + if (double.TryParse(message[14], NumberStyles.Float, CultureInfo.InvariantCulture, out tmp)) + PDop = tmp; + else + PDop = double.NaN; + + if (double.TryParse(message[15], NumberStyles.Float, CultureInfo.InvariantCulture, out tmp)) + HDop = tmp; + else + HDop = double.NaN; + + if (double.TryParse(message[16], NumberStyles.Float, CultureInfo.InvariantCulture, out tmp)) + VDop = tmp; + else + VDop = double.NaN; + } + + /// + /// Mode + /// + public ModeSelection GpsMode { get; private set; } + + /// + /// Mode + /// + public Mode FixMode { get; private set; } + + /// + /// IDs of SVs used in position fix + /// + public int[] SVs { get; private set; } + + /// + /// Dilution of precision + /// + public double PDop { get; set; } + + /// + /// Horizontal dilution of precision + /// + public double HDop { get; set; } + + /// + /// Vertical dilution of precision + /// + public double VDop { get; set; } + } +} diff --git a/src/NmeaParser.Shared/Nmea/NmeaMessage.cs b/src/NmeaParser.Shared/Nmea/NmeaMessage.cs index d3c7a40..32a29e3 100644 --- a/src/NmeaParser.Shared/Nmea/NmeaMessage.cs +++ b/src/NmeaParser.Shared/Nmea/NmeaMessage.cs @@ -48,7 +48,7 @@ namespace NmeaParser.Nmea checksumTest ^= Convert.ToByte(message[i]); } if (checksum != checksumTest) - throw new ArgumentException("Invalid nmea message: Checksum failure"); + throw new ArgumentException(string.Format("Invalid nmea message: Checksum failure. Got {0:X2}, Expected {1:X2}", checksum, checksumTest)); } string[] parts = message.Split(new char[] { ',' }); diff --git a/src/NmeaParser.Shared/NmeaParser.Shared.projitems b/src/NmeaParser.Shared/NmeaParser.Shared.projitems index 5c35b1f..6aae2c1 100644 --- a/src/NmeaParser.Shared/NmeaParser.Shared.projitems +++ b/src/NmeaParser.Shared/NmeaParser.Shared.projitems @@ -12,6 +12,7 @@ + diff --git a/src/NmeaParser.Tests/NmeaMessages.cs b/src/NmeaParser.Tests/NmeaMessages.cs index 3aa5874..2f1e09a 100644 --- a/src/NmeaParser.Tests/NmeaMessages.cs +++ b/src/NmeaParser.Tests/NmeaMessages.cs @@ -147,5 +147,50 @@ namespace NmeaParser.Tests Assert.AreEqual(4.0, rme.SphericalError); Assert.AreEqual("M", rme.SphericalErrorUnits); } + + [TestMethod] + public void TestGpgsa_Empty() + { + string input = "$GPGSA,A,3,,,,,,16,18,,22,24,,,,,*14"; + var msg = NmeaMessage.Parse(input); + Assert.IsInstanceOfType(msg, typeof(Gpgsa)); + Gpgsa gsa = (Gpgsa)msg; + Assert.AreEqual(Gpgsa.ModeSelection.Auto, gsa.GpsMode); + Assert.AreEqual(Gpgsa.Mode._3D, gsa.FixMode); + Assert.AreEqual(4, gsa.SVs.Length); + Assert.AreEqual(16, gsa.SVs[0]); + Assert.AreEqual(18, gsa.SVs[1]); + Assert.AreEqual(22, gsa.SVs[2]); + Assert.AreEqual(24, gsa.SVs[3]); + Assert.AreEqual(double.NaN, gsa.PDop); + Assert.AreEqual(double.NaN, gsa.HDop); + Assert.AreEqual(double.NaN, gsa.VDop); + } + [TestMethod] + public void TestGpgsa() + { + string input = "$GPGSA,M,2,19,28,14,18,27,22,31,39,40,42,43,44,1.7,1.0,1.3*3C"; + var msg = NmeaMessage.Parse(input); + Assert.IsInstanceOfType(msg, typeof(Gpgsa)); + Gpgsa gsa = (Gpgsa)msg; + Assert.AreEqual(Gpgsa.ModeSelection.Manual, gsa.GpsMode); + Assert.AreEqual(Gpgsa.Mode._2D, gsa.FixMode); + Assert.AreEqual(12, gsa.SVs.Length); + Assert.AreEqual(19, gsa.SVs[0]); + Assert.AreEqual(28, gsa.SVs[1]); + Assert.AreEqual(14, gsa.SVs[2]); + Assert.AreEqual(18, gsa.SVs[3]); + Assert.AreEqual(27, gsa.SVs[4]); + Assert.AreEqual(22, gsa.SVs[5]); + Assert.AreEqual(31, gsa.SVs[6]); + Assert.AreEqual(39, gsa.SVs[7]); + Assert.AreEqual(40, gsa.SVs[8]); + Assert.AreEqual(42, gsa.SVs[9]); + Assert.AreEqual(43, gsa.SVs[10]); + Assert.AreEqual(44, gsa.SVs[11]); + Assert.AreEqual(1.7, gsa.PDop); + Assert.AreEqual(1.0, gsa.HDop); + Assert.AreEqual(1.3, gsa.VDop); + } } }