NMEA: serialization of sentences changed, gains performance by about 7 percent on...
[marnav.git] / README.md
blob3065b5553c6c3fc42a59786f816c182e2346cf19
1 marnav
2 ======
4 Copyright (c) 2017 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++ (C++11 right now, C++14 as soon as compilers
30   catch up, but not necessarily bleeding edge)
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):
47 - AAM: Waypoint Arrival Alarm
48 - ALM: GPS Almanac Data
49 - APA: Autopilot Sentence "A"
50 - APB: Autopilot Sentence "B"
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 - GTD: Geographic Location in Time Differences
71 - HDG: Heading - Deviation & Variation
72 - HDT: Heading - True
73 - HFB: Trawl Headrope to Footrope and Bottom
74 - HSC: Heading Steering Command
75 - ITS: Trawl Door Spread 2 Distance
76 - LCD: Loran-C Signal Data
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 - VTG: Track made good and Ground speed
107 - VWR: Relative Wind Speed and Angle.
108 - VPW: Speed - Measured Parallel to Wind
109 - WCV: Waypoint Closure Velocity
110 - WNC: Distance - Waypoint to Waypoint
111 - WPL: Waypoint Location
112 - XDR: Transducer Measurement
113 - XTE: Cross-Track Error, Measured
114 - XTR: Cross Track Error - Dead Reckoning
115 - ZDA: Time & Date - UTC, day, month, year and local time zone
116 - ZDL: Time and Distance to Variable Point
117 - ZFO: UTC & Time from origin Waypoint
118 - ZTG: UTC & Time to Destination Waypoint
120 Obsolete (according to the standard) but implemented:
121 - DBK: Depth Below Keel
122 - HDM: Heading - Magnetic (obsolete as of 2009)
123 - R00: Waypoints in active route
125 Vendor Extensions:
126 - PGRME: Garmin Estimated Error
127 - PGRMM: Garmin Map Datum
128 - PGRMZ: Garmin Altitude Information
130 Miscellaneous:
131 - Tag Block Support (generic for all sentences)
134 ### AIS
136 Supported messages for AIS (decode and encode):
137 - Type 01: Position Report Class A
138 - Type 02: Position Report Class A (Assigned Schedule)
139 - Type 03: Position Report Class A (Response to Interrogation)
140 - Type 04: Base Station Report
141 - Type 05: Static and Voyage Related Data
142 - Type 06: Binary Addressed Message
143 - Type 07: Binary Acknowledge
144 - Type 08: Binary Broadcast Message
145 - Type 09: Standard SAR Aircraft Position Report
146 - Type 10: UTC/Date Inquiry
147 - Type 11: UTC/Date Response
148 - Type 12: Addressed Safety-Related Message
149 - Type 13: Safety-Related Acknowledgement
150 - Type 14: Safety-Related Broadcast Message
151 - Type 17: DGNSS Broadcast Binary Message
152 - Type 18: Standard Class B CS Position Report
153 - Type 19: Extended Class B CS Position Report
154 - Type 20: Data Link Management
155 - Type 21: Aid-to-Navigation Report
156 - Type 22: Channel Management
157 - Type 23: Group Assignment Command
158 - Type 24: Static Data Report (part A and B, norma and auxiliary vessel)
160 Supported payload of binary message 08:
161 - 001/11: Meteorological and Hydrological Data (IMO236)
162 - 200/10: Inland ship static and voyage related data (Inland AIS)
164 ### SeaTalk
166 Suported messages for SeaTalk (decode and encode):
167 - Type 00: depth below transducer
168 - Type 01: equipment id
169 - Type 05: Engine RPM and PITCH
170 - Type 10: apparent wind angle
171 - Type 11: apparent wind speed
172 - Type 20: speed through water
173 - Type 21: trip mileage
174 - Type 22: total mileage
175 - Type 23: water temperature 1
176 - Type 24: Display unit for Mileage and Speed
177 - Type 25: total and trip log
178 - Type 26: Speed through Water
179 - Type 27: water temperature 2
180 - Type 30: Set Lamp Intensity
181 - Type 36: Cancel MOB condition
182 - Type 38: Codelock data (**experimental**)
183 - Type 50: LAT Postion
184 - Type 51: LON Postion
185 - Type 52: Speed over Ground
186 - Type 53: Magnetic Course in Degrees
187 - Type 54: GMT Time
188 - Type 56: Date
189 - Type 58: LAT/LON
190 - Type 59: Set Count Down Timer (sent by ST60)
191 - Type 65: Select Fathom display unit for depth display (see message 00)
192 - Type 66: Wind Alarm
193 - Type 6C: Second equipment-ID
194 - Type 86: Keystroke
195 - Type 87: Response Level
196 - Type 89: Compass heading (sent by ST40 compass instrument)
199 ### IO
201 - Reading data from serial ports (NMEA, SeaTalk)
204 ### Geodesic Functions
206 Basic geodesic functions, suitable for martime navigation.
208 - Calculation of CPA (closest point of approach)
209   and TCPA (time to closest point of approach)
210 - Distance of two points on a sphere
211 - Distance of two points on an ellipsoid using formula of Vincenty
212 - Distance of two points on an ellipsoid using formula of Lambert
217 Examples
218 --------
220 More examples [here](doc/examples.md).
222 ### Parse NMEA Sentence
224 ~~~~~~~~~~~~~{.cpp}
225 using namespace marnav;
227 auto sentence = nmea::make_sentence(
228         "$GPRMC,201034,A,4702.4040,N,00818.3281,E,0.0,328.4,260807,0.6,E,A*17");
229 std::cout << sentence->tag() << "\n";
230 auto rmc = nmea::sentence_cast<nmea::rmc>(sentence);
231 std::cout << "latitude : " << nmea::to_string(rmc->get_latitude()) << "\n";
232 std::cout << "longitude: " << nmea::to_string(rmc->get_longitude()) << "\n";
233 ~~~~~~~~~~~~~
235 Create a specific sentence directly:
237 ~~~~~~~~~~~~~{.cpp}
238 using namespace marnav;
240 auto rmc = nmea::create_sentence<nmea::rmc>(
241         "$GPRMC,201034,A,4702.4040,N,00818.3281,E,0.0,328.4,260807,0.6,E,A*17");
242 std::cout << "latitude : " << nmea::to_string(rmc.get_latitude()) << "\n";
243 std::cout << "longitude: " << nmea::to_string(rmc.get_longitude()) << "\n";
244 ~~~~~~~~~~~~~
246 ### Write NMEA Sentence
248 ~~~~~~~~~~~~~{.cpp}
249 nmea::mtw mtw;
250 mtw.set_temperature(22.5);
251 std::string data = nmea::to_string(mtw);
252 ~~~~~~~~~~~~~
254 ### Parse AIS Message from NMEA data
256 ~~~~~~~~~~~~~{.cpp}
257 using namespace marnav;
259 // received sentences
260 const std::vector<std::string> received_strings
261         = {"!AIVDM,2,1,3,B,55P5TL01VIaAL@7WKO@mBplU@<PDhh000000001S;AJ::4A80?4i@E53,0*3E",
262                 "!AIVDM,2,2,3,B,1@0000000000000,2*55"};
264 // parse NMEA sentences
265 std::vector<std::unique_ptr<nmea::sentence>> sentences;
266 for (auto const & txt : received_strings) {
267         auto sentence = nmea::make_sentence(txt);
268         if (sentence->id() == nmea::sentence_id::VDM) {
269                 sentences.push_back(std::move(sentence));
270         }
273 // parse and and process AIS messags
274 auto payload = nmea::collect_payload(sentences.begin(), sentences.end());
275 auto message = ais::make_message(payload);
276 if (message->type() == ais::message_id::static_and_voyage_related_data) {
277         auto report = ais::message_cast<ais::message_05>(message);
278         std::cout << "shipname: " << report->get_shipname() << "\n";
279         std::cout << "callsign: " << report->get_callsign() << "\n";
281 ~~~~~~~~~~~~~
283 ### Create NMEA sentences from AIS data
285 ~~~~~~~~~~~~~{.cpp}
286 using namespace marnav;
288 // prepare AIS data
289 ais::message_01 pos_report;
290 pos_report.set_sog(82);
291 // ... most data not shown here
293 // create payload
294 auto payload = ais::encode_message(pos_report);
296 // create NMEA sentences
297 for (uint32_t fragment = 0; fragment < payload.size(); ++fragment) {
298         nmea::vdm vdm;
299         vdm.set_n_fragments(payload.size());
300         vdm.set_fragment(fragment + 1);
301         vdm.set_radio_channel(nmea::ais_channel::B);
302         vdm.set_payload(payload[fragment]);
304         // collect, send or do something with the sentence...
305         std::string s = nmea::to_string(vdm);
306         std::cout << s << "\n";
308 ~~~~~~~~~~~~~
310 or simply use `nmea::make_vdms`:
312 ~~~~~~~~~~~~~{.cpp}
313 using namespace marnav;
315 // prepare AIS data
316 ais::message_01 pos_report;
317 pos_report.set_sog(82);
318 // ... most data not shown here
320 // create payload
321 auto payload = ais::encode_message(pos_report);
323 // create NMEA sentences
324 auto sentences = nmea::make_vdms(payload);
326 // process sentences, somehow...
327 for (auto const & sentence : sentences) {
328         std::cout << nmea::to_string(*sentence) << "\n";
330 ~~~~~~~~~~~~~
334 Requirements
335 ------------
337 This chapter describes the requirements in order to build the library.
338 Tools and their versions are listed below, newer/older/other tools
339 (i.e. compilers, etc.) may work, but not tested.
341 Compiler:
342 - GCC 4.9
343 - GCC 5
344 - GCC 6
345 - Clang 3.6
346 - Clang 3.7
347 - Clang 3.8
348 - Clang 3.9
349 - Clang 4.0
351 Tools needed to build the library:
352 - cmake 3.2 or newer
354 Tools needed to develop the library:
355 - git
356 - clang-format 3.9
358 Tools needed to build the documentation:
359 - doxygen
360 - graphviz
361 - LaTeX (there are formulas!)
363 Optional used for development:
364 - lcov / genhtml, c++filt
365 - cppcheck
366 - clang-analyze 3.9
367 - ctags, cscope
368 - perf
370 Optional (no core dependency):
371 - Boost.ASIO (used only for some examples)
372 - Qt 5 (used only for some examples)
374 Opeating system:
375 - Linux
377 There are no other dependencies despite the standard library (C++11)
378 to build this library.
382 Build
383 -----
385 The following build types `-DCMAKE_BUILD_TYPE=x` are possible:
386 - Debug
387 - Release
388 - Coverage
390 Build options:
391 - `ENABLE_STATIC` : enables static build, if `OFF`, a shared library is being built.
392   Default: `ON`
393 - `ENABLE_WARNING_HELL` : enables _much_ more warnings, used for development purposes.
394   Currently implemented only for GCC.  Default is `OFF`
395 - `ENABLE_PROFILING` : enables profiling for `gprof`
396 - `ENABLE_BENCHMARK` : enables benchmarking (disables some optimization)
397 - `ENABLE_SANITIZER` : enables address and undefined sanitizers
399 Features:
400 - `ENABLE_AIS ` : enables AIS support. Default: `ON`
401 - `ENABLE_SEATALK` : enables SeaTalk support. Default: `ON`
402 - `ENABLE_IO` : enables IO support. Default: `ON`
404 Components:
405 - `ENABLE_EXAMPLES`: enables examples. Default: `ON`
406 - `ENABLE_TESTS`: enables unit tests, integration tests and benchmarks. Default: `ON`
407 - `ENABLE_TOOLS`: enables tools. Default: `ON`
410 ### Library
412         mkdir build
413         cd build
414         cmake -DCMAKE_BUILD_TYPE=Release ..
415         make
418 ### Documentation
420         mkdir build
421         cd build
422         cmake ..
423         make doc
426 ### Package
428         make package
430 or individual package types:
432         cpack -G TGZ
433         cpack -G DEB
436 ### Developpers Choice
438         mkdir build
439         cd build
440         cmake -DCMAKE_BUILD_TYPE=Coverage -DENABLE_WARNING_HELL=YES ..
441         make -j 8
442         make coverage doc cppcheck
445 ### Static Analysis with Clang
447 There is a script ```bin/static-analysis-clang``` for doing this, or do it manually:
449         mkdir build
450         cd build
451         cmake -DCMAKE_CXX_COMPILER=/usr/share/clang/scan-build-3.9/libexec/c++-analyzer ..
452         scan-build-3.9 -o doc/analysis --use-analyzer=/usr/bin/clang++-3.9 make
454 After the build, ```scan-build``` will tell you what to do in order to inspect
455 the findings.
458 ### Perform Benchmarks
460 Build in `Release` mode, perform individual benchmarks:
462         mkdir build
463         cd build
464         cmake -DCMAKE_BUILD_TYPE=Release ..
465         make -j 8
466         test/benchmark_nmea_split
468 Using `perf` to do performance analysis:
470         mkdir build
471         cd build
472         cmake -DCMAKE_BUILD_TYPE=Release -DENABLE_BENCHMARK=ON ..
473         make -j 8
474         perf record -g test/benchmark_nmea_split
475         perf report -g 'graph,0.5,caller'
478 ### Formatting Test
480 There is a helper script ```bin/check-format``` which uses ```clang-format``` to
481 check the formatting of all files in the directories containing code (```src```,
482 ```test``` and ```examples```). This script can be used manually:
484         bin/check-format
486 or used as git pre-commit hook:
488         cd .git/hooks
489         ln -s ../../bin/check-format pre-commit
491 which prevents a commit if there are files not complying with the formatting
492 rules. Be aware of using the script as pre-commit hook, the checking can take
493 several seconds.
498 Authors
499 -------
501 Mario Konrad (mario.konrad@gmx.net) with help from others.
503 Search the repository for a complete list:
505         git log --format=%an | sort -u
509 Links
510 -----
512 A (non-complete) collection of resources from where information was gathered.
514 - [NMEA Revealed](http://www.catb.org/gpsd/NMEA.html) (by Eric S. Raymond)
515 - [NMEA FAQ](http://www.kh-gps.de/nmea.faq)
516 - [it-digin's blog](http://www.it-digin.com/blog/?cat=4)
517 - [AIVDM/AIVDO Protocol decoding](http://www.catb.org/gpsd/AIVDM.html) (by Eric S. Raymond)
518 - [DSC Position Request](http://www.thehulltruth.com/marine-electronics-forum/43945-dsc-position-request.html)
519 - [NMEA-0183 Sentences DSC,DSE](http://www.cruisersforum.com/forums/f13/nmea-0183-sentences-dsc-dse-124887.html)
520 - [SerialMon - NMEA 0183 Protocol](http://www.serialmon.com/protocols/nmea0183.html)
521 - [SeaTalk Reference](http://thomasknauf.de/seatalk.htm) (by Thomas Knauf)
522 - [Navigation Center - AIS Standard Class B Equipment Position Report](http://www.navcen.uscg.gov/?pageName=AISMessagesB)
523 - [GPS Forums](http://www.gps-forums.net)
524 - [NMEA Datensaetze](http://www.nmea.de/nmea0183datensaetze.html)
525 - [AIS VDM & VDO Message Decoder](http://www.maritec.co.za/tools/aisvdmvdodecoding/)
529 LICENSE
530 -------
532 > NOTE:
533 > The official NMEA 0183 Standard document is not available for free. It was not
534 > consulted at any point during the development of this library. All information
535 > was found from free sources on the internet. This library (especially the NMEA
536 > part) is not derivative work of this standard.
539 See also [LICENSE](LICENSE)
541 (BSD)
544 Copyright (c) 2016, Mario Konrad
545 All rights reserved.
547 Redistribution and use in source and binary forms, with or without
548 modification, are permitted provided that the following conditions are met:
549 1. Redistributions of source code must retain the above copyright
550    notice, this list of conditions and the following disclaimer.
551 2. Redistributions in binary form must reproduce the above copyright
552    notice, this list of conditions and the following disclaimer in the
553    documentation and/or other materials provided with the distribution.
554 3. All advertising materials mentioning features or use of this software
555    must display the following acknowledgement:
556    This product includes software developed by Mario Konrad.
557 4. Neither the name of the software nor the names of its contributors
558    may be used to endorse or promote products derived from this software
559    without specific prior written permission.
561 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
562 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
563 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
564 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
565 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
566 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
567 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
568 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
569 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
570 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.