AgIsoStack++
A control-function-focused implementation of the major ISOBUS and J1939 protocols
Loading...
Searching...
No Matches
nmea2000_message_definitions.cpp
Go to the documentation of this file.
1//================================================================================================
14//================================================================================================
18#include "isobus/utility/system_timing.hpp"
19
20namespace isobus
21{
22 namespace NMEA2000Messages
23 {
24 VesselHeading::VesselHeading(std::shared_ptr<ControlFunction> source) :
25 senderControlFunction(source)
26 {
27 }
28
29 std::shared_ptr<ControlFunction> VesselHeading::get_control_function() const
30 {
32 }
33
34 std::uint32_t VesselHeading::get_timestamp() const
35 {
37 }
38
39 bool VesselHeading::set_timestamp(std::uint32_t timestamp)
40 {
41 bool retVal = (timestamp != messageTimestamp_ms);
42 messageTimestamp_ms = timestamp;
43 return retVal;
44 }
45
46 std::uint16_t VesselHeading::get_raw_heading() const
47 {
48 return headingReading;
49 }
50
52 {
53 return (headingReading * 1E-4f);
54 }
55
56 bool VesselHeading::set_heading(std::uint16_t heading)
57 {
58 bool retVal = (heading != headingReading);
59 headingReading = heading;
60 return retVal;
61 }
62
64 {
65 return magneticDeviation;
66 }
67
69 {
70 return (magneticDeviation * 1E-4f);
71 }
72
73 bool VesselHeading::set_magnetic_deviation(std::int16_t deviation)
74 {
75 bool retVal = (deviation != magneticDeviation);
76 magneticDeviation = deviation;
77 return retVal;
78 }
79
81 {
82 return magneticVariation;
83 }
84
86 {
87 return (magneticVariation * 1E-4f);
88 }
89
90 bool VesselHeading::set_magnetic_variation(std::int16_t variation)
91 {
92 bool retVal = (variation != magneticVariation);
93 magneticVariation = variation;
94 return retVal;
95 }
96
97 std::uint8_t VesselHeading::get_sequence_id() const
98 {
99 return sequenceID;
100 }
101
102 bool VesselHeading::set_sequence_id(std::uint8_t sequenceNumber)
103 {
104 bool retVal = (sequenceNumber != sequenceID);
105 sequenceID = sequenceNumber;
106 return retVal;
107 }
108
113
115 {
116 bool retVal = (sensorReference != reference);
117 sensorReference = reference;
118 return retVal;
119 }
120
121 void VesselHeading::serialize(std::vector<std::uint8_t> &buffer) const
122 {
123 buffer.resize(CAN_DATA_LENGTH);
124 buffer.at(0) = (sequenceID <= MAX_SEQUENCE_ID) ? sequenceID : 0xFF;
125 buffer.at(1) = static_cast<std::uint8_t>(headingReading & 0xFF);
126 buffer.at(2) = static_cast<std::uint8_t>((headingReading >> 8) & 0xFF);
127 buffer.at(3) = static_cast<std::uint8_t>(magneticDeviation & 0xFF);
128 buffer.at(4) = static_cast<std::uint8_t>((magneticDeviation >> 8) & 0xFF);
129 buffer.at(5) = static_cast<std::uint8_t>(magneticVariation & 0xFF);
130 buffer.at(6) = static_cast<std::uint8_t>((magneticVariation >> 8) & 0xFF);
131 buffer.at(7) = static_cast<std::uint8_t>(sensorReference) & 0x03;
132 buffer.at(7) |= 0xFC;
133 }
134
135 bool VesselHeading::deserialize(const CANMessage &receivedMessage)
136 {
137 bool retVal = false;
138
139 if (CAN_DATA_LENGTH == receivedMessage.get_data_length())
140 {
141 retVal |= set_sequence_id(receivedMessage.get_uint8_at(0));
142 retVal |= set_heading(receivedMessage.get_uint16_at(1));
143 retVal |= set_magnetic_deviation(receivedMessage.get_uint16_at(3));
144 retVal |= set_magnetic_variation(receivedMessage.get_uint16_at(5));
145 retVal |= set_sensor_reference(static_cast<HeadingSensorReference>(receivedMessage.get_uint8_at(7) & 0x03));
146 set_timestamp(SystemTiming::get_timestamp_ms());
147 }
148 else
149 {
150 LOG_WARNING("[NMEA2K]: Can't deserialize vessel heading. DLC must be 8.");
151 }
152 return retVal;
153 }
154
156 {
158 }
159
160 RateOfTurn::RateOfTurn(std::shared_ptr<ControlFunction> source) :
161 senderControlFunction(source)
162 {
163 }
164
165 std::shared_ptr<ControlFunction> RateOfTurn::get_control_function() const
166 {
168 }
169
170 std::uint32_t RateOfTurn::get_timestamp() const
171 {
172 return messageTimestamp_ms;
173 }
174
175 bool RateOfTurn::set_timestamp(std::uint32_t timestamp)
176 {
177 bool retVal = (messageTimestamp_ms != timestamp);
178 messageTimestamp_ms = timestamp;
179 return retVal;
180 }
181
183 {
184 return rateOfTurn;
185 }
186
188 {
189 return (static_cast<double>(rateOfTurn) * (1.0 / 32.0 * 1E-6));
190 }
191
192 bool RateOfTurn::set_rate_of_turn(std::int32_t turnRate)
193 {
194 bool retVal = (rateOfTurn != turnRate);
195 rateOfTurn = turnRate;
196 return retVal;
197 }
198
199 std::uint8_t RateOfTurn::get_sequence_id() const
200 {
201 return sequenceID;
202 }
203
204 bool RateOfTurn::set_sequence_id(std::uint8_t sequenceNumber)
205 {
206 bool retVal = (sequenceID != sequenceNumber);
207 sequenceID = sequenceNumber;
208 return retVal;
209 }
210
211 void RateOfTurn::serialize(std::vector<std::uint8_t> &buffer) const
212 {
213 buffer.resize(CAN_DATA_LENGTH);
214
215 buffer.at(0) = (sequenceID <= MAX_SEQUENCE_ID) ? sequenceID : 0xFF;
216 buffer.at(1) = static_cast<std::uint8_t>(rateOfTurn & 0xFF);
217 buffer.at(2) = static_cast<std::uint8_t>((rateOfTurn >> 8) & 0xFF);
218 buffer.at(3) = static_cast<std::uint8_t>((rateOfTurn >> 16) & 0xFF);
219 buffer.at(4) = static_cast<std::uint8_t>((rateOfTurn >> 24) & 0xFF);
220 buffer.at(5) = 0xFF; // Reserved bytes
221 buffer.at(6) = 0xFF;
222 buffer.at(7) = 0xFF;
223 }
224
225 bool RateOfTurn::deserialize(const CANMessage &receivedMessage)
226 {
227 bool retVal = false;
228
229 if (CAN_DATA_LENGTH == receivedMessage.get_data_length())
230 {
231 auto turnRate = static_cast<std::int32_t>(receivedMessage.get_uint8_at(1));
232 turnRate |= (static_cast<std::int32_t>(receivedMessage.get_uint8_at(2)) << 8);
233 turnRate |= (static_cast<std::int32_t>(receivedMessage.get_uint8_at(3)) << 16);
234 turnRate |= (static_cast<std::int32_t>(receivedMessage.get_uint8_at(4)) << 24);
235 retVal |= set_sequence_id(receivedMessage.get_uint8_at(0));
236 retVal |= set_rate_of_turn(turnRate);
237 set_timestamp(SystemTiming::get_timestamp_ms());
238 }
239 else
240 {
241 LOG_WARNING("[NMEA2K]: Can't deserialize rate of turn. DLC must be 8.");
242 }
243 return retVal;
244 }
245
247 {
249 }
250
251 PositionRapidUpdate::PositionRapidUpdate(std::shared_ptr<ControlFunction> source) :
252 senderControlFunction(source)
253 {
254 }
255
256 std::shared_ptr<ControlFunction> PositionRapidUpdate::get_control_function() const
257 {
259 }
260
262 {
263 return messageTimestamp_ms;
264 }
265
266 bool PositionRapidUpdate::set_timestamp(std::uint32_t timestamp)
267 {
268 bool retVal = (messageTimestamp_ms != timestamp);
269 messageTimestamp_ms = timestamp;
270 return retVal;
271 }
272
274 {
275 return latitude;
276 }
277
279 {
280 return (static_cast<double>(latitude) * 1E-7);
281 }
282
284 {
285 return (static_cast<double>(longitude) * 1E-7);
286 }
287
289 {
290 return longitude;
291 }
292
293 bool PositionRapidUpdate::set_latitude(std::int32_t latitudeToSet)
294 {
295 bool retVal = (latitude != latitudeToSet);
296 latitude = latitudeToSet;
297 return retVal;
298 }
299
300 bool PositionRapidUpdate::set_longitude(std::int32_t longitudeToSet)
301 {
302 bool retVal = (longitude != longitudeToSet);
303 longitude = longitudeToSet;
304 return retVal;
305 }
306
307 void PositionRapidUpdate::serialize(std::vector<std::uint8_t> &buffer) const
308 {
309 buffer.resize(CAN_DATA_LENGTH);
310
311 buffer.at(0) = static_cast<std::uint8_t>(latitude & 0xFF);
312 buffer.at(1) = static_cast<std::uint8_t>((latitude >> 8) & 0xFF);
313 buffer.at(2) = static_cast<std::uint8_t>((latitude >> 16) & 0xFF);
314 buffer.at(3) = static_cast<std::uint8_t>((latitude >> 24) & 0xFF);
315 buffer.at(4) = static_cast<std::uint8_t>(longitude & 0xFF);
316 buffer.at(5) = static_cast<std::uint8_t>((longitude >> 8) & 0xFF);
317 buffer.at(6) = static_cast<std::uint8_t>((longitude >> 16) & 0xFF);
318 buffer.at(7) = static_cast<std::uint8_t>((longitude >> 24) & 0xFF);
319 }
320
321 bool PositionRapidUpdate::deserialize(const CANMessage &receivedMessage)
322 {
323 bool retVal = false;
324
325 if (CAN_DATA_LENGTH == receivedMessage.get_data_length())
326 {
327 auto decodedLatitude = static_cast<std::int32_t>(receivedMessage.get_uint8_at(0));
328 decodedLatitude |= (static_cast<std::int32_t>(receivedMessage.get_uint8_at(1)) << 8);
329 decodedLatitude |= (static_cast<std::int32_t>(receivedMessage.get_uint8_at(2)) << 16);
330 decodedLatitude |= (static_cast<std::int32_t>(receivedMessage.get_uint8_at(3)) << 24);
331 auto decodedLongitude = static_cast<std::int32_t>(receivedMessage.get_uint8_at(4));
332 decodedLongitude |= (static_cast<std::int32_t>(receivedMessage.get_uint8_at(5)) << 8);
333 decodedLongitude |= (static_cast<std::int32_t>(receivedMessage.get_uint8_at(6)) << 16);
334 decodedLongitude |= (static_cast<std::int32_t>(receivedMessage.get_uint8_at(7)) << 24);
335 retVal |= set_latitude(decodedLatitude);
336 retVal |= set_longitude(decodedLongitude);
337 set_timestamp(SystemTiming::get_timestamp_ms());
338 }
339 else
340 {
341 LOG_WARNING("[NMEA2K]: Can't deserialize position rapid update. DLC must be 8.");
342 }
343 return retVal;
344 }
345
347 {
349 }
350
352 senderControlFunction(source)
353 {
354 }
355
357 {
359 }
360
365
367 {
368 bool retVal = (messageTimestamp_ms != timestamp);
369 messageTimestamp_ms = timestamp;
370 return retVal;
371 }
372
377
382
384 {
385 bool retVal = (courseOverGround != course);
386 courseOverGround = course;
387 return retVal;
388 }
389
394
399
401 {
402 bool retVal = (speedOverGround != speed);
403 speedOverGround = speed;
404 return retVal;
405 }
406
411
413 {
414 bool retVal = (sequenceID != sequenceNumber);
415 sequenceID = sequenceNumber;
416 return retVal;
417 }
418
423
425 {
426 bool retVal = (cogReference != reference);
427 cogReference = reference;
428 return retVal;
429 }
430
431 void CourseOverGroundSpeedOverGroundRapidUpdate::serialize(std::vector<std::uint8_t> &buffer) const
432 {
433 buffer.resize(CAN_DATA_LENGTH);
434
435 buffer.at(0) = sequenceID;
436 buffer.at(1) = (0xFC | static_cast<std::uint8_t>(cogReference));
437 buffer.at(2) = static_cast<std::uint8_t>(courseOverGround & 0xFF);
438 buffer.at(3) = static_cast<std::uint8_t>((courseOverGround >> 8) & 0xFF);
439 buffer.at(4) = static_cast<std::uint8_t>(speedOverGround & 0xFF);
440 buffer.at(5) = static_cast<std::uint8_t>((speedOverGround >> 8) & 0xFF);
441 buffer.at(6) = 0xFF; // Reserved
442 buffer.at(7) = 0xFF; // Reserved
443 }
444
446 {
447 bool retVal = false;
448
449 if (CAN_DATA_LENGTH == receivedMessage.get_data_length())
450 {
451 retVal |= set_sequence_id(receivedMessage.get_uint8_at(0));
452 retVal |= set_course_over_ground_reference(static_cast<CourseOverGroundReference>(receivedMessage.get_uint8_at(1) & 0x03));
453 retVal |= set_course_over_ground(receivedMessage.get_uint16_at(2));
454 retVal |= set_speed_over_ground(receivedMessage.get_uint16_at(4));
455 set_timestamp(SystemTiming::get_timestamp_ms());
456 }
457 else
458 {
459 LOG_WARNING("[NMEA2K]: Can't deserialize COG/SOG rapid update. DLC must be 8.");
460 }
461 return retVal;
462 }
463
468
470 senderControlFunction(source)
471 {
472 }
473
474 std::shared_ptr<ControlFunction> PositionDeltaHighPrecisionRapidUpdate::get_control_function() const
475 {
477 }
478
483
485 {
486 bool retVal = (messageTimestamp_ms != timestamp);
487 messageTimestamp_ms = timestamp;
488 return retVal;
489 }
490
495
497 {
498 return (static_cast<double>(latitudeDelta) * 10E-7);
499 }
500
502 {
503 bool retVal = (latitudeDelta != delta);
504 latitudeDelta = delta;
505 return retVal;
506 }
507
512
514 {
515 return (static_cast<double>(longitudeDelta) * 10E-7);
516 }
517
519 {
520 bool retVal = (longitudeDelta != delta);
521 longitudeDelta = delta;
522 return retVal;
523 }
524
526 {
527 return sequenceID;
528 }
529
531 {
532 bool retVal = (sequenceNumber != sequenceID);
533 sequenceID = sequenceNumber;
534 return retVal;
535 }
536
538 {
539 return timeDelta;
540 }
541
543 {
544 return ((static_cast<double>(timeDelta) * 5.0) / 1000.0);
545 }
546
548 {
549 bool retVal = (timeDelta != delta);
550 timeDelta = delta;
551 return retVal;
552 }
553
554 void PositionDeltaHighPrecisionRapidUpdate::serialize(std::vector<std::uint8_t> &buffer) const
555 {
556 buffer.resize(CAN_DATA_LENGTH);
557
558 buffer.at(0) = sequenceID;
559 buffer.at(1) = timeDelta;
560 buffer.at(2) = static_cast<std::uint8_t>(latitudeDelta & 0xFF);
561 buffer.at(3) = static_cast<std::uint8_t>((latitudeDelta >> 8) & 0xFF);
562 buffer.at(4) = static_cast<std::uint8_t>((latitudeDelta >> 16) & 0xFF);
563 buffer.at(5) = static_cast<std::uint8_t>(longitudeDelta & 0xFF);
564 buffer.at(6) = static_cast<std::uint8_t>((longitudeDelta >> 8) & 0xFF);
565 buffer.at(7) = static_cast<std::uint8_t>((longitudeDelta >> 16) & 0xFF);
566 }
567
569 {
570 bool retVal = false;
571
572 if (CAN_DATA_LENGTH == receivedMessage.get_data_length())
573 {
574 retVal = set_sequence_id(receivedMessage.get_uint8_at(0));
575 retVal |= set_time_delta(receivedMessage.get_uint8_at(1));
576 retVal |= set_latitude_delta(receivedMessage.get_uint24_at(2));
577 retVal |= set_longitude_delta(receivedMessage.get_uint24_at(5));
578 set_timestamp(SystemTiming::get_timestamp_ms());
579 }
580 else
581 {
582 LOG_WARNING("[NMEA2K]: Cannot deserialize position delta high precision rapid update. DLC must be 8 bytes.");
583 }
584 return retVal;
585 }
586
591
592 GNSSPositionData::GNSSPositionData(std::shared_ptr<ControlFunction> source) :
593 senderControlFunction(source)
594 {
595 }
596
597 std::shared_ptr<ControlFunction> GNSSPositionData::get_control_function() const
598 {
600 }
601
603 {
604 return altitude;
605 }
606
608 {
609 return (static_cast<double>(altitude) * 1E-6);
610 }
611
612 bool GNSSPositionData::set_altitude(std::int64_t altitudeToSet)
613 {
614 bool retVal = (altitude != altitudeToSet);
615 altitude = altitudeToSet;
616 return retVal;
617 }
618
620 {
621 return latitude;
622 }
623
625 {
626 return (static_cast<double>(latitude) * 1E-16);
627 }
628
629 bool GNSSPositionData::set_latitude(std::int64_t latitudeToSet)
630 {
631 bool retVal = (latitude != latitudeToSet);
632 latitude = latitudeToSet;
633 return retVal;
634 }
635
637 {
638 return longitude;
639 }
640
642 {
643 return (static_cast<double>(longitude) * 1E-16);
644 }
645
646 bool GNSSPositionData::set_longitude(std::int64_t longitudeToSet)
647 {
648 bool retVal = (longitude != longitudeToSet);
649 longitude = longitudeToSet;
650 return retVal;
651 }
652
654 {
655 return geoidalSeparation;
656 }
657
659 {
660 return (geoidalSeparation * 0.01f);
661 }
662
663 bool GNSSPositionData::set_geoidal_separation(std::int32_t separation)
664 {
665 bool retVal = (geoidalSeparation != separation);
666 geoidalSeparation = separation;
667 return retVal;
668 }
669
671 {
672 return messageTimestamp_ms;
673 }
674
675 bool GNSSPositionData::set_timestamp(std::uint32_t timestamp)
676 {
677 bool retVal = (messageTimestamp_ms != timestamp);
678 messageTimestamp_ms = timestamp;
679 return retVal;
680 }
681
683 {
684 return sequenceID;
685 }
686
687 bool GNSSPositionData::set_sequence_id(std::uint8_t sequenceNumber)
688 {
689 bool retVal = (sequenceNumber != sequenceID);
690 sequenceID = sequenceNumber;
691 return retVal;
692 }
693
698
700 {
701 bool retVal = (systemType != type);
702 systemType = type;
703 return retVal;
704 }
705
710
712 {
713 bool retVal = (method != gnssFixMethod);
714 method = gnssFixMethod;
715 return retVal;
716 }
717
722
724 {
725 bool retVal = (integrityChecking != integrity);
726 integrityChecking = integrity;
727 return retVal;
728 }
729
731 {
733 }
734
736 {
737 bool retVal = (numberOfSpaceVehicles != numberOfSVs);
738 numberOfSpaceVehicles = numberOfSVs;
739 return retVal;
740 }
741
746
751
753 {
754 bool retVal = (horizontalDilutionOfPrecision != hdop);
756 return retVal;
757 }
758
763
768
770 {
771 bool retVal = (positionalDilutionOfPrecision != pdop);
773 return retVal;
774 }
775
777 {
778 return referenceStations.size();
779 }
780
782 {
783 bool retVal = (referenceStations.size() != stations);
784 referenceStations.resize(stations);
785 return retVal;
786 }
787
788 std::uint16_t GNSSPositionData::get_reference_station_id(std::size_t index) const
789 {
790 std::uint16_t retVal = 0;
791
792 if (index < referenceStations.size())
793 {
794 retVal = referenceStations.at(index).stationID;
795 }
796 return retVal;
797 }
798
800 {
801 std::uint16_t retVal = 0;
802
803 if (index < referenceStations.size())
804 {
805 retVal = referenceStations.at(index).ageOfDGNSSCorrections;
806 }
807 return retVal;
808 }
809
811 {
812 return (get_raw_reference_station_corrections_age(index) * 0.01f);
813 }
814
816 {
817 TypeOfSystem retVal = TypeOfSystem::Null;
818
819 if (index < referenceStations.size())
820 {
821 retVal = referenceStations.at(index).stationType;
822 }
823 return retVal;
824 }
825
826 bool GNSSPositionData::set_reference_station(std::size_t index, std::uint16_t ID, TypeOfSystem type, std::uint16_t ageOfCorrections)
827 {
828 bool retVal = false;
829
830 if (index < referenceStations.size())
831 {
832 retVal |= referenceStations.at(index).ageOfDGNSSCorrections != ageOfCorrections;
833 retVal |= referenceStations.at(index).stationID != ID;
834 retVal |= referenceStations.at(index).stationType != type;
835 referenceStations.at(index) = ReferenceStationData(ID, type, ageOfCorrections);
836 }
837 return retVal;
838 }
839
841 {
842 return positionDate;
843 }
844
845 bool GNSSPositionData::set_position_date(std::uint16_t dateToSet)
846 {
847 bool retVal = (positionDate != dateToSet);
848 positionDate = dateToSet;
849 return retVal;
850 }
851
853 {
854 return positionTime;
855 }
856
858 {
859 return 1E-04 * positionTime;
860 }
861
862 bool GNSSPositionData::set_position_time(std::uint32_t timeToSet)
863 {
864 bool retVal = (positionTime != timeToSet);
865 positionTime = timeToSet;
866 return retVal;
867 }
868
869 void GNSSPositionData::serialize(std::vector<std::uint8_t> &buffer) const
870 {
871 buffer.resize(MINIMUM_LENGTH_BYTES);
872
873 buffer.at(0) = sequenceID;
874 buffer.at(1) = static_cast<std::uint8_t>(positionDate & 0xFF);
875 buffer.at(2) = static_cast<std::uint8_t>((positionDate >> 8) & 0xFF);
876 buffer.at(3) = static_cast<std::uint8_t>(positionTime & 0xFF);
877 buffer.at(4) = static_cast<std::uint8_t>((positionTime >> 8) & 0xFF);
878 buffer.at(5) = static_cast<std::uint8_t>((positionTime >> 16) & 0xFF);
879 buffer.at(6) = static_cast<std::uint8_t>((positionTime >> 24) & 0xFF);
880 buffer.at(7) = static_cast<std::uint8_t>(latitude & 0xFF);
881 buffer.at(8) = static_cast<std::uint8_t>((latitude >> 8) & 0xFF);
882 buffer.at(9) = static_cast<std::uint8_t>((latitude >> 16) & 0xFF);
883 buffer.at(10) = static_cast<std::uint8_t>((latitude >> 24) & 0xFF);
884 buffer.at(11) = static_cast<std::uint8_t>((latitude >> 32) & 0xFF);
885 buffer.at(12) = static_cast<std::uint8_t>((latitude >> 40) & 0xFF);
886 buffer.at(13) = static_cast<std::uint8_t>((latitude >> 48) & 0xFF);
887 buffer.at(14) = static_cast<std::uint8_t>((latitude >> 56) & 0xFF);
888 buffer.at(15) = static_cast<std::uint8_t>(longitude & 0xFF);
889 buffer.at(16) = static_cast<std::uint8_t>((longitude >> 8) & 0xFF);
890 buffer.at(17) = static_cast<std::uint8_t>((longitude >> 16) & 0xFF);
891 buffer.at(18) = static_cast<std::uint8_t>((longitude >> 24) & 0xFF);
892 buffer.at(19) = static_cast<std::uint8_t>((longitude >> 32) & 0xFF);
893 buffer.at(20) = static_cast<std::uint8_t>((longitude >> 40) & 0xFF);
894 buffer.at(21) = static_cast<std::uint8_t>((longitude >> 48) & 0xFF);
895 buffer.at(22) = static_cast<std::uint8_t>((longitude >> 56) & 0xFF);
896 buffer.at(23) = static_cast<std::uint8_t>(altitude & 0xFF);
897 buffer.at(24) = static_cast<std::uint8_t>((altitude >> 8) & 0xFF);
898 buffer.at(25) = static_cast<std::uint8_t>((altitude >> 16) & 0xFF);
899 buffer.at(26) = static_cast<std::uint8_t>((altitude >> 24) & 0xFF);
900 buffer.at(27) = static_cast<std::uint8_t>((altitude >> 32) & 0xFF);
901 buffer.at(28) = static_cast<std::uint8_t>((altitude >> 40) & 0xFF);
902 buffer.at(29) = static_cast<std::uint8_t>((altitude >> 48) & 0xFF);
903 buffer.at(30) = static_cast<std::uint8_t>((altitude >> 56) & 0xFF);
904 buffer.at(31) = (static_cast<std::uint8_t>(systemType) & 0x0F);
905 buffer.at(31) |= ((static_cast<std::uint8_t>(method) & 0x0F) << 4);
906 buffer.at(32) = (static_cast<std::uint8_t>(integrityChecking) | 0xFC);
907 buffer.at(33) = numberOfSpaceVehicles;
908 buffer.at(34) = static_cast<std::uint8_t>(horizontalDilutionOfPrecision & 0xFF);
909 buffer.at(35) = static_cast<std::uint8_t>((horizontalDilutionOfPrecision >> 8) & 0xFF);
910 buffer.at(36) = static_cast<std::uint8_t>(positionalDilutionOfPrecision & 0xFF);
911 buffer.at(37) = static_cast<std::uint8_t>((positionalDilutionOfPrecision >> 8) & 0xFF);
912 buffer.at(38) = static_cast<std::uint8_t>(geoidalSeparation & 0xFF);
913 buffer.at(39) = static_cast<std::uint8_t>((geoidalSeparation >> 8) & 0xFF);
914 buffer.at(40) = static_cast<std::uint8_t>((geoidalSeparation >> 16) & 0xFF);
915 buffer.at(41) = static_cast<std::uint8_t>((geoidalSeparation >> 24) & 0xFF);
916 buffer.at(42) = get_number_of_reference_stations();
917
918 for (std::uint8_t i = 0; i < get_number_of_reference_stations(); i++)
919 {
920 buffer.push_back((static_cast<std::uint8_t>(referenceStations.at(i).stationType) & 0x0F) |
921 ((referenceStations.at(i).stationID & 0x0F) << 4));
922 buffer.push_back(static_cast<std::uint8_t>(referenceStations.at(i).stationID >> 4));
923 buffer.push_back(static_cast<std::uint8_t>(referenceStations.at(i).ageOfDGNSSCorrections & 0xFF));
924 buffer.push_back(static_cast<std::uint8_t>((referenceStations.at(i).ageOfDGNSSCorrections >> 8) & 0xFF));
925 }
926 }
927
928 bool GNSSPositionData::deserialize(const CANMessage &receivedMessage)
929 {
930 bool retVal = false;
931
932 if (receivedMessage.get_data_length() >= MINIMUM_LENGTH_BYTES)
933 {
934 retVal = set_sequence_id(receivedMessage.get_uint8_at(0));
935 retVal |= set_position_date(receivedMessage.get_uint16_at(1));
936 retVal |= set_position_time(receivedMessage.get_uint32_at(3));
937 retVal |= set_latitude(receivedMessage.get_int64_at(7));
938 retVal |= set_longitude(receivedMessage.get_int64_at(15));
939 retVal |= set_altitude(receivedMessage.get_int64_at(23));
940 retVal |= set_type_of_system(static_cast<TypeOfSystem>(receivedMessage.get_uint8_at(31) & 0x0F));
941 retVal |= set_gnss_method(static_cast<GNSSMethod>((receivedMessage.get_uint8_at(31) >> 4) & 0x0F));
942 retVal |= set_integrity(static_cast<Integrity>(receivedMessage.get_uint8_at(32) & 0x03));
943 retVal |= set_number_of_space_vehicles(receivedMessage.get_uint8_at(33));
944 retVal |= set_horizontal_dilution_of_precision(receivedMessage.get_int16_at(34));
945 retVal |= set_positional_dilution_of_precision(receivedMessage.get_int16_at(36));
946 retVal |= set_geoidal_separation(receivedMessage.get_int32_at(38));
947
948 referenceStations.clear();
949 retVal |= set_number_of_reference_stations(receivedMessage.get_uint8_at(42));
950
951 for (std::uint8_t i = 0; i < get_number_of_reference_stations(); i++)
952 {
953 if (receivedMessage.get_data_length() >= static_cast<std::uint32_t>(MINIMUM_LENGTH_BYTES + (i * 4)))
954 {
955 referenceStations.at(i) = ReferenceStationData((receivedMessage.get_uint16_at(MINIMUM_LENGTH_BYTES + (i * 4)) >> 4),
956 static_cast<TypeOfSystem>(receivedMessage.get_uint8_at(MINIMUM_LENGTH_BYTES + (i * 4)) & 0x0F),
957 receivedMessage.get_uint16_at(2 + MINIMUM_LENGTH_BYTES + (i * 4)));
958 }
959 else
960 {
961 LOG_WARNING("[NMEA2K]: Can't fully parse GNSS position data reference station info because message length is not long enough.");
962 break;
963 }
964 }
965 }
966 else
967 {
968 LOG_WARNING("[NMEA2K]: Cannot deserialize GNSS position data. DLC must be >= 43 bytes.");
969 }
970 return retVal;
971 }
972
974 {
976 }
977
979 stationID(id),
980 stationType(type),
981 ageOfDGNSSCorrections(age)
982 {
983 }
984
985 Datum::Datum(std::shared_ptr<ControlFunction> source) :
987 {
990 }
991
992 std::shared_ptr<ControlFunction> Datum::get_control_function() const
993 {
995 }
996
997 std::uint32_t Datum::get_timestamp() const
998 {
999 return messageTimestamp_ms;
1000 }
1001
1002 bool Datum::set_timestamp(std::uint32_t timestamp)
1003 {
1004 bool retVal = (messageTimestamp_ms != timestamp);
1005 messageTimestamp_ms = timestamp;
1006 return retVal;
1007 }
1008
1009 std::string Datum::get_local_datum() const
1010 {
1011 return localDatum;
1012 }
1013
1014 bool Datum::set_local_datum(const std::string &datum)
1015 {
1016 bool retVal = (datum != localDatum);
1017 localDatum = datum;
1018
1019 if (localDatum.length() != DATUM_STRING_LENGTHS)
1020 {
1022 }
1023 return retVal;
1024 }
1025
1026 std::string Datum::get_reference_datum() const
1027 {
1028 return referenceDatum;
1029 }
1030
1031 bool Datum::set_reference_datum(const std::string &datum)
1032 {
1033 bool retVal = (datum != referenceDatum);
1034 referenceDatum = datum;
1035
1036 if (referenceDatum.length() != DATUM_STRING_LENGTHS)
1037 {
1039 }
1040 return retVal;
1041 }
1042
1044 {
1045 return deltaLatitude;
1046 }
1047
1049 {
1050 return (static_cast<double>(deltaLatitude) * 1E-7);
1051 }
1052
1053 bool Datum::set_delta_latitude(std::int32_t delta)
1054 {
1055 bool retVal = (deltaLatitude != delta);
1056 deltaLatitude = delta;
1057 return retVal;
1058 }
1059
1061 {
1062 return (static_cast<double>(deltaLongitude) * 1E-7);
1063 }
1064
1066 {
1067 return deltaLongitude;
1068 }
1069
1070 bool Datum::set_delta_longitude(std::int32_t delta)
1071 {
1072 bool retVal = (deltaLongitude != delta);
1073 deltaLongitude = delta;
1074 return retVal;
1075 }
1076
1078 {
1079 return deltaAltitude;
1080 }
1081
1083 {
1084 return (1E-2f * deltaAltitude);
1085 }
1086
1087 bool Datum::set_delta_altitude(std::int32_t delta)
1088 {
1089 bool retVal = (deltaAltitude != delta);
1090 deltaAltitude = delta;
1091 return retVal;
1092 }
1093
1094 void Datum::serialize(std::vector<std::uint8_t> &buffer) const
1095 {
1096 buffer.resize(LENGTH_BYTES);
1097
1098 buffer.at(0) = localDatum.at(0);
1099 buffer.at(1) = localDatum.at(1);
1100 buffer.at(2) = localDatum.at(2);
1101 buffer.at(3) = localDatum.at(3);
1102 buffer.at(4) = static_cast<std::uint8_t>(deltaLatitude & 0xFF);
1103 buffer.at(5) = static_cast<std::uint8_t>((deltaLatitude >> 8) & 0xFF);
1104 buffer.at(6) = static_cast<std::uint8_t>((deltaLatitude >> 16) & 0xFF);
1105 buffer.at(7) = static_cast<std::uint8_t>((deltaLatitude >> 24) & 0xFF);
1106 buffer.at(8) = static_cast<std::uint8_t>(deltaLongitude & 0xFF);
1107 buffer.at(9) = static_cast<std::uint8_t>((deltaLongitude >> 8) & 0xFF);
1108 buffer.at(10) = static_cast<std::uint8_t>((deltaLongitude >> 16) & 0xFF);
1109 buffer.at(11) = static_cast<std::uint8_t>((deltaLongitude >> 24) & 0xFF);
1110 buffer.at(12) = static_cast<std::uint8_t>(deltaAltitude & 0xFF);
1111 buffer.at(13) = static_cast<std::uint8_t>((deltaAltitude >> 8) & 0xFF);
1112 buffer.at(14) = static_cast<std::uint8_t>((deltaAltitude >> 16) & 0xFF);
1113 buffer.at(15) = static_cast<std::uint8_t>((deltaAltitude >> 24) & 0xFF);
1114 buffer.at(16) = referenceDatum.at(0);
1115 buffer.at(17) = referenceDatum.at(1);
1116 buffer.at(18) = referenceDatum.at(2);
1117 buffer.at(19) = referenceDatum.at(3);
1118 }
1119
1120 bool Datum::deserialize(const CANMessage &receivedMessage)
1121 {
1122 bool retVal = false;
1123
1124 if (receivedMessage.get_data_length() >= LENGTH_BYTES)
1125 {
1126 std::string tempString;
1127 tempString.push_back(static_cast<char>(receivedMessage.get_uint8_at(0)));
1128 tempString.push_back(static_cast<char>(receivedMessage.get_uint8_at(1)));
1129 tempString.push_back(static_cast<char>(receivedMessage.get_uint8_at(2)));
1130 tempString.push_back(static_cast<char>(receivedMessage.get_uint8_at(3)));
1131 retVal = set_local_datum(tempString);
1132 retVal |= set_delta_latitude(receivedMessage.get_int32_at(4));
1133 retVal |= set_delta_longitude(receivedMessage.get_int32_at(8));
1134 retVal |= set_delta_altitude(receivedMessage.get_int32_at(12));
1135 tempString.clear();
1136 tempString.push_back(static_cast<char>(receivedMessage.get_uint8_at(16)));
1137 tempString.push_back(static_cast<char>(receivedMessage.get_uint8_at(17)));
1138 tempString.push_back(static_cast<char>(receivedMessage.get_uint8_at(18)));
1139 tempString.push_back(static_cast<char>(receivedMessage.get_uint8_at(19)));
1140 retVal |= set_reference_datum(tempString);
1141 }
1142 else
1143 {
1144 LOG_WARNING("[NMEA2K]: Can't deserialize Datum message. Message length must be at least 20 bytes.");
1145 }
1146 return retVal;
1147 }
1148
1149 std::uint32_t Datum::get_timeout()
1150 {
1152 }
1153 }
1154}
An abstraction of a CAN message, could be > 8 data bytes.
A class that acts as a logging sink. The intent is that someone could make their own derived class of...
A class that represents a generic CAN message of arbitrary length.
std::int16_t get_int16_at(const std::uint32_t index, const ByteFormat format=ByteFormat::LittleEndian) const
Get a 16-bit signed integer from the buffer at a specific index. A 16-bit signed integer can hold a v...
std::uint32_t get_data_length() const
Returns the length of the data in the CAN message.
std::uint32_t get_uint24_at(const std::uint32_t index, const ByteFormat format=ByteFormat::LittleEndian) const
Get a right-aligned 24-bit integer from the buffer (returned as a uint32_t) at a specific index....
std::uint8_t get_uint8_at(const std::uint32_t index) const
Get a 8-bit unsigned byte from the buffer at a specific index. A 8-bit unsigned byte can hold a value...
std::int32_t get_int32_at(const std::uint32_t index, const ByteFormat format=ByteFormat::LittleEndian) const
Get a 32-bit signed integer from the buffer at a specific index. A 32-bit signed integer can hold a v...
std::uint16_t get_uint16_at(const std::uint32_t index, const ByteFormat format=ByteFormat::LittleEndian) const
Get a 16-bit unsigned integer from the buffer at a specific index. A 16-bit unsigned integer can hold...
std::int64_t get_int64_at(const std::uint32_t index, const ByteFormat format=ByteFormat::LittleEndian) const
Get a 64-bit signed integer from the buffer at a specific index. A 64-bit signed integer can hold a v...
std::uint32_t get_uint32_at(const std::uint32_t index, const ByteFormat format=ByteFormat::LittleEndian) const
Get a 32-bit unsigned integer from the buffer at a specific index. A 32-bit unsigned integer can hold...
std::uint16_t courseOverGround
This field contains the direction of the path over ground actually followed by the vessel in 0....
CourseOverGroundReference get_course_over_ground_reference() const
Returns the reference to which the course over ground is relative.
static constexpr std::uint32_t CYCLIC_MESSAGE_RATE_MS
The transmit interval for this message as specified in NMEA2000.
CourseOverGroundReference cogReference
Used to indicate the reference for the course over ground, ie true or magnetic north.
std::uint16_t speedOverGround
This field contains the speed of the vessel in 0.01 m/s.
static std::uint32_t get_timeout()
Returns the timeout (the sending interval) for this message in milliseconds.
std::shared_ptr< ControlFunction > senderControlFunction
The sender of the message data.
std::uint8_t sequenceID
The sequence identifier field is used to tie related PGNs together. Somewhat arbitrary.
bool set_speed_over_ground(std::uint16_t speed)
Sets the speed over ground in units of 0.01 meters per second.
std::uint8_t get_sequence_id() const
Returns the sequence ID. This is used to associate data within other PGNs with this message.
bool deserialize(const CANMessage &receivedMessage)
Deserializes a CAN message to populate this object's contents. Updates the timestamp when called.
void serialize(std::vector< std::uint8_t > &buffer) const
Serializes the current state of this object into a buffer to be sent on the CAN bus.
CourseOverGroundSpeedOverGroundRapidUpdate(std::shared_ptr< ControlFunction > source)
Constructor for a CourseOverGroundSpeedOverGroundRapidUpdate message data object.
bool set_course_over_ground(std::uint16_t course)
Sets the course over ground in units of 0.0001 radians.
std::uint32_t get_timestamp() const
Returns a timestamp in milliseconds corresponding to when the message was last sent or received.
float get_speed_over_ground() const
Returns the speed over ground in units of meters per second.
CourseOverGroundReference
Enumerates the references to which the course may be relative to.
std::shared_ptr< ControlFunction > get_control_function() const
Returns the control function sending this instance of this message.
std::uint16_t get_raw_course_over_ground() const
Returns the course over ground in its base units of 0.0001 radians (between 0 and 2 pi radians)
std::uint16_t get_raw_speed_over_ground() const
Returns the speed over ground in units of 0.01 meters per second.
float get_course_over_ground() const
Returns the course over ground in units of radians.
bool set_timestamp(std::uint32_t timestamp)
Sets the time in milliseconds when the message was last sent or received.
bool set_sequence_id(std::uint8_t sequenceNumber)
Sets the sequence ID for this message.
bool set_course_over_ground_reference(CourseOverGroundReference reference)
Sets the reference to which the course over ground is relative.
std::uint32_t messageTimestamp_ms
A timestamp in milliseconds when this message was last sent or received.
std::int32_t deltaLongitude
Position in the local datum is offset from the position in the reference datum as indicated by this l...
std::int32_t deltaLatitude
Position in the local datum is offset from the position in the reference datum as indicated by this l...
bool deserialize(const CANMessage &receivedMessage)
Deserializes a CAN message to populate this object's contents. Updates the timestamp when called.
std::shared_ptr< ControlFunction > get_control_function() const
Returns the control function sending this instance of this message.
static constexpr std::uint32_t CYCLIC_MESSAGE_RATE_MS
The transmit interval for this message as specified in NMEA2000.
bool set_delta_altitude(std::int32_t delta)
Sets the altitude offset of position in the local datum relative to the position in the reference dat...
std::int32_t deltaAltitude
The altitude delta in units of 0.01 meters. Positive values indicate Up.
std::string get_reference_datum() const
Returns the 4 character ascii datum code that identifies the reference datum.
static std::uint32_t get_timeout()
Returns the timeout (the sending interval) for this message in milliseconds.
void serialize(std::vector< std::uint8_t > &buffer) const
Serializes the current state of this object into a buffer to be sent on the CAN bus.
Datum(std::shared_ptr< ControlFunction > source)
Constructor for a Datum message data object.
static constexpr std::uint8_t DATUM_STRING_LENGTHS
The size of the datum codes in bytes.
bool set_reference_datum(const std::string &datum)
Sets the 4 character ascii datum code that identifies the reference datum.
std::uint32_t get_timestamp() const
Returns a timestamp in milliseconds corresponding to when the message was last sent or received.
bool set_delta_latitude(std::int32_t delta)
Sets latitude offset of position in the local datum from the position in the reference datum in units...
float get_delta_altitude() const
Returns the altitude offset of position in the local datum relative to the position in the reference ...
std::uint32_t messageTimestamp_ms
A timestamp in milliseconds when this message was last sent or received.
std::int32_t get_raw_delta_longitude() const
Returns longitude offset of position in the local datum from the position in the reference datum....
std::int32_t get_raw_delta_altitude() const
Returns the altitude offset of position in the local datum relative to the position in the reference ...
std::string localDatum
A 4 character ascii datum code. The first three chars are the datum ID.The fourth char is the local d...
double get_delta_latitude() const
Returns latitude offset of position in the local datum from the position in the reference datum....
double get_delta_longitude() const
Returns longitude offset of position in the local datum from the position in the reference datum....
std::string get_local_datum() const
Returns the 4 character ascii datum code.
bool set_delta_longitude(std::int32_t delta)
Sets longitude offset of position in the local datum from the position in the reference datum in unit...
bool set_local_datum(const std::string &datum)
Sets the local datum's 4 character ascii datum code.
bool set_timestamp(std::uint32_t timestamp)
Sets the time in milliseconds when the message was last sent or received.
std::string referenceDatum
A 4 character ascii datum code that identifies the reference datum.
std::int32_t get_raw_delta_latitude() const
Returns latitude offset of position in the local datum from the position in the reference datum....
std::shared_ptr< ControlFunction > senderControlFunction
The sender of the message data.
static constexpr std::uint8_t LENGTH_BYTES
The size of this message in bytes.
ReferenceStationData()=default
Default constructor for a ReferenceStationData with default values.
Integrity get_integrity() const
Sets the integrity being reported for this position solution if applicable.
TypeOfSystem get_type_of_system() const
Returns the reported type of GNSS system that produced this position solution.
double get_altitude() const
Returns the altitude portion of the position fix in scaled units of meters. Range is +/- 9....
bool set_geoidal_separation(std::int32_t separation)
Sets the geoidal separation.
double get_position_time() const
Returns the number of seconds since midnight.
bool set_integrity(Integrity integrity)
Sets the integrity reported for this position solution.
std::int64_t get_raw_latitude() const
Returns our current position's latitude in its base units of 1x10E-16 degrees.
std::int64_t get_raw_longitude() const
Returns our current position's longitude in its base units of 1x10E-16 degrees.
GNSSMethod
Enumerates the GNSS methods that can be reported in this message.
TypeOfSystem
Enumerates the different GNSS systems that can be reported in this message.
std::shared_ptr< ControlFunction > senderControlFunction
The sender of the message data.
bool set_horizontal_dilution_of_precision(std::int16_t hdop)
Sets the horizontal dilution of precision (HDOP)
std::shared_ptr< ControlFunction > get_control_function() const
Returns the control function sending this instance of this message.
bool set_sequence_id(std::uint8_t sequenceNumber)
Sets the sequence ID for this message.
std::uint8_t get_number_of_space_vehicles() const
Returns the number of space vehicles used in this position solution.
bool set_position_time(std::uint32_t timeToSet)
Sets the number of seconds since midnight.
std::uint32_t messageTimestamp_ms
A timestamp in milliseconds when this message was last sent or received.
std::uint32_t positionTime
The number of seconds since midnight on the current day. Allows for up to 2 leap seconds per day....
std::int16_t get_raw_horizontal_dilution_of_precision() const
Returns the HDOP for this solution. This Indicates the contribution of satellite configuration geomet...
float get_reference_station_corrections_age(std::size_t index) const
Returns the specified reference station's DGNSS corrections age by index.
bool set_number_of_space_vehicles(std::uint8_t numberOfSVs)
Sets the number of space vehicles in view and used in this position solution.
Integrity integrityChecking
Stores the integrity of the values in the message.
static std::uint32_t get_timeout()
Returns the timeout (the sending interval) for this message in milliseconds.
std::uint32_t get_timestamp() const
Returns a timestamp in milliseconds corresponding to when the message was last sent or received.
bool set_altitude(std::int64_t altitudeToSet)
Sets the reported altitude in units of 1x10E-6 meters. Range is +/- 9.223 x 10E+12 meters.
std::uint8_t get_number_of_reference_stations() const
Returns the number of reference stations used in this position solution (if applicable to GNSS method...
bool set_gnss_method(GNSSMethod gnssFixMethod)
Sets the GNSS method to report as the source of this position solution, such as RTK float or DGNSS.
std::uint16_t get_reference_station_id(std::size_t index) const
Returns the specified reference station's ID by index.
std::int32_t get_raw_geoidal_separation() const
Returns the geoidal separation in units of 0.01 meters.
std::int64_t get_raw_altitude() const
Returns the altitude portion of the position fix in its base units of 1x10E-6 meters....
static constexpr std::uint8_t MINIMUM_LENGTH_BYTES
The minimum size of this message in bytes.
std::int16_t get_raw_positional_dilution_of_precision() const
Returns the PDOP for this solution. This Indicates the contribution of satellite configuration geomet...
float get_horizontal_dilution_of_precision() const
Returns the HDOP for this solution. This Indicates the contribution of satellite configuration geomet...
GNSSPositionData(std::shared_ptr< ControlFunction > source)
Constructor for a GNSSPositionData message data object.
std::uint32_t get_raw_position_time() const
Returns the number of seconds since midnight.
std::uint8_t sequenceID
The sequence identifier field is used to tie related PGNs together. Somewhat arbitrary.
bool set_latitude(std::int64_t latitudeToSet)
Sets the reported latitude in its base units of 1x10E-16 degrees.
std::int16_t horizontalDilutionOfPrecision
Indicates the contribution of satellite configuration geometry to positioning error....
static constexpr std::uint32_t CYCLIC_MESSAGE_RATE_MS
The transmit interval for this message as specified in NMEA2000.
TypeOfSystem systemType
The type of GNSS system used when generating this message.
std::int16_t positionalDilutionOfPrecision
Indicates the contribution of satellite configuration geometry to positioning error....
bool set_position_date(std::uint16_t dateToSet)
Sets the date to report relative to UTC since Jan 1 1970. Max normal value is 65532.
double get_longitude() const
Returns our current position's longitude in units of degrees.
GNSSMethod method
Stores the method used to provide the GNSS fix.
bool set_reference_station(std::size_t index, std::uint16_t ID, TypeOfSystem type, std::uint16_t ageOfCorrections)
Sets the data for the specified reference station by index.
std::uint8_t get_sequence_id() const
Returns the sequence ID. This is used to associate data within other PGNs with this message.
bool set_positional_dilution_of_precision(std::int16_t pdop)
Sets the positional dilution of precision (PDOP)
GNSSMethod get_gnss_method() const
Returns the GNSS method being reported as part of this position solution, such as RTK Float or DGNSS.
void serialize(std::vector< std::uint8_t > &buffer) const
Serializes the current state of this object into a buffer to be sent on the CAN bus.
bool set_longitude(std::int64_t longitudeToSet)
Sets the reported longitude in its base units of 1x10E-16 degrees.
std::uint16_t positionDate
Number of days relative to UTC since Jan 1 1970 (so 0 is equal to Jan 1, 1970). Max value is 65532 da...
std::uint16_t get_position_date() const
Returns the date associated with the current position.
bool set_timestamp(std::uint32_t timestamp)
Sets the time in milliseconds when the message was last sent or received.
double get_latitude() const
Returns our current position's latitude in units of degrees.
bool deserialize(const CANMessage &receivedMessage)
Deserializes a CAN message to populate this object's contents. Updates the timestamp when called.
std::int64_t longitude
The current longitude in 1x10E-16 degrees. Range is -90 to 90 degrees. Negative values are west longi...
bool set_type_of_system(TypeOfSystem type)
Sets the reported type of GNSS system that produced this position solution.
TypeOfSystem get_reference_station_system_type(std::size_t index) const
Returns the specified reference station's system type by index.
std::int64_t altitude
The current altitude in 1x10E-6 meters. Range is +/- 9.223 x 10E+12 meters.
std::vector< ReferenceStationData > referenceStations
Stores data about the reference stations used to generate this position solution.
std::uint8_t numberOfSpaceVehicles
Number of GPS satellites in view.
bool set_number_of_reference_stations(std::uint8_t stations)
Sets the number of reference stations used in this position solution.
std::uint16_t get_raw_reference_station_corrections_age(std::size_t index) const
Returns the specified reference station's DGNSS corrections age by index.
std::int64_t latitude
The current latitude in 1x10E-16 degrees. Range is -90 to 90 degrees. Negative values are south latit...
float get_positional_dilution_of_precision() const
Returns the PDOP for this solution. This Indicates the contribution of satellite configuration geomet...
float get_geoidal_separation() const
Returns the geoidal separation in units of meters.
Integrity
Enumerates the integrity checking modes that can be reported in this message. You will most often see...
std::int32_t geoidalSeparation
The difference between the earth ellipsoid and mean-sea-level (geoid) defined by the reference datum ...
std::int32_t get_raw_latitude_delta() const
Returns the latitude delta relative to our last position in 1x10E-16 degrees.
std::uint32_t get_timestamp() const
Returns a timestamp in milliseconds corresponding to when the message was last sent or received.
std::int32_t longitudeDelta
The longitude delta in 1x10E-16 degrees.
bool set_time_delta(std::uint8_t delta)
Sets the time delta, in units of 5x10e-3 seconds.
std::uint32_t messageTimestamp_ms
A timestamp in milliseconds when this message was last sent or received.
std::uint8_t get_raw_time_delta() const
Returns the raw time delta since the last reported time in 5x10e-3 seconds.
double get_latitude_delta() const
Returns the latitude delta relative to our last position in degrees.
void serialize(std::vector< std::uint8_t > &buffer) const
Serializes the current state of this object into a buffer to be sent on the CAN bus.
double get_longitude_delta() const
Returns the longitude delta relative to our last position in degrees.
static constexpr std::uint32_t CYCLIC_MESSAGE_RATE_MS
The transmit interval for this message as specified in NMEA2000.
std::uint8_t sequenceID
The sequence identifier field is used to tie related PGNs together. In this case, ties back to GNSS P...
bool set_longitude_delta(std::int32_t delta)
Sets the current longitude delta relative to our last position in 1x10E-16 degrees.
bool set_timestamp(std::uint32_t timestamp)
Sets the time in milliseconds when the message was last sent or received.
static std::uint32_t get_timeout()
Returns the timeout (the sending interval) for this message in milliseconds.
std::shared_ptr< ControlFunction > senderControlFunction
The sender of the message data.
std::int32_t latitudeDelta
The latitude delta in 1x10E-16 degrees.
std::int32_t get_raw_longitude_delta() const
Returns the longitude delta relative to our last position in 1x10E-16 degrees.
PositionDeltaHighPrecisionRapidUpdate(std::shared_ptr< ControlFunction > source)
Constructor for a PositionDeltaHighPrecisionRapidUpdate message data object.
double get_time_delta() const
Returns the raw time delta since the last reported time in seconds.
std::shared_ptr< ControlFunction > get_control_function() const
Returns the control function sending this instance of this message.
bool set_sequence_id(std::uint8_t sequenceNumber)
Sets the sequence ID for this message.
std::uint8_t get_sequence_id() const
Returns the sequence ID. This is used to associate data within other PGNs with this message.
bool set_latitude_delta(std::int32_t delta)
Sets the current latitude delta in units of 1x10E-16 degrees.
bool deserialize(const CANMessage &receivedMessage)
Deserializes a CAN message to populate this object's contents. Updates the timestamp when called.
std::int32_t longitude
The longitude in 1*10E-7 degrees. Negative values indicate west longitudes.
bool set_latitude(std::int32_t latitudeToSet)
Sets the current latitude in units of 1*10E-7 degrees.
std::uint32_t messageTimestamp_ms
A timestamp in milliseconds when this message was last sent or received.
std::int32_t latitude
The latitude in 1*10E-7 degrees. Negative values indicate south latitudes.
bool deserialize(const CANMessage &receivedMessage)
Deserializes a CAN message to populate this object's contents. Updates the timestamp when called.
std::shared_ptr< ControlFunction > senderControlFunction
The sender of the message data.
static constexpr std::uint32_t CYCLIC_MESSAGE_RATE_MS
The transmit interval for this message as specified in NMEA2000.
std::uint32_t get_timestamp() const
Returns a timestamp in milliseconds corresponding to when the message was last sent or received.
bool set_longitude(std::int32_t longitudeToSet)
Sets the current longitude in units of 1*10E-7 degrees.
PositionRapidUpdate(std::shared_ptr< ControlFunction > source)
Constructor for a PositionRapidUpdate message data object.
void serialize(std::vector< std::uint8_t > &buffer) const
Serializes the current state of this object into a buffer to be sent on the CAN bus.
std::shared_ptr< ControlFunction > get_control_function() const
Returns the control function sending this instance of this message.
bool set_timestamp(std::uint32_t timestamp)
Sets the time in milliseconds when the message was last sent or received.
static std::uint32_t get_timeout()
Returns the timeout (the sending interval) for this message in milliseconds.
std::shared_ptr< ControlFunction > senderControlFunction
The sender of the message data.
static std::uint32_t get_timeout()
Returns the timeout (the sending interval) for this message in milliseconds.
std::int32_t rateOfTurn
The rate of turn in 1/32 * 10e-6 rad/s. Positive values indicate turning right (starboard) relative t...
std::shared_ptr< ControlFunction > get_control_function() const
Returns the control function sending this instance of this message.
std::uint32_t messageTimestamp_ms
A timestamp in milliseconds when this message was last sent or received.
void serialize(std::vector< std::uint8_t > &buffer) const
Serializes the current state of this object into a buffer to be sent on the CAN bus.
static constexpr std::uint32_t CYCLIC_MESSAGE_RATE_MS
The interval in milliseconds on which this message should be sent/received.
std::uint8_t sequenceID
The sequence identifier field is used to tie related PGNs together. Somewhat arbitrary.
RateOfTurn(std::shared_ptr< ControlFunction > source)
Constructor for a RateOfTurn message data object.
std::uint8_t get_sequence_id() const
Returns the sequence ID. This is used to associate data within other PGNs with this message.
bool set_sequence_id(std::uint8_t sequenceNumber)
Sets the sequence ID for this message.
bool set_rate_of_turn(std::int32_t turnRate)
Sets the rate of turn in units of 1/32 x 10E-6 rad/s.
std::uint32_t get_timestamp() const
Returns a timestamp in milliseconds corresponding to when the message was last sent or received.
double get_rate_of_turn() const
Returns the rate of turn of the vessel/vehicle in rad/s.
bool set_timestamp(std::uint32_t timestamp)
Sets the time in milliseconds when the message was last sent or received.
std::int32_t get_raw_rate_of_turn() const
Returns the rate of turn of the vessel/vehicle in units of 1/32 x 10E-6 rad/s.
bool deserialize(const CANMessage &receivedMessage)
Deserializes a CAN message to populate this object's contents. Updates the timestamp when called.
bool set_magnetic_deviation(std::int16_t deviation)
Sets the magnetic deviation in 0.0001 radians.
std::uint16_t get_raw_heading() const
Returns the vessel heading in units of 0.0001 radians, which are the message's base units.
float get_heading() const
Returns the vessel heading in radians.
bool set_heading(std::uint16_t heading)
Sets the vessel heading.
HeadingSensorReference get_sensor_reference() const
Returns the reference to which the reported heading is relative to.
static std::uint32_t get_timeout()
Returns the timeout (the sending interval) for this message in milliseconds.
VesselHeading(std::shared_ptr< ControlFunction > source)
Constructor for a VesselHeading message data object.
bool deserialize(const CANMessage &receivedMessage)
Deserializes a CAN message to populate this object's contents. Updates the timestamp when called.
HeadingSensorReference sensorReference
Indicates what the heading is relative to, ie true or magnetic north.
bool set_sensor_reference(HeadingSensorReference reference)
Sets the reference to which the reported heading is relative to.
std::shared_ptr< ControlFunction > get_control_function() const
Returns the control function sending this instance of this message.
std::uint8_t get_sequence_id() const
Returns the sequence ID. This is used to associate data within other PGNs with this message.
std::int16_t get_raw_magnetic_variation() const
Returns the magnetic variation in units of 0.0001 radians.
float get_magnetic_deviation() const
Returns the magnetic deviation in radians.
HeadingSensorReference
The reference which the vessel heading is relative to.
std::int16_t get_raw_magnetic_deviation() const
Returns the magnetic deviation in 0.0001 radians.
std::uint8_t sequenceID
The sequence identifier field is used to tie related PGNs together. Somewhat arbitrary.
bool set_magnetic_variation(std::int16_t variation)
Sets the magnetic variation, in units of 0.0001 radians.
std::uint32_t messageTimestamp_ms
A timestamp in milliseconds when this message was last sent or received.
bool set_sequence_id(std::uint8_t sequenceNumber)
Sets the sequence ID for this message.
static constexpr std::uint32_t CYCLIC_MESSAGE_RATE_MS
The interval in milliseconds on which this message should be sent/received.
std::uint16_t headingReading
The raw heading in 0.0001 radians, relative to the indicated HeadingSensorReference.
std::uint32_t get_timestamp() const
Returns a timestamp in milliseconds corresponding to when the message was last sent or received.
std::shared_ptr< ControlFunction > senderControlFunction
The sender of the message data.
void serialize(std::vector< std::uint8_t > &buffer) const
Takes the current state of the object and serializes it into a buffer to be sent.
bool set_timestamp(std::uint32_t timestamp)
Sets the time in milliseconds when the message was last sent or received.
float get_magnetic_variation() const
Returns the magnetic variation in units of radians.
std::int16_t magneticVariation
The magnetic variation if applicable in 0.0001 radians. Positive values are easterly....
std::int16_t magneticDeviation
The magnetic deviation if not included in the reading in 0.0001 radians. Positive values are easterly...
constexpr std::uint8_t MAX_SEQUENCE_ID
The max non-special allowable value of a NMEA2K sequence ID.
This namespace encompasses all of the ISO11783 stack's functionality to reduce global namespace pollu...
constexpr std::uint8_t CAN_DATA_LENGTH
The length of a classical CAN frame.
This file contains class definitions that will comprise the individual components of the NMEA2000 mes...