nmealib 0.0.4
NMEA 0183/NMEA 2000 parsing library
Loading...
Searching...
No Matches
hdg.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<HDG> HDG::create(std::unique_ptr<Message0183> baseMessage) {
14 std::string context = "HDG::create";
15 if (baseMessage->getSentenceType() != "HDG") {
16 NMEALIB_RETURN_ERROR(NotHDGException(context, "Expected sentence type 'HDG', 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() != 5) {
37 NMEALIB_RETURN_ERROR(NotHDGException(context, "Invalid fields in HDG payload: expected 5, got " + std::to_string(fields.size()) + ". Payload: " + payload));
38 }
39
40 double magneticHeading = 0.0;
41 double magneticDeviation = 0.0;
42 double magneticVariation = 0.0;
43 if (!detail::parseOptionalDouble(fields[0], magneticHeading) ||
44 !detail::parseOptionalDouble(fields[1], magneticDeviation) ||
45 !detail::parseOptionalDouble(fields[3], magneticVariation)) {
46 NMEALIB_RETURN_ERROR(NmeaException(context, "Error parsing HDG fields"));
47 }
48
49 char deviationDirection = fields[2].empty() ? '\0' : fields[2][0];
50 char variationDirection = fields[4].empty() ? '\0' : fields[4][0];
51
52 return std::unique_ptr<HDG>(new HDG(std::move(*baseMessage),
53 magneticHeading,
54 magneticDeviation,
55 deviationDirection,
56 magneticVariation,
57 variationDirection));
58}
59
60HDG::HDG(Message0183 baseMessage,
61 double magneticHeading,
62 double magneticDeviation,
63 char deviationDirection,
64 double magneticVariation,
65 char variationDirection) noexcept
66 : Message0183(std::move(baseMessage)),
67 magneticHeading_(magneticHeading),
68 magneticDeviation_(magneticDeviation),
69 deviationDirection_(deviationDirection),
70 magneticVariation_(magneticVariation),
71 variationDirection_(variationDirection) {}
72
73HDG::HDG(std::string talkerId,
74 double magneticHeading,
75 double magneticDeviation,
76 char deviationDirection,
77 double magneticVariation,
78 char variationDirection)
79 : Message0183(*Message0183::create(composeRaw(talkerId,
80 magneticHeading,
81 magneticDeviation,
82 deviationDirection,
83 magneticVariation,
84 variationDirection))),
85 magneticHeading_(magneticHeading),
86 magneticDeviation_(magneticDeviation),
87 deviationDirection_(deviationDirection),
88 magneticVariation_(magneticVariation),
89 variationDirection_(variationDirection) {}
90
91std::unique_ptr<nmealib::Message> HDG::clone() const {
92 return std::unique_ptr<HDG>(new HDG(*this));
93}
94
95std::string HDG::getStringContent(bool verbose) const noexcept {
96 std::ostringstream ss;
97 ss << this->toString(verbose);
98 ss << std::fixed << std::setprecision(1);
99 const char deviationDirection = (deviationDirection_ == '\0') ? '-' : deviationDirection_;
100 const char variationDirection = (variationDirection_ == '\0') ? '-' : variationDirection_;
101
102 if (verbose) {
103 ss << "\tMagnetic Heading: " << magneticHeading_ << "\n";
104 ss << "\tMagnetic Deviation: " << magneticDeviation_ << " " << deviationDirection << "\n";
105 ss << "\tMagnetic Variation: " << magneticVariation_ << " " << variationDirection << "\n";
106 } else {
107 ss << "HeadingM=" << magneticHeading_
108 << ", Dev=" << magneticDeviation_ << deviationDirection
109 << ", Var=" << magneticVariation_ << variationDirection;
110 }
111
112 return ss.str();
113}
114
115std::string HDG::composeRaw(const std::string& talkerId,
116 double magneticHeading,
117 double magneticDeviation,
118 char deviationDirection,
119 double magneticVariation,
120 char variationDirection) {
121 std::ostringstream payloadStream;
122 payloadStream << talkerId << "HDG,";
123 payloadStream << std::fixed << std::setprecision(1) << magneticHeading << ",";
124 payloadStream << std::fixed << std::setprecision(1) << magneticDeviation << ",";
125 payloadStream << deviationDirection << ",";
126 payloadStream << std::fixed << std::setprecision(1) << magneticVariation << ",";
127 payloadStream << variationDirection;
128
129 std::string payload = payloadStream.str();
130 return "$" + payload + "\r\n";
131}
132
133double HDG::getMagneticHeading() const noexcept {
134 return magneticHeading_;
135}
136
137double HDG::getMagneticDeviation() const noexcept {
138 return magneticDeviation_;
139}
140
141char HDG::getDeviationDirection() const noexcept {
142 return deviationDirection_;
143}
144
145double HDG::getMagneticVariation() const noexcept {
146 return magneticVariation_;
147}
148
149char HDG::getVariationDirection() const noexcept {
150 return variationDirection_;
151}
152
153bool HDG::operator==(const HDG& other) const noexcept {
154 return Message0183::operator==(other);
155}
156
157} // namespace nmea0183
158} // namespace nmealib
Represents a parsed NMEA 0183 HDG (Heading, Deviation & Variation) sentence.
Definition hdg.h:37
bool operator==(const HDG &other) const noexcept
Definition hdg.cpp:153
double getMagneticVariation() const noexcept
Definition hdg.cpp:145
std::unique_ptr< nmealib::Message > clone() const override
Creates a polymorphic deep copy of this message.
Definition hdg.cpp:91
std::string getStringContent(bool verbose) const noexcept override
Returns a human-readable string representation of the message content.
Definition hdg.cpp:95
char getVariationDirection() const noexcept
Definition hdg.cpp:149
double getMagneticDeviation() const noexcept
Definition hdg.cpp:137
char getDeviationDirection() const noexcept
Definition hdg.cpp:141
double getMagneticHeading() const noexcept
Definition hdg.cpp:133
HDG(std::string talkerId, double magneticHeading, double magneticDeviation, char deviationDirection, double magneticVariation, char variationDirection)
Construct an HDG message from individual field values.
Definition hdg.cpp:73
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
#define NMEALIB_RETURN_ERROR(exceptionExpr)
bool parseOptionalDouble(const std::string &text, double &value) noexcept
Definition parse.h:86