diff --git a/extras/test/src/test_ArduinoNmeaParser.cpp b/extras/test/src/test_ArduinoNmeaParser.cpp index 1aac9ca..5fa8481 100644 --- a/extras/test/src/test_ArduinoNmeaParser.cpp +++ b/extras/test/src/test_ArduinoNmeaParser.cpp @@ -137,18 +137,7 @@ TEST_CASE("NMEA message with data corruption (checksum mismatch) received", "[Pa REQUIRE(parser.error() == ArduinoNmeaParser::Error::Checksum); } -TEST_CASE("Invalid GPRMC message received", "[Parser-06]") -{ - ArduinoNmeaParser parser(nullptr); - - std::string const GPRMC = "$GPRMC,052852.105,A,5230.868,Y,01320.958,E,077.0,023.5,080720,000.0,W*6E\r\n"; - - REQUIRE(parser.error() == ArduinoNmeaParser::Error::None); - encode(parser, GPRMC); - REQUIRE(parser.error() == ArduinoNmeaParser::Error::RMC); -} - -TEST_CASE("Multiple NMEA messages received", "[Parser-07]") +TEST_CASE("Multiple NMEA messages received", "[Parser-06]") { ArduinoNmeaParser parser(nullptr); diff --git a/extras/test/src/test_GxRMC.cpp b/extras/test/src/test_GxRMC.cpp index 30400af..aa8608a 100644 --- a/extras/test/src/test_GxRMC.cpp +++ b/extras/test/src/test_GxRMC.cpp @@ -33,7 +33,8 @@ SCENARIO("Extracting latitude/longiture from valid GPRMC message", "[GxRMC-01]") { std::string const GPRMC = "$GPRMC,062101.714,A,5001.869,N,01912.114,E,955535.7,116.2,290520,000.0,W*45\r\n"; - REQUIRE(nmea::GxRMC::parse(GPRMC.c_str(), data) == true); + nmea::GxRMC::parse(GPRMC.c_str(), data); + REQUIRE(data.latitude == Approx(50.03114442)); REQUIRE(data.longitude == Approx(19.20189679)); } @@ -42,7 +43,8 @@ SCENARIO("Extracting latitude/longiture from valid GPRMC message", "[GxRMC-01]") { std::string const GPRMC = "$GPRMC,122311.239,A,4056.748,N,11212.614,W,,,290620,000.0,W*63\r\n"; - REQUIRE(nmea::GxRMC::parse(GPRMC.c_str(), data) == true); + nmea::GxRMC::parse(GPRMC.c_str(), data); + REQUIRE(data.latitude == Approx(40.9458060446613)); REQUIRE(data.longitude == Approx(-112.210235595703)); } @@ -51,7 +53,8 @@ SCENARIO("Extracting latitude/longiture from valid GPRMC message", "[GxRMC-01]") { std::string const GPRMC = "$GPRMC,122311.239,A,2727.069,S,05859.190,W,,,290620,000.0,W*76\r\n"; - REQUIRE(nmea::GxRMC::parse(GPRMC.c_str(), data) == true); + nmea::GxRMC::parse(GPRMC.c_str(), data); + REQUIRE(data.latitude == Approx(-27.4511422937699)); REQUIRE(data.longitude == Approx(-58.986502289772)); } @@ -60,7 +63,8 @@ SCENARIO("Extracting latitude/longiture from valid GPRMC message", "[GxRMC-01]") { std::string const GPRMC = "$GPRMC,122311.239,A,0610.522,S,10649.632,E,,,290620,000.0,W*6D\r\n"; - REQUIRE(nmea::GxRMC::parse(GPRMC.c_str(), data) == true); + nmea::GxRMC::parse(GPRMC.c_str(), data); + REQUIRE(data.latitude == Approx(-6.17536097471491)); REQUIRE(data.longitude == Approx(106.827192306519)); } @@ -86,7 +90,8 @@ TEST_CASE("Extracting speed over ground from valid GPRMC message", "[GxRMC-03]") { std::string const GPRMC = ("$GPRMC,052856.105,A,5230.874,N,01321.056,E,085.7,206.4,080720,000.0,W*78\r\n"); - REQUIRE(nmea::GxRMC::parse(GPRMC.c_str(), data) == true); + nmea::GxRMC::parse(GPRMC.c_str(), data); + /* 85.7 kts ~= 44.088 m/s */ REQUIRE(data.speed == Approx(44.088f)); } @@ -95,7 +100,8 @@ TEST_CASE("Extracting track angle from valid GPRMC message", "[GxRMC-04]") { std::string const GPRMC = ("$GPRMC,052856.105,A,5230.874,N,01321.056,E,085.7,206.4,080720,000.0,W*78\r\n"); - REQUIRE(nmea::GxRMC::parse(GPRMC.c_str(), data) == true); + nmea::GxRMC::parse(GPRMC.c_str(), data); + REQUIRE(data.course == Approx(206.4f)); } @@ -103,7 +109,8 @@ TEST_CASE("Extracting position time from valid GPRMC message", "[GxRMC-05]") { std::string const GPRMC = ("$GPRMC,052856.105,A,5230.874,N,01321.056,E,085.7,206.4,080720,000.0,W*78\r\n"); - REQUIRE(nmea::GxRMC::parse(GPRMC.c_str(), data) == true); + nmea::GxRMC::parse(GPRMC.c_str(), data); + /* 052856.105 -> 05:28:56.105 -> */ REQUIRE(data.time_utc.hour == 5); REQUIRE(data.time_utc.minute == 28); @@ -115,7 +122,8 @@ TEST_CASE("Extracting date from valid GPRMC message", "[GxRMC-06]") { std::string const GPRMC = ("$GPRMC,052856.105,A,5230.874,N,01321.056,E,085.7,206.4,080720,000.0,W*78\r\n"); - REQUIRE(nmea::GxRMC::parse(GPRMC.c_str(), data) == true); + nmea::GxRMC::parse(GPRMC.c_str(), data); + REQUIRE(data.date.day == 8); REQUIRE(data.date.month == 7); REQUIRE(data.date.year == 2020); @@ -125,7 +133,8 @@ TEST_CASE("Extracting magnetic variation from valid GPRMC message", "[GxRMC-07]" { std::string const GPRMC = ("$GPRMC,052856.105,A,5230.874,N,01321.056,E,085.7,206.4,080720,000.0,W*78\r\n"); - REQUIRE(nmea::GxRMC::parse(GPRMC.c_str(), data) == true); + nmea::GxRMC::parse(GPRMC.c_str(), data); + REQUIRE(data.magnetic_variation == Approx(0.0)); } @@ -133,16 +142,25 @@ TEST_CASE("Extracted status indicates void ('V') position data", "[GxRMC-08]") { std::string const GPRMC = ("$GPRMC,052856.105,V,5230.874,N,01321.056,E,085.7,206.4,080720,000.0,W*78\r\n"); - data.latitude = 1.0f; data.longitude = 2.0f; data.speed = 3.0f; data.course = 4.0f; - data.time_utc.hour = -1; data.time_utc.minute = -1; data.time_utc.second = -1; data.time_utc.microsecond = -1; + nmea::GxRMC::parse(GPRMC.c_str(), data); - REQUIRE(nmea::GxRMC::parse(GPRMC.c_str(), data) == true); - REQUIRE(data.latitude == 1.0f); - REQUIRE(data.longitude == 2.0f); - REQUIRE(data.speed == 3.0f); - REQUIRE(data.course == 4.0f); - REQUIRE(data.time_utc.hour == 5); - REQUIRE(data.time_utc.minute == 28); - REQUIRE(data.time_utc.second == 56); - REQUIRE(data.time_utc.microsecond == 105); + REQUIRE(data.is_valid == false); +} + +TEST_CASE("GxRMC message contains only date and time, but no location fix yet ", "[GxRMC-09]") +{ + std::string const GPRMC = ("$GPRMC,144602.00,V,,,,,,,011120,,,N*7B\r\n"); + + nmea::GxRMC::parse(GPRMC.c_str(), data); + + /* RMC TIME = '144602.00' */ + REQUIRE(data.time_utc.hour == 14); + REQUIRE(data.time_utc.minute == 46); + REQUIRE(data.time_utc.second == 02); + REQUIRE(data.time_utc.microsecond == 0); + + /* RMC DATE = '011120' */ + REQUIRE(data.date.day == 1); + REQUIRE(data.date.month == 11); + REQUIRE(data.date.year == 2020); } diff --git a/src/ArduinoNmeaParser.cpp b/src/ArduinoNmeaParser.cpp index bf298e7..82dfb63 100644 --- a/src/ArduinoNmeaParser.cpp +++ b/src/ArduinoNmeaParser.cpp @@ -120,10 +120,8 @@ void ArduinoNmeaParser::terminateParserBuffer() void ArduinoNmeaParser::parseGxRMC() { - if (!nmea::GxRMC::parse(_parser_buf.buf, _rmc)) - _error = Error::RMC; - else { - if (_on_rmc_update) + nmea::GxRMC::parse(_parser_buf.buf, _rmc); + + if (_on_rmc_update) _on_rmc_update(_rmc); - } } diff --git a/src/ArduinoNmeaParser.h b/src/ArduinoNmeaParser.h index 035fd31..d52575d 100644 --- a/src/ArduinoNmeaParser.h +++ b/src/ArduinoNmeaParser.h @@ -45,7 +45,7 @@ class ArduinoNmeaParser inline const nmea::RmcData rmc() const { return _rmc; } - enum class Error { None, Checksum, RMC }; + enum class Error { None, Checksum }; inline void clearerr() { _error = Error::None; } inline Error error () const { return _error; } diff --git a/src/nmea/GxRMC.cpp b/src/nmea/GxRMC.cpp index fdfda35..ee720fb 100644 --- a/src/nmea/GxRMC.cpp +++ b/src/nmea/GxRMC.cpp @@ -34,7 +34,7 @@ constexpr float kts_to_m_per_s(float const v) { return (v / 1.9438444924574f); } * PUBLIC MEMBER FUNCTIONS **************************************************************************************/ -bool GxRMC::parse(char const * gprmc, RmcData & data) +void GxRMC::parse(char const * gprmc, RmcData & data) { ParserState state = ParserState::MessadeId; @@ -68,14 +68,11 @@ bool GxRMC::parse(char const * gprmc, RmcData & data) case ParserState::MagneticVariation: next_state = handle_MagneticVariation (token, data.magnetic_variation); break; case ParserState::MagneticVariationEastWest: next_state = handle_MagneticVariationEastWest(token, data.magnetic_variation); break; case ParserState::Checksum: next_state = handle_Checksum (token); break; - case ParserState::Done: return true; break; - case ParserState::Error: return false; break; + case ParserState::Done: break; }; state = next_state; } - - return (state == ParserState::Done); } /************************************************************************************** @@ -84,9 +81,6 @@ bool GxRMC::parse(char const * gprmc, RmcData & data) GxRMC::ParserState GxRMC::handle_MessadeId(char const * token, RmcSource & source) { - if (!util::rmc_isGxRMC(token)) - return ParserState::Error; - if (util::rmc_isGPRMC(token)) source = RmcSource::GPS; else if (util::rmc_isGLRMC(token)) @@ -116,20 +110,12 @@ GxRMC::ParserState GxRMC::handle_UTCPositionFix(char const * token, Time & time_ GxRMC::ParserState GxRMC::handle_Status(char const * token, bool & is_valid) { - is_valid = false; - - if (strlen(token) == 0) - return ParserState::Error; - - if(!strncmp(token, "A", 1)) { + if(strlen(token) > 0 && !strncmp(token, "A", 1)) is_valid = true; - return ParserState::LatitudeVal; - } - - if(!strncmp(token, "V", 1)) - return ParserState::Done; + else + is_valid = false; - return ParserState::Error; + return ParserState::LatitudeVal; } GxRMC::ParserState GxRMC::handle_LatitudeVal(char const * token, float & latitude) @@ -144,18 +130,10 @@ GxRMC::ParserState GxRMC::handle_LatitudeVal(char const * token, float & latitud GxRMC::ParserState GxRMC::handle_LatitudeNS(char const * token, float & latitude) { - if (strlen(token)) - { - if(!strncmp(token, "N", 1)) - return ParserState::LongitudeVal; - - if(!strncmp(token, "S", 1)) { - latitude *= (-1.0f); - return ParserState::LongitudeVal; - } - } + if (strlen(token) > 0 && !strncmp(token, "S", 1)) + latitude *= (-1.0f); - return ParserState::Error; + return ParserState::LongitudeVal; } GxRMC::ParserState GxRMC::handle_LongitudeVal(char const * token, float & longitude) @@ -170,18 +148,10 @@ GxRMC::ParserState GxRMC::handle_LongitudeVal(char const * token, float & longit GxRMC::ParserState GxRMC::handle_LongitudeEW(char const * token, float & longitude) { - if (strlen(token)) - { - if(!strncmp(token, "E", 1)) - return ParserState::SpeedOverGround; - - if(!strncmp(token, "W", 1)) { - longitude *= (-1.0f); - return ParserState::SpeedOverGround; - } - } + if (strlen(token) > 0 && !strncmp(token, "W", 1)) + longitude *= (-1.0f); - return ParserState::Error; + return ParserState::SpeedOverGround; } GxRMC::ParserState GxRMC::handle_SpeedOverGround(char const * token, float & speed) diff --git a/src/nmea/GxRMC.h b/src/nmea/GxRMC.h index 798d7b2..9363e72 100644 --- a/src/nmea/GxRMC.h +++ b/src/nmea/GxRMC.h @@ -32,7 +32,7 @@ class GxRMC public: - static bool parse(char const * gprmc, RmcData & data); + static void parse(char const * gprmc, RmcData & data); private: @@ -54,8 +54,7 @@ class GxRMC MagneticVariation, MagneticVariationEastWest, Checksum, - Done, - Error + Done }; static ParserState handle_MessadeId (char const * token, RmcSource & source);