Build: docker for clang-14.0.0
[marnav.git] / README.md
blob8181be4cfc220b14133708e910b7c70d89ffd54b
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 - Reading data from serial ports (NMEA, SeaTalk)
18 - Basic geodesic functions, suitable for martime navigation.
20 See chapter _Features_ for a complete and detailed list.
22 ---
24 Goals
25 -----
27 There are already implementaions for reading and writing NMEA-0183 or AIS.
28 The goal of this library is
29 - to have an implementation in modern C++
30 - easy to use API (std lib like, integrating well)
31 - unit tested (high test coverage)
32 - trivial integration into projects (liberal license, as few dependencies as
33   possible)
34 - (more or less) well documented
35 - (more or less) complete, as far as information is freely available
36 - having fun
38 ---
40 Features
41 --------
43 ### NMEA-0183
45 Supported sentences for NMEA-0183 (read and write):
47 - AAM: Waypoint Arrival Alarm
48 - ACK: Acknowledge Alarm
49 - ALM: GPS Almanac Data
50 - ALR: Set Alarm State
51 - APB: Autopilot Sentence "B"
52 - BEC: Bearing and Distance to Waypoint
53 - BOD: Bearing - Waypoint to Waypoint
54 - BWC: Bearing & Distance to Waypoint - Geat Circle
55 - BWR: Bearing and Distance to Waypoint - Rhumb Line
56 - BWW: Bearing - Waypoint to Waypoint
57 - DBT: Depth Below Transducer
58 - DPT: Depth of Water
59 - DSC: Digital Selective Calling Information (**experimental**)
60 - DSE: Extended DSC (**experimental**)
61 - DTM: Datum Reference
62 - FSI: Frequency Set Information
63 - GBS: GPS Satellite Fault Detection
64 - GGA: Global Positioning System Fix Data
65 - GLC: Geographic Position, Loran-C
66 - GLL: Geographic Position - Latitude/Longitude
67 - GNS: Fix data
68 - GRS: GPS Range Residuals
69 - GSA: Geographic Position - Latitude/Longitude
70 - GST: GPS Pseudorange Noise Statistics
71 - GSV: Satellites in view
72 - HDG: Heading - Deviation & Variation
73 - HDT: Heading - True
74 - HFB: Trawl Headrope to Footrope and Bottom
75 - HSC: Heading Steering Command
76 - ITS: Trawl Door Spread 2 Distance
77 - LCD: Loran-C Signal Data
78 - MOB: Man over Board
79 - MSK: Control for a Beacon Receiver
80 - MSS: Beacon Receiver Status
81 - MTW: Mean Temperature of Water
82 - MWD: Wind Direction and Speed
83 - MWV: Wind Speed and Angle
84 - OSD: Own Ship Data
85 - RMA: Recommended Minimum Navigation Information
86 - RMB: Recommended Minimum Navigation Information
87 - RMC: Recommended Minimum Navigation Information
88 - ROT: Rate Of Turn
89 - RPM: Revolutions
90 - RSA: Rudder Sensor Angle
91 - RSD: RADAR System Data (**experimental**)
92 - RTE: Routes
93 - SFI: Scanning Frequency Information
94 - STN: Multiple Data ID
95 - TDS: Trawl Door Spread Distance
96 - TEP: Transit Satellite Predicted Elevation
97 - TFI: Trawl Filling Indicator
98 - TLL: Target Latitude and Longitude
99 - TPC: Trawl Position Cartesian Coordinates
100 - TPR: Trawl Position Relative Vessel
101 - TPT: Trawl Position True
102 - TTM: Tracked Target Message
103 - VBW: Dual Ground/Water Speed
104 - VDM: AIS VHF Data-Link Message
105 - VDO: AIS VHF Data-Link Own-Vessel Report
106 - VDR: Set and Drift
107 - VHW: Water speed and heading
108 - VLW: Distance Traveled through Water
109 - VPW: Speed - Measured Parallel to Wind
110 - VTG: Track made good and Ground speed
111 - WCV: Waypoint Closure Velocity
112 - WNC: Distance - Waypoint to Waypoint
113 - WPL: Waypoint Location
114 - XDR: Transducer Measurement
115 - XTE: Cross-Track Error, Measured
116 - XTR: Cross Track Error - Dead Reckoning
117 - ZDA: Time & Date - UTC, day, month, year and local time zone
118 - ZDL: Time and Distance to Variable Point
119 - ZFO: UTC & Time from origin Waypoint
120 - ZPI - Arrival time at point of interest
121 - ZTG: UTC & Time to Destination Waypoint
123 Obsolete (according to [NMEA Revealed]) but implemented:
125 - APA: Autopilot Sentence "A"
126 - DBK: Depth Below Keel
127 - GTD: Geographic Location in Time Differences
128 - HDM: Heading - Magnetic (obsolete as of 2009)
129 - MTA: Air Temperature
130 - R00: Waypoints in active route
131 - VWE: Wind Track Efficiency
132 - VWR: Relative Wind Speed and Angle.
133 - WDC: Distance to Waypoint
134 - WDR: Distance to Waypoint, Rumb line
135 - ZFI: Elapsed time since point of interest
136 - ZLZ: Time of Day
137 - ZTA: UTC & Estimated arrival time at point of interest
138 - ZTE: UTC & Estimated remaining time to event
140 Vendor Extensions:
142 - PGRME: Garmin Estimated Error
143 - PGRMM: Garmin Map Datum
144 - PGRMZ: Garmin Altitude Information
145 - STALK: SeaTalk Raw Format
147 Miscellaneous:
149 - Tag Block Support (generic for all sentences)
152 ### AIS
154 Supported messages for AIS (decode and encode):
156 - Type 01: Position Report Class A
157 - Type 02: Position Report Class A (Assigned Schedule)
158 - Type 03: Position Report Class A (Response to Interrogation)
159 - Type 04: Base Station Report
160 - Type 05: Static and Voyage Related Data
161 - Type 06: Binary Addressed Message
162 - Type 07: Binary Acknowledge
163 - Type 08: Binary Broadcast Message
164 - Type 09: Standard SAR Aircraft Position Report
165 - Type 10: UTC/Date Inquiry
166 - Type 11: UTC/Date Response
167 - Type 12: Addressed Safety-Related Message
168 - Type 13: Safety-Related Acknowledgement
169 - Type 14: Safety-Related Broadcast Message
170 - Type 17: DGNSS Broadcast Binary Message
171 - Type 18: Standard Class B CS Position Report
172 - Type 19: Extended Class B CS Position Report
173 - Type 20: Data Link Management
174 - Type 21: Aid-to-Navigation Report
175 - Type 22: Channel Management
176 - Type 23: Group Assignment Command
177 - Type 24: Static Data Report (part A and B, norma and auxiliary vessel)
179 Supported payload of binary message 08:
180 - 001/11: Meteorological and Hydrological Data (IMO236)
181 - 200/10: Inland ship static and voyage related data (Inland AIS)
183 ### SeaTalk
185 Suported messages for SeaTalk (decode and encode):
187 - Type 00: depth below transducer
188 - Type 01: equipment id
189 - Type 05: Engine RPM and PITCH
190 - Type 10: apparent wind angle
191 - Type 11: apparent wind speed
192 - Type 20: speed through water
193 - Type 21: trip mileage
194 - Type 22: total mileage
195 - Type 23: water temperature 1
196 - Type 24: Display unit for Mileage and Speed
197 - Type 25: total and trip log
198 - Type 26: Speed through Water
199 - Type 27: water temperature 2
200 - Type 30: Set Lamp Intensity
201 - Type 36: Cancel MOB condition
202 - Type 38: Codelock data (**experimental**)
203 - Type 50: LAT Postion
204 - Type 51: LON Postion
205 - Type 52: Speed over Ground
206 - Type 53: Magnetic Course in Degrees
207 - Type 54: GMT Time
208 - Type 56: Date
209 - Type 58: LAT/LON
210 - Type 59: Set Count Down Timer (sent by ST60)
211 - Type 65: Select Fathom display unit for depth display (see message 00)
212 - Type 66: Wind Alarm
213 - Type 6C: Second equipment-ID
214 - Type 86: Keystroke
215 - Type 87: Response Level
216 - Type 89: Compass heading (sent by ST40 compass instrument)
219 ### IO
221 - Reading data from serial ports (NMEA, SeaTalk)
224 ### Geodesic Functions
226 Basic geodesic functions, suitable for martime navigation.
228 - Calculation of CPA (closest point of approach)
229   and TCPA (time to closest point of approach)
230 - Distance of two points on a sphere
231 - Distance of two points on an ellipsoid using formula of Vincenty
232 - Distance of two points on an ellipsoid using formula of Lambert
237 Examples
238 --------
240 More examples [here](examples/README.md).
242 ### Parse NMEA Sentence
244 ~~~~~~~~~~~~~{.cpp}
245 using namespace marnav;
247 auto sentence = nmea::make_sentence(
248         "$GPRMC,201034,A,4702.4040,N,00818.3281,E,0.0,328.4,260807,0.6,E,A*17");
249 std::cout << sentence->tag() << "\n";
250 auto rmc = nmea::sentence_cast<nmea::rmc>(sentence);
251 std::cout << "latitude : " << nmea::to_string(rmc->get_latitude()) << "\n";
252 std::cout << "longitude: " << nmea::to_string(rmc->get_longitude()) << "\n";
253 ~~~~~~~~~~~~~
255 Create a specific sentence directly:
257 ~~~~~~~~~~~~~{.cpp}
258 using namespace marnav;
260 auto rmc = nmea::create_sentence<nmea::rmc>(
261         "$GPRMC,201034,A,4702.4040,N,00818.3281,E,0.0,328.4,260807,0.6,E,A*17");
262 std::cout << "latitude : " << nmea::to_string(rmc.get_latitude()) << "\n";
263 std::cout << "longitude: " << nmea::to_string(rmc.get_longitude()) << "\n";
264 ~~~~~~~~~~~~~
266 ### Write NMEA Sentence
268 ~~~~~~~~~~~~~{.cpp}
269 nmea::mtw mtw;
270 mtw.set_temperature(units::celsius{22.5});
271 std::string data = nmea::to_string(mtw);
272 ~~~~~~~~~~~~~
274 ### Parse AIS Message from NMEA data
276 ~~~~~~~~~~~~~{.cpp}
277 using namespace marnav;
279 // received sentences
280 const std::vector<std::string> received_strings
281         = {"!AIVDM,2,1,3,B,55P5TL01VIaAL@7WKO@mBplU@<PDhh000000001S;AJ::4A80?4i@E53,0*3E",
282                 "!AIVDM,2,2,3,B,1@0000000000000,2*55"};
284 // parse NMEA sentences
285 std::vector<std::unique_ptr<nmea::sentence>> sentences;
286 for (auto const & txt : received_strings) {
287         auto sentence = nmea::make_sentence(txt);
288         if (sentence->id() == nmea::sentence_id::VDM) {
289                 sentences.push_back(std::move(sentence));
290         }
293 // parse and and process AIS messags
294 auto payload = nmea::collect_payload(sentences.begin(), sentences.end());
295 auto message = ais::make_message(payload);
296 if (message->type() == ais::message_id::static_and_voyage_related_data) {
297         auto report = ais::message_cast<ais::message_05>(message);
298         std::cout << "shipname: " << report->get_shipname() << "\n";
299         std::cout << "callsign: " << report->get_callsign() << "\n";
301 ~~~~~~~~~~~~~
303 ### Create NMEA sentences from AIS data
305 ~~~~~~~~~~~~~{.cpp}
306 using namespace marnav;
308 // prepare AIS data
309 ais::message_01 pos_report;
310 pos_report.set_sog(units::knots{8.2});
311 // ... most data not shown here
313 // create payload
314 auto payload = ais::encode_message(pos_report);
316 // create NMEA sentences
317 for (uint32_t fragment = 0; fragment < payload.size(); ++fragment) {
318         nmea::vdm vdm;
319         vdm.set_n_fragments(payload.size());
320         vdm.set_fragment(fragment + 1);
321         vdm.set_radio_channel(nmea::ais_channel::B);
322         vdm.set_payload(payload[fragment]);
324         // collect, send or do something with the sentence...
325         std::string s = nmea::to_string(vdm);
326         std::cout << s << "\n";
328 ~~~~~~~~~~~~~
330 or simply use `nmea::make_vdms`:
332 ~~~~~~~~~~~~~{.cpp}
333 using namespace marnav;
335 // prepare AIS data
336 ais::message_01 pos_report;
337 pos_report.set_sog(units::knots{8.2});
338 // ... most data not shown here
340 // create payload
341 auto payload = ais::encode_message(pos_report);
343 // create NMEA sentences
344 auto sentences = nmea::make_vdms(payload);
346 // process sentences, somehow...
347 for (auto const & sentence : sentences) {
348         std::cout << nmea::to_string(*sentence) << "\n";
350 ~~~~~~~~~~~~~
354 Requirements
355 ------------
357 This chapter describes the requirements in order to build the library.
358 Tools and their versions are listed below, newer/older/other tools
359 (i.e. compilers, etc.) may work, but not tested.
361 Compiler:
362 - GCC 7
363 - GCC 8
364 - GCC 9
365 - GCC 10
366 - GCC 11
367 - Clang 4
368 - Clang 5
369 - Clang 6
370 - Clang 7
371 - Clang 8
372 - Clang 9
373 - Clang 10
374 - Clang 11
375 - Clang 12
376 - Clang 13
378 Tools needed to build the library:
379 - cmake 3.19 or newer
381 Tools needed to develop the library:
382 - git
383 - clang-format 10
385 Tools needed to build the documentation:
386 - doxygen
387 - graphviz
388 - LaTeX (there are formulas!)
390 Optional used for development:
391 - lcov / genhtml, c++filt
392 - cppcheck
393 - clang-tools (analyzer)
394 - ctags, cscope
395 - perf
397 Optional (no core dependency):
398 - Boost.ASIO (used only for some examples)
399 - Qt 5 (used only for some examples)
401 Opeating system:
402 - Linux
404 There are no other dependencies despite the standard library (C++17)
405 to build this library.
409 Build
410 -----
412 The following build types `-DCMAKE_BUILD_TYPE=x` are possible:
413 - Debug
414 - Release
415 - Coverage
417 Build options:
418 - `ENABLE_STATIC` : enables static build, if `OFF`, a shared library is being built.
419   Default: `ON`
420 - `ENABLE_PROFILING` : enables profiling for `gprof`
421 - `ENABLE_BENCHMARK` : enables benchmarking (disables some optimization)
422 - `ENABLE_SANITIZER` : enables address and undefined sanitizers
424 Features:
425 - `ENABLE_IO` : enables IO support. Default: `ON`
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.