NMEA: sentence ZFI added
[marnav.git] / README.md
blob5120ca5326166e879e06adf0662454572d8a7f6c
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 - ALM: GPS Almanac Data
49 - APB: Autopilot Sentence "B"
50 - BEC: Bearing and Distance to Waypoint
51 - BOD: Bearing - Waypoint to Waypoint
52 - BWC: Bearing & Distance to Waypoint - Geat Circle
53 - BWR: Bearing and Distance to Waypoint - Rhumb Line
54 - BWW: Bearing - Waypoint to Waypoint
55 - DBT: Depth Below Transducer
56 - DPT: Depth of Water
57 - DSC: Digital Selective Calling Information (**experimental**)
58 - DSE: Extended DSC (**experimental**)
59 - DTM: Datum Reference
60 - FSI: Frequency Set Information
61 - GBS: GPS Satellite Fault Detection
62 - GGA: Global Positioning System Fix Data
63 - GLC: Geographic Position, Loran-C
64 - GLL: Geographic Position - Latitude/Longitude
65 - GNS: Fix data
66 - GRS: GPS Range Residuals
67 - GSA: Geographic Position - Latitude/Longitude
68 - GST: GPS Pseudorange Noise Statistics
69 - GSV: Satellites in view
70 - HDG: Heading - Deviation & Variation
71 - HDT: Heading - True
72 - HFB: Trawl Headrope to Footrope and Bottom
73 - HSC: Heading Steering Command
74 - ITS: Trawl Door Spread 2 Distance
75 - LCD: Loran-C Signal Data
76 - MOB: Man over Board
77 - MSK: Control for a Beacon Receiver
78 - MSS: Beacon Receiver Status
79 - MTW: Mean Temperature of Water
80 - MWD: Wind Direction and Speed
81 - MWV: Wind Speed and Angle
82 - OSD: Own Ship Data
83 - RMA: Recommended Minimum Navigation Information
84 - RMB: Recommended Minimum Navigation Information
85 - RMC: Recommended Minimum Navigation Information
86 - ROT: Rate Of Turn
87 - RPM: Revolutions
88 - RSA: Rudder Sensor Angle
89 - RSD: RADAR System Data (**experimental**)
90 - RTE: Routes
91 - SFI: Scanning Frequency Information
92 - STN: Multiple Data ID
93 - TDS: Trawl Door Spread Distance
94 - TFI: Trawl Filling Indicator
95 - TLL: Target Latitude and Longitude
96 - TPC: Trawl Position Cartesian Coordinates
97 - TPR: Trawl Position Relative Vessel
98 - TPT: Trawl Position True
99 - TTM: Tracked Target Message
100 - VBW: Dual Ground/Water Speed
101 - VDM: AIS VHF Data-Link Message
102 - VDO: AIS VHF Data-Link Own-Vessel Report
103 - VDR: Set and Drift
104 - VHW: Water speed and heading
105 - VLW: Distance Traveled through Water
106 - VPW: Speed - Measured Parallel to Wind
107 - VTG: Track made good and Ground speed
108 - WCV: Waypoint Closure Velocity
109 - WDC: Distance to Waypoint
110 - WDR: Distance to Waypoint, Rumb line
111 - WNC: Distance - Waypoint to Waypoint
112 - WPL: Waypoint Location
113 - XDR: Transducer Measurement
114 - XTE: Cross-Track Error, Measured
115 - XTR: Cross Track Error - Dead Reckoning
116 - ZDA: Time & Date - UTC, day, month, year and local time zone
117 - ZDL: Time and Distance to Variable Point
118 - ZFO: UTC & Time from origin Waypoint
119 - ZTG: UTC & Time to Destination Waypoint
121 Obsolete (according to [NMEA Revealed]) but implemented:
123 - APA: Autopilot Sentence "A"
124 - DBK: Depth Below Keel
125 - GTD: Geographic Location in Time Differences
126 - HDM: Heading - Magnetic (obsolete as of 2009)
127 - MTA: Air Temperature
128 - R00: Waypoints in active route
129 - VWE: Wind Track Efficiency
130 - VWR: Relative Wind Speed and Angle.
131 - ZFI: Elapsed time since point of interest
133 Vendor Extensions:
135 - PGRME: Garmin Estimated Error
136 - PGRMM: Garmin Map Datum
137 - PGRMZ: Garmin Altitude Information
138 - STALK: SeaTalk Raw Format
140 Miscellaneous:
142 - Tag Block Support (generic for all sentences)
145 ### AIS
147 Supported messages for AIS (decode and encode):
149 - Type 01: Position Report Class A
150 - Type 02: Position Report Class A (Assigned Schedule)
151 - Type 03: Position Report Class A (Response to Interrogation)
152 - Type 04: Base Station Report
153 - Type 05: Static and Voyage Related Data
154 - Type 06: Binary Addressed Message
155 - Type 07: Binary Acknowledge
156 - Type 08: Binary Broadcast Message
157 - Type 09: Standard SAR Aircraft Position Report
158 - Type 10: UTC/Date Inquiry
159 - Type 11: UTC/Date Response
160 - Type 12: Addressed Safety-Related Message
161 - Type 13: Safety-Related Acknowledgement
162 - Type 14: Safety-Related Broadcast Message
163 - Type 17: DGNSS Broadcast Binary Message
164 - Type 18: Standard Class B CS Position Report
165 - Type 19: Extended Class B CS Position Report
166 - Type 20: Data Link Management
167 - Type 21: Aid-to-Navigation Report
168 - Type 22: Channel Management
169 - Type 23: Group Assignment Command
170 - Type 24: Static Data Report (part A and B, norma and auxiliary vessel)
172 Supported payload of binary message 08:
173 - 001/11: Meteorological and Hydrological Data (IMO236)
174 - 200/10: Inland ship static and voyage related data (Inland AIS)
176 ### SeaTalk
178 Suported messages for SeaTalk (decode and encode):
180 - Type 00: depth below transducer
181 - Type 01: equipment id
182 - Type 05: Engine RPM and PITCH
183 - Type 10: apparent wind angle
184 - Type 11: apparent wind speed
185 - Type 20: speed through water
186 - Type 21: trip mileage
187 - Type 22: total mileage
188 - Type 23: water temperature 1
189 - Type 24: Display unit for Mileage and Speed
190 - Type 25: total and trip log
191 - Type 26: Speed through Water
192 - Type 27: water temperature 2
193 - Type 30: Set Lamp Intensity
194 - Type 36: Cancel MOB condition
195 - Type 38: Codelock data (**experimental**)
196 - Type 50: LAT Postion
197 - Type 51: LON Postion
198 - Type 52: Speed over Ground
199 - Type 53: Magnetic Course in Degrees
200 - Type 54: GMT Time
201 - Type 56: Date
202 - Type 58: LAT/LON
203 - Type 59: Set Count Down Timer (sent by ST60)
204 - Type 65: Select Fathom display unit for depth display (see message 00)
205 - Type 66: Wind Alarm
206 - Type 6C: Second equipment-ID
207 - Type 86: Keystroke
208 - Type 87: Response Level
209 - Type 89: Compass heading (sent by ST40 compass instrument)
212 ### IO
214 - Reading data from serial ports (NMEA, SeaTalk)
217 ### Geodesic Functions
219 Basic geodesic functions, suitable for martime navigation.
221 - Calculation of CPA (closest point of approach)
222   and TCPA (time to closest point of approach)
223 - Distance of two points on a sphere
224 - Distance of two points on an ellipsoid using formula of Vincenty
225 - Distance of two points on an ellipsoid using formula of Lambert
230 Examples
231 --------
233 More examples [here](examples/README.md).
235 ### Parse NMEA Sentence
237 ~~~~~~~~~~~~~{.cpp}
238 using namespace marnav;
240 auto sentence = nmea::make_sentence(
241         "$GPRMC,201034,A,4702.4040,N,00818.3281,E,0.0,328.4,260807,0.6,E,A*17");
242 std::cout << sentence->tag() << "\n";
243 auto rmc = nmea::sentence_cast<nmea::rmc>(sentence);
244 std::cout << "latitude : " << nmea::to_string(rmc->get_latitude()) << "\n";
245 std::cout << "longitude: " << nmea::to_string(rmc->get_longitude()) << "\n";
246 ~~~~~~~~~~~~~
248 Create a specific sentence directly:
250 ~~~~~~~~~~~~~{.cpp}
251 using namespace marnav;
253 auto rmc = nmea::create_sentence<nmea::rmc>(
254         "$GPRMC,201034,A,4702.4040,N,00818.3281,E,0.0,328.4,260807,0.6,E,A*17");
255 std::cout << "latitude : " << nmea::to_string(rmc.get_latitude()) << "\n";
256 std::cout << "longitude: " << nmea::to_string(rmc.get_longitude()) << "\n";
257 ~~~~~~~~~~~~~
259 ### Write NMEA Sentence
261 ~~~~~~~~~~~~~{.cpp}
262 nmea::mtw mtw;
263 mtw.set_temperature(units::celsius{22.5});
264 std::string data = nmea::to_string(mtw);
265 ~~~~~~~~~~~~~
267 ### Parse AIS Message from NMEA data
269 ~~~~~~~~~~~~~{.cpp}
270 using namespace marnav;
272 // received sentences
273 const std::vector<std::string> received_strings
274         = {"!AIVDM,2,1,3,B,55P5TL01VIaAL@7WKO@mBplU@<PDhh000000001S;AJ::4A80?4i@E53,0*3E",
275                 "!AIVDM,2,2,3,B,1@0000000000000,2*55"};
277 // parse NMEA sentences
278 std::vector<std::unique_ptr<nmea::sentence>> sentences;
279 for (auto const & txt : received_strings) {
280         auto sentence = nmea::make_sentence(txt);
281         if (sentence->id() == nmea::sentence_id::VDM) {
282                 sentences.push_back(std::move(sentence));
283         }
286 // parse and and process AIS messags
287 auto payload = nmea::collect_payload(sentences.begin(), sentences.end());
288 auto message = ais::make_message(payload);
289 if (message->type() == ais::message_id::static_and_voyage_related_data) {
290         auto report = ais::message_cast<ais::message_05>(message);
291         std::cout << "shipname: " << report->get_shipname() << "\n";
292         std::cout << "callsign: " << report->get_callsign() << "\n";
294 ~~~~~~~~~~~~~
296 ### Create NMEA sentences from AIS data
298 ~~~~~~~~~~~~~{.cpp}
299 using namespace marnav;
301 // prepare AIS data
302 ais::message_01 pos_report;
303 pos_report.set_sog(units::knots{8.2});
304 // ... most data not shown here
306 // create payload
307 auto payload = ais::encode_message(pos_report);
309 // create NMEA sentences
310 for (uint32_t fragment = 0; fragment < payload.size(); ++fragment) {
311         nmea::vdm vdm;
312         vdm.set_n_fragments(payload.size());
313         vdm.set_fragment(fragment + 1);
314         vdm.set_radio_channel(nmea::ais_channel::B);
315         vdm.set_payload(payload[fragment]);
317         // collect, send or do something with the sentence...
318         std::string s = nmea::to_string(vdm);
319         std::cout << s << "\n";
321 ~~~~~~~~~~~~~
323 or simply use `nmea::make_vdms`:
325 ~~~~~~~~~~~~~{.cpp}
326 using namespace marnav;
328 // prepare AIS data
329 ais::message_01 pos_report;
330 pos_report.set_sog(units::knots{8.2});
331 // ... most data not shown here
333 // create payload
334 auto payload = ais::encode_message(pos_report);
336 // create NMEA sentences
337 auto sentences = nmea::make_vdms(payload);
339 // process sentences, somehow...
340 for (auto const & sentence : sentences) {
341         std::cout << nmea::to_string(*sentence) << "\n";
343 ~~~~~~~~~~~~~
347 Requirements
348 ------------
350 This chapter describes the requirements in order to build the library.
351 Tools and their versions are listed below, newer/older/other tools
352 (i.e. compilers, etc.) may work, but not tested.
354 Compiler:
355 - GCC 4.9
356 - GCC 5
357 - GCC 6
358 - GCC 7
359 - GCC 8
360 - GCC 9
361 - GCC 10
362 - GCC 11
363 - Clang 4
364 - Clang 5
365 - Clang 6
366 - Clang 7
367 - Clang 8
368 - Clang 9
369 - Clang 10
370 - Clang 11
371 - Clang 12
373 Tools needed to build the library:
374 - cmake 3.11 or newer
376 Tools needed to develop the library:
377 - git
378 - clang-format 10
380 Tools needed to build the documentation:
381 - doxygen
382 - graphviz
383 - LaTeX (there are formulas!)
385 Optional used for development:
386 - lcov / genhtml, c++filt
387 - cppcheck
388 - clang-tools (analyzer)
389 - ctags, cscope
390 - perf
392 Optional (no core dependency):
393 - Boost.ASIO (used only for some examples)
394 - Qt 5 (used only for some examples)
396 Opeating system:
397 - Linux
399 There are no other dependencies despite the standard library (C++11)
400 to build this library.
404 Build
405 -----
407 The following build types `-DCMAKE_BUILD_TYPE=x` are possible:
408 - Debug
409 - Release
410 - Coverage
412 Build options:
413 - `ENABLE_STATIC` : enables static build, if `OFF`, a shared library is being built.
414   Default: `ON`
415 - `ENABLE_PROFILING` : enables profiling for `gprof`
416 - `ENABLE_BENCHMARK` : enables benchmarking (disables some optimization)
417 - `ENABLE_SANITIZER` : enables address and undefined sanitizers
419 Features:
420 - `ENABLE_IO` : enables IO support. Default: `ON`
422 Components:
423 - `ENABLE_EXAMPLES`: enables examples. Default: `ON`
424 - `ENABLE_TESTS`: enables unit tests, integration tests and benchmarks. Default: `ON`
425 - `ENABLE_TOOLS`: enables tools. Default: `ON`
428 ### Library
430         mkdir build
431         cd build
432         cmake -DCMAKE_BUILD_TYPE=Release ..
433         make
436 ### Documentation
438         mkdir build
439         cd build
440         cmake ..
441         make doc
444 ### Package
446         make package
448 or individual package types:
450         cpack -G TGZ
451         cpack -G DEB
454 ### Developpers Choice
456         mkdir build
457         cd build
458         cmake -DCMAKE_BUILD_TYPE=Coverage ..
459         make -j 8
460         make coverage doc cppcheck
463 ### Static Analysis with Clang
465 There is a script ```bin/static-analysis-clang``` for doing this, there is not yet
466 an integration of clang-tidy in the cmake build.
469 ### Perform Benchmarks
471 Build in `Release` mode, perform individual benchmarks:
473         mkdir build
474         cd build
475         cmake -DCMAKE_BUILD_TYPE=Release ..
476         make -j 8
477         test/benchmark_nmea_split
479 Using `perf` to do performance analysis:
481         mkdir build
482         cd build
483         cmake -DCMAKE_BUILD_TYPE=Release -DENABLE_BENCHMARK=ON ..
484         make -j 8
485         perf record -g test/benchmark_nmea_split
486         perf report -g 'graph,0.5,caller'
489 ### Formatting Test
491 There is a helper script ```bin/check-format``` which uses ```clang-format``` to
492 check the formatting of all files in the directories containing code (```src```,
493 ```test``` and ```examples```). This script can be used manually:
495         bin/check-format
497 or used as git pre-commit hook:
499         cd .git/hooks
500         ln -s ../../bin/check-format pre-commit
502 which prevents a commit if there are files not complying with the formatting
503 rules. Be aware of using the script as pre-commit hook, the checking can take
504 several seconds.
509 Authors
510 -------
512 Mario Konrad (mario.konrad@gmx.net) with help from others.
514 Search the repository for a complete list:
516         git log --format=%an | sort -u
520 Links
521 -----
523 A (non-complete) collection of resources from where information was gathered.
525 - [NMEA Revealed](http://www.catb.org/gpsd/NMEA.html) (by Eric S. Raymond)
526 - [NMEA FAQ](http://www.kh-gps.de/nmea.faq)
527 - [it-digin's blog](http://www.it-digin.com/blog/?cat=4)
528 - [AIVDM/AIVDO Protocol decoding](http://www.catb.org/gpsd/AIVDM.html) (by Eric S. Raymond)
529 - [DSC Position Request](http://www.thehulltruth.com/marine-electronics-forum/43945-dsc-position-request.html)
530 - [NMEA-0183 Sentences DSC,DSE](http://www.cruisersforum.com/forums/f13/nmea-0183-sentences-dsc-dse-124887.html)
531 - [SerialMon - NMEA 0183 Protocol](http://www.serialmon.com/protocols/nmea0183.html)
532 - [SeaTalk Reference](http://thomasknauf.de/seatalk.htm) (by Thomas Knauf)
533 - [Navigation Center - AIS Standard Class B Equipment Position Report](http://www.navcen.uscg.gov/?pageName=AISMessagesB)
534 - [GPS Forums](http://www.gps-forums.net)
535 - [NMEA Datensaetze](http://www.nmea.de/nmea0183datensaetze.html)
536 - [AIS VDM & VDO Message Decoder](http://www.maritec.co.za/tools/aisvdmvdodecoding/)
537 - [AIS VDM & VDO Message Decoder](http://www.maritec.co.za/tools/aisvdmvdodecoding/)
538 - [Code comments from library NMEA0183](https://github.com/SammyB428/NMEA0183)
542 LICENSE
543 -------
545 > NOTE:
546 > The official NMEA 0183 Standard document is not available for free. It was not
547 > consulted at any point during the development of this library. All information
548 > was found from free sources on the internet. This library (especially the NMEA
549 > part) is not derivative work of this standard.
552 See also [LICENSE](LICENSE)
554 (BSD)
557 Copyright (c) 2021, Mario Konrad
558 All rights reserved.
560 Redistribution and use in source and binary forms, with or without
561 modification, are permitted provided that the following conditions are met:
562 1. Redistributions of source code must retain the above copyright
563    notice, this list of conditions and the following disclaimer.
564 2. Redistributions in binary form must reproduce the above copyright
565    notice, this list of conditions and the following disclaimer in the
566    documentation and/or other materials provided with the distribution.
567 3. All advertising materials mentioning features or use of this software
568    must display the following acknowledgement:
569    This product includes software developed by Mario Konrad.
570 4. Neither the name of the software nor the names of its contributors
571    may be used to endorse or promote products derived from this software
572    without specific prior written permission.
574 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
575 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
576 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
577 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
578 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
579 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
580 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
581 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
582 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
583 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.