nmealib 0.0.4
NMEA 0183/NMEA 2000 parsing library
Loading...
Searching...
No Matches
vhw.cpp
Go to the documentation of this file.
2
5
6#include <iomanip>
7#include <sstream>
8#include <vector>
9
10namespace nmealib {
11namespace nmea0183 {
12
13std::unique_ptr<VHW> VHW::create(std::unique_ptr<Message0183> baseMessage) {
14 std::string context = "VHW::create";
15 if (baseMessage->getSentenceType() != "VHW") {
16 NMEALIB_RETURN_ERROR(NotVHWException(context, "Expected sentence type 'VHW', got " + baseMessage->getSentenceType()));
17 }
18
19 std::string payload = baseMessage->getPayload();
20 std::istringstream ss(payload);
21 std::string token;
22 std::vector<std::string> fields;
23
24 while (std::getline(ss, token, ',')) {
25 fields.push_back(token);
26 }
27
28 if (!payload.empty() && payload.back() == ',') {
29 fields.push_back("");
30 }
31
32 if (!fields.empty()) {
33 fields.erase(fields.begin());
34 }
35
36 if (fields.size() != 8) {
37 NMEALIB_RETURN_ERROR(NotVHWException(context, "Invalid fields in VHW payload: expected 8, got " + std::to_string(fields.size()) + ". Payload: " + payload));
38 }
39
40 double headingTrue = 0.0;
41 double headingMagnetic = 0.0;
42 double speedKnots = 0.0;
43 double speedKph = 0.0;
44 if (!detail::parseOptionalDouble(fields[0], headingTrue) ||
45 !detail::parseOptionalDouble(fields[2], headingMagnetic) ||
46 !detail::parseOptionalDouble(fields[4], speedKnots) ||
47 !detail::parseOptionalDouble(fields[6], speedKph)) {
48 NMEALIB_RETURN_ERROR(NmeaException(context, "Error parsing VHW fields"));
49 }
50
51 char headingTrueType = fields[1].empty() ? '\0' : fields[1][0];
52 char headingMagneticType = fields[3].empty() ? '\0' : fields[3][0];
53 char speedKnotsType = fields[5].empty() ? '\0' : fields[5][0];
54 char speedKphType = fields[7].empty() ? '\0' : fields[7][0];
55
56 return std::unique_ptr<VHW>(new VHW(std::move(*baseMessage),
57 headingTrue,
58 headingTrueType,
59 headingMagnetic,
60 headingMagneticType,
61 speedKnots,
62 speedKnotsType,
63 speedKph,
64 speedKphType));
65}
66
67VHW::VHW(Message0183 baseMessage,
68 double headingTrue,
69 char headingTrueType,
70 double headingMagnetic,
71 char headingMagneticType,
72 double speedKnots,
73 char speedKnotsType,
74 double speedKph,
75 char speedKphType) noexcept
76 : Message0183(std::move(baseMessage)),
77 headingTrue_(headingTrue),
78 headingTrueType_(headingTrueType),
79 headingMagnetic_(headingMagnetic),
80 headingMagneticType_(headingMagneticType),
81 speedKnots_(speedKnots),
82 speedKnotsType_(speedKnotsType),
83 speedKph_(speedKph),
84 speedKphType_(speedKphType) {}
85
86VHW::VHW(std::string talkerId,
87 double headingTrue,
88 double headingMagnetic,
89 double speedKnots,
90 double speedKph)
91 : Message0183(*Message0183::create(composeRaw(talkerId,
92 headingTrue,
93 headingMagnetic,
94 speedKnots,
95 speedKph))),
96 headingTrue_(headingTrue),
97 headingTrueType_('T'),
98 headingMagnetic_(headingMagnetic),
99 headingMagneticType_('M'),
100 speedKnots_(speedKnots),
101 speedKnotsType_('N'),
102 speedKph_(speedKph),
103 speedKphType_('K') {}
104
105std::unique_ptr<nmealib::Message> VHW::clone() const {
106 return std::unique_ptr<VHW>(new VHW(*this));
107}
108
109std::string VHW::getStringContent(bool verbose) const noexcept {
110 std::ostringstream ss;
111 ss << this->toString(verbose);
112 ss << std::fixed << std::setprecision(2);
113
114 if (verbose) {
115 ss << "\tHeading: " << headingTrue_ << " " << headingTrueType_ << "\n";
116 ss << "\tHeading: " << headingMagnetic_ << " " << headingMagneticType_ << "\n";
117 ss << "\tSpeed: " << speedKnots_ << "kts\n"
118 << "\tSpeed: " << speedKph_ << "kph";
119 ss << "\n";
120 } else {
121 ss << "True=" << headingTrue_
122 << ", Magnetic=" << headingMagnetic_
123 << ", Knots=" << speedKnots_
124 << ", KPH=" << speedKph_;
125 }
126
127 return ss.str();
128}
129
130std::string VHW::composeRaw(const std::string& talkerId,
131 double headingTrue,
132 double headingMagnetic,
133 double speedKnots,
134 double speedKph) {
135 std::ostringstream payloadStream;
136 payloadStream << talkerId << "VHW,";
137 payloadStream << std::fixed << std::setprecision(2) << headingTrue << ",T,";
138 payloadStream << std::fixed << std::setprecision(2) << headingMagnetic << ",M,";
139 payloadStream << std::fixed << std::setprecision(3) << speedKnots << ",N,";
140 payloadStream << std::fixed << std::setprecision(3) << speedKph << ",K";
141
142 std::string payload = payloadStream.str();
143 return "$" + payload + "\r\n";
144}
145
146double VHW::getHeadingTrue() const noexcept {
147 return headingTrue_;
148}
149
150char VHW::getHeadingTrueType() const noexcept {
151 return headingTrueType_;
152}
153
154double VHW::getHeadingMagnetic() const noexcept {
155 return headingMagnetic_;
156}
157
158char VHW::getHeadingMagneticType() const noexcept {
159 return headingMagneticType_;
160}
161
162double VHW::getSpeedKnots() const noexcept {
163 return speedKnots_;
164}
165
166char VHW::getSpeedKnotsType() const noexcept {
167 return speedKnotsType_;
168}
169
170double VHW::getSpeedKph() const noexcept {
171 return speedKph_;
172}
173
174char VHW::getSpeedKphType() const noexcept {
175 return speedKphType_;
176}
177
178bool VHW::operator==(const VHW& other) const noexcept {
179 return Message0183::operator==(other);
180}
181
182} // namespace nmea0183
183} // namespace nmealib
Represents an NMEA 0183 sentence.
Definition nmea0183.h:98
bool operator==(const Message0183 &other) const noexcept
Compares two Message0183 objects for equality based on their content and timestamp.
Definition nmea0183.cpp:204
Represents a parsed NMEA 0183 VHW (Water Speed and Heading) sentence.
Definition vhw.h:36
std::unique_ptr< nmealib::Message > clone() const override
Create a polymorphic copy of this VHW message.
Definition vhw.cpp:105
char getSpeedKphType() const noexcept
Get km/h unit indicator (typically 'K').
Definition vhw.cpp:174
char getHeadingTrueType() const noexcept
Get true heading type indicator (typically 'T').
Definition vhw.cpp:150
double getHeadingMagnetic() const noexcept
Get magnetic heading in degrees.
Definition vhw.cpp:154
bool operator==(const VHW &other) const noexcept
Compare two VHW messages for equality.
Definition vhw.cpp:178
std::string getStringContent(bool verbose) const noexcept override
Return a human-readable string representation of this message.
Definition vhw.cpp:109
double getHeadingTrue() const noexcept
Get true heading in degrees.
Definition vhw.cpp:146
char getHeadingMagneticType() const noexcept
Get magnetic heading type indicator (typically 'M').
Definition vhw.cpp:158
double getSpeedKph() const noexcept
Get speed through water in kilometers per hour.
Definition vhw.cpp:170
double getSpeedKnots() const noexcept
Get speed through water in knots.
Definition vhw.cpp:162
VHW(std::string talkerId, double headingTrue, double headingMagnetic, double speedKnots, double speedKph)
Construct a VHW message from individual field values.
Definition vhw.cpp:86
char getSpeedKnotsType() const noexcept
Get knots unit indicator (typically 'N').
Definition vhw.cpp:166
#define NMEALIB_RETURN_ERROR(exceptionExpr)
bool parseOptionalDouble(const std::string &text, double &value) noexcept
Definition parse.h:86