13std::unique_ptr<GSA> GSA::create(std::unique_ptr<Message0183> baseMessage) {
14 std::string context =
"GSA::create";
15 if (baseMessage->getSentenceType() !=
"GSA") {
16 NMEALIB_RETURN_ERROR(NotGSAException(context,
"Expected sentence type 'GSA', got " + baseMessage->getSentenceType()));
19 std::string payload = baseMessage->getPayload();
20 std::istringstream ss(payload);
22 std::vector<std::string> fields;
24 while (std::getline(ss, token,
',')) {
25 fields.push_back(token);
28 if (!payload.empty() && payload.back() ==
',') {
32 if (!fields.empty()) {
33 fields.erase(fields.begin());
36 if (fields.size() != 17 && fields.size() != 18) {
37 NMEALIB_RETURN_ERROR(NotGSAException(context,
"Invalid fields in GSA payload: expected 17 or 18, got " + std::to_string(fields.size()) +
". Payload: " + payload));
40 char selectionMode = fields[0].empty() ?
'\0' : fields[0][0];
41 unsigned int mode = 0U;
46 std::array<unsigned int, 12> satelliteIds{};
47 for (
size_t index = 0; index < satelliteIds.size(); ++index) {
62 std::optional<unsigned int> systemId = std::nullopt;
63 if (fields.size() == 18 && !fields[17].empty()) {
64 unsigned int parsedSystemId = 0U;
68 systemId = parsedSystemId;
71 return std::unique_ptr<GSA>(
new GSA(std::move(*baseMessage),
81GSA::GSA(Message0183 baseMessage,
84 std::array<unsigned int, 12> satelliteIds,
88 std::optional<unsigned int> systemId) noexcept
89 : Message0183(std::move(baseMessage)),
90 selectionMode_(selectionMode),
92 satelliteIds_(satelliteIds),
96 systemId_(systemId) {}
98GSA::GSA(std::string talkerId,
101 std::array<unsigned int, 12> satelliteIds,
105 std::optional<unsigned int> systemId)
114 selectionMode_(selectionMode),
116 satelliteIds_(satelliteIds),
120 systemId_(systemId) {}
123 return std::unique_ptr<GSA>(
new GSA(*
this));
127 std::ostringstream ss;
128 ss << this->toString(verbose);
131 ss <<
"\tSelection Mode: " << selectionMode_ <<
"\n";
132 ss <<
"\tMode: " << mode_ <<
"\n";
133 ss <<
"\tSatellites: ";
136 for (
unsigned int satelliteId : satelliteIds_) {
137 if (satelliteId == 0u) {
151 <<
"\tPDOP: " << pdop_ <<
"\n"
152 <<
"\tHDOP: " << hdop_ <<
"\n"
153 <<
"\tVDOP: " << vdop_;
155 if (systemId_.has_value()) {
157 <<
"\tSystem ID: " << systemId_.value();
161 ss <<
"SelectionMode=" << selectionMode_
162 <<
", Mode=" << mode_
163 <<
", PDOP=" << pdop_
164 <<
", HDOP=" << hdop_
165 <<
", VDOP=" << vdop_;
166 if (systemId_.has_value()) {
167 ss <<
", SystemID=" << systemId_.value();
174std::string GSA::composeRaw(
const std::string& talkerId,
177 std::array<unsigned int, 12> satelliteIds,
181 std::optional<unsigned int> systemId) {
182 std::ostringstream payloadStream;
183 payloadStream << talkerId <<
"GSA,";
184 payloadStream << selectionMode <<
",";
185 payloadStream << mode;
187 for (
unsigned int satelliteId : satelliteIds) {
188 payloadStream <<
",";
189 if (satelliteId != 0u) {
190 payloadStream << std::setw(2) << std::setfill(
'0') << satelliteId;
194 payloadStream <<
"," << std::fixed << std::setprecision(2) << pdop;
195 payloadStream <<
"," << std::fixed << std::setprecision(2) << hdop;
196 payloadStream <<
"," << std::fixed << std::setprecision(2) << vdop;
198 if (systemId.has_value()) {
199 payloadStream <<
"," << systemId.value();
202 std::string payload = payloadStream.str();
203 return "$" + payload +
"\r\n";
207 return selectionMode_;
215 return satelliteIds_;
219 return index < satelliteIds_.size() ? satelliteIds_[index] : 0u;
235 return systemId_.has_value();
Represents a parsed NMEA 0183 GSA (GNSS DOP and Active Satellites) sentence.
bool hasSystemId() const noexcept
Return whether an optional system ID is present.
GSA(std::string talkerId, char selectionMode, unsigned int mode, std::array< unsigned int, 12 > satelliteIds, double pdop, double hdop, double vdop, std::optional< unsigned int > systemId=std::nullopt)
Construct a GSA message from individual field values.
unsigned int getSatelliteId(size_t index) const noexcept
Get one satellite ID by slot index.
double getVdop() const noexcept
Get VDOP value.
std::unique_ptr< nmealib::Message > clone() const override
Create a polymorphic copy of this GSA message.
std::optional< unsigned int > getSystemId() const noexcept
Get optional GNSS system ID.
double getHdop() const noexcept
Get HDOP value.
bool operator==(const GSA &other) const noexcept
Compare two GSA messages for equality.
double getPdop() const noexcept
Get PDOP value.
unsigned int getMode() const noexcept
Get fix dimension mode.
std::array< unsigned int, 12 > getSatelliteIds() const noexcept
Get all 12 satellite ID slots (0 for empty).
char getSelectionMode() const noexcept
Get selection mode indicator.
std::string getStringContent(bool verbose) const noexcept override
Return a human-readable string representation of this message.
Represents an NMEA 0183 sentence.
bool operator==(const Message0183 &other) const noexcept
Compares two Message0183 objects for equality based on their content and timestamp.
#define NMEALIB_RETURN_ERROR(exceptionExpr)
bool parseUnsigned(const std::string &text, T &value, int base=10) noexcept
bool parseOptionalUnsigned(const std::string &text, unsigned int &value) noexcept
bool parseOptionalDouble(const std::string &text, double &value) noexcept