public void CorrectlyDecodesXdrEvenIfExtraChars() { // Seen in one example (the last "A" shouldn't be there) string sentence = "$IIXDR,A,4,D,ROLL,A,-2,D,PTCH,A*1A"; var inSentence = TalkerSentence.FromSentenceString(sentence, out var error); Assert.Equal(NmeaError.None, error); Assert.NotNull(inSentence); var decoded = (TransducerMeasurement)inSentence !.TryGetTypedValue(ref _lastPacketTime) !; Assert.NotNull(decoded); var roll = decoded.DataSets[0]; Assert.Equal(4.0, roll.Value); Assert.Equal("A", roll.DataType); Assert.Equal("D", roll.Unit); Assert.Equal("ROLL", roll.DataName); var pitch = decoded.DataSets[1]; Assert.Equal(-2.0, pitch.Value); Assert.Equal("A", pitch.DataType); Assert.Equal("D", pitch.Unit); Assert.Equal("PTCH", pitch.DataName); }
public void ChecksumWorksAlsoWithNonAsciiCharacters() { string sentence = "$GPBOD,16.8,T,14.9,M,Grenze des Beschränkungsgebiete,*A9"; var ts = TalkerSentence.FromSentenceString(sentence, out var error); Assert.NotNull(ts); Assert.Equal(NmeaError.None, error); }
public void ChecksumIsNotHex() { string sentence = "$GPRMC,211730.997,A,3511.28,S,13823.26,E,7.0,229.0,190120,,,*QQ"; var ts = TalkerSentence.FromSentenceString(sentence, out var error); Assert.Null(ts); Assert.Equal(NmeaError.InvalidChecksum, error); }
public void NoHeader() { string sentence = "RMC,211730.997,A,3511.28,S,13823.26,E,7.0,229.0,190120,,,*1A"; var ts = TalkerSentence.FromSentenceString(sentence, out var error); Assert.Null(ts); Assert.Equal(NmeaError.NoSyncByte, error); }
/// <summary> /// Translates the properties of this instance into an NMEA message /// </summary> /// <returns>A complete NMEA message</returns> public virtual string ToNmeaMessage() { string start = TalkerId == TalkerId.Ais ? "!" : "$"; string msg = $"{start}{TalkerId}{SentenceId},{ToNmeaParameterList()}"; byte checksum = TalkerSentence.CalculateChecksum(msg); return(msg + "*" + checksum.ToString("X2")); }
public void ValidSentenceButNoChecksum() { string sentence = "$GPRMC,211730.997,A,3511.28,S,13823.26,E,7.0,229.0,190120,,,"; var ts = TalkerSentence.FromSentenceString(sentence, out var error) !; Assert.NotNull(ts); Assert.Equal(NmeaError.None, error); Assert.Equal(new SentenceId("RMC"), ts.Id); Assert.Equal(TalkerId.GlobalPositioningSystem, ts.TalkerId); Assert.Equal(12, ts.Fields.Count()); }
public void CanParseAllTheseMessages(string input) { var inSentence = TalkerSentence.FromSentenceString(input, out var error); Assert.Equal(NmeaError.None, error); Assert.NotNull(inSentence); var decoded = inSentence !.TryGetTypedValue(ref _lastPacketTime); Assert.NotNull(decoded); Assert.False(decoded is RawSentence); }
private void ParseSequencesAndAddToCache(IEnumerable <string> inputSequences) { DateTimeOffset now = DateTimeOffset.Now; foreach (var seq in inputSequences) { var decoded = TalkerSentence.FromSentenceString(seq, out var error) !; Assert.Equal(NmeaError.None, error); Assert.NotNull(decoded); var s = decoded.TryGetTypedValue(ref now) !; _autopilot.SentenceCache.Add(s); } }
public void HdmDecode() { string msg = "$GPHDM,99.9,M"; var decoded = TalkerSentence.FromSentenceString(msg, out var error); Assert.Equal(NmeaError.None, error); Assert.NotNull(decoded); HeadingMagnetic hdm = (HeadingMagnetic)decoded !.TryGetTypedValue(ref _lastPacketTime) !; Assert.True(hdm.Valid); Assert.Equal(99.9, hdm.Angle.Degrees, 1); }
public void HdtDecode() { string msg = "$GPHDT,99.9,T"; var decoded = TalkerSentence.FromSentenceString(msg, out var error); Assert.Equal(NmeaError.None, error); Assert.NotNull(decoded); HeadingTrue xte = (HeadingTrue)decoded !.TryGetTypedValue(ref _lastPacketTime) !; Assert.True(xte.Valid); Assert.Equal(99.9, xte.Angle.Degrees, 1); }
public void XteDecode() { string msg = "$GPXTE,A,A,0.00,L,N,D*06"; var decoded = TalkerSentence.FromSentenceString(msg, out var error); Assert.Equal(NmeaError.None, error); Assert.NotNull(decoded); CrossTrackError xte = (CrossTrackError)decoded !.TryGetTypedValue(ref _lastPacketTime) !; Assert.True(xte.Valid); Assert.Equal(Length.Zero, xte.Distance); }
public void SentenceDecode() { string sentence = "$GPRMC,211730.997,A,3511.28,S,13823.26,E,7.0,229.0,190120,,,*35"; var ts = TalkerSentence.FromSentenceString(sentence, out var error) !; Assert.NotNull(ts); _lastPacketTime = DateTimeOffset.UtcNow; var decoded = ts.TryGetTypedValue(ref _lastPacketTime); Assert.NotNull(decoded); Assert.IsType <RecommendedMinimumNavigationInformation>(decoded); Assert.Equal(21, decoded !.DateTime.Hour); Assert.Equal(17, decoded !.DateTime.Minute); }
public void DontCrashOnTheseInvalidSentences(string sentence) { var inSentence = TalkerSentence.FromSentenceString(sentence, out var error); if (error == NmeaError.InvalidChecksum) { Assert.Null(inSentence); } else { Assert.NotNull(inSentence); Assert.True(inSentence !.Fields != null); } }
private static void UsingSerial() { DateTimeOffset lastMessageTime = DateTimeOffset.UtcNow; using (var sp = new SerialPort("/dev/ttyS0")) { sp.NewLine = "\r\n"; sp.Open(); // Device streams continuously and therefore most of the time we would end up in the middle of the line // therefore ignore first line so that we align correctly sp.ReadLine(); bool gotRmc = false; while (!gotRmc) { string line = sp.ReadLine(); TalkerSentence?sentence = TalkerSentence.FromSentenceString(line, out _); if (sentence == null) { continue; } object?typed = sentence.TryGetTypedValue(ref lastMessageTime); if (typed == null) { Console.WriteLine($"Sentence identifier `{sentence.Id}` is not known."); } else if (typed is RecommendedMinimumNavigationInformation rmc) { gotRmc = true; if (rmc.Position.ContainsValidPosition()) { Console.WriteLine($"Your location: {rmc.Position}"); } else { Console.WriteLine($"You cannot be located."); } } else { Console.WriteLine($"Sentence of type `{typed.GetType().FullName}` not handled."); } } } }
public void TrueWindSpeedDecode() { string msg = "$WIMWV,220.0,T,5.0,N,A*20"; var decoded = TalkerSentence.FromSentenceString(msg, out var error); Assert.Equal(NmeaError.None, error); Assert.NotNull(decoded); WindSpeedAndAngle mwv = (WindSpeedAndAngle)decoded !.TryGetTypedValue(ref _lastPacketTime) !; Assert.Equal(Angle.FromDegrees(220), mwv.Angle); Assert.False(mwv.Relative); Assert.Equal(Speed.FromKnots(5.0), mwv.Speed); }
public void MwvDecode() { string text = "$YDMWV,331.6,R,0.7,M,A"; var decoded = TalkerSentence.FromSentenceString(text, out var error); Assert.Equal(NmeaError.None, error); Assert.NotNull(decoded); WindSpeedAndAngle wind = (WindSpeedAndAngle)decoded !.TryGetTypedValue(ref _lastPacketTime) !; Assert.True(wind.Valid); Assert.True(wind.Relative); Assert.Equal(331.6 - 360.0, wind.Angle.Degrees, 1); Assert.Equal(0.7, wind.Speed.MetersPerSecond, 1); }
public void ZdaDecode() { _lastPacketTime = DateTimeOffset.UtcNow; string text = "$GPZDA,135302.036,02,02,2020,+01,00*7F"; var decoded = TalkerSentence.FromSentenceString(text, out var error); Assert.Equal(NmeaError.None, error); Assert.NotNull(decoded); TimeDate zda = (TimeDate)decoded !.TryGetTypedValue(ref _lastPacketTime) !; Assert.True(zda.Valid); Assert.Equal(1.0, zda.LocalTimeOffset.TotalHours); Assert.Equal(new DateTime(2020, 02, 02, 13, 53, 02, 36, DateTimeKind.Utc), zda.DateTime); }
public void ZdaDecodeNoTime() { _lastPacketTime = DateTimeOffset.UtcNow; DateTimeOffset start = _lastPacketTime; string text = "$GPZDA,,,,,,*48"; var decoded = TalkerSentence.FromSentenceString(text, out var error); Assert.Equal(NmeaError.None, error); Assert.NotNull(decoded); TimeDate zda = (TimeDate)decoded !.TryGetTypedValue(ref _lastPacketTime) !; Assert.False(zda.Valid); Assert.Equal(0, zda.LocalTimeOffset.TotalHours); Assert.Equal(start, _lastPacketTime); // Should not have changed }
public void DecodeWithDifferentSequenceIdLength(string sentence, string expectedSentenceId) { var ts = TalkerSentence.FromSentenceString(sentence, out var error) !; Assert.NotNull(ts); _lastPacketTime = DateTimeOffset.UtcNow; var decoded = ts.TryGetTypedValue(ref _lastPacketTime); Assert.NotNull(decoded); if (decoded != null) { Assert.IsType <RawSentence>(decoded); Assert.Equal(new SentenceId(expectedSentenceId), decoded.SentenceId); Assert.Equal(sentence, decoded.ToNmeaMessage()); } }
public void SentenceRoundTripIsUnaffectedByCulture(string input) { // de-DE has "," as decimal separator. Big trouble if using CurrentCulture for any parsing or formatting here using (new SetCultureForTest("de-DE")) { var inSentence = TalkerSentence.FromSentenceString(input, out var error); Assert.Equal(NmeaError.None, error); Assert.NotNull(inSentence); var decoded = inSentence !.TryGetTypedValue(ref _lastPacketTime); Assert.NotNull(decoded); TalkerSentence outSentence = new TalkerSentence(decoded !); string output = outSentence.ToString(); output = output.Remove(output.IndexOf("*", StringComparison.Ordinal)); Assert.Equal(input, output); } }
public void ApparentWindSpeedDecode() { string msg = "$WIMWV,350.0,R,16.8,N,A*1A"; var decoded = TalkerSentence.FromSentenceString(msg, out var error); Assert.Equal(NmeaError.None, error); Assert.NotNull(decoded); WindSpeedAndAngle mwv = (WindSpeedAndAngle)decoded !.TryGetTypedValue(ref _lastPacketTime) !; Assert.Equal(AngleUnit.Degree, mwv.Angle.Unit); Assert.Equal(Angle.FromDegrees(-10).Degrees, mwv.Angle.Degrees, 3); Assert.True(mwv.Relative); Assert.Equal(SpeedUnit.Knot, mwv.Speed.Unit); Assert.Equal(Speed.FromKnots(16.8), mwv.Speed); }
public void SentenceRoundTrip(string input) { var inSentence = TalkerSentence.FromSentenceString(input, out var error); Assert.Equal(NmeaError.None, error); Assert.NotNull(inSentence); var decoded = inSentence !.TryGetTypedValue(ref _lastPacketTime) !; Assert.NotNull(decoded); TalkerSentence outSentence = new TalkerSentence(decoded); string output = outSentence.ToString(); Assert.Equal(input, output); // Just test that this doesn't cause an exception Assert.NotNull(decoded.ToReadableContent()); }
public void TwoWaysOfGettingSentenceAreEqual(string input) { // de-DE has "," as decimal separator. Big trouble if using CurrentCulture for any parsing or formatting here using (new SetCultureForTest("de-DE")) { var inSentence = TalkerSentence.FromSentenceString(input, out var error); Assert.Equal(NmeaError.None, error); Assert.NotNull(inSentence); var decoded = inSentence !.TryGetTypedValue(ref _lastPacketTime); Assert.NotNull(decoded); TalkerSentence outSentence = new TalkerSentence(decoded !); string output = outSentence.ToString(); // For convenience, a sentence can also be directly converted to a nmea string. Check that the result is equal. String alternateToString = decoded !.ToNmeaMessage(); Assert.Equal(output, alternateToString); } }
public void GgaDecode() { _lastPacketTime = DateTimeOffset.UtcNow; string msg = "$GPGGA,163810,4728.7027,N,00929.9666,E,2,12,0.6,397.4,M,46.8,M,,*4C"; var inSentence = TalkerSentence.FromSentenceString(msg, out var error); Assert.Equal(NmeaError.None, error); Assert.NotNull(inSentence); GlobalPositioningSystemFixData nmeaSentence = (GlobalPositioningSystemFixData)inSentence !.TryGetTypedValue(ref _lastPacketTime) !; var expectedPos = new GeographicPosition(47.478378333333332, 9.4994433333333337, 397.4 + 46.8); Assert.True(expectedPos.EqualPosition(nmeaSentence.Position)); Assert.Equal(GpsQuality.DifferentialFix, nmeaSentence.Status); Assert.Equal(12, nmeaSentence.NumberOfSatellites); Assert.Equal(0.6, nmeaSentence.Hdop); Assert.Equal(_lastPacketTime.Date, nmeaSentence.DateTime.Date); Assert.Equal(new TimeSpan(0, 16, 38, 10), nmeaSentence.DateTime.TimeOfDay); }
public void RmbDecode() { string text = "$GPRMB,A,0.02,R,R3,R4,4728.9218,N,00930.3359,E,0.026,222.0,2.4,V,D"; var decoded = TalkerSentence.FromSentenceString(text, out var error); Assert.Equal(NmeaError.None, error); Assert.NotNull(decoded); RecommendedMinimumNavToDestination nav = (RecommendedMinimumNavToDestination)decoded !.TryGetTypedValue(ref _lastPacketTime) !; Assert.True(nav.Valid); Assert.Equal(-0.02, nav.CrossTrackError.NauticalMiles, 2); Assert.Equal("R3", nav.PreviousWayPointName); Assert.Equal("R4", nav.NextWayPointName); Assert.Equal(47.48203, nav.NextWayPoint.Latitude, 6); Assert.Equal(9.505598, nav.NextWayPoint.Longitude, 6); Assert.Equal(0.026, nav.DistanceToWayPoint.GetValueOrDefault(Length.Zero).NauticalMiles, 3); Assert.Equal(222.0, nav.BearingToWayPoint.GetValueOrDefault(Angle.Zero).Degrees, 1); Assert.Equal(2.4, nav.ApproachSpeed.GetValueOrDefault(Speed.Zero).Knots, 1); }
public void GsvDecode() { const string msg = "$YDGSV,5,1,18,19,29,257,45,22,30,102,45,04,76,143,44,06,47,295,42"; var decoded = TalkerSentence.FromSentenceString(msg, out var error); Assert.Equal(NmeaError.None, error); Assert.NotNull(decoded); SatellitesInView nav = (SatellitesInView)decoded !.TryGetTypedValue(ref _lastPacketTime) !; Assert.False(nav.ReplacesOlderInstance); Assert.Equal(4, nav.Satellites.Count); Assert.Equal(18, nav.TotalSatellites); foreach (var s in nav.Satellites) { Assert.True(!string.IsNullOrWhiteSpace(s.Id)); Assert.True(s.Elevation > Angle.Zero && s.Elevation < Angle.FromDegrees(90)); Assert.True(s.Azimuth > Angle.Zero && s.Azimuth < Angle.FromDegrees(360)); } }
/// <summary> /// Internal constructor /// </summary> public CrossTrackError(TalkerSentence sentence, DateTimeOffset time) : this(sentence.TalkerId, Matches(sentence) ? sentence.Fields : throw new ArgumentException($"SentenceId does not match expected id '{Id}'"), time) { }
/// <summary> /// Internal constructor /// </summary> public DepthBelowSurface(TalkerSentence sentence, DateTimeOffset time) : this(sentence.TalkerId, Matches(sentence) ? sentence.Fields : throw new ArgumentException($"SentenceId does not match expected id '{Id}'"), time) { }
private static bool Matches(TalkerSentence sentence) => Matches(sentence.Id);
/// <summary> /// Internal constructor /// </summary> public MeteorologicalComposite(TalkerSentence sentence, DateTimeOffset time) : this(sentence.TalkerId, Matches(sentence) ? sentence.Fields : throw new ArgumentException($"SentenceId does not match expected id '{Id}'"), time) { }