General: separation of marav-io as a library
[marnav.git] / README.md
blob6e435514aca1bc031e288970708e1e228bcfb2d5
1 marnav
2 ======
4 Copyright (c) 2021 Mario Konrad (mario.konrad@gmx.net)
6 ---
8 Abstract
9 --------
11 This is a C++ library for **MAR**itime **NAV**igation purposes.
13 It supports (partially):
14 - NMEA-0183
15 - AIS
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.
23 ---
25 Goals
26 -----
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
34   possible)
35 - (more or less) well documented
36 - (more or less) complete, as far as information is freely available
37 - having fun
39 ---
41 Features
42 --------
44 ### NMEA-0183
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
59 - DPT: Depth of Water
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
68 - GNS: Fix data
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
74 - HDT: Heading - True
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
79 - MOB: Man over Board
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
85 - OSD: Own Ship Data
86 - RMA: Recommended Minimum Navigation Information
87 - RMB: Recommended Minimum Navigation Information
88 - RMC: Recommended Minimum Navigation Information
89 - ROT: Rate Of Turn
90 - RPM: Revolutions
91 - RSA: Rudder Sensor Angle
92 - RSD: RADAR System Data (**experimental**)
93 - RTE: Routes
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
107 - VDR: Set and Drift
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
137 - ZLZ: Time of Day
138 - ZTA: UTC & Estimated arrival time at point of interest
139 - ZTE: UTC & Estimated remaining time to event
141 Vendor Extensions:
143 - PGRME: Garmin Estimated Error
144 - PGRMM: Garmin Map Datum
145 - PGRMZ: Garmin Altitude Information
146 - STALK: SeaTalk Raw Format
148 Miscellaneous:
150 - Tag Block Support (generic for all sentences)
153 ### AIS
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)
184 ### SeaTalk
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
208 - Type 54: GMT Time
209 - Type 56: Date
210 - Type 58: LAT/LON
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
215 - Type 86: Keystroke
216 - Type 87: Response Level
217 - Type 89: Compass heading (sent by ST40 compass instrument)
220 ### IO
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
240 Examples
241 --------
243 More examples [here](examples/README.md).
245 ### Parse NMEA Sentence
247 ~~~~~~~~~~~~~{.cpp}
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";
256 ~~~~~~~~~~~~~
258 Create a specific sentence directly:
260 ~~~~~~~~~~~~~{.cpp}
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";
267 ~~~~~~~~~~~~~
269 ### Write NMEA Sentence
271 ~~~~~~~~~~~~~{.cpp}
272 nmea::mtw mtw;
273 mtw.set_temperature(units::celsius{22.5});
274 std::string data = nmea::to_string(mtw);
275 ~~~~~~~~~~~~~
277 ### Parse AIS Message from NMEA data
279 ~~~~~~~~~~~~~{.cpp}
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));
293         }
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";
304 ~~~~~~~~~~~~~
306 ### Create NMEA sentences from AIS data
308 ~~~~~~~~~~~~~{.cpp}
309 using namespace marnav;
311 // prepare AIS data
312 ais::message_01 pos_report;
313 pos_report.set_sog(units::knots{8.2});
314 // ... most data not shown here
316 // create payload
317 auto payload = ais::encode_message(pos_report);
319 // create NMEA sentences
320 for (uint32_t fragment = 0; fragment < payload.size(); ++fragment) {
321         nmea::vdm vdm;
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";
331 ~~~~~~~~~~~~~
333 or simply use `nmea::make_vdms`:
335 ~~~~~~~~~~~~~{.cpp}
336 using namespace marnav;
338 // prepare AIS data
339 ais::message_01 pos_report;
340 pos_report.set_sog(units::knots{8.2});
341 // ... most data not shown here
343 // create payload
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";
353 ~~~~~~~~~~~~~
357 Requirements
358 ------------
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.
364 Compiler:
365 - GCC 7
366 - GCC 8
367 - GCC 9
368 - GCC 10
369 - GCC 11
370 - Clang 4
371 - Clang 5
372 - Clang 6
373 - Clang 7
374 - Clang 8
375 - Clang 9
376 - Clang 10
377 - Clang 11
378 - Clang 12
379 - Clang 13
381 Tools needed to build the library:
382 - cmake 3.19 or newer
384 Tools needed to develop the library:
385 - git
386 - clang-format 10
388 Tools needed to build the documentation:
389 - doxygen
390 - graphviz
391 - LaTeX (there are formulas!)
393 Optional used for development:
394 - lcov / genhtml, c++filt
395 - cppcheck
396 - clang-tools (analyzer)
397 - ctags, cscope
398 - perf
400 Optional (no core dependency):
401 - Boost.ASIO (used only for some examples)
402 - Qt 5 (used only for some examples)
404 Opeating system:
405 - Linux
407 There are no other dependencies despite the standard library (C++17)
408 to build this library.
412 Build
413 -----
415 The following build types `-DCMAKE_BUILD_TYPE=x` are possible:
416 - Debug
417 - Release
418 - Coverage
420 Build options:
421 - `ENABLE_STATIC` : enables static build, if `OFF`, a shared library is being built.
422   Default: `ON`
423 - `ENABLE_PROFILING` : enables profiling for `gprof`
424 - `ENABLE_BENCHMARK` : enables benchmarking (disables some optimization)
425 - `ENABLE_SANITIZER` : enables address and undefined sanitizers
427 Components:
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`
434 ### Library
436         mkdir build
437         cd build
438         cmake -DCMAKE_BUILD_TYPE=Release ..
439         make
442 ### Documentation
444         mkdir build
445         cd build
446         cmake ..
447         make doc
450 ### Package
452         make package
454 or individual package types:
456         cpack -G TGZ
457         cpack -G DEB
460 ### Developpers Choice
462         mkdir build
463         cd build
464         cmake -DCMAKE_BUILD_TYPE=Coverage ..
465         make -j 8
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:
479         mkdir build
480         cd build
481         cmake -DCMAKE_BUILD_TYPE=Release ..
482         make -j 8
483         test/benchmark_nmea_split
485 Using `perf` to do performance analysis:
487         mkdir build
488         cd build
489         cmake -DCMAKE_BUILD_TYPE=Release -DENABLE_BENCHMARK=ON ..
490         make -j 8
491         perf record -g test/benchmark_nmea_split
492         perf report -g 'graph,0.5,caller'
495 ### Formatting Test
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:
501         bin/check-format
503 or used as git pre-commit hook:
505         cd .git/hooks
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
510 several seconds.
515 Authors
516 -------
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
526 Links
527 -----
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)
549 LICENSE
550 -------
552 > NOTE:
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)
561 (BSD)
564 Copyright (c) 2021, Mario Konrad
565 All rights reserved.
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.