13std::unique_ptr<APB> APB::create(std::unique_ptr<Message0183> baseMessage) {
14 std::string context =
"APB::create";
15 if (baseMessage->getSentenceType() !=
"APB") {
16 NMEALIB_RETURN_ERROR(NotAPBException(context,
"Expected sentence type 'APB', 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() != 14) {
37 NMEALIB_RETURN_ERROR(NotAPBException(context,
"Invalid fields in APB payload: expected 14, got " + std::to_string(fields.size()) +
". Payload: " + payload));
40 double crossTrackErrorMagnitude = 0.0;
41 double bearingOriginToDestination = 0.0;
42 double bearingPresentToDestination = 0.0;
43 double headingToSteerToDestinationWaypoint = 0.0;
51 char status1 = fields[0].empty() ?
'\0' : fields[0][0];
52 char status2 = fields[1].empty() ?
'\0' : fields[1][0];
53 char directionToSteer = fields[3].empty() ?
'\0' : fields[3][0];
54 char crossTrackUnits = fields[4].empty() ?
'\0' : fields[4][0];
55 char arrivalCircleStatus = fields[5].empty() ?
'\0' : fields[5][0];
56 char perpendicularPassedAtWaypoint = fields[6].empty() ?
'\0' : fields[6][0];
57 char bearingOriginToDestinationType = fields[8].empty() ?
'\0' : fields[8][0];
58 std::string destinationWaypointId = fields[9];
59 char bearingPresentToDestinationType = fields[11].empty() ?
'\0' : fields[11][0];
60 char headingToSteerToDestinationWaypointType = fields[13].empty() ?
'\0' : fields[13][0];
62 return std::unique_ptr<APB>(
new APB(std::move(*baseMessage),
65 crossTrackErrorMagnitude,
69 perpendicularPassedAtWaypoint,
70 bearingOriginToDestination,
71 bearingOriginToDestinationType,
72 destinationWaypointId,
73 bearingPresentToDestination,
74 bearingPresentToDestinationType,
75 headingToSteerToDestinationWaypoint,
76 headingToSteerToDestinationWaypointType));
79APB::APB(Message0183 baseMessage,
82 double crossTrackErrorMagnitude,
83 char directionToSteer,
85 char arrivalCircleStatus,
86 char perpendicularPassedAtWaypoint,
87 double bearingOriginToDestination,
88 char bearingOriginToDestinationType,
89 std::string destinationWaypointId,
90 double bearingPresentToDestination,
91 char bearingPresentToDestinationType,
92 double headingToSteerToDestinationWaypoint,
93 char headingToSteerToDestinationWaypointType) noexcept
94 : Message0183(std::move(baseMessage)),
97 crossTrackErrorMagnitude_(crossTrackErrorMagnitude),
98 directionToSteer_(directionToSteer),
99 crossTrackUnits_(crossTrackUnits),
100 arrivalCircleStatus_(arrivalCircleStatus),
101 perpendicularPassedAtWaypoint_(perpendicularPassedAtWaypoint),
102 bearingOriginToDestination_(bearingOriginToDestination),
103 bearingOriginToDestinationType_(bearingOriginToDestinationType),
104 destinationWaypointId_(std::move(destinationWaypointId)),
105 bearingPresentToDestination_(bearingPresentToDestination),
106 bearingPresentToDestinationType_(bearingPresentToDestinationType),
107 headingToSteerToDestinationWaypoint_(headingToSteerToDestinationWaypoint),
108 headingToSteerToDestinationWaypointType_(headingToSteerToDestinationWaypointType) {}
110APB::APB(std::string talkerId,
113 double crossTrackErrorMagnitude,
114 char directionToSteer,
115 char crossTrackUnits,
116 char arrivalCircleStatus,
117 char perpendicularPassedAtWaypoint,
118 double bearingOriginToDestination,
119 char bearingOriginToDestinationType,
120 std::string destinationWaypointId,
121 double bearingPresentToDestination,
122 char bearingPresentToDestinationType,
123 double headingToSteerToDestinationWaypoint,
124 char headingToSteerToDestinationWaypointType)
128 crossTrackErrorMagnitude,
132 perpendicularPassedAtWaypoint,
133 bearingOriginToDestination,
134 bearingOriginToDestinationType,
135 destinationWaypointId,
136 bearingPresentToDestination,
137 bearingPresentToDestinationType,
138 headingToSteerToDestinationWaypoint,
139 headingToSteerToDestinationWaypointType))),
142 crossTrackErrorMagnitude_(crossTrackErrorMagnitude),
143 directionToSteer_(directionToSteer),
144 crossTrackUnits_(crossTrackUnits),
145 arrivalCircleStatus_(arrivalCircleStatus),
146 perpendicularPassedAtWaypoint_(perpendicularPassedAtWaypoint),
147 bearingOriginToDestination_(bearingOriginToDestination),
148 bearingOriginToDestinationType_(bearingOriginToDestinationType),
149 destinationWaypointId_(std::move(destinationWaypointId)),
150 bearingPresentToDestination_(bearingPresentToDestination),
151 bearingPresentToDestinationType_(bearingPresentToDestinationType),
152 headingToSteerToDestinationWaypoint_(headingToSteerToDestinationWaypoint),
153 headingToSteerToDestinationWaypointType_(headingToSteerToDestinationWaypointType) {}
156 return std::unique_ptr<APB>(
new APB(*
this));
160 std::ostringstream ss;
161 ss << this->toString(verbose);
162 ss << std::fixed << std::setprecision(2);
165 ss <<
"\tStatus 1: " << status1_ <<
"\n";
166 ss <<
"\tStatus 2: " << status2_ <<
"\n";
167 ss <<
"\tCross Track Error Magnitude: " << crossTrackErrorMagnitude_ <<
"\n";
168 ss <<
"\tDirection to Steer: " << directionToSteer_ <<
"\n";
169 ss <<
"\tCross Track Units: " << crossTrackUnits_ <<
"\n";
170 ss <<
"\tArrival Circle Status: " << arrivalCircleStatus_ <<
"\n";
171 ss <<
"\tPerpendicular Passed at Waypoint: " << perpendicularPassedAtWaypoint_ <<
"\n";
172 ss <<
"\tBearing Origin->Destination: " << bearingOriginToDestination_ <<
" " << bearingOriginToDestinationType_ <<
"\n";
173 ss <<
"\tDestination Waypoint ID: " << destinationWaypointId_ <<
"\n";
174 ss <<
"\tBearing Present->Destination: " << bearingPresentToDestination_ <<
" " << bearingPresentToDestinationType_ <<
"\n";
175 ss <<
"\tHeading to Steer: " << headingToSteerToDestinationWaypoint_ <<
" " << headingToSteerToDestinationWaypointType_ <<
"\n";
177 ss <<
"Status1=" << status1_
178 <<
", Status2=" << status2_
179 <<
", XTE=" << crossTrackErrorMagnitude_ << crossTrackUnits_
180 <<
", Steer=" << directionToSteer_
181 <<
", Arrival=" << arrivalCircleStatus_
182 <<
", Perpendicular=" << perpendicularPassedAtWaypoint_
183 <<
", BOD=" << bearingOriginToDestination_ << bearingOriginToDestinationType_
184 <<
", Dest=" << destinationWaypointId_
185 <<
", BPD=" << bearingPresentToDestination_ << bearingPresentToDestinationType_
186 <<
", Heading=" << headingToSteerToDestinationWaypoint_ << headingToSteerToDestinationWaypointType_;
192std::string APB::composeRaw(
const std::string& talkerId,
195 double crossTrackErrorMagnitude,
196 char directionToSteer,
197 char crossTrackUnits,
198 char arrivalCircleStatus,
199 char perpendicularPassedAtWaypoint,
200 double bearingOriginToDestination,
201 char bearingOriginToDestinationType,
202 const std::string& destinationWaypointId,
203 double bearingPresentToDestination,
204 char bearingPresentToDestinationType,
205 double headingToSteerToDestinationWaypoint,
206 char headingToSteerToDestinationWaypointType) {
207 std::ostringstream payloadStream;
208 payloadStream << talkerId <<
"APB,";
209 payloadStream << status1 <<
",";
210 payloadStream << status2 <<
",";
211 payloadStream << std::fixed << std::setprecision(2) << crossTrackErrorMagnitude <<
",";
212 payloadStream << directionToSteer <<
",";
213 payloadStream << crossTrackUnits <<
",";
214 payloadStream << arrivalCircleStatus <<
",";
215 payloadStream << perpendicularPassedAtWaypoint <<
",";
216 payloadStream << std::fixed << std::setprecision(3) << bearingOriginToDestination <<
",";
217 payloadStream << bearingOriginToDestinationType <<
",";
218 payloadStream << destinationWaypointId <<
",";
219 payloadStream << std::fixed << std::setprecision(3) << bearingPresentToDestination <<
",";
220 payloadStream << bearingPresentToDestinationType <<
",";
221 payloadStream << std::fixed << std::setprecision(3) << headingToSteerToDestinationWaypoint <<
",";
222 payloadStream << headingToSteerToDestinationWaypointType;
224 std::string payload = payloadStream.str();
225 return "$" + payload +
"\r\n";
237 return crossTrackErrorMagnitude_;
241 return directionToSteer_;
245 return crossTrackUnits_;
249 return arrivalCircleStatus_;
253 return perpendicularPassedAtWaypoint_;
257 return bearingOriginToDestination_;
261 return bearingOriginToDestinationType_;
265 return destinationWaypointId_;
269 return bearingPresentToDestination_;
273 return bearingPresentToDestinationType_;
277 return headingToSteerToDestinationWaypoint_;
281 return headingToSteerToDestinationWaypointType_;
Represents a parsed NMEA 0183 APB (Autopilot Sentence "B") sentence.
char getHeadingToSteerToDestinationWaypointType() const noexcept
Get heading type for heading-to-steer ('M' or 'T').
double getBearingOriginToDestination() const noexcept
Get bearing from origin to destination.
char getBearingPresentToDestinationType() const noexcept
Get bearing type for present-to-destination ('M' or 'T').
double getHeadingToSteerToDestinationWaypoint() const noexcept
Get heading to steer to destination waypoint.
APB(std::string talkerId, char status1, char status2, double crossTrackErrorMagnitude, char directionToSteer, char crossTrackUnits, char arrivalCircleStatus, char perpendicularPassedAtWaypoint, double bearingOriginToDestination, char bearingOriginToDestinationType, std::string destinationWaypointId, double bearingPresentToDestination, char bearingPresentToDestinationType, double headingToSteerToDestinationWaypoint, char headingToSteerToDestinationWaypointType)
Construct an APB message from individual field values.
char getStatus1() const noexcept
Get primary APB status flag.
char getCrossTrackUnits() const noexcept
Get cross-track units indicator.
double getCrossTrackErrorMagnitude() const noexcept
Get cross-track error magnitude in nautical miles.
char getBearingOriginToDestinationType() const noexcept
Get bearing type for origin-to-destination ('M' or 'T').
char getArrivalCircleStatus() const noexcept
Get arrival circle status flag.
std::unique_ptr< nmealib::Message > clone() const override
Create a polymorphic copy of this APB message.
bool operator==(const APB &other) const noexcept
Compare two APB messages for equality.
char getPerpendicularPassedAtWaypoint() const noexcept
Get perpendicular-passed status flag.
double getBearingPresentToDestination() const noexcept
Get bearing from present position to destination.
std::string getStringContent(bool verbose) const noexcept override
Return a human-readable string representation of this message.
char getStatus2() const noexcept
Get secondary APB status flag.
std::string getDestinationWaypointId() const noexcept
Get destination waypoint identifier.
char getDirectionToSteer() const noexcept
Get steering direction indicator ('L' or 'R').
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 parseOptionalDouble(const std::string &text, double &value) noexcept