nmealib 0.0.4
NMEA 0183/NMEA 2000 parsing library
Loading...
Searching...
No Matches
vwr.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<VWR> VWR::create(std::unique_ptr<Message0183> baseMessage) {
14 std::string context = "VWR::create";
15 if (baseMessage->getSentenceType() != "VWR") {
16 NMEALIB_RETURN_ERROR(NotVWRException(context, "Expected sentence type 'VWR', 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(NotVWRException(context, "Invalid fields in VWR payload: expected 8, got " + std::to_string(fields.size()) + ". Payload: " + payload));
38 }
39
40 double windAngle = 0.0;
41 double speedKnots = 0.0;
42 double speedMps = 0.0;
43 double speedKph = 0.0;
44 if (!detail::parseOptionalDouble(fields[0], windAngle) ||
45 !detail::parseOptionalDouble(fields[2], speedKnots) ||
46 !detail::parseOptionalDouble(fields[4], speedMps) ||
47 !detail::parseOptionalDouble(fields[6], speedKph)) {
48 NMEALIB_RETURN_ERROR(NmeaException(context, "Error parsing VWR fields"));
49 }
50
51 char windSide = fields[1].empty() ? '\0' : fields[1][0];
52 char speedKnotsUnit = fields[3].empty() ? '\0' : fields[3][0];
53 char speedMpsUnit = fields[5].empty() ? '\0' : fields[5][0];
54 char speedKphUnit = fields[7].empty() ? '\0' : fields[7][0];
55
56 return std::unique_ptr<VWR>(new VWR(std::move(*baseMessage),
57 windAngle,
58 windSide,
59 speedKnots,
60 speedKnotsUnit,
61 speedMps,
62 speedMpsUnit,
63 speedKph,
64 speedKphUnit));
65}
66
67VWR::VWR(Message0183 baseMessage,
68 double windAngle,
69 char windSide,
70 double speedKnots,
71 char speedKnotsUnit,
72 double speedMps,
73 char speedMpsUnit,
74 double speedKph,
75 char speedKphUnit) noexcept
76 : Message0183(std::move(baseMessage)),
77 windAngle_(windAngle),
78 windSide_(windSide),
79 speedKnots_(speedKnots),
80 speedKnotsUnit_(speedKnotsUnit),
81 speedMps_(speedMps),
82 speedMpsUnit_(speedMpsUnit),
83 speedKph_(speedKph),
84 speedKphUnit_(speedKphUnit) {}
85
86VWR::VWR(std::string talkerId,
87 double windAngle,
88 char windSide,
89 double speedKnots,
90 double speedMps,
91 double speedKph)
92 : Message0183(*Message0183::create(composeRaw(talkerId,
93 windAngle,
94 windSide,
95 speedKnots,
96 speedMps,
97 speedKph))),
98 windAngle_(windAngle),
99 windSide_(windSide),
100 speedKnots_(speedKnots),
101 speedKnotsUnit_('N'),
102 speedMps_(speedMps),
103 speedMpsUnit_('M'),
104 speedKph_(speedKph),
105 speedKphUnit_('K') {}
106
107std::unique_ptr<nmealib::Message> VWR::clone() const {
108 return std::unique_ptr<VWR>(new VWR(*this));
109}
110
111std::string VWR::getStringContent(bool verbose) const noexcept {
112 std::ostringstream ss;
113 ss << this->toString(verbose);
114 ss << std::fixed << std::setprecision(2);
115
116 if (verbose) {
117 ss << "\tWind Angle: " << windAngle_ << "\n";
118 ss << "\tWind Side: " << windSide_ << "\n";
119 ss << "\tSpeed: " << speedKnots_ << "kts\n";
120 ss << "\tSpeed: " << speedMps_ << " m/s\n";
121 ss << "\tSpeed: " << speedKph_ << " kph";
122 ss << "\n";
123 } else {
124 ss << "Angle=" << windAngle_ << windSide_
125 << ", Knots=" << speedKnots_
126 << ", m/s=" << speedMps_
127 << ", KPH=" << speedKph_;
128 }
129
130 return ss.str();
131}
132
133std::string VWR::composeRaw(const std::string& talkerId,
134 double windAngle,
135 char windSide,
136 double speedKnots,
137 double speedMps,
138 double speedKph) {
139 std::ostringstream payloadStream;
140 payloadStream << talkerId << "VWR,";
141 payloadStream << std::fixed << std::setprecision(1) << windAngle << ",";
142 payloadStream << windSide << ",";
143 payloadStream << std::fixed << std::setprecision(1) << speedKnots << ",N,";
144 payloadStream << std::fixed << std::setprecision(1) << speedMps << ",M,";
145 payloadStream << std::fixed << std::setprecision(1) << speedKph << ",K";
146
147 std::string payload = payloadStream.str();
148 return "$" + payload + "\r\n";
149}
150
151double VWR::getWindAngle() const noexcept {
152 return windAngle_;
153}
154
155char VWR::getWindSide() const noexcept {
156 return windSide_;
157}
158
159double VWR::getSpeedKnots() const noexcept {
160 return speedKnots_;
161}
162
163char VWR::getSpeedKnotsUnit() const noexcept {
164 return speedKnotsUnit_;
165}
166
167double VWR::getSpeedMps() const noexcept {
168 return speedMps_;
169}
170
171char VWR::getSpeedMpsUnit() const noexcept {
172 return speedMpsUnit_;
173}
174
175double VWR::getSpeedKph() const noexcept {
176 return speedKph_;
177}
178
179char VWR::getSpeedKphUnit() const noexcept {
180 return speedKphUnit_;
181}
182
183bool VWR::operator==(const VWR& other) const noexcept {
184 return Message0183::operator==(other);
185}
186
187} // namespace nmea0183
188} // 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 VWR sentence (Relative Wind Speed and Angle).
Definition vwr.h:37
double getSpeedKph() const noexcept
Returns the wind speed in kilometers per hour.
Definition vwr.cpp:175
double getWindAngle() const noexcept
Returns the wind direction magnitude in degrees (0–180).
Definition vwr.cpp:151
bool operator==(const VWR &other) const noexcept
Definition vwr.cpp:183
char getSpeedKnotsUnit() const noexcept
Returns the knots unit indicator character.
Definition vwr.cpp:163
VWR(std::string talkerId, double windAngle, char windSide, double speedKnots, double speedMps, double speedKph)
Construct a VWR sentence from individual field values.
Definition vwr.cpp:86
char getSpeedMpsUnit() const noexcept
Returns the meters-per-second unit indicator character.
Definition vwr.cpp:171
char getWindSide() const noexcept
Returns the wind direction side relative to the vessel.
Definition vwr.cpp:155
std::string getStringContent(bool verbose) const noexcept override
Returns a human-readable string representation of the message content.
Definition vwr.cpp:111
double getSpeedKnots() const noexcept
Returns the wind speed in knots.
Definition vwr.cpp:159
std::unique_ptr< nmealib::Message > clone() const override
Creates a polymorphic deep copy of this Message0183.
Definition vwr.cpp:107
double getSpeedMps() const noexcept
Returns the wind speed in meters per second.
Definition vwr.cpp:167
char getSpeedKphUnit() const noexcept
Returns the kilometers-per-hour unit indicator character.
Definition vwr.cpp:179
#define NMEALIB_RETURN_ERROR(exceptionExpr)
bool parseOptionalDouble(const std::string &text, double &value) noexcept
Definition parse.h:86