From 6c1ae5db06bde5cbd23a63c0f32f2fa6055c8e72 Mon Sep 17 00:00:00 2001 From: mort5161 Date: Fri, 25 Jul 2014 14:21:41 -0700 Subject: [PATCH] Added GPRMB --- src/NmeaParser.Shared/Nmea/Gps/GPRMB.cs | 122 ++++++++++++++++++ .../NmeaParser.Shared.projitems | 1 + src/NmeaParser.Tests/NmeaMessages.cs | 57 ++++++++ src/NmeaParser.Tests/NmeaParser.Tests.csproj | 8 +- 4 files changed, 186 insertions(+), 2 deletions(-) create mode 100644 src/NmeaParser.Shared/Nmea/Gps/GPRMB.cs diff --git a/src/NmeaParser.Shared/Nmea/Gps/GPRMB.cs b/src/NmeaParser.Shared/Nmea/Gps/GPRMB.cs new file mode 100644 index 0000000..b7ad118 --- /dev/null +++ b/src/NmeaParser.Shared/Nmea/Gps/GPRMB.cs @@ -0,0 +1,122 @@ +// +// 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 +{ + /// + /// Recommended minimum navigation information + /// + [NmeaMessageType(Type = "GPRMB")] + public class Gprmb : NmeaMessage + { + public enum DataStatus + { + OK, + Warning + } + protected override void LoadMessage(string[] message) + { + Status = message[0] == "A" ? DataStatus.OK : Gprmb.DataStatus.Warning; + double tmp; + if (double.TryParse(message[1], NumberStyles.Float, CultureInfo.InvariantCulture, out tmp)) + { + CrossTrackError = tmp; + + if (message[2] == "L") //Steer left + CrossTrackError *= -1; + } + else + CrossTrackError = double.NaN; + + if(message[3].Length > 0) + OriginWaypointID = int.Parse(message[3], CultureInfo.InvariantCulture); + if (message[3].Length > 0) + DestinationWaypointID = int.Parse(message[4], CultureInfo.InvariantCulture); + DestinationLatitude = NmeaMessage.StringToLatitude(message[5], message[6]); + DestinationLongitude = NmeaMessage.StringToLongitude(message[7], message[8]); + if (double.TryParse(message[9], NumberStyles.Float, CultureInfo.InvariantCulture, out tmp)) + RangeToDestination = tmp; + else + RangeToDestination = double.NaN; + if (double.TryParse(message[10], NumberStyles.Float, CultureInfo.InvariantCulture, out tmp)) + TrueBearing = tmp; + else + TrueBearing = double.NaN; + if (double.TryParse(message[11], NumberStyles.Float, CultureInfo.InvariantCulture, out tmp)) + Velocity = tmp; + else + Velocity = double.NaN; + Arrived = message[12] == "A"; + } + + /// + /// Data Status + /// + public DataStatus Status { get; private set; } + + /// + /// Cross-track error (steer left when negative, right when positive) + /// + public double CrossTrackError { get; private set; } + + /// + /// Origin waypoint ID + /// + public double OriginWaypointID { get; private set; } + + /// + /// Destination waypoint ID + /// + public double DestinationWaypointID { get; private set; } + + /// + /// Destination Latitude + /// + public double DestinationLatitude { get; private set; } + + /// + /// Destination Longitude + /// + public double DestinationLongitude { get; private set; } + + /// + /// Range to destination in nautical miles + /// + public double RangeToDestination { get; private set; } + + /// + /// True bearing to destination + /// + public double TrueBearing { get; private set; } + + /// + /// Velocity towards destination in knots + /// + public double Velocity { get; private set; } + + /// + /// Arrived (true if arrived) + /// + public bool Arrived { get; private set; } + } +} diff --git a/src/NmeaParser.Shared/NmeaParser.Shared.projitems b/src/NmeaParser.Shared/NmeaParser.Shared.projitems index 10fa91b..de02017 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 cf155f7..ad32f0f 100644 --- a/src/NmeaParser.Tests/NmeaMessages.cs +++ b/src/NmeaParser.Tests/NmeaMessages.cs @@ -21,12 +21,69 @@ using System.Text; using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; using NmeaParser.Nmea; using NmeaParser.Nmea.Gps; +using System.Threading.Tasks; +using System.IO; namespace NmeaParser.Tests { [TestClass] public class NmeaMessages { + [TestMethod] + public async Task ParseNmeaFile() + { + var file = await Windows.Storage.StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///NmeaSampleData.txt")); + System.IO.StreamReader reader = new System.IO.StreamReader(await file.OpenStreamForReadAsync()); + while(!reader.EndOfStream) + { + var line = reader.ReadLine(); + if(line.StartsWith("$")) + { + var msg = NmeaMessage.Parse(line); + Assert.IsNotNull(msg); + Assert.IsNotInstanceOfType(msg, typeof(Nmea.UnknownMessage), "Type " + msg.MessageType + " not supported"); + } + } + } + + [TestMethod] + public void TestGprmb_Empty() + { + string input = "$GPRMB,A,,,,,,,,,,,,A,A*0B"; + var msg = NmeaMessage.Parse(input); + Assert.IsInstanceOfType(msg, typeof(Gprmb)); + Gprmb rmb = (Gprmb)msg; + Assert.AreEqual(true, rmb.Arrived); + Assert.AreEqual(double.NaN, rmb.CrossTrackError); + Assert.AreEqual(double.NaN, rmb.DestinationLatitude); + Assert.AreEqual(double.NaN, rmb.DestinationLongitude); + Assert.AreEqual(0, rmb.DestinationWaypointID); + Assert.AreEqual(0, rmb.OriginWaypointID); + Assert.AreEqual(double.NaN, rmb.RangeToDestination); + Assert.AreEqual(Gprmb.DataStatus.OK, rmb.Status); + Assert.AreEqual(double.NaN, rmb.TrueBearing); + Assert.AreEqual(double.NaN, rmb.Velocity); + } + + [TestMethod] + public void TestGprmb() + { + string input = "$GPRMB,A,0.66,L,003,004,4917.24,S,12309.57,W,001.3,052.5,000.5,V*3D"; + var msg = NmeaMessage.Parse(input); + Assert.IsInstanceOfType(msg, typeof(Gprmb)); + Gprmb rmb = (Gprmb)msg; + Assert.AreEqual(Gprmb.DataStatus.OK, rmb.Status); + Assert.AreEqual(-.66, rmb.CrossTrackError); + Assert.AreEqual(3, rmb.OriginWaypointID); + Assert.AreEqual(4, rmb.DestinationWaypointID); + Assert.AreEqual(-49.287333333333333333, rmb.DestinationLatitude); + Assert.AreEqual(-123.1595, rmb.DestinationLongitude); + Assert.AreEqual(1.3, rmb.RangeToDestination); + Assert.AreEqual(52.5, rmb.TrueBearing); + Assert.AreEqual(.5, rmb.Velocity); + Assert.AreEqual(false, rmb.Arrived); + } + [TestMethod] public void TestGprmc() { diff --git a/src/NmeaParser.Tests/NmeaParser.Tests.csproj b/src/NmeaParser.Tests/NmeaParser.Tests.csproj index 8d2dddd..c58d807 100644 --- a/src/NmeaParser.Tests/NmeaParser.Tests.csproj +++ b/src/NmeaParser.Tests/NmeaParser.Tests.csproj @@ -9,8 +9,8 @@ {5B5BAF9D-3FB9-47F9-AE07-B8CC43EC887C} Library Properties - BTDevices.Tests - BTDevices.Tests + NmeaParser.Tests + NmeaParser.Tests en-US 8.1 12 @@ -56,6 +56,10 @@ + + NmeaSampleData.txt + PreserveNewest + PreserveNewest