From 8d8a0fb06142f5d668f8370c052a09457cc5ca90 Mon Sep 17 00:00:00 2001 From: Mario Konrad Date: Thu, 4 Nov 2021 21:38:56 +0100 Subject: [PATCH] NMEA: sentence ZFI added --- README.md | 19 +++++++--- TODO.md | 1 - doc/nmea.dox | 1 + include/marnav/nmea/sentence_id.hpp | 1 + include/marnav/nmea/zfi.hpp | 60 ++++++++++++++++++++++++++++++ src/CMakeLists.txt | 1 + src/marnav/nmea/name.cpp | 2 + src/marnav/nmea/nmea.cpp | 4 +- src/marnav/nmea/zfi.cpp | 35 ++++++++++++++++++ src/nmeadump.cpp | 10 +++++ test/CMakeLists.txt | 1 + test/nmea/Test_nmea.cpp | 4 +- test/nmea/Test_nmea_zfi.cpp | 73 +++++++++++++++++++++++++++++++++++++ 13 files changed, 202 insertions(+), 10 deletions(-) create mode 100644 include/marnav/nmea/zfi.hpp create mode 100644 src/marnav/nmea/zfi.cpp create mode 100644 test/nmea/Test_nmea_zfi.cpp diff --git a/README.md b/README.md index bb4b4f25..5120ca53 100644 --- a/README.md +++ b/README.md @@ -43,9 +43,9 @@ Features ### NMEA-0183 Supported sentences for NMEA-0183 (read and write): + - AAM: Waypoint Arrival Alarm - ALM: GPS Almanac Data -- APA: Autopilot Sentence "A" - APB: Autopilot Sentence "B" - BEC: Bearing and Distance to Waypoint - BOD: Bearing - Waypoint to Waypoint @@ -67,7 +67,6 @@ Supported sentences for NMEA-0183 (read and write): - GSA: Geographic Position - Latitude/Longitude - GST: GPS Pseudorange Noise Statistics - GSV: Satellites in view -- GTD: Geographic Location in Time Differences - HDG: Heading - Deviation & Variation - HDT: Heading - True - HFB: Trawl Headrope to Footrope and Bottom @@ -77,7 +76,6 @@ Supported sentences for NMEA-0183 (read and write): - MOB: Man over Board - MSK: Control for a Beacon Receiver - MSS: Beacon Receiver Status -- MTA: Air Temperature - MTW: Mean Temperature of Water - MWD: Wind Direction and Speed - MWV: Wind Speed and Angle @@ -107,8 +105,6 @@ Supported sentences for NMEA-0183 (read and write): - VLW: Distance Traveled through Water - VPW: Speed - Measured Parallel to Wind - VTG: Track made good and Ground speed -- VWE: Wind Track Efficiency -- VWR: Relative Wind Speed and Angle. - WCV: Waypoint Closure Velocity - WDC: Distance to Waypoint - WDR: Distance to Waypoint, Rumb line @@ -122,24 +118,34 @@ Supported sentences for NMEA-0183 (read and write): - ZFO: UTC & Time from origin Waypoint - ZTG: UTC & Time to Destination Waypoint -Obsolete (according to the standard) but implemented: +Obsolete (according to [NMEA Revealed]) but implemented: + +- APA: Autopilot Sentence "A" - DBK: Depth Below Keel +- GTD: Geographic Location in Time Differences - HDM: Heading - Magnetic (obsolete as of 2009) +- MTA: Air Temperature - R00: Waypoints in active route +- VWE: Wind Track Efficiency +- VWR: Relative Wind Speed and Angle. +- ZFI: Elapsed time since point of interest Vendor Extensions: + - PGRME: Garmin Estimated Error - PGRMM: Garmin Map Datum - PGRMZ: Garmin Altitude Information - STALK: SeaTalk Raw Format Miscellaneous: + - Tag Block Support (generic for all sentences) ### AIS Supported messages for AIS (decode and encode): + - Type 01: Position Report Class A - Type 02: Position Report Class A (Assigned Schedule) - Type 03: Position Report Class A (Response to Interrogation) @@ -170,6 +176,7 @@ Supported payload of binary message 08: ### SeaTalk Suported messages for SeaTalk (decode and encode): + - Type 00: depth below transducer - Type 01: equipment id - Type 05: Engine RPM and PITCH diff --git a/TODO.md b/TODO.md index 0c8edc0c..7eddd42b 100644 --- a/TODO.md +++ b/TODO.md @@ -31,7 +31,6 @@ TODO @todo Implement NMEA sentence: OLN @todo Implement NMEA sentence: TEP @todo Implement NMEA sentence: TRF -@todo Implement NMEA sentence: ZFI @todo Implement NMEA sentence: ZLZ @todo Implement NMEA sentence: ZPI @todo Implement NMEA sentence: ZTA diff --git a/doc/nmea.dox b/doc/nmea.dox index 4a1315e0..d4e0ef64 100644 --- a/doc/nmea.dox +++ b/doc/nmea.dox @@ -80,6 +80,7 @@ Supported sentences for NMEA-0183 (read and write): - \link marnav::nmea::xtr \c XTR \endlink : Cross Track Error - Dead Reckoning - \link marnav::nmea::zda \c ZDA \endlink : Time & Date - UTC, day, month, year and local time zone - \link marnav::nmea::zdl \c ZDL \endlink : Time and Distance to Variable Point +- \link marnav::nmea::zfi \c ZFI \endlink : Elapsed time from point of interest - \link marnav::nmea::zfo \c ZFO \endlink : UTC & Time from origin Waypoint - \link marnav::nmea::ztg \c ZTG \endlink : UTC & Time to Destination Waypoint diff --git a/include/marnav/nmea/sentence_id.hpp b/include/marnav/nmea/sentence_id.hpp index b17bd6f3..c86655fd 100644 --- a/include/marnav/nmea/sentence_id.hpp +++ b/include/marnav/nmea/sentence_id.hpp @@ -137,6 +137,7 @@ enum class sentence_id : uint32_t { WDC, ///< Distance to Waypoint WDR, ///< Distance to Waypoint, Rumb line VWT, ///< True Wind Speed and Angle + ZFI, ///< Elapsed time from point of interest // vendor extensions diff --git a/include/marnav/nmea/zfi.hpp b/include/marnav/nmea/zfi.hpp new file mode 100644 index 00000000..ad7c2d7e --- /dev/null +++ b/include/marnav/nmea/zfi.hpp @@ -0,0 +1,60 @@ +#ifndef MARNAV_NMEA_ZFI_HPP +#define MARNAV_NMEA_ZFI_HPP + +#include +#include +#include + +namespace marnav +{ +namespace nmea +{ +/// @brief ZFI - Elapsed time from point of interest +/// +/// @code +/// 1 2 3 +/// | | | +/// $--ZFI,hhmmss.ss,hhmmss.ss,c--c*hh +/// @endcode +/// +/// Field Number: +/// 1. Time UTC +/// 2. Elapsed time +/// 3. Waypoint ID +/// +class zfi : public sentence +{ + friend class detail::factory; + +public: + constexpr static sentence_id ID = sentence_id::ZFI; + constexpr static const char * TAG = "ZFI"; + + zfi(); + zfi(const zfi &) = default; + zfi & operator=(const zfi &) = default; + zfi(zfi &&) = default; + zfi & operator=(zfi &&) = default; + +protected: + zfi(talker talk, fields::const_iterator first, fields::const_iterator last); + virtual void append_data_to(std::string &) const override; + +private: + nmea::time time_utc_; + nmea::duration time_elapsed_; + waypoint waypoint_id_; + +public: + nmea::time get_time_utc() const { return time_utc_; } + nmea::duration get_time_elapsed() const { return time_elapsed_; } + waypoint get_waypoint_id() const { return waypoint_id_; } + + void set_time_utc(nmea::time t) noexcept { time_utc_ = t; } + void set_time_elapsed(nmea::duration t) noexcept { time_elapsed_ = t; } + void set_waypoint_id(const waypoint & t) { waypoint_id_ = t; } +}; +} +} + +#endif diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6a4a5724..0f681f90 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -164,6 +164,7 @@ target_sources(marnav marnav/nmea/xtr.cpp marnav/nmea/zda.cpp marnav/nmea/zdl.cpp + marnav/nmea/zfi.cpp marnav/nmea/zfo.cpp marnav/nmea/ztg.cpp marnav/seatalk/message.cpp diff --git a/src/marnav/nmea/name.cpp b/src/marnav/nmea/name.cpp index 628c9e8a..9a3cc08c 100644 --- a/src/marnav/nmea/name.cpp +++ b/src/marnav/nmea/name.cpp @@ -265,6 +265,8 @@ std::string to_name(sentence_id t) return "Distance to Waypoint, Rumb line"; case sentence_id::WDC: return "Distance to Waypoint"; + case sentence_id::ZFI: + return "Elapsed time since point of interest"; } return "-"; } diff --git a/src/marnav/nmea/nmea.cpp b/src/marnav/nmea/nmea.cpp index 30acad01..2364b05b 100644 --- a/src/marnav/nmea/nmea.cpp +++ b/src/marnav/nmea/nmea.cpp @@ -84,6 +84,7 @@ #include #include #include +#include #include #include #include @@ -142,7 +143,8 @@ static const std::vector known_sentences = { REGISTER_SENTENCE(wcv), REGISTER_SENTENCE(wdc), REGISTER_SENTENCE(wdr), REGISTER_SENTENCE(wnc), REGISTER_SENTENCE(wpl), REGISTER_SENTENCE(xdr), REGISTER_SENTENCE(xte), REGISTER_SENTENCE(xtr), REGISTER_SENTENCE(zda), - REGISTER_SENTENCE(zdl), REGISTER_SENTENCE(zfo), REGISTER_SENTENCE(ztg), + REGISTER_SENTENCE(zdl), REGISTER_SENTENCE(zfi), REGISTER_SENTENCE(zfo), + REGISTER_SENTENCE(ztg), // vendor extensions REGISTER_SENTENCE(pgrme), REGISTER_SENTENCE(pgrmm), REGISTER_SENTENCE(pgrmz), diff --git a/src/marnav/nmea/zfi.cpp b/src/marnav/nmea/zfi.cpp new file mode 100644 index 00000000..8e5e0cd4 --- /dev/null +++ b/src/marnav/nmea/zfi.cpp @@ -0,0 +1,35 @@ +#include +#include +#include + +namespace marnav +{ +namespace nmea +{ +constexpr sentence_id zfi::ID; +constexpr const char * zfi::TAG; + +zfi::zfi() + : sentence(ID, TAG, talker::global_positioning_system) +{ +} + +zfi::zfi(talker talk, fields::const_iterator first, fields::const_iterator last) + : sentence(ID, TAG, talk) +{ + if (std::distance(first, last) != 3) + throw std::invalid_argument{"invalid number of fields in zfi"}; + + read(*(first + 0), time_utc_); + read(*(first + 1), time_elapsed_); + read(*(first + 2), waypoint_id_); +} + +void zfi::append_data_to(std::string & s) const +{ + append(s, to_string(time_utc_)); + append(s, to_string(time_elapsed_)); + append(s, to_string(waypoint_id_)); +} +} +} diff --git a/src/nmeadump.cpp b/src/nmeadump.cpp index 442cf1ae..130e90d8 100644 --- a/src/nmeadump.cpp +++ b/src/nmeadump.cpp @@ -108,6 +108,7 @@ #include #include #include +#include #include #include #include @@ -1100,6 +1101,14 @@ static void print_detail_zdl(const marnav::nmea::sentence * s) print("Type of Point", render(t->get_type_point())); } +static void print_detail_zfi(const marnav::nmea::sentence * s) +{ + const auto t = marnav::nmea::sentence_cast(s); + print("Time UTC", render(t->get_time_utc())); + print("Elapsed Time", render(t->get_time_elapsed())); + print("Origin Waypoint", render(t->get_waypoint_id())); +} + static void print_detail_zfo(const marnav::nmea::sentence * s) { const auto t = marnav::nmea::sentence_cast(s); @@ -1980,6 +1989,7 @@ static void dump_nmea(const std::string & line) ADD_SENTENCE(xtr), ADD_SENTENCE(zda), ADD_SENTENCE(zdl), + ADD_SENTENCE(zfi), ADD_SENTENCE(zfo), ADD_SENTENCE(ztg), diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 97976030..e8953821 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -138,6 +138,7 @@ target_sources(testrunner nmea/Test_nmea_xtr.cpp nmea/Test_nmea_zda.cpp nmea/Test_nmea_zdl.cpp + nmea/Test_nmea_zfi.cpp nmea/Test_nmea_zfo.cpp nmea/Test_nmea_ztg.cpp seatalk/Test_seatalk_message.cpp diff --git a/test/nmea/Test_nmea.cpp b/test/nmea/Test_nmea.cpp index 98ddb760..a7ab3667 100644 --- a/test/nmea/Test_nmea.cpp +++ b/test/nmea/Test_nmea.cpp @@ -114,14 +114,14 @@ TEST_F(Test_nmea, get_supported_sentences_str) { auto v = nmea::get_supported_sentences_str(); - EXPECT_EQ(85u, v.size()); + EXPECT_EQ(86u, v.size()); } TEST_F(Test_nmea, get_supported_sentences_id) { auto v = nmea::get_supported_sentences_id(); - EXPECT_EQ(85u, v.size()); + EXPECT_EQ(86u, v.size()); } TEST_F(Test_nmea, tag_to_id) diff --git a/test/nmea/Test_nmea_zfi.cpp b/test/nmea/Test_nmea_zfi.cpp new file mode 100644 index 00000000..f9d128ab --- /dev/null +++ b/test/nmea/Test_nmea_zfi.cpp @@ -0,0 +1,73 @@ +#include +#include "type_traits_helper.hpp" +#include +#include + +namespace +{ +using namespace marnav; + +class Test_nmea_zfi : public ::testing::Test +{ +}; + +TEST_F(Test_nmea_zfi, contruction) +{ + EXPECT_NO_THROW(nmea::zfi zfi); +} + +TEST_F(Test_nmea_zfi, properties) +{ + nmea_sentence_traits(); +} + +TEST_F(Test_nmea_zfi, parse) +{ + auto s = nmea::make_sentence("$GPZFI,123456.1,012345.12,POINT1*27"); + ASSERT_NE(nullptr, s); + + auto zfi = nmea::sentence_cast(s); + ASSERT_NE(nullptr, zfi); + + EXPECT_STREQ("POINT1", zfi->get_waypoint_id().c_str()); +} + +TEST_F(Test_nmea_zfi, parse_invalid_number_of_arguments) +{ + EXPECT_ANY_THROW( + nmea::detail::factory::sentence_parse(nmea::talker::none, {2, "@"})); + EXPECT_ANY_THROW( + nmea::detail::factory::sentence_parse(nmea::talker::none, {4, "@"})); +} + +TEST_F(Test_nmea_zfi, empty_to_string) +{ + nmea::zfi zfi; + + EXPECT_STREQ("$GPZFI,000000,000000,*6E", nmea::to_string(zfi).c_str()); +} + +TEST_F(Test_nmea_zfi, set_time_utc) +{ + nmea::zfi zfi; + zfi.set_time_utc(nmea::time{12, 34, 56}); + + EXPECT_STREQ("$GPZFI,123456,000000,*69", nmea::to_string(zfi).c_str()); +} + +TEST_F(Test_nmea_zfi, set_time_elapsed) +{ + nmea::zfi zfi; + zfi.set_time_elapsed(nmea::duration{12, 34, 56}); + + EXPECT_STREQ("$GPZFI,000000,123456,*69", nmea::to_string(zfi).c_str()); +} + +TEST_F(Test_nmea_zfi, set_waypoint_id) +{ + nmea::zfi zfi; + zfi.set_waypoint_id(nmea::waypoint{"POINT1"}); + + EXPECT_STREQ("$GPZFI,000000,000000,POINT1*13", nmea::to_string(zfi).c_str()); +} +} -- 2.11.4.GIT