From 2f804ba766fccb950a419b7710f1101082d4025f Mon Sep 17 00:00:00 2001 From: JhnFlory <130918387+JhnFlory@users.noreply.github.com> Date: Wed, 30 Aug 2023 12:44:31 +0300 Subject: [PATCH] Add NMEA 4.1 Nav Status field to RMC sentence (#142) --- .../sf/marineapi/nmea/parser/RMCParser.java | 24 +++++++- .../marineapi/nmea/sentence/RMCSentence.java | 15 +++++ .../net/sf/marineapi/nmea/util/NavStatus.java | 61 +++++++++++++++++++ .../marineapi/nmea/parser/ChecksumTest.java | 2 +- .../net/sf/marineapi/nmea/parser/RMCTest.java | 39 ++++++++++-- .../nmea/parser/SentenceParserTest.java | 2 +- 6 files changed, 134 insertions(+), 9 deletions(-) create mode 100644 src/main/java/net/sf/marineapi/nmea/util/NavStatus.java diff --git a/src/main/java/net/sf/marineapi/nmea/parser/RMCParser.java b/src/main/java/net/sf/marineapi/nmea/parser/RMCParser.java index 8c4d30b9..b8d49f56 100644 --- a/src/main/java/net/sf/marineapi/nmea/parser/RMCParser.java +++ b/src/main/java/net/sf/marineapi/nmea/parser/RMCParser.java @@ -29,6 +29,7 @@ import net.sf.marineapi.nmea.util.FaaMode; import net.sf.marineapi.nmea.util.Position; import net.sf.marineapi.nmea.util.Time; +import net.sf.marineapi.nmea.util.NavStatus; /** * RMC sentence parser. @@ -49,6 +50,7 @@ class RMCParser extends PositionParser implements RMCSentence { private static final int MAG_VARIATION = 9; private static final int VAR_HEMISPHERE = 10; private static final int MODE = 11; + private static final int NAV_STATUS = 12; /** * Creates a new instance of RMCParser. @@ -61,12 +63,12 @@ public RMCParser(String nmea) { } /** - * Creates a ZDA parser with empty sentence. + * Creates a RMC parser with empty sentence. * * @param talker TalkerId to set */ public RMCParser(TalkerId talker) { - super(talker, SentenceId.RMC, 12); + super(talker, SentenceId.RMC, 13); } /* @@ -109,6 +111,12 @@ public FaaMode getMode() { return FaaMode.valueOf(getCharValue(MODE)); } + /* + * (non-Javadoc) + * + */ + public NavStatus getNavStatus() { return NavStatus.valueOf(getCharValue(NAV_STATUS)); } + /* * (non-Javadoc) * @see net.sf.marineapi.nmea.sentence.PositionSentence#getPosition() @@ -181,7 +189,7 @@ public void setDate(Date date) { public void setDirectionOfVariation(CompassPoint dir) { if (dir != CompassPoint.EAST && dir != CompassPoint.WEST) { throw new IllegalArgumentException( - "Invalid variation direction, expected EAST or WEST."); + "Invalid variation direction, expected EAST or WEST."); } setCharValue(VAR_HEMISPHERE, dir.toChar()); } @@ -197,6 +205,16 @@ public void setMode(FaaMode mode) { setCharValue(MODE, mode.toChar()); } + /* + * (non-Javadoc) + * + */ + @Override + public void setNavStatus(NavStatus navStatus) { + setFieldCount(13); + setCharValue(NAV_STATUS, navStatus.toChar()); + } + /* * (non-Javadoc) * @see diff --git a/src/main/java/net/sf/marineapi/nmea/sentence/RMCSentence.java b/src/main/java/net/sf/marineapi/nmea/sentence/RMCSentence.java index e703db6c..dc0aaf36 100644 --- a/src/main/java/net/sf/marineapi/nmea/sentence/RMCSentence.java +++ b/src/main/java/net/sf/marineapi/nmea/sentence/RMCSentence.java @@ -23,6 +23,7 @@ import net.sf.marineapi.nmea.util.CompassPoint; import net.sf.marineapi.nmea.util.DataStatus; import net.sf.marineapi.nmea.util.FaaMode; +import net.sf.marineapi.nmea.util.NavStatus; /** * Recommended minimum navigation information type C. Current time and date, @@ -84,6 +85,13 @@ public interface RMCSentence extends PositionSentence, TimeSentence, */ FaaMode getMode(); + /** + * Get the Navigation Status. + * + * @return NavStatus enum + */ + NavStatus getNavStatus(); + /** * Get current speed over ground (SOG). * @@ -142,6 +150,13 @@ public interface RMCSentence extends PositionSentence, TimeSentence, */ void setMode(FaaMode mode); + /** + * Set the Navigation Status. + * + * @param navStatus NavStatus enum to set + */ + void setNavStatus(NavStatus navStatus); + /** * Set current speed over ground (SOG). * diff --git a/src/main/java/net/sf/marineapi/nmea/util/NavStatus.java b/src/main/java/net/sf/marineapi/nmea/util/NavStatus.java new file mode 100644 index 00000000..bb22e920 --- /dev/null +++ b/src/main/java/net/sf/marineapi/nmea/util/NavStatus.java @@ -0,0 +1,61 @@ +package net.sf.marineapi.nmea.util; + +/** + *

FAA operating modes reported by RMC sentences since NMEA 4.1.

+ * @author John + */ + +public enum NavStatus { + + /** Navigation status is autonomous. */ + AUTONOMOUS('A'), + + /** Navigation status is differential. */ + DIFFERENTIAL('D'), + + /** Navigation status is Estimated. */ + ESTIMATED('E'), + + /** Navigation status is Manual. */ + MANUAL('M'), + + /** Navigation status is Not valid. */ + NOT_VALID('N'), + + /** Navigation status is Simulator. */ + SIMULATOR('S'), + + /** Navigation status is Valid. */ + VALID('V'); + + private final char navStatus; + + NavStatus(char navStatusCh) { + navStatus = navStatusCh; + } + + /** + * Returns the corresponding char indicator of Navigation Status. + * + * @return NavStatus char used in sentences. + */ + public char toChar() { + return navStatus; + } + + /** + * Returns the NavStatus enum corresponding the actual char indicator used in + * the sentencess. + * + * @param ch Char mode indicator + * @return NavStatus enum + */ + public static NavStatus valueOf(char ch) { + for (NavStatus gm : values()) { + if (gm.toChar() == ch) { + return gm; + } + } + return valueOf(String.valueOf(ch)); + } +} diff --git a/src/test/java/net/sf/marineapi/nmea/parser/ChecksumTest.java b/src/test/java/net/sf/marineapi/nmea/parser/ChecksumTest.java index 3e2b5ab1..e0e654e0 100644 --- a/src/test/java/net/sf/marineapi/nmea/parser/ChecksumTest.java +++ b/src/test/java/net/sf/marineapi/nmea/parser/ChecksumTest.java @@ -78,7 +78,7 @@ public void testCalculate() { assertEquals("1D", Checksum.calculate(BODTest.EXAMPLE)); assertEquals("63", Checksum.calculate(GGATest.EXAMPLE)); assertEquals("26", Checksum.calculate(GLLTest.EXAMPLE)); - assertEquals("0B", Checksum.calculate(RMCTest.EXAMPLE)); + assertEquals("74", Checksum.calculate(RMCTest.EXAMPLE)); assertEquals("3D", Checksum.calculate(GSATest.EXAMPLE)); assertEquals("73", Checksum.calculate(GSVTest.EXAMPLE)); assertEquals("58", Checksum.calculate(RMBTest.EXAMPLE)); diff --git a/src/test/java/net/sf/marineapi/nmea/parser/RMCTest.java b/src/test/java/net/sf/marineapi/nmea/parser/RMCTest.java index c2681401..04c15fe2 100644 --- a/src/test/java/net/sf/marineapi/nmea/parser/RMCTest.java +++ b/src/test/java/net/sf/marineapi/nmea/parser/RMCTest.java @@ -11,6 +11,7 @@ import net.sf.marineapi.nmea.util.FaaMode; import net.sf.marineapi.nmea.util.Position; import net.sf.marineapi.nmea.util.Time; +import net.sf.marineapi.nmea.util.NavStatus; import org.junit.Before; import org.junit.Test; @@ -23,10 +24,10 @@ public class RMCTest { /** Example sentence */ - public static final String EXAMPLE = "$GPRMC,120044.567,A,6011.552,N,02501.941,E,000.0,360.0,160705,006.1,E,A*0B"; + public static final String EXAMPLE = "$GPRMC,120044.567,A,6011.552,N,02501.941,E,000.0,360.0,160705,006.1,E,A,S*74"; /** Example of legacy format (short by one field) */ - public static final String EXAMPLE_LEGACY = "$GPRMC,183729,A,3907.356,N,12102.482,W,000.0,360.0,080301,015.5,E*6F"; + public static final String EXAMPLE_LEGACY = "$GPRMC,183729,A,3907.356,N,12102.482,W,000.0,360.0,080301,015.5,E,S*10"; RMCParser empty; RMCParser rmc; @@ -45,8 +46,8 @@ public void setUp() { @Test public void testConstructor() { - assertEquals(12, empty.getFieldCount()); - assertEquals(11, legacy.getFieldCount()); + assertEquals(13, empty.getFieldCount()); + assertEquals(12, legacy.getFieldCount()); } /** @@ -114,6 +115,14 @@ public void testGetFaaMode() { assertEquals(FaaMode.AUTOMATIC, rmc.getMode()); } + /** + * Test method for {@link RMCParser#getNavStatus()}. + */ + @Test + public void testGetNavStatus() { + assertEquals(NavStatus.SIMULATOR, rmc.getNavStatus()); + } + /** * Test method for * {@link net.sf.marineapi.nmea.parser.RMCParser#getVariation()} . @@ -253,6 +262,28 @@ public void testSetFaaMode() { assertEquals(FaaMode.ESTIMATED, rmc.getMode()); } + /** + * Test method for + * {@link net.sf.marineapi.nmea.parser.RMCParser#setNavStatus(NavStatus)}. + */ + @Test + public void testSetNavStatus() { + rmc.setNavStatus(NavStatus.MANUAL); + assertEquals(NavStatus.MANUAL, rmc.getNavStatus()); + rmc.setNavStatus(NavStatus.AUTONOMOUS); + assertEquals(NavStatus.AUTONOMOUS, rmc.getNavStatus()); + rmc.setNavStatus(NavStatus.DIFFERENTIAL); + assertEquals(NavStatus.DIFFERENTIAL, rmc.getNavStatus()); + rmc.setNavStatus(NavStatus.NOT_VALID); + assertEquals(NavStatus.NOT_VALID, rmc.getNavStatus()); + rmc.setNavStatus(NavStatus.ESTIMATED); + assertEquals(NavStatus.ESTIMATED, rmc.getNavStatus()); + rmc.setNavStatus(NavStatus.VALID); + assertEquals(NavStatus.VALID, rmc.getNavStatus()); + rmc.setNavStatus(NavStatus.SIMULATOR); + assertEquals(NavStatus.SIMULATOR, rmc.getNavStatus()); + } + /** * Test method for * {@link net.sf.marineapi.nmea.parser.RMCParser#setFaaMode()}. diff --git a/src/test/java/net/sf/marineapi/nmea/parser/SentenceParserTest.java b/src/test/java/net/sf/marineapi/nmea/parser/SentenceParserTest.java index aea0dec3..2dc77769 100644 --- a/src/test/java/net/sf/marineapi/nmea/parser/SentenceParserTest.java +++ b/src/test/java/net/sf/marineapi/nmea/parser/SentenceParserTest.java @@ -331,7 +331,7 @@ public void testGetStringValueWithValidIndex() { String val = instance.getStringValue(0); assertEquals("120044.567", val); val = instance.getStringValue(instance.getFieldCount() - 1); - assertEquals("A", val); + assertEquals("S", val); } catch (IndexOutOfBoundsException e) { fail("Unexpected IndexOutOfBoundsException"); } catch (Exception e) {