4 Copyright (c) 2021 Mario Konrad (mario.konrad@gmx.net)
11 This is a C++ library for **MAR**itime **NAV**igation purposes.
13 It supports (partially):
16 - SeaTalk (Raymarine device communication)
17 - Basic geodesic functions, suitable for martime navigation.
18 - Reading data from serial ports (NMEA, SeaTalk). This is a separate library,
19 available only if required environment is present, typically a Linux system.
21 See chapter _Features_ for a complete and detailed list.
28 There are already implementaions for reading and writing NMEA-0183 or AIS.
29 The goal of this library is
30 - to have an implementation in modern C++
31 - easy to use API (std lib like, integrating well)
32 - unit tested (high test coverage)
33 - trivial integration into projects (liberal license, as few dependencies as
35 - (more or less) well documented
36 - (more or less) complete, as far as information is freely available
46 Supported sentences for NMEA-0183 (read and write):
48 - AAM: Waypoint Arrival Alarm
49 - ACK: Acknowledge Alarm
50 - ALM: GPS Almanac Data
51 - ALR: Set Alarm State
52 - APB: Autopilot Sentence "B"
53 - BEC: Bearing and Distance to Waypoint
54 - BOD: Bearing - Waypoint to Waypoint
55 - BWC: Bearing & Distance to Waypoint - Geat Circle
56 - BWR: Bearing and Distance to Waypoint - Rhumb Line
57 - BWW: Bearing - Waypoint to Waypoint
58 - DBT: Depth Below Transducer
60 - DSC: Digital Selective Calling Information (**experimental**)
61 - DSE: Extended DSC (**experimental**)
62 - DTM: Datum Reference
63 - FSI: Frequency Set Information
64 - GBS: GPS Satellite Fault Detection
65 - GGA: Global Positioning System Fix Data
66 - GLC: Geographic Position, Loran-C
67 - GLL: Geographic Position - Latitude/Longitude
69 - GRS: GPS Range Residuals
70 - GSA: Geographic Position - Latitude/Longitude
71 - GST: GPS Pseudorange Noise Statistics
72 - GSV: Satellites in view
73 - HDG: Heading - Deviation & Variation
75 - HFB: Trawl Headrope to Footrope and Bottom
76 - HSC: Heading Steering Command
77 - ITS: Trawl Door Spread 2 Distance
78 - LCD: Loran-C Signal Data
80 - MSK: Control for a Beacon Receiver
81 - MSS: Beacon Receiver Status
82 - MTW: Mean Temperature of Water
83 - MWD: Wind Direction and Speed
84 - MWV: Wind Speed and Angle
86 - RMA: Recommended Minimum Navigation Information
87 - RMB: Recommended Minimum Navigation Information
88 - RMC: Recommended Minimum Navigation Information
91 - RSA: Rudder Sensor Angle
92 - RSD: RADAR System Data (**experimental**)
94 - SFI: Scanning Frequency Information
95 - STN: Multiple Data ID
96 - TDS: Trawl Door Spread Distance
97 - TEP: Transit Satellite Predicted Elevation
98 - TFI: Trawl Filling Indicator
99 - TLL: Target Latitude and Longitude
100 - TPC: Trawl Position Cartesian Coordinates
101 - TPR: Trawl Position Relative Vessel
102 - TPT: Trawl Position True
103 - TTM: Tracked Target Message
104 - VBW: Dual Ground/Water Speed
105 - VDM: AIS VHF Data-Link Message
106 - VDO: AIS VHF Data-Link Own-Vessel Report
108 - VHW: Water speed and heading
109 - VLW: Distance Traveled through Water
110 - VPW: Speed - Measured Parallel to Wind
111 - VTG: Track made good and Ground speed
112 - WCV: Waypoint Closure Velocity
113 - WNC: Distance - Waypoint to Waypoint
114 - WPL: Waypoint Location
115 - XDR: Transducer Measurement
116 - XTE: Cross-Track Error, Measured
117 - XTR: Cross Track Error - Dead Reckoning
118 - ZDA: Time & Date - UTC, day, month, year and local time zone
119 - ZDL: Time and Distance to Variable Point
120 - ZFO: UTC & Time from origin Waypoint
121 - ZPI - Arrival time at point of interest
122 - ZTG: UTC & Time to Destination Waypoint
124 Obsolete (according to [NMEA Revealed]) but implemented:
126 - APA: Autopilot Sentence "A"
127 - DBK: Depth Below Keel
128 - GTD: Geographic Location in Time Differences
129 - HDM: Heading - Magnetic (obsolete as of 2009)
130 - MTA: Air Temperature
131 - R00: Waypoints in active route
132 - VWE: Wind Track Efficiency
133 - VWR: Relative Wind Speed and Angle.
134 - WDC: Distance to Waypoint
135 - WDR: Distance to Waypoint, Rumb line
136 - ZFI: Elapsed time since point of interest
138 - ZTA: UTC & Estimated arrival time at point of interest
139 - ZTE: UTC & Estimated remaining time to event
143 - PGRME: Garmin Estimated Error
144 - PGRMM: Garmin Map Datum
145 - PGRMZ: Garmin Altitude Information
146 - STALK: SeaTalk Raw Format
150 - Tag Block Support (generic for all sentences)
155 Supported messages for AIS (decode and encode):
157 - Type 01: Position Report Class A
158 - Type 02: Position Report Class A (Assigned Schedule)
159 - Type 03: Position Report Class A (Response to Interrogation)
160 - Type 04: Base Station Report
161 - Type 05: Static and Voyage Related Data
162 - Type 06: Binary Addressed Message
163 - Type 07: Binary Acknowledge
164 - Type 08: Binary Broadcast Message
165 - Type 09: Standard SAR Aircraft Position Report
166 - Type 10: UTC/Date Inquiry
167 - Type 11: UTC/Date Response
168 - Type 12: Addressed Safety-Related Message
169 - Type 13: Safety-Related Acknowledgement
170 - Type 14: Safety-Related Broadcast Message
171 - Type 17: DGNSS Broadcast Binary Message
172 - Type 18: Standard Class B CS Position Report
173 - Type 19: Extended Class B CS Position Report
174 - Type 20: Data Link Management
175 - Type 21: Aid-to-Navigation Report
176 - Type 22: Channel Management
177 - Type 23: Group Assignment Command
178 - Type 24: Static Data Report (part A and B, norma and auxiliary vessel)
180 Supported payload of binary message 08:
181 - 001/11: Meteorological and Hydrological Data (IMO236)
182 - 200/10: Inland ship static and voyage related data (Inland AIS)
186 Suported messages for SeaTalk (decode and encode):
188 - Type 00: depth below transducer
189 - Type 01: equipment id
190 - Type 05: Engine RPM and PITCH
191 - Type 10: apparent wind angle
192 - Type 11: apparent wind speed
193 - Type 20: speed through water
194 - Type 21: trip mileage
195 - Type 22: total mileage
196 - Type 23: water temperature 1
197 - Type 24: Display unit for Mileage and Speed
198 - Type 25: total and trip log
199 - Type 26: Speed through Water
200 - Type 27: water temperature 2
201 - Type 30: Set Lamp Intensity
202 - Type 36: Cancel MOB condition
203 - Type 38: Codelock data (**experimental**)
204 - Type 50: LAT Postion
205 - Type 51: LON Postion
206 - Type 52: Speed over Ground
207 - Type 53: Magnetic Course in Degrees
211 - Type 59: Set Count Down Timer (sent by ST60)
212 - Type 65: Select Fathom display unit for depth display (see message 00)
213 - Type 66: Wind Alarm
214 - Type 6C: Second equipment-ID
216 - Type 87: Response Level
217 - Type 89: Compass heading (sent by ST40 compass instrument)
222 - Reading data from serial ports (NMEA, SeaTalk).
223 Available only if the environment supports the implementation,
224 typically a Linux system.
227 ### Geodesic Functions
229 Basic geodesic functions, suitable for martime navigation.
231 - Calculation of CPA (closest point of approach)
232 and TCPA (time to closest point of approach)
233 - Distance of two points on a sphere
234 - Distance of two points on an ellipsoid using formula of Vincenty
235 - Distance of two points on an ellipsoid using formula of Lambert
243 More examples [here](examples/README.md).
245 ### Parse NMEA Sentence
248 using namespace marnav;
250 auto sentence = nmea::make_sentence(
251 "$GPRMC,201034,A,4702.4040,N,00818.3281,E,0.0,328.4,260807,0.6,E,A*17");
252 std::cout << sentence->tag() << "\n";
253 auto rmc = nmea::sentence_cast<nmea::rmc>(sentence);
254 std::cout << "latitude : " << nmea::to_string(rmc->get_latitude()) << "\n";
255 std::cout << "longitude: " << nmea::to_string(rmc->get_longitude()) << "\n";
258 Create a specific sentence directly:
261 using namespace marnav;
263 auto rmc = nmea::create_sentence<nmea::rmc>(
264 "$GPRMC,201034,A,4702.4040,N,00818.3281,E,0.0,328.4,260807,0.6,E,A*17");
265 std::cout << "latitude : " << nmea::to_string(rmc.get_latitude()) << "\n";
266 std::cout << "longitude: " << nmea::to_string(rmc.get_longitude()) << "\n";
269 ### Write NMEA Sentence
273 mtw.set_temperature(units::celsius{22.5});
274 std::string data = nmea::to_string(mtw);
277 ### Parse AIS Message from NMEA data
280 using namespace marnav;
282 // received sentences
283 const std::vector<std::string> received_strings
284 = {"!AIVDM,2,1,3,B,55P5TL01VIaAL@7WKO@mBplU@<PDhh000000001S;AJ::4A80?4i@E53,0*3E",
285 "!AIVDM,2,2,3,B,1@0000000000000,2*55"};
287 // parse NMEA sentences
288 std::vector<std::unique_ptr<nmea::sentence>> sentences;
289 for (auto const & txt : received_strings) {
290 auto sentence = nmea::make_sentence(txt);
291 if (sentence->id() == nmea::sentence_id::VDM) {
292 sentences.push_back(std::move(sentence));
296 // parse and and process AIS messags
297 auto payload = nmea::collect_payload(sentences.begin(), sentences.end());
298 auto message = ais::make_message(payload);
299 if (message->type() == ais::message_id::static_and_voyage_related_data) {
300 auto report = ais::message_cast<ais::message_05>(message);
301 std::cout << "shipname: " << report->get_shipname() << "\n";
302 std::cout << "callsign: " << report->get_callsign() << "\n";
306 ### Create NMEA sentences from AIS data
309 using namespace marnav;
312 ais::message_01 pos_report;
313 pos_report.set_sog(units::knots{8.2});
314 // ... most data not shown here
317 auto payload = ais::encode_message(pos_report);
319 // create NMEA sentences
320 for (uint32_t fragment = 0; fragment < payload.size(); ++fragment) {
322 vdm.set_n_fragments(payload.size());
323 vdm.set_fragment(fragment + 1);
324 vdm.set_radio_channel(nmea::ais_channel::B);
325 vdm.set_payload(payload[fragment]);
327 // collect, send or do something with the sentence...
328 std::string s = nmea::to_string(vdm);
329 std::cout << s << "\n";
333 or simply use `nmea::make_vdms`:
336 using namespace marnav;
339 ais::message_01 pos_report;
340 pos_report.set_sog(units::knots{8.2});
341 // ... most data not shown here
344 auto payload = ais::encode_message(pos_report);
346 // create NMEA sentences
347 auto sentences = nmea::make_vdms(payload);
349 // process sentences, somehow...
350 for (auto const & sentence : sentences) {
351 std::cout << nmea::to_string(*sentence) << "\n";
360 This chapter describes the requirements in order to build the library.
361 Tools and their versions are listed below, newer/older/other tools
362 (i.e. compilers, etc.) may work, but not tested.
381 Tools needed to build the library:
382 - cmake 3.19 or newer
384 Tools needed to develop the library:
388 Tools needed to build the documentation:
391 - LaTeX (there are formulas!)
393 Optional used for development:
394 - lcov / genhtml, c++filt
396 - clang-tools (analyzer)
400 Optional (no core dependency):
401 - Boost.ASIO (used only for some examples)
402 - Qt 5 (used only for some examples)
407 There are no other dependencies despite the standard library (C++17)
408 to build this library.
415 The following build types `-DCMAKE_BUILD_TYPE=x` are possible:
421 - `ENABLE_STATIC` : enables static build, if `OFF`, a shared library is being built.
423 - `ENABLE_PROFILING` : enables profiling for `gprof`
424 - `ENABLE_BENCHMARK` : enables benchmarking (disables some optimization)
425 - `ENABLE_SANITIZER` : enables address and undefined sanitizers
428 - `ENABLE_EXAMPLES`: enables examples. Default: `ON`
429 - `ENABLE_TOOLS`: enables tools. Default: `ON`
430 - `ENABLE_TESTS`: enables unit tests, integration tests and benchmarks. Default: `ON`
431 - `ENABLE_TESTS_BENCHMARK`: enables benchmark tests, enabled only if `ENABLE_TESTS` is also enabled. Default: `ON`
438 cmake -DCMAKE_BUILD_TYPE=Release ..
454 or individual package types:
460 ### Developpers Choice
464 cmake -DCMAKE_BUILD_TYPE=Coverage ..
466 make coverage doc cppcheck
469 ### Static Analysis with Clang
471 There is a script ```bin/static-analysis-clang``` for doing this, there is not yet
472 an integration of clang-tidy in the cmake build.
475 ### Perform Benchmarks
477 Build in `Release` mode, perform individual benchmarks:
481 cmake -DCMAKE_BUILD_TYPE=Release ..
483 test/benchmark_nmea_split
485 Using `perf` to do performance analysis:
489 cmake -DCMAKE_BUILD_TYPE=Release -DENABLE_BENCHMARK=ON ..
491 perf record -g test/benchmark_nmea_split
492 perf report -g 'graph,0.5,caller'
497 There is a helper script ```bin/check-format``` which uses ```clang-format``` to
498 check the formatting of all files in the directories containing code (```src```,
499 ```test``` and ```examples```). This script can be used manually:
503 or used as git pre-commit hook:
506 ln -s ../../bin/check-format pre-commit
508 which prevents a commit if there are files not complying with the formatting
509 rules. Be aware of using the script as pre-commit hook, the checking can take
518 Mario Konrad (mario.konrad@gmx.net) with help from others.
520 Search the repository for a complete list:
522 git log --format=%an | sort -u
529 A (non-complete) collection of resources from where information was gathered.
531 - [NMEA Revealed](http://www.catb.org/gpsd/NMEA.html) (by Eric S. Raymond)
532 - [NMEA FAQ](http://www.kh-gps.de/nmea.faq)
533 - [it-digin's blog](http://www.it-digin.com/blog/?cat=4)
534 - [AIVDM/AIVDO Protocol decoding](http://www.catb.org/gpsd/AIVDM.html) (by Eric S. Raymond)
535 - [DSC Position Request](http://www.thehulltruth.com/marine-electronics-forum/43945-dsc-position-request.html)
536 - [NMEA-0183 Sentences DSC,DSE](http://www.cruisersforum.com/forums/f13/nmea-0183-sentences-dsc-dse-124887.html)
537 - [NMEA-0183 Sentence ALR](https://www.cruisersforum.com/forums/f134/opencpn-and-external-nmea0183-alarms-81396.html)
538 - [SerialMon - NMEA 0183 Protocol](http://www.serialmon.com/protocols/nmea0183.html)
539 - [SeaTalk Reference](http://thomasknauf.de/seatalk.htm) (by Thomas Knauf)
540 - [Navigation Center - AIS Standard Class B Equipment Position Report](http://www.navcen.uscg.gov/?pageName=AISMessagesB)
541 - [GPS Forums](http://www.gps-forums.net)
542 - [NMEA Datensaetze](http://www.nmea.de/nmea0183datensaetze.html)
543 - [AIS VDM & VDO Message Decoder](http://www.maritec.co.za/tools/aisvdmvdodecoding/)
544 - [AIS VDM & VDO Message Decoder](http://www.maritec.co.za/tools/aisvdmvdodecoding/)
545 - [Code comments from library NMEA0183](https://github.com/SammyB428/NMEA0183)
553 > The official NMEA 0183 Standard document is not available for free. It was not
554 > consulted at any point during the development of this library. All information
555 > was found from free sources on the internet. This library (especially the NMEA
556 > part) is not derivative work of this standard.
559 See also [LICENSE](LICENSE)
564 Copyright (c) 2021, Mario Konrad
567 Redistribution and use in source and binary forms, with or without
568 modification, are permitted provided that the following conditions are met:
569 1. Redistributions of source code must retain the above copyright
570 notice, this list of conditions and the following disclaimer.
571 2. Redistributions in binary form must reproduce the above copyright
572 notice, this list of conditions and the following disclaimer in the
573 documentation and/or other materials provided with the distribution.
574 3. All advertising materials mentioning features or use of this software
575 must display the following acknowledgement:
576 This product includes software developed by Mario Konrad.
577 4. Neither the name of the software nor the names of its contributors
578 may be used to endorse or promote products derived from this software
579 without specific prior written permission.
581 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
582 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
583 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
584 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
585 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
586 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
587 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
588 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
589 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
590 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.