1 // This is a diagnostics tool and also serves as demonstration
2 // on how to use the library.
4 // This tool is able to read data fromm stdin, file or a serial
7 // Usage, read from file:
9 // nmeadump -f logged-data.txt
11 // Usage, read from NMEA-0183 port:
13 // nmeadump -p /dev/ttyUSB0 -s 4800
15 // Usage, read from NMEA-0183-HS port:
17 // nmeadump -p /dev/ttyUSB0 -s 38400
19 // Usage, read from stdin:
21 // cat logged-data.txt | nmeadump
24 #include <marnav/nmea/ais_helper.hpp>
25 #include <marnav/nmea/checksum.hpp>
26 #include <marnav/nmea/name.hpp>
27 #include <marnav/nmea/nmea.hpp>
28 #include <marnav/nmea/route.hpp>
29 #include <marnav/nmea/sentence.hpp>
30 #include <marnav/nmea/string.hpp>
31 #include <marnav/nmea/waypoint.hpp>
33 #include <marnav/nmea/aam.hpp>
34 #include <marnav/nmea/alm.hpp>
35 #include <marnav/nmea/alr.hpp>
36 #include <marnav/nmea/apa.hpp>
37 #include <marnav/nmea/apb.hpp>
38 #include <marnav/nmea/bec.hpp>
39 #include <marnav/nmea/bod.hpp>
40 #include <marnav/nmea/bwc.hpp>
41 #include <marnav/nmea/bwr.hpp>
42 #include <marnav/nmea/bww.hpp>
43 #include <marnav/nmea/dbk.hpp>
44 #include <marnav/nmea/dbt.hpp>
45 #include <marnav/nmea/dpt.hpp>
46 #include <marnav/nmea/dsc.hpp>
47 #include <marnav/nmea/dse.hpp>
48 #include <marnav/nmea/dtm.hpp>
49 #include <marnav/nmea/fsi.hpp>
50 #include <marnav/nmea/gbs.hpp>
51 #include <marnav/nmea/gga.hpp>
52 #include <marnav/nmea/glc.hpp>
53 #include <marnav/nmea/gll.hpp>
54 #include <marnav/nmea/gns.hpp>
55 #include <marnav/nmea/grs.hpp>
56 #include <marnav/nmea/gsa.hpp>
57 #include <marnav/nmea/gst.hpp>
58 #include <marnav/nmea/gsv.hpp>
59 #include <marnav/nmea/gtd.hpp>
60 #include <marnav/nmea/hdg.hpp>
61 #include <marnav/nmea/hfb.hpp>
62 #include <marnav/nmea/hdm.hpp>
63 #include <marnav/nmea/hdt.hpp>
64 #include <marnav/nmea/hsc.hpp>
65 #include <marnav/nmea/its.hpp>
66 #include <marnav/nmea/lcd.hpp>
67 #include <marnav/nmea/mob.hpp>
68 #include <marnav/nmea/msk.hpp>
69 #include <marnav/nmea/mss.hpp>
70 #include <marnav/nmea/mta.hpp>
71 #include <marnav/nmea/mtw.hpp>
72 #include <marnav/nmea/mwd.hpp>
73 #include <marnav/nmea/mwv.hpp>
74 #include <marnav/nmea/osd.hpp>
75 #include <marnav/nmea/r00.hpp>
76 #include <marnav/nmea/rma.hpp>
77 #include <marnav/nmea/rmb.hpp>
78 #include <marnav/nmea/rmc.hpp>
79 #include <marnav/nmea/rot.hpp>
80 #include <marnav/nmea/rpm.hpp>
81 #include <marnav/nmea/rsa.hpp>
82 #include <marnav/nmea/rsd.hpp>
83 #include <marnav/nmea/rte.hpp>
84 #include <marnav/nmea/sfi.hpp>
85 #include <marnav/nmea/stn.hpp>
86 #include <marnav/nmea/tds.hpp>
87 #include <marnav/nmea/tfi.hpp>
88 #include <marnav/nmea/tll.hpp>
89 #include <marnav/nmea/tpc.hpp>
90 #include <marnav/nmea/tpr.hpp>
91 #include <marnav/nmea/tpt.hpp>
92 #include <marnav/nmea/ttm.hpp>
93 #include <marnav/nmea/vbw.hpp>
94 #include <marnav/nmea/vdm.hpp>
95 #include <marnav/nmea/vdo.hpp>
96 #include <marnav/nmea/vdr.hpp>
97 #include <marnav/nmea/vhw.hpp>
98 #include <marnav/nmea/vlw.hpp>
99 #include <marnav/nmea/vpw.hpp>
100 #include <marnav/nmea/vtg.hpp>
101 #include <marnav/nmea/vwe.hpp>
102 #include <marnav/nmea/vwr.hpp>
103 #include <marnav/nmea/wcv.hpp>
104 #include <marnav/nmea/wdc.hpp>
105 #include <marnav/nmea/wdr.hpp>
106 #include <marnav/nmea/wnc.hpp>
107 #include <marnav/nmea/wpl.hpp>
108 #include <marnav/nmea/xdr.hpp>
109 #include <marnav/nmea/xte.hpp>
110 #include <marnav/nmea/xtr.hpp>
111 #include <marnav/nmea/zda.hpp>
112 #include <marnav/nmea/zdl.hpp>
113 #include <marnav/nmea/zfi.hpp>
114 #include <marnav/nmea/zfo.hpp>
115 #include <marnav/nmea/zlz.hpp>
116 #include <marnav/nmea/zpi.hpp>
117 #include <marnav/nmea/zta.hpp>
118 #include <marnav/nmea/zte.hpp>
119 #include <marnav/nmea/ztg.hpp>
120 #include <marnav/nmea/pgrme.hpp>
121 #include <marnav/nmea/pgrmm.hpp>
122 #include <marnav/nmea/pgrmz.hpp>
123 #include <marnav/nmea/stalk.hpp>
125 #include <marnav/ais/ais.hpp>
126 #include <marnav/ais/name.hpp>
128 #include <marnav/ais/message_01.hpp>
129 #include <marnav/ais/message_02.hpp>
130 #include <marnav/ais/message_03.hpp>
131 #include <marnav/ais/message_04.hpp>
132 #include <marnav/ais/message_05.hpp>
133 #include <marnav/ais/message_06.hpp>
134 #include <marnav/ais/message_07.hpp>
135 #include <marnav/ais/message_08.hpp>
136 #include <marnav/ais/message_09.hpp>
137 #include <marnav/ais/message_10.hpp>
138 #include <marnav/ais/message_11.hpp>
139 #include <marnav/ais/message_12.hpp>
140 #include <marnav/ais/message_13.hpp>
141 #include <marnav/ais/message_14.hpp>
142 #include <marnav/ais/message_17.hpp>
143 #include <marnav/ais/message_18.hpp>
144 #include <marnav/ais/message_19.hpp>
145 #include <marnav/ais/message_20.hpp>
146 #include <marnav/ais/message_21.hpp>
147 #include <marnav/ais/message_22.hpp>
148 #include <marnav/ais/message_23.hpp>
149 #include <marnav/ais/message_24.hpp>
150 #include <marnav/ais/binary_001_11.hpp>
151 #include <marnav/ais/binary_200_10.hpp>
153 #include <marnav/io/default_nmea_reader.hpp>
154 #include <marnav/io/serial.hpp>
156 #include <marnav/units/units.hpp>
158 #include <marnav/utils/unique.hpp>
159 #include <marnav/utils/mmsi_country.hpp>
161 #include <cxxopts.hpp>
163 #include <fmt/format.h>
164 #include <fmt/printf.h>
175 static constexpr const char * normal
= "\033[0m";
176 static constexpr const char * black
= "\033[30m";
177 static constexpr const char * red
= "\033[31m";
178 static constexpr const char * green
= "\033[32m";
179 static constexpr const char * yellow
= "\033[33m";
180 static constexpr const char * blue
= "\033[34m";
181 static constexpr const char * magenta
= "\033[35m";
182 static constexpr const char * cyan
= "\033[36m";
183 static constexpr const char * white
= "\033[37m";
188 template <class Container
>
189 static bool contains(
190 const Container
& container
, const typename
Container::value_type
& element
)
192 return std::find(std::begin(container
), std::end(container
), element
)
193 != std::end(container
);
200 marnav::io::serial::baud speed
;
202 std::string input_string
;
206 static std::string
trim(const std::string
& s
)
208 static const char * whitespace
= "\n\r\t ";
209 const auto begin
= s
.find_first_not_of(whitespace
);
210 const auto end
= s
.find_last_not_of(whitespace
);
211 return begin
!= std::string::npos
? s
.substr(begin
, end
- begin
+ 1) : "";
217 template <typename T
>
218 static std::string
render(const T
& t
)
220 return marnav::nmea::to_string(t
);
223 static std::string
render(const std::string
& t
)
228 static std::string
render(bool t
)
230 return t
? "true" : "false";
233 static std::string
render(char t
)
235 return fmt::sprintf("%c", t
);
238 static std::string
render(const uint32_t t
)
240 return fmt::sprintf("%u", t
);
243 static std::string
render(const int32_t t
)
245 return fmt::sprintf("%d", t
);
248 static std::string
render(const uint8_t t
)
250 return fmt::sprintf("%u", t
);
253 static std::string
render(const double t
)
255 return fmt::sprintf("%-8.3f", t
);
258 static std::string
render(const marnav::utils::mmsi
& t
)
260 const auto country
= mmsi_country(t
).name
;
261 if (!country
.empty())
263 "%09u (%s)", static_cast<marnav::utils::mmsi::value_type
>(t
), country
);
264 return fmt::sprintf("%09u", static_cast<marnav::utils::mmsi::value_type
>(t
));
267 static std::string
render(const marnav::nmea::time
& t
)
269 return fmt::sprintf("%02u:%02u:%02u", t
.hour(), t
.minutes(), t
.seconds());
272 static std::string
render(const marnav::geo::latitude
& t
)
274 using namespace marnav::nmea
;
276 " %02u\u00b0%02u'%04.1f%s", t
.degrees(), t
.minutes(), t
.seconds(), to_string(t
.hem()));
279 static std::string
render(const marnav::geo::longitude
& t
)
281 using namespace marnav::nmea
;
283 "%03u\u00b0%02u'%04.1f%s", t
.degrees(), t
.minutes(), t
.seconds(), to_string(t
.hem()));
286 static std::string
render(const marnav::geo::position
& p
)
288 using namespace marnav::nmea
;
289 return fmt::sprintf("%s %s", render(p
.lat()), render(p
.lon()));
292 static std::string
render(const marnav::ais::message_23::report_interval t
)
295 case marnav::ais::message_23::report_interval::autonomous_mode
:
296 return "Autonomous Mode";
297 case marnav::ais::message_23::report_interval::minutes_10
:
299 case marnav::ais::message_23::report_interval::minutes_06
:
301 case marnav::ais::message_23::report_interval::minutes_03
:
303 case marnav::ais::message_23::report_interval::minutes_01
:
305 case marnav::ais::message_23::report_interval::seconds_30
:
307 case marnav::ais::message_23::report_interval::seconds_15
:
309 case marnav::ais::message_23::report_interval::seconds_10
:
311 case marnav::ais::message_23::report_interval::seconds_05
:
313 case marnav::ais::message_23::report_interval::next_shorter
:
314 return "Next Shorter";
315 case marnav::ais::message_23::report_interval::next_longer
:
316 return "Next Longer";
321 static std::string
render(const marnav::ais::message_24::part t
)
324 case marnav::ais::message_24::part::A
:
326 case marnav::ais::message_24::part::B
:
332 static std::string
render(const marnav::ais::binary_001_11::trend t
)
335 case marnav::ais::binary_001_11::trend::steady
:
337 case marnav::ais::binary_001_11::trend::decreasing
:
338 return "decreasing ";
339 case marnav::ais::binary_001_11::trend::increasing
:
341 case marnav::ais::binary_001_11::trend::not_available
:
342 return "not available";
347 static std::string
render(const marnav::ais::binary_001_11::ice t
)
350 case marnav::ais::binary_001_11::ice::no
:
352 case marnav::ais::binary_001_11::ice::yes
:
354 case marnav::ais::binary_001_11::ice::not_available
:
355 return "not available";
360 static std::string
render(const marnav::ais::binary_001_11::precipitation t
)
363 case marnav::ais::binary_001_11::precipitation::rain
:
365 case marnav::ais::binary_001_11::precipitation::thunderstorm
:
366 return "thunderstorm";
367 case marnav::ais::binary_001_11::precipitation::freezing_rain
:
368 return "freezing_rain";
369 case marnav::ais::binary_001_11::precipitation::mixed_ice
:
371 case marnav::ais::binary_001_11::precipitation::snow
:
373 case marnav::ais::binary_001_11::precipitation::not_available
:
374 return "not available";
379 static std::string
render(const marnav::ais::binary_200_10::loaded_state t
)
382 case marnav::ais::binary_200_10::loaded_state::not_available
:
383 return "not available";
384 case marnav::ais::binary_200_10::loaded_state::unloaded
:
386 case marnav::ais::binary_200_10::loaded_state::loaded
:
392 static std::string
render(const marnav::ais::rate_of_turn t
)
395 return "not available";
396 if (t
.is_not_turning())
397 return "not turning";
398 if (t
.is_more_5deg30s_right())
399 return "more 5deg/30s right";
400 if (t
.is_more_5deg30s_left())
401 return "more 5deg/30s left";
402 return fmt::sprintf("%f", t
.value());
405 static std::string
render(const marnav::ais::ship_type t
)
407 return marnav::ais::to_name(t
);
410 static std::string
render(const marnav::ais::epfd_fix_type t
)
412 return marnav::ais::to_name(t
);
415 static std::string
render(const marnav::ais::off_position_indicator t
)
417 return marnav::ais::to_name(t
);
420 static std::string
render(const marnav::ais::virtual_aid t
)
422 return marnav::ais::to_name(t
);
425 static std::string
render(const marnav::ais::aid_type_id t
)
427 return marnav::ais::to_name(t
);
430 static std::string
render(const marnav::ais::message_id t
)
432 return marnav::ais::to_name(t
);
435 static std::string
render(const marnav::ais::maneuver_indicator_id t
)
437 return marnav::ais::to_name(t
);
440 static std::string
render(const marnav::ais::data_terminal t
)
442 return marnav::ais::to_name(t
);
445 static std::string
render(const marnav::ais::navigation_status t
)
447 return marnav::ais::to_name(t
);
450 static std::string
render(const marnav::nmea::mob::mob_status t
)
453 case marnav::nmea::mob::mob_status::mob_activated
:
454 return "mob activated";
455 case marnav::nmea::mob::mob_status::test_mode
:
457 case marnav::nmea::mob::mob_status::manual_button
:
458 return "manual button";
459 case marnav::nmea::mob::mob_status::mob_not_in_use
:
460 return "mob not in use";
461 case marnav::nmea::mob::mob_status::error
:
467 static std::string
render(const marnav::nmea::mob::mob_position_source t
)
470 case marnav::nmea::mob::mob_position_source::position_estimated
:
471 return "position estimated";
472 case marnav::nmea::mob::mob_position_source::position_reported
:
473 return "position reported";
474 case marnav::nmea::mob::mob_position_source::reserved
:
476 case marnav::nmea::mob::mob_position_source::error
:
482 static std::string
render(const marnav::nmea::mob::battery_status t
)
485 case marnav::nmea::mob::battery_status::good
:
487 case marnav::nmea::mob::battery_status::low
:
489 case marnav::nmea::mob::battery_status::reserved
:
491 case marnav::nmea::mob::battery_status::error
:
497 static std::string
render(const marnav::nmea::tfi::state t
)
500 case marnav::nmea::tfi::state::off
:
502 case marnav::nmea::tfi::state::on
:
504 case marnav::nmea::tfi::state::no_answer
:
510 static std::string
render(const marnav::nmea::sentence_id t
)
512 return marnav::nmea::to_name(t
);
515 static std::string
render(const marnav::nmea::talker t
)
517 return marnav::nmea::to_name(t
);
520 static std::string
render(const marnav::nmea::unit::distance t
)
522 return marnav::nmea::to_name(t
);
525 static std::string
render(const marnav::nmea::unit::temperature t
)
527 return marnav::nmea::to_name(t
);
530 static std::string
render(const marnav::nmea::unit::velocity t
)
532 return marnav::nmea::to_name(t
);
535 static std::string
render(const marnav::nmea::side t
)
537 return marnav::nmea::to_name(t
);
540 static std::string
render(const marnav::nmea::reference t
)
542 return marnav::nmea::to_name(t
);
545 static std::string
render(const marnav::nmea::quality t
)
547 return marnav::nmea::to_name(t
);
550 static std::string
render(const marnav::nmea::direction t
)
552 return marnav::nmea::to_string(t
);
555 static std::string
render(const marnav::nmea::selection_mode t
)
557 return marnav::nmea::to_name(t
);
560 static std::string
render(const marnav::nmea::status t
)
562 return marnav::nmea::to_name(t
);
565 static std::string
render(const marnav::nmea::route_mode t
)
567 return marnav::nmea::to_name(t
);
570 static std::string
render(const marnav::nmea::route
& t
)
575 static std::string
render(const marnav::nmea::waypoint
& t
)
580 static std::string
render(const marnav::nmea::mode_indicator t
)
582 return marnav::nmea::to_name(t
);
585 static std::string
render(const marnav::nmea::dsc::format_specifier t
)
587 return marnav::nmea::to_name(t
);
590 static std::string
render(const marnav::nmea::dsc::category t
)
592 return marnav::nmea::to_name(t
);
595 static std::string
render(const marnav::nmea::dsc::acknowledgement t
)
597 return marnav::nmea::to_name(t
);
600 static std::string
render(const marnav::nmea::dsc::extension_indicator t
)
602 return marnav::nmea::to_name(t
);
605 static std::string
render(const marnav::nmea::dse::query_flag t
)
607 return marnav::nmea::to_name(t
);
610 static std::string
render(const marnav::nmea::dse::code_id t
)
612 return marnav::nmea::to_name(t
);
615 static std::string
render(const marnav::nmea::alr::condition t
)
617 return marnav::nmea::to_name(t
);
620 static std::string
render(const marnav::nmea::alr::acknowledge t
)
622 return marnav::nmea::to_name(t
);
625 static std::string
render(const std::vector
<uint8_t> & t
)
628 s
.reserve(t
.size() * 3 - 1);
629 for (auto i
= begin(t
); i
!= end(t
); ++i
)
630 s
.append(fmt::sprintf(((i
== begin(t
)) ? "%02x" : " %02x"), *i
));
634 static std::string
render(const marnav::units::nautical_miles
& t
)
636 return fmt::sprintf("%s %s", render(t
.value()), render(marnav::nmea::unit::distance::nm
));
639 static std::string
render(const marnav::units::knots
& t
)
641 return fmt::sprintf("%s %s", render(t
.value()), render(marnav::nmea::unit::velocity::knot
));
644 static std::string
render(const marnav::units::meters
& t
)
647 "%s %s", render(t
.value()), render(marnav::nmea::unit::distance::meter
));
650 static std::string
render(const marnav::units::feet
& t
)
652 return fmt::sprintf("%s %s", render(t
.value()), render(marnav::nmea::unit::distance::feet
));
655 static std::string
render(const marnav::units::meters_per_second
& t
)
657 return fmt::sprintf("%s %s", render(t
.value()), render(marnav::nmea::unit::velocity::mps
));
660 static std::string
render(const marnav::units::celsius
& t
)
663 "%s %s", render(t
.value()), render(marnav::nmea::unit::temperature::celsius
));
666 static std::string
render(const marnav::units::length
& t
)
668 // all lengths are rendered in meters by default
669 return render(t
.get
<marnav::units::meters
>());
672 static std::string
render(const marnav::units::velocity
& t
)
674 // all velocities are rendered in knots by default
675 return render(t
.get
<marnav::units::knots
>());
678 static std::string
render(const marnav::units::temperature
& t
)
680 // all temperatures are rendered in celsius by default
681 return render(t
.get
<marnav::units::celsius
>());
684 static std::string
render(const marnav::geo::region
& t
)
686 return fmt::sprintf("%s/%s - %s/%s", render(t
.top()), render(t
.left()), render(t
.bottom()),
690 template <typename T
>
691 static std::string
render(const marnav::utils::optional
<T
> & t
)
698 static void print(const std::string
& name
, const std::string
& value
)
700 fmt::printf("\t%-30s : %s\n", name
, value
);
703 static void print(const std::string
& title
)
705 fmt::printf("\t%s\n", title
);
708 static void print_detail_hdg(const marnav::nmea::sentence
* s
)
710 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::hdg
>(s
);
711 print("Heading", render(t
->get_heading()));
712 print("Magn Deviation",
713 fmt::sprintf("%s %s", render(t
->get_magn_dev()), render(t
->get_magn_dev_hem())));
714 print("Magn Variation",
715 fmt::sprintf("%s %s", render(t
->get_magn_var()), render(t
->get_magn_var_hem())));
718 static void print_detail_hfb(const marnav::nmea::sentence
* s
)
720 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::hfb
>(s
);
721 print("Distance Head Foot [m]", render(t
->get_distance_head_foot()));
722 print("Distance Head Bottom [m]", render(t
->get_distance_head_bottom()));
725 static void print_detail_hdm(const marnav::nmea::sentence
* s
)
727 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::hdm
>(s
);
728 print("Heading", render(t
->get_heading()));
731 static void print_detail_hdt(const marnav::nmea::sentence
* s
)
733 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::hdt
>(s
);
734 print("Heading", render(t
->get_heading()));
737 static void print_detail_hsc(const marnav::nmea::sentence
* s
)
739 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::hsc
>(s
);
740 print("Heading True", render(t
->get_heading_true()));
741 print("Heading Magnetic", render(t
->get_heading_mag()));
744 static void print_detail_its(const marnav::nmea::sentence
* s
)
746 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::its
>(s
);
747 print("Distance [m]", render(t
->get_distance()));
750 static void print_detail_lcd(const marnav::nmea::sentence
* s
)
752 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::lcd
>(s
);
753 print("GRI microseconds", render(t
->get_gri()));
754 print("Master", fmt::sprintf("SNR:%d ECD:%d", t
->get_master().snr
, t
->get_master().ecd
));
755 for (int i
= 0; i
< marnav::nmea::lcd::max_differences
; ++i
) {
756 const auto diff
= t
->get_time_diff(i
);
758 print(fmt::sprintf("Time Diff %d", i
),
759 fmt::sprintf("SNR:%d ECD:%d", diff
->snr
, diff
->ecd
));
764 static void print_detail_mob(const marnav::nmea::sentence
* s
)
766 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::mob
>(s
);
767 print("MOB Emitter ID", render(t
->get_emitter_id()));
768 print("MOB Status", render(t
->get_mob_status()));
769 print("MOB Time UTC", render(t
->get_mob_activation_utc()));
770 print("MOB Position Source", render(t
->get_mob_position_source()));
771 print("Date of Position", render(t
->get_position_date()));
772 print("Time of Position", render(t
->get_position_time()));
773 print("Latitude", render(t
->get_lat()));
774 print("Longitude", render(t
->get_lon()));
775 print("COG", render(t
->get_cog()));
776 print("SOG", render(t
->get_sog()));
777 print("MMSI", render(t
->get_mmsi()));
778 print("Battery Status", render(t
->get_battery_status()));
781 static void print_detail_msk(const marnav::nmea::sentence
* s
)
783 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::msk
>(s
);
784 print("Frequency to use", render(t
->get_frequency()));
785 print("Frequency Mode", render(t
->get_frequency_mode()));
786 print("Beacon Bit Rate", render(t
->get_bitrate()));
787 print("Beacon Mode", render(t
->get_bitrate_mode()));
788 print("Frequency for MSS message status", render(t
->get_frequency_mss_status()));
791 static void print_detail_rmb(const marnav::nmea::sentence
* s
)
793 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::rmb
>(s
);
794 print("Active", render(t
->get_active()));
795 print("Cross Track Error", render(t
->get_cross_track_error()));
796 print("Waypoint From", render(t
->get_waypoint_from()));
797 print("Waypoint To", render(t
->get_waypoint_to()));
798 print("Latitude", render(t
->get_lat()));
799 print("Longitude", render(t
->get_lon()));
800 print("Range", render(t
->get_range()));
801 print("Bearing", render(t
->get_bearing()));
802 print("Dest. Velocity", render(t
->get_dst_velocity()));
803 print("Arrival Status", render(t
->get_arrival_status()));
804 print("Mode Indicator", render(t
->get_mode_ind()));
807 static void print_detail_rmc(const marnav::nmea::sentence
* s
)
809 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::rmc
>(s
);
810 print("Time UTC", render(t
->get_time_utc()));
811 print("Status", render(t
->get_status()));
812 print("Latitude", render(t
->get_lat()));
813 print("Longitude", render(t
->get_lon()));
814 print("SOG", render(t
->get_sog()));
815 print("Heading", render(t
->get_heading()));
816 print("Date", render(t
->get_date()));
817 print("Magn Dev", fmt::sprintf("%s %s", render(t
->get_mag()), render(t
->get_mag_hem())));
818 print("Mode Ind ", render(t
->get_mode_ind()));
821 static void print_detail_rot(const marnav::nmea::sentence
* s
)
823 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::rot
>(s
);
824 print("Rate of Turn", render(t
->get_deg_per_minute()));
825 print("Status", render(t
->get_data_valid()));
828 static void print_detail_rpm(const marnav::nmea::sentence
* s
)
830 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::rpm
>(s
);
831 print("Source", render(t
->get_source()));
832 print("Source Number", render(t
->get_source_number()));
833 print("RPM", render(t
->get_revolutions()));
834 print("Propeller Pitch", render(t
->get_propeller_pitch()));
835 print("Status", render(t
->get_data_valid()));
838 static void print_detail_rsa(const marnav::nmea::sentence
* s
)
840 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::rsa
>(s
);
841 print("Starbord Angle", render(t
->get_rudder1()));
842 print("Starbord Status", render(t
->get_rudder1_valid()));
843 print("Port Angle", render(t
->get_rudder2()));
844 print("Port Status", render(t
->get_rudder2_valid()));
847 static void print_detail_rsd(const marnav::nmea::sentence
* s
)
849 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::rsd
>(s
);
850 print("Cursor Range from own ship", render(t
->get_cursor_range()));
851 print("Cursor Bearing from own ship", render(t
->get_cursor_bearing()));
852 print("Range Scale", render(t
->get_range_scale()));
853 print("Range Units", render(t
->get_range_unit()));
856 static void print_detail_vtg(const marnav::nmea::sentence
* s
)
858 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::vtg
>(s
);
859 print("Track True", render(t
->get_track_true()));
860 print("Track Magn", render(t
->get_track_magn()));
861 print("Speed Knots", render(t
->get_speed_kn()));
862 print("Speed kmh", render(t
->get_speed_kmh()));
863 print("Mode Indicator", render(t
->get_mode_ind()));
866 static void print_detail_gll(const marnav::nmea::sentence
* s
)
868 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::gll
>(s
);
869 print("Latitude", render(t
->get_lat()));
870 print("Longitude", render(t
->get_lon()));
871 print("Time UTC", render(t
->get_time_utc()));
872 print("Status", render(t
->get_data_valid()));
873 print("Mode Indicator", render(t
->get_mode_ind()));
876 static void print_detail_gns(const marnav::nmea::sentence
* s
)
878 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::gns
>(s
);
879 print("Time UTC", render(t
->get_time_utc()));
880 print("Latitude", render(t
->get_lat()));
881 print("Longitude", render(t
->get_lon()));
882 print("Mode Indicator", render(t
->get_mode_ind()));
883 print("Number of Satellites", render(t
->get_number_of_satellites()));
884 print("HDROP", render(t
->get_hdrop()));
885 print("Antenna Altitude [m]", render(t
->get_antenna_altitude()));
886 print("Geoidal Separation [m]", render(t
->get_geodial_separation()));
887 print("Age of differential Data", render(t
->get_age_of_differential_data()));
888 print("Differential Ref Station ID", render(t
->get_differential_ref_station_id()));
891 static void print_detail_grs(const marnav::nmea::sentence
* s
)
893 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::grs
>(s
);
894 print("UTC time associated with GGA", render(t
->get_time_utc()));
895 print("Status", render(t
->get_usage()));
896 for (int i
= 0; i
< marnav::nmea::grs::num_satellite_residuals
; ++i
) {
897 const auto residual
= t
->get_sat_residual(i
);
899 print(fmt::sprintf("Sat %02d Residual [m]", i
), render(*residual
));
903 static void print_detail_bec(const marnav::nmea::sentence
* s
)
905 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::bec
>(s
);
906 print("Time UTC", render(t
->get_time_utc()));
907 print("Bearing True", render(t
->get_bearing_true()));
908 print("Bearing Magn", render(t
->get_bearing_magn()));
909 print("Distance [nm]", render(t
->get_distance().get
<marnav::units::nautical_miles
>()));
910 print("Waypoint", render(t
->get_waypoint()));
913 static void print_detail_bod(const marnav::nmea::sentence
* s
)
915 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::bod
>(s
);
916 print("Bearing True", render(t
->get_bearing_true()));
917 print("Bearing Magn", render(t
->get_bearing_magn()));
918 print("Waypoint To", render(t
->get_waypoint_to()));
919 print("Waypoint From", render(t
->get_waypoint_from()));
922 static void print_detail_bwc(const marnav::nmea::sentence
* s
)
924 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::bwc
>(s
);
925 print("Time UTC", render(t
->get_time_utc()));
926 print("Bearing True", render(t
->get_bearing_true()));
927 print("Bearing Magnetic", render(t
->get_bearing_mag()));
930 "%s %s", render(t
->get_distance()), render(marnav::nmea::unit::distance::nm
)));
931 print("Waypoint", render(t
->get_waypoint_id()));
932 print("Mode Indicator", render(t
->get_mode_ind()));
935 static void print_detail_bwr(const marnav::nmea::sentence
* s
)
937 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::bwr
>(s
);
938 print("Time UTC", render(t
->get_time_utc()));
939 print("Latitude", render(t
->get_lat()));
940 print("Longitude", render(t
->get_lon()));
941 print("Bearing True", render(t
->get_bearing_true()));
942 print("Bearing Magnetic", render(t
->get_bearing_mag()));
943 print("Distance NM", render(t
->get_distance()));
944 print("Waypoint", render(t
->get_waypoint_id()));
945 print("Mode Indicator", render(t
->get_mode_ind()));
948 static void print_detail_bww(const marnav::nmea::sentence
* s
)
950 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::bww
>(s
);
951 print("Bearing True", render(t
->get_bearing_true()));
952 print("Bearing Magnetic", render(t
->get_bearing_magn()));
953 print("Waypoint To", render(t
->get_waypoint_to()));
954 print("Waypoint From", render(t
->get_waypoint_from()));
957 static void print_detail_gsa(const marnav::nmea::sentence
* s
)
959 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::gsa
>(s
);
960 print("Selection Mode", render(t
->get_sel_mode()));
961 print("Mode", render(t
->get_mode()));
962 for (auto i
= 0; i
< marnav::nmea::gsa::max_satellite_ids
; ++i
) {
963 print(fmt::sprintf("Satellite %02u", i
), render(t
->get_satellite_id(i
)));
965 print("PDOP", render(t
->get_pdop()));
966 print("HDOP", render(t
->get_hdop()));
967 print("VDOP", render(t
->get_vdop()));
970 static void print_detail_gst(const marnav::nmea::sentence
* s
)
972 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::gst
>(s
);
973 print("Time UTC", render(t
->get_time_utc()));
974 print("Total RMS", render(t
->get_total_rms()));
975 print("Std Dev Semi-Major Axis", render(t
->get_dev_semi_major()));
976 print("Std Dev Semi-Minor Axis", render(t
->get_dev_semi_minor()));
977 print("Orientation Semi-Major Axis", render(t
->get_orientation()));
978 print("Std Dev. Latitude Error", render(t
->get_dev_lat()));
979 print("Std Dev. Longitude Error", render(t
->get_dev_lon()));
980 print("Std Dev. Altitude Error", render(t
->get_dev_alt()));
983 static void print_detail_glc(const marnav::nmea::sentence
* s
)
985 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::glc
>(s
);
986 print("GRI", render(t
->get_gri()));
989 "DIFF:%s STATUS:%s", render(t
->get_master().diff
), render(t
->get_master().status
)));
990 for (int i
= 0; i
< marnav::nmea::glc::max_differences
; ++i
) {
991 const auto & td
= t
->get_time_diff(i
);
993 print(fmt::sprintf("Time Diff %d", i
),
994 fmt::sprintf("DIFF:%s STATUS:%s", render(td
->diff
), render(td
->status
)));
999 static void print_detail_gga(const marnav::nmea::sentence
* s
)
1001 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::gga
>(s
);
1002 print("Time", render(t
->get_time()));
1003 print("Latitude", render(t
->get_lat()));
1004 print("Longitude", render(t
->get_lon()));
1005 print("Quality Ind", render(t
->get_quality_indicator()));
1006 print("Num Satellites", render(t
->get_n_satellites()));
1007 print("Horiz Dilution", render(t
->get_hor_dilution()));
1008 print("Altitude", render(t
->get_altitude()));
1009 print("Geodial Sep", render(t
->get_geodial_separation()));
1010 print("DGPS Age", render(t
->get_dgps_age()));
1011 print("DGPS Ref", render(t
->get_dgps_ref()));
1014 static void print_detail_osd(const marnav::nmea::sentence
* s
)
1016 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::osd
>(s
);
1017 print("Heading", render(t
->get_heading()));
1018 print("Status", render(t
->get_data_valid()));
1019 print("Vessel Course True", render(t
->get_course()));
1020 print("Vessel Speed",
1021 fmt::sprintf("%s %s", render(t
->get_speed()), render(t
->get_speed_unit())));
1022 print("Vessel Set", render(t
->get_vessel_set()));
1023 print("Vessel Drift",
1024 fmt::sprintf("%s %s", render(t
->get_vessel_drift()), render(t
->get_speed_unit())));
1027 static void print_detail_r00(const marnav::nmea::sentence
* s
)
1029 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::r00
>(s
);
1030 for (int i
= 0; i
< marnav::nmea::r00::max_waypoint_ids
; ++i
) {
1031 const auto & wp
= t
->get_waypoint_id(i
);
1033 print("Waypoint", render(*wp
));
1038 static void print_detail_rma(const marnav::nmea::sentence
* s
)
1040 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::rma
>(s
);
1041 print("Blink Warning", render(t
->get_blink_warning()));
1042 print("Latitude", render(t
->get_lat()));
1043 print("Longitude", render(t
->get_lon()));
1044 print("Time Diff A", render(t
->get_time_diff_a()));
1045 print("Time Diff B", render(t
->get_time_diff_b()));
1046 print("SOG [kn]", render(t
->get_sog()));
1047 print("Track made good", render(t
->get_track()));
1048 print("Magnetic Variation",
1050 "%s %s", render(t
->get_magnetic_var()), render(t
->get_magnetic_var_hem())));
1053 static void print_detail_mwv(const marnav::nmea::sentence
* s
)
1055 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::mwv
>(s
);
1056 print("Angle", fmt::sprintf("%s %s", render(t
->get_angle()), render(t
->get_angle_ref())));
1057 print("Speed", fmt::sprintf("%s %s", render(t
->get_speed()), render(t
->get_speed_unit())));
1058 print("Data Valid", render(t
->get_data_valid()));
1061 static void print_detail_gsv(const marnav::nmea::sentence
* s
)
1063 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::gsv
>(s
);
1064 print("Num Messages", render(t
->get_n_messages()));
1065 print("Messages Number", render(t
->get_message_number()));
1066 print("Num Sat in View", render(t
->get_n_satellites_in_view()));
1067 for (int i
= 0; i
< 4; ++i
) {
1068 const auto sat
= t
->get_sat(i
);
1071 fmt::sprintf("PRN:%02u ELEV:%02u AZIMUTH:%03u SNR:%s", sat
->prn
, sat
->elevation
,
1072 sat
->azimuth
, render(sat
->snr
)));
1077 static void print_detail_gtd(const marnav::nmea::sentence
* s
)
1079 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::gtd
>(s
);
1080 for (int i
= 0; i
< marnav::nmea::gtd::max_time_diffs
; ++i
)
1081 print(fmt::sprintf("Time Diff %d", i
), render(t
->get_time_diff(i
)));
1084 static void print_detail_zda(const marnav::nmea::sentence
* s
)
1086 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::zda
>(s
);
1087 print("Time UTC", render(t
->get_time_utc()));
1088 print("Date", render(t
->get_date()));
1089 print("Local Zone Hours", render(t
->get_local_zone_hours()));
1090 print("Local Zone Min", render(t
->get_local_zone_minutes()));
1093 static void print_detail_zdl(const marnav::nmea::sentence
* s
)
1095 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::zdl
>(s
);
1096 print("Time to Point", render(t
->get_time_to_point()));
1097 print("Distance to Point NM", render(t
->get_distance()));
1098 print("Type of Point", render(t
->get_type_point()));
1101 static void print_detail_zfi(const marnav::nmea::sentence
* s
)
1103 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::zfi
>(s
);
1104 print("Time UTC", render(t
->get_time_utc()));
1105 print("Elapsed Time", render(t
->get_time_elapsed()));
1106 print("Origin Waypoint", render(t
->get_waypoint_id()));
1109 static void print_detail_zfo(const marnav::nmea::sentence
* s
)
1111 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::zfo
>(s
);
1112 print("Time UTC", render(t
->get_time_utc()));
1113 print("Elapsed Time", render(t
->get_time_elapsed()));
1114 print("Origin Waypoint", render(t
->get_waypoint_id()));
1117 static void print_detail_zta(const marnav::nmea::sentence
* s
)
1119 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::zta
>(s
);
1120 print("Time UTC", render(t
->get_time_utc()));
1121 print("Time Arrival", render(t
->get_time_arrival()));
1122 print("Destination Waypoint", render(t
->get_waypoint_id()));
1125 static void print_detail_zte(const marnav::nmea::sentence
* s
)
1127 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::zte
>(s
);
1128 print("Time UTC", render(t
->get_time_utc()));
1129 print("Time Remaining", render(t
->get_time_remaining()));
1130 print("Destination Waypoint", render(t
->get_waypoint_id()));
1133 static void print_detail_zlz(const marnav::nmea::sentence
* s
)
1135 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::zlz
>(s
);
1136 print("Time UTC", render(t
->get_time_utc()));
1137 print("Time Local", render(t
->get_time_local()));
1138 print("Local Zone Description", render(t
->get_local_zone_description()));
1141 static void print_detail_zpi(const marnav::nmea::sentence
* s
)
1143 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::zpi
>(s
);
1144 print("Time UTC", render(t
->get_time_utc()));
1145 print("Time at Arrival", render(t
->get_time_arrival()));
1146 print("Destination Waypoint", render(t
->get_waypoint_id()));
1149 static void print_detail_ztg(const marnav::nmea::sentence
* s
)
1151 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::ztg
>(s
);
1152 print("Time UTC", render(t
->get_time_utc()));
1153 print("Time Remaining", render(t
->get_time_remaining()));
1154 print("Destination Waypoint", render(t
->get_waypoint_id()));
1157 static void print_detail_dtm(const marnav::nmea::sentence
* s
)
1159 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::dtm
>(s
);
1160 print("Ref", render(t
->get_ref()));
1161 print("Subcode", render(t
->get_subcode()));
1162 print("Latitude Offset", render(t
->get_lat_offset()));
1163 print("Latitude Hem", render(t
->get_lat_hem()));
1164 print("Longitude Offset", render(t
->get_lon_offset()));
1165 print("Longitude Hem", render(t
->get_lon_hem()));
1166 print("Altitude", render(t
->get_altitude().get
<marnav::units::meters
>()));
1167 print("Name", render(t
->get_name()));
1170 static void print_detail_fsi(const marnav::nmea::sentence
* s
)
1172 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::fsi
>(s
);
1173 print("Tx Freuency 100 Hz", render(t
->get_tx_frequency()));
1174 print("Rx Freuency 100 Hz", render(t
->get_rx_frequency()));
1175 print("Mode of Operation", render(t
->get_communications_mode()));
1176 print("Power Level", render(t
->get_power_level()));
1177 print("Sentence Status Flag", render(t
->get_sentence_status()));
1180 static void print_detail_gbs(const marnav::nmea::sentence
* s
)
1182 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::gbs
>(s
);
1183 print("Time UTC", render(t
->get_time_utc()));
1184 print("Error Latitude", render(t
->get_err_lat().get
<marnav::units::meters
>()));
1185 print("Error Longitude", render(t
->get_err_lon().get
<marnav::units::meters
>()));
1186 print("Error Altitude", render(t
->get_err_alt().get
<marnav::units::meters
>()));
1187 print("Satellite PRN", render(t
->get_satellite()));
1188 print("Probability", render(t
->get_probability()));
1189 print("Bias", render(t
->get_bias().get
<marnav::units::meters
>()));
1190 print("Standard Deviation of bias", render(t
->get_bias_dev()));
1193 static void print_detail_aam(const marnav::nmea::sentence
* s
)
1195 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::aam
>(s
);
1196 print("Arrival Circle Entred", render(t
->get_arrival_circle_entered()));
1197 print("Perpendicular Passed", render(t
->get_perpendicualar_passed()));
1198 print("Arrival Circle Radius",
1199 render(t
->get_arrival_circle_radius().get
<marnav::units::nautical_miles
>()));
1200 print("Waypoint", render(t
->get_waypoint_id()));
1203 static void print_detail_alm(const marnav::nmea::sentence
* s
)
1205 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::alm
>(s
);
1206 print("Number of Messages", render(t
->get_number_of_messages()));
1207 print("Message Number", render(t
->get_message_number()));
1208 print("Satellite PRN", render(t
->get_satellite_prn()));
1209 print("GPS Week Number", render(t
->get_gps_week_number()));
1210 print("SV Health", render(t
->get_sv_health()));
1211 print("Eccentricity", render(t
->get_eccentricity()));
1212 print("Almanac Reference Time", render(t
->get_almanac_reference_time()));
1213 print("Inclination Angle", render(t
->get_inclination_angle()));
1214 print("Rate of right ascension", render(t
->get_rate_of_right_ascension()));
1215 print("Root of Semimajor Axis", render(t
->get_root_of_semimajor_axis()));
1216 print("Argument of perigee", render(t
->get_argument_of_perigee()));
1217 print("Longitude of ascension node", render(t
->get_longitude_of_ascension_node()));
1218 print("Mean Anomaly", render(t
->get_mean_anomaly()));
1219 print("F0 clock parameter", render(t
->get_f0_clock_parameter()));
1220 print("F1 clock parameter", render(t
->get_f1_clock_parameter()));
1223 static void print_detail_alr(const marnav::nmea::sentence
* s
)
1225 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::alr
>(s
);
1226 print("Time UTC", render(t
->get_time_utc()));
1227 print("Alarm Number", render(t
->get_number()));
1228 print("Alarm Condition", render(t
->get_condition()));
1229 print("Alarm Acknowledge", render(t
->get_acknowledge()));
1230 print("Alarm Text", render(t
->get_text()));
1233 static void print_detail_apa(const marnav::nmea::sentence
* s
)
1235 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::apa
>(s
);
1236 print("Lorac C Blink Warning", render(t
->get_loran_c_blink_warning()));
1237 print("Lorac C Cycle Lock Warning", render(t
->get_loran_c_cycle_lock_warning()));
1238 print("Magnitude of Cross Track Error", render(t
->get_cross_track_error_magnitude()));
1239 print("Direction to Steer", render(t
->get_direction_to_steer()));
1240 print("Cross Track Units", render(t
->get_cross_track_unit()));
1241 print("Status Arrival", render(t
->get_status_arrival()));
1242 print("Status Perpendicular Passed", render(t
->get_status_perpendicular_passing()));
1243 print("Bearing Origin to Dest", render(t
->get_bearing_origin_to_destination()));
1244 print("Bearing Origin to Dest Ref", render(t
->get_bearing_origin_to_destination_ref()));
1245 print("Destination Waypoint", render(t
->get_waypoint_id()));
1248 static void print_detail_rte(const marnav::nmea::sentence
* s
)
1250 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::rte
>(s
);
1251 print("Number of Messages", render(t
->get_n_messages()));
1252 print("Message Number", render(t
->get_message_number()));
1253 print("Message Mode", render(t
->get_message_mode()));
1254 for (int i
= 0; i
< marnav::nmea::rte::max_waypoints
; ++i
) {
1255 const auto wp
= t
->get_waypoint_id(i
);
1257 print(fmt::sprintf("Waypoint %i", i
), render(wp
));
1261 static void print_detail_sfi(const marnav::nmea::sentence
* s
)
1263 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::sfi
>(s
);
1264 print("Number of Messages", render(t
->get_n_messages()));
1265 print("Message Number", render(t
->get_message_number()));
1266 for (const auto & f
: t
->get_frequencies())
1267 print("Frequency [kHz]", fmt::sprintf("%s %s", render(f
.frequency
), render(f
.mode
)));
1270 static void print_detail_stn(const marnav::nmea::sentence
* s
)
1272 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::stn
>(s
);
1273 print("Number ID", render(t
->get_number()));
1276 static void print_detail_tds(const marnav::nmea::sentence
* s
)
1278 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::tds
>(s
);
1279 print("Distance [m]", render(t
->get_distance()));
1282 static void print_detail_tfi(const marnav::nmea::sentence
* s
)
1284 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::tfi
>(s
);
1285 print("Sensor #1", render(t
->get_sensor(0)));
1286 print("Sensor #2", render(t
->get_sensor(1)));
1287 print("Sensor #3", render(t
->get_sensor(2)));
1290 static void print_detail_tll(const marnav::nmea::sentence
* s
)
1292 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::tll
>(s
);
1293 print("Target Number", render(t
->get_number()));
1294 print("Latitude", render(t
->get_lat()));
1295 print("Longitude", render(t
->get_lon()));
1296 print("Target Name", render(t
->get_name()));
1297 print("Time UTC", render(t
->get_time_utc()));
1298 print("Target Status", render(t
->get_status()));
1299 print("Reference Target", render(t
->get_reference_target()));
1302 static void print_detail_tpc(const marnav::nmea::sentence
* s
)
1304 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::tpc
>(s
);
1305 print("Horiz. Range from Center Line [m]", render(t
->get_distance_centerline()));
1306 print("Horiz. dist from Transd. along [m]", render(t
->get_distance_transducer()));
1307 print("Depth [m]", render(t
->get_depth()));
1310 static void print_detail_tpr(const marnav::nmea::sentence
* s
)
1312 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::tpr
>(s
);
1313 print("Horizontal Range [m]", render(t
->get_range()));
1314 print("Bearing to Target to Vessel", render(t
->get_bearing()));
1315 print("Depth [m]", render(t
->get_depth()));
1318 static void print_detail_tpt(const marnav::nmea::sentence
* s
)
1320 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::tpt
>(s
);
1321 print("Horizontal Range [m]", render(t
->get_range()));
1322 print("Bearing to Target True", render(t
->get_bearing()));
1323 print("Depth [m]", render(t
->get_depth()));
1326 static void print_detail_ttm(const marnav::nmea::sentence
* s
)
1328 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::ttm
>(s
);
1329 print("Target Number", render(t
->get_target_number()));
1330 print("Target Distance", render(t
->get_target_distance()));
1331 print("Bearing from own ship", render(t
->get_bearing_from_ownship()));
1332 print("Bearing from own ship Ref", render(t
->get_bearing_from_ownship_ref()));
1333 print("Target Speed", render(t
->get_target_speed()));
1334 print("Target Course", render(t
->get_target_course()));
1335 print("Target Course Ref", render(t
->get_target_course_ref()));
1336 print("CPA", render(t
->get_distance_cpa()));
1337 print("TCPA", render(t
->get_tcpa()));
1338 print("Unknown", render(t
->get_unknown()));
1339 print("Target Name", render(t
->get_target_name()));
1340 print("Target Status", render(t
->get_target_status()));
1341 print("Reference Target", render(t
->get_reference_target()));
1344 static void print_detail_vbw(const marnav::nmea::sentence
* s
)
1346 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::vbw
>(s
);
1347 print("Longitudinal Water Speed", render(t
->get_water_speed_longitudinal()));
1348 print("Transverse Water Speed", render(t
->get_water_speed_transveral()));
1349 print("Status", render(t
->get_water_speed_status()));
1350 print("Longitudinal Ground Speed", render(t
->get_ground_speed_longitudinal()));
1351 print("Transverse Ground Speed", render(t
->get_ground_speed_transveral()));
1352 print("Status", render(t
->get_ground_speed_status()));
1355 static void print_detail_vdr(const marnav::nmea::sentence
* s
)
1357 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::vdr
>(s
);
1358 print("Degrees True", render(t
->get_degrees_true()));
1359 print("Degrees Magnetic", render(t
->get_degrees_magn()));
1360 print("Speed of Current", render(t
->get_speed()));
1363 static void print_detail_mss(const marnav::nmea::sentence
* s
)
1365 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::mss
>(s
);
1366 print("Signal Strength [dB 1uV]", render(t
->get_signal_strength()));
1367 print("Signal to Noise Ratio (dB)", render(t
->get_signal_to_noise_ratio()));
1368 print("Beacon Frequency [kHz]", render(t
->get_beacon_frequency()));
1369 print("Beacon Data Rate BPS", render(t
->get_beacon_datarate()));
1370 print("unknown", render(t
->get_unknown()));
1373 static void print_detail_mta(const marnav::nmea::sentence
* s
)
1375 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::mta
>(s
);
1376 print("Air Temperature", render(t
->get_temperature()));
1379 static void print_detail_mtw(const marnav::nmea::sentence
* s
)
1381 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::mtw
>(s
);
1382 print("Water Temperature", render(t
->get_temperature()));
1385 static void print_detail_mwd(const marnav::nmea::sentence
* s
)
1387 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::mwd
>(s
);
1388 print("Direction True", render(t
->get_direction_true()));
1389 print("Direction Magnetic", render(t
->get_direction_mag()));
1390 print("Speed kn", render(t
->get_speed_kn()));
1391 print("Speed m/s", render(t
->get_speed_ms()));
1394 static void print_detail_dbk(const marnav::nmea::sentence
* s
)
1396 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::dbk
>(s
);
1397 print("Depth Feet", render(t
->get_depth_feet()));
1398 print("Depth Meter", render(t
->get_depth_meter()));
1399 print("Depth Fathom", render(t
->get_depth_fathom()));
1402 static void print_detail_dbt(const marnav::nmea::sentence
* s
)
1404 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::dbt
>(s
);
1405 print("Depth Feet", render(t
->get_depth_feet()));
1406 print("Depth Meter", render(t
->get_depth_meter()));
1407 print("Depth Fathom", render(t
->get_depth_fathom()));
1410 static void print_detail_dpt(const marnav::nmea::sentence
* s
)
1412 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::dpt
>(s
);
1413 print("Depth", render(t
->get_depth_meter().get
<marnav::units::meters
>()));
1414 print("Offset from Transducer",
1415 render(t
->get_transducer_offset().get
<marnav::units::meters
>()));
1416 print("Max Depth", render(t
->get_max_depth()));
1419 static void print_detail_dsc(const marnav::nmea::sentence
* s
)
1421 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::dsc
>(s
);
1422 print("Format Specificer", render(t
->get_fmt_spec()));
1423 print("Category", render(t
->get_cat()));
1424 print("MMSI", render(t
->get_mmsi()));
1425 print("Geographical Area", render(t
->get_geographical_area()));
1426 print("Acklowledgement", render(t
->get_ack()));
1427 print("Extension Indicator", render(t
->get_extension()));
1430 static void print_detail_dse(const marnav::nmea::sentence
* s
)
1432 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::dse
>(s
);
1433 print("Number of Messages", render(t
->get_number_of_messages()));
1434 print("Sentence Number", render(t
->get_sentence_number()));
1435 print("Query Flag", render(t
->get_flag()));
1436 print("MMSI", render(t
->get_mmsi()));
1439 static void print_detail_apb(const marnav::nmea::sentence
* s
)
1441 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::apb
>(s
);
1442 print("Loran C blink warn", render(t
->get_loran_c_blink_warning()));
1443 print("Loran C cycle lock warn", render(t
->get_loran_c_cycle_lock_warning()));
1444 print("Cross Track Error Magnitude", render(t
->get_cross_track_error_magnitude()));
1445 print("Direction to Steer", render(t
->get_direction_to_steer()));
1446 print("Cross Track Unit", render(t
->get_cross_track_unit()));
1447 print("Status Arrival", render(t
->get_status_arrival()));
1448 print("Status Perpendicular Pass", render(t
->get_status_perpendicular_passing()));
1449 print("Bearing Org to Dest", render(t
->get_bearing_origin_to_destination()));
1450 print("Bearing Org to Dest Ref", render(t
->get_bearing_origin_to_destination_ref()));
1451 print("Waypoint", render(t
->get_waypoint_id()));
1452 print("Bearing Pos to Dest", render(t
->get_bearing_pos_to_destination()));
1453 print("Bearing Pos to Dest Ref", render(t
->get_bearing_pos_to_destination_ref()));
1454 print("Heading to Steer to Dest", render(t
->get_heading_to_steer_to_destination()));
1455 print("Heading to Steer to Dest Ref", render(t
->get_heading_to_steer_to_destination_ref()));
1456 print("Mode Indicator", render(t
->get_mode_ind()));
1459 static void print_detail_pgrme(const marnav::nmea::sentence
* s
)
1461 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::pgrme
>(s
);
1462 print("HPE", render(t
->get_horizontal_position_error()));
1463 print("VPE", render(t
->get_vertical_position_error()));
1464 print("O.sph.eq.pos err", render(t
->get_overall_spherical_equiv_position_error()));
1467 static void print_detail_pgrmm(const marnav::nmea::sentence
* s
)
1469 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::pgrmm
>(s
);
1470 print("Map Datum", render(t
->get_map_datum()));
1473 static void print_detail_pgrmz(const marnav::nmea::sentence
* s
)
1475 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::pgrmz
>(s
);
1476 print("Altitude", render(t
->get_altitude()));
1477 print("Fix Type", render(t
->get_fix()));
1480 static void print_detail_stalk(const marnav::nmea::sentence
* s
)
1482 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::stalk
>(s
);
1483 print("Data", render(t
->get_data()));
1486 static void print_detail_vwe(const marnav::nmea::sentence
* s
)
1488 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::vwe
>(s
);
1489 print("Efficiency", render(t
->get_efficiency()));
1492 static void print_detail_vwr(const marnav::nmea::sentence
* s
)
1494 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::vwr
>(s
);
1495 print("Angle", fmt::sprintf("%s %s", render(t
->get_angle()), render(t
->get_angle_side())));
1496 print("Speed kn", render(t
->get_speed_knots()));
1497 print("Speed m/s", render(t
->get_speed_mps()));
1498 print("Speed km/h", render(t
->get_speed_kmh()));
1501 static void print_detail_wcv(const marnav::nmea::sentence
* s
)
1503 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::wcv
>(s
);
1504 print("Speed kn", render(t
->get_speed()));
1505 print("Waypoint", render(t
->get_waypoint_id()));
1508 static void print_detail_wdc(const marnav::nmea::sentence
* s
)
1510 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::wdc
>(s
);
1511 print("Distance NM", render(t
->get_distance()));
1512 print("Waypoint", render(t
->get_waypoint_id()));
1515 static void print_detail_wdr(const marnav::nmea::sentence
* s
)
1517 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::wdr
>(s
);
1518 print("Distance NM", render(t
->get_distance()));
1519 print("Waypoint", render(t
->get_waypoint_id()));
1522 static void print_detail_wnc(const marnav::nmea::sentence
* s
)
1524 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::wnc
>(s
);
1525 print("Distnace NM", render(t
->get_distance_nm()));
1526 print("Distnace km", render(t
->get_distance_km()));
1527 print("Waypoint To", render(t
->get_waypoint_to()));
1528 print("Waypoint From", render(t
->get_waypoint_from()));
1531 static void print_detail_wpl(const marnav::nmea::sentence
* s
)
1533 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::wpl
>(s
);
1534 print("Latitude", render(t
->get_lat()));
1535 print("Longitude", render(t
->get_lon()));
1536 print("Waypoint", render(t
->get_waypoint_id()));
1539 static void print_detail_xdr(const marnav::nmea::sentence
* s
)
1541 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::xdr
>(s
);
1542 for (auto i
= 0; i
< marnav::nmea::xdr::max_transducer_info
; ++i
) {
1543 const auto info
= t
->get_info(i
);
1545 print("Transducer Info",
1546 fmt::sprintf("Type:%c Data:%f Unit:%c Name:%s", info
->transducer_type
,
1547 info
->measurement_data
, info
->units_of_measurement
, info
->name
));
1552 static void print_detail_xte(const marnav::nmea::sentence
* s
)
1554 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::xte
>(s
);
1555 print("Status 1", render(t
->get_status1()));
1556 print("Status 2", render(t
->get_status2()));
1557 print("Cross Track Error Magnitude", render(t
->get_cross_track_error_magnitude()));
1558 print("Direction to Steer", render(t
->get_direction_to_steer()));
1559 print("Mode Indicator", render(t
->get_mode_ind()));
1562 static void print_detail_xtr(const marnav::nmea::sentence
* s
)
1564 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::xtr
>(s
);
1565 print("Cross Track Error Magnitude", render(t
->get_cross_track_error_magnitude()));
1566 print("Direction to Steer", render(t
->get_direction_to_steer()));
1569 static void print_detail_vlw(const marnav::nmea::sentence
* s
)
1571 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::vlw
>(s
);
1572 print("Distance Cumulative NM", render(t
->get_distance_cum()));
1573 print("Distance since Rest NM", render(t
->get_distance_reset()));
1576 static void print_detail_vpw(const marnav::nmea::sentence
* s
)
1578 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::vpw
>(s
);
1579 print("Speed kn", render(t
->get_speed_knots()));
1580 print("Speed m/s", render(t
->get_speed_meters_per_second()));
1583 static void print_detail_vhw(const marnav::nmea::sentence
* s
)
1585 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::vhw
>(s
);
1586 print("Heading True", render(t
->get_heading_true()));
1587 print("Heading Magn", render(t
->get_heading_magn()));
1588 print("Speed kn", render(t
->get_speed_knots()));
1589 print("Speed km/h", render(t
->get_speed_kmh()));
1592 static void print_detail_message_01_common(const marnav::ais::message_01
* t
)
1594 print("Repeat Indicator", render(t
->get_repeat_indicator()));
1595 print("MMSI", render(t
->get_mmsi()));
1596 print("Nav Status", render(t
->get_nav_status()));
1597 print("ROT", render(t
->get_rot()));
1598 print("SOG", render(t
->get_sog()));
1599 print("Pos Accuracy", render(t
->get_position_accuracy()));
1600 print("Latitude", render(t
->get_lat()));
1601 print("Longitude", render(t
->get_lon()));
1602 print("COG", render(t
->get_cog()));
1603 print("HDG", render(t
->get_hdg()));
1604 print("Time Stamp", render(t
->get_timestamp()));
1605 print("Maneuver Indicator", render(t
->get_maneuver_indicator()));
1606 print("RAIM", render(t
->get_raim()));
1607 print("Radio Status", render(t
->get_radio_status()));
1610 static void print_detail_message_01(const marnav::ais::message
* m
)
1612 print_detail_message_01_common(marnav::ais::message_cast
<marnav::ais::message_01
>(m
));
1615 static void print_detail_message_02(const marnav::ais::message
* m
)
1617 print_detail_message_01_common(marnav::ais::message_cast
<marnav::ais::message_02
>(m
));
1620 static void print_detail_message_03(const marnav::ais::message
* m
)
1622 print_detail_message_01_common(marnav::ais::message_cast
<marnav::ais::message_03
>(m
));
1625 static void print_detail_message_04_common(const marnav::ais::message_04
* t
)
1627 print("Repeat Indicator", render(t
->get_repeat_indicator()));
1628 print("MMSI", render(t
->get_mmsi()));
1629 print("Year", render(t
->get_year()));
1630 print("Month", render(t
->get_month()));
1631 print("Day", render(t
->get_day()));
1632 print("Hour", render(t
->get_hour()));
1633 print("Minute", render(t
->get_minute()));
1634 print("Second", render(t
->get_second()));
1635 print("Pos Accuracy", render(t
->get_position_accuracy()));
1636 print("Latitude", render(t
->get_lat()));
1637 print("Longitude", render(t
->get_lon()));
1638 print("EPFD Fix", render(t
->get_epfd_fix()));
1639 print("RAIM", render(t
->get_raim()));
1640 print("Radio Status", render(t
->get_radio_status()));
1643 static void print_detail_message_04(const marnav::ais::message
* m
)
1645 print_detail_message_04_common(marnav::ais::message_cast
<marnav::ais::message_04
>(m
));
1648 static void print_detail_message_11(const marnav::ais::message
* m
)
1650 print_detail_message_04_common(marnav::ais::message_cast
<marnav::ais::message_11
>(m
));
1653 static void print_detail_message_12(const marnav::ais::message
* m
)
1655 const auto t
= marnav::ais::message_cast
<marnav::ais::message_12
>(m
);
1656 print("Repeat Indicator", render(t
->get_repeat_indicator()));
1657 print("MMSI", render(t
->get_mmsi()));
1658 print("Seqence Number", render(t
->get_seqno()));
1659 print("Destination MMSI", render(t
->get_dest_mmsi()));
1660 print("Retransmit", render(t
->get_retransmit()));
1661 print("Text", render(t
->get_text()));
1664 static void print_detail_message_13(const marnav::ais::message
* m
)
1666 const auto t
= marnav::ais::message_cast
<marnav::ais::message_13
>(m
);
1667 print("Repeat Indicator", render(t
->get_repeat_indicator()));
1668 print("MMSI", render(t
->get_mmsi()));
1669 print("MMSI_1", render(t
->get_mmsi_1()));
1670 print("MMSI_2", render(t
->get_mmsi_2()));
1671 print("MMSI_3", render(t
->get_mmsi_3()));
1672 print("MMSI_4", render(t
->get_mmsi_4()));
1675 static void print_detail_message_14(const marnav::ais::message
* m
)
1677 const auto t
= marnav::ais::message_cast
<marnav::ais::message_14
>(m
);
1678 print("Repeat Indicator", render(t
->get_repeat_indicator()));
1679 print("MMSI", render(t
->get_mmsi()));
1680 print("Text", render(t
->get_text()));
1683 static void print_detail_message_05(const marnav::ais::message
* m
)
1685 const auto t
= marnav::ais::message_cast
<marnav::ais::message_05
>(m
);
1686 print("Repeat Indicator", render(t
->get_repeat_indicator()));
1687 print("MMSI", render(t
->get_mmsi()));
1688 print("AIS Version", render(t
->get_ais_version()));
1689 print("IMO", render(t
->get_imo_number()));
1690 print("Callsign", render(t
->get_callsign()));
1691 print("Shipname", render(t
->get_shipname()));
1692 print("Shiptype", render(t
->get_shiptype()));
1693 print("Length", render(t
->get_vessel_dimension().length()));
1694 print("Width", render(t
->get_vessel_dimension().width()));
1695 print("Draught", render(t
->get_draught()));
1696 print("EPFD Fix", render(t
->get_epfd_fix()));
1697 print("ETA Month", render(t
->get_eta_month()));
1698 print("ETA Day", render(t
->get_eta_day()));
1699 print("ETA Hour", render(t
->get_eta_hour()));
1700 print("ETA Minute", render(t
->get_eta_minute()));
1701 print("Destination", render(t
->get_destination()));
1702 print("DTE", render(t
->get_dte()));
1705 static void print_detail_message_06(const marnav::ais::message
* m
)
1707 const auto t
= marnav::ais::message_cast
<marnav::ais::message_06
>(m
);
1708 print("Repeat Indicator", render(t
->get_repeat_indicator()));
1709 print("MMSI", render(t
->get_mmsi()));
1710 print("Sequence No", render(t
->get_sequnce_no()));
1711 print("Destination MMSI", render(t
->get_dest_mmsi()));
1712 print("Retransmit Flag", render(t
->get_retransmit_flag()));
1713 print("DAC", render(t
->get_dac()));
1714 print("FID", render(t
->get_fid()));
1716 fmt::printf("\n\twarning: message 06: decoding of payload not implemented: %03d/%02d\n",
1717 t
->get_dac(), t
->get_fid());
1720 static void print_detail_message_07(const marnav::ais::message
* m
)
1722 const auto t
= marnav::ais::message_cast
<marnav::ais::message_07
>(m
);
1723 print("Repeat Indicator", render(t
->get_repeat_indicator()));
1724 print("MMSI", render(t
->get_mmsi()));
1725 print("MMSI_1", render(t
->get_mmsi_1()));
1726 print("MMSI_2", render(t
->get_mmsi_2()));
1727 print("MMSI_3", render(t
->get_mmsi_3()));
1728 print("MMSI_4", render(t
->get_mmsi_4()));
1731 static void print_detail_message_08(const marnav::ais::message
* m
)
1733 const auto t
= marnav::ais::message_cast
<marnav::ais::message_08
>(m
);
1734 print("Repeat Indicator", render(t
->get_repeat_indicator()));
1735 print("MMSI", render(t
->get_mmsi()));
1736 print("DAC", render(t
->get_dac()));
1737 print("FID", render(t
->get_fid()));
1739 if (t
->get_dac() == 1 && t
->get_fid() == 11) {
1740 marnav::ais::binary_001_11 b
;
1743 print("Meteological and Hydrological Data (001/11) IMO236");
1744 print("Position", render(b
.get_position()));
1745 print("Day", render(b
.get_day()));
1746 print("Hour", render(b
.get_hour()));
1747 print("Minute", render(b
.get_minute()));
1748 print("Wind Speed 10min avg [kn]", render(b
.get_wind_speed_avg()));
1749 print("Wind Gust [kn]", render(b
.get_wind_gust()));
1750 print("Wind Direction", render(b
.get_wind_direction()));
1751 print("Wind Gust Direction", render(b
.get_wind_gust_direction()));
1752 print("Temperature [C]", render(b
.get_temperature()));
1753 print("Humidity [%]", render(b
.get_humidity()));
1754 print("Dew Point [%]", render(b
.get_dew_point()));
1755 print("Air Pressure [hPa]", render(b
.get_pressure()));
1756 print("Air Pressure Trend", render(b
.get_pressure_trend()));
1757 print("Visibility [NM]", render(b
.get_visibility()));
1758 print("Water Level [m]", render(b
.get_water_level()));
1759 print("Water Level Trend", render(b
.get_water_level_trend()));
1760 print("Sufrace Current Speed [kn]", render(b
.get_surface_current_speed()));
1761 print("Sufrace Current Direction", render(b
.get_surface_current_direction()));
1762 print("Current 2 Speed [kn]", render(b
.get_current_2_speed()));
1763 print("Current 2 Direction", render(b
.get_current_2_direction()));
1764 print("Current 2 Depth [m]", render(b
.get_current_2_depth()));
1765 print("Current 3 Speed [kn]", render(b
.get_current_3_speed()));
1766 print("Current 3 Direction", render(b
.get_current_3_direction()));
1767 print("Current 3 Depth [m]", render(b
.get_current_3_depth()));
1768 print("Wave Height [m]", render(b
.get_wave_height()));
1769 print("Wave Period [s]", render(b
.get_wave_period()));
1770 print("Wave Direction", render(b
.get_wave_direction()));
1771 print("Swell Height [m]", render(b
.get_swell_height()));
1772 print("Swell Period [s]", render(b
.get_swell_period()));
1773 print("Swell Direction", render(b
.get_swell_direction()));
1774 print("Sea State", render(b
.get_sea_state()));
1775 print("Water Temperature [C]", render(b
.get_water_temperature()));
1776 print("Precipitation", render(b
.get_precipitation()));
1777 print("Salinity [%]", render(b
.get_salinity()));
1778 print("Ice", render(b
.get_ice()));
1779 } else if (t
->get_dac() == 200 && t
->get_fid() == 10) {
1780 marnav::ais::binary_200_10 b
;
1783 print("Inland ship static and voyage related data (200/10)");
1784 print("Vessel ID", render(b
.get_vessel_id()));
1785 print("Length [m]", render(b
.get_length()));
1786 print("Beam [m]", render(b
.get_beam()));
1787 print("Shiptype", render(b
.get_shiptype()));
1788 print("Hazard", render(b
.get_hazard()));
1789 print("Draught [m]", render(b
.get_draught()));
1790 print("Loaded", render(b
.get_loaded()));
1791 print("Speed quality", render(b
.get_speed_q()));
1792 print("Course quality", render(b
.get_course_q()));
1793 print("Heading quality", render(b
.get_heading_q()));
1795 fmt::printf("\n\twarning: message 08: decoding of payload not implemented: %03d/%02d\n",
1796 t
->get_dac(), t
->get_fid());
1800 static void print_detail_message_09(const marnav::ais::message
* m
)
1802 const auto t
= marnav::ais::message_cast
<marnav::ais::message_09
>(m
);
1803 print("Repeat Indicator", render(t
->get_repeat_indicator()));
1804 print("MMSI", render(t
->get_mmsi()));
1805 print("Altitude", render(t
->get_altitude()));
1806 print("Speed", render(t
->get_speed()));
1807 print("Pos Accuracy", render(t
->get_position_accuracy()));
1808 print("COG", render(t
->get_course()));
1809 print("UTC Second", render(t
->get_utc_second()));
1810 print("DTE", render(t
->get_dte()));
1811 print("RAIM", render(t
->get_raim()));
1812 print("Radio Status", render(t
->get_radio_status()));
1815 static void print_detail_message_10(const marnav::ais::message
* m
)
1817 const auto t
= marnav::ais::message_cast
<marnav::ais::message_10
>(m
);
1818 print("Repeat Indicator", render(t
->get_repeat_indicator()));
1819 print("MMSI", render(t
->get_mmsi()));
1820 print("Destination MMSI", render(t
->get_dest_mmsi()));
1823 static void print_detail_message_17(const marnav::ais::message
* m
)
1825 const auto t
= marnav::ais::message_cast
<marnav::ais::message_17
>(m
);
1826 print("Repeat Indicator", render(t
->get_repeat_indicator()));
1827 print("MMSI", render(t
->get_mmsi()));
1828 print("Latitude", render(t
->get_lat()));
1829 print("Longitude", render(t
->get_lon()));
1831 // TODO: print payload as hex string
1834 static void print_detail_message_18(const marnav::ais::message
* m
)
1836 const auto t
= marnav::ais::message_cast
<marnav::ais::message_18
>(m
);
1837 print("Repeat Indicator", render(t
->get_repeat_indicator()));
1838 print("MMSI", render(t
->get_mmsi()));
1839 print("SOG", render(t
->get_sog()));
1840 print("Pos Accuracy", render(t
->get_position_accuracy()));
1841 print("Latitude", render(t
->get_lat()));
1842 print("Longitude", render(t
->get_lon()));
1843 print("COG", render(t
->get_cog()));
1844 print("HDG", render(t
->get_hdg()));
1845 print("Time Stamp", render(t
->get_timestamp()));
1846 print("CS Unit", render(t
->get_cs_unit()));
1847 print("Display Flag", render(t
->get_display_flag()));
1848 print("DSC Flag", render(t
->get_dsc_flag()));
1849 print("Band Flag", render(t
->get_band_flag()));
1850 print("Message 22 Flag", render(t
->get_message_22_flag()));
1851 print("Assigned", render(t
->get_assigned()));
1852 print("RAIM", render(t
->get_raim()));
1853 print("Radio Status", render(t
->get_radio_status()));
1856 static void print_detail_message_19(const marnav::ais::message
* m
)
1858 const auto t
= marnav::ais::message_cast
<marnav::ais::message_19
>(m
);
1859 print("Repeat Indicator", render(t
->get_repeat_indicator()));
1860 print("MMSI", render(t
->get_mmsi()));
1861 print("SOG", render(t
->get_sog()));
1862 print("Pos Accuracy", render(t
->get_position_accuracy()));
1863 print("Latitude", render(t
->get_lat()));
1864 print("Longitude", render(t
->get_lon()));
1865 print("COG", render(t
->get_cog()));
1866 print("HDG", render(t
->get_hdg()));
1867 print("Time Stamp", render(t
->get_timestamp()));
1868 print("Ship Name", render(t
->get_shipname()));
1869 print("Ship Type", render(t
->get_shiptype()));
1870 print("Length", render(t
->get_vessel_dimension().length()));
1871 print("Width", render(t
->get_vessel_dimension().width()));
1872 print("EPFD Fix", render(t
->get_epfd_fix()));
1873 print("RAIM", render(t
->get_raim()));
1874 print("DTE", render(t
->get_dte()));
1875 print("Assigned", render(t
->get_assigned()));
1878 static void print_detail_message_20(const marnav::ais::message
* m
)
1880 const auto t
= marnav::ais::message_cast
<marnav::ais::message_20
>(m
);
1881 print("Repeat Indicator", render(t
->get_repeat_indicator()));
1882 print("MMSI", render(t
->get_mmsi()));
1883 for (int i
= 0; i
< 3; ++i
) {
1884 const auto entry
= t
->get_entry(i
);
1885 print(fmt::sprintf("Entry %d", i
+ 1),
1886 fmt::sprintf("Offset:%4u Slots:%1u Timeout:%1u Increment:%4u", entry
.offset
,
1887 entry
.slots
, entry
.timeout
, entry
.increment
));
1891 static void print_detail_message_21(const marnav::ais::message
* m
)
1893 const auto t
= marnav::ais::message_cast
<marnav::ais::message_21
>(m
);
1894 print("Repeat Indicator", render(t
->get_repeat_indicator()));
1895 print("MMSI", render(t
->get_mmsi()));
1896 print("Aid Type", render(t
->get_aid_type()));
1897 print("Name", render(t
->get_name()));
1898 print("Pos Accuracy", render(t
->get_position_accuracy()));
1899 print("Latitude", render(t
->get_lat()));
1900 print("Longitude", render(t
->get_lon()));
1901 print("Length", render(t
->get_vessel_dimension().length()));
1902 print("Width", render(t
->get_vessel_dimension().width()));
1903 print("EPFD Fix", render(t
->get_epfd_fix()));
1904 print("UTC Second", render(t
->get_utc_second()));
1905 print("Off Pos Indicator", render(t
->get_off_position()));
1906 print("Regional", render(t
->get_regional()));
1907 print("RAIM", render(t
->get_raim()));
1908 print("Virtual Aid Flag", render(t
->get_virtual_aid_flag()));
1909 print("Assigned", render(t
->get_assigned()));
1910 print("Name Extension", render(t
->get_name_extension()));
1913 static void print_detail_message_22(const marnav::ais::message
* m
)
1915 const auto t
= marnav::ais::message_cast
<marnav::ais::message_22
>(m
);
1916 print("Repeat Indicator", render(t
->get_repeat_indicator()));
1917 print("MMSI", render(t
->get_mmsi()));
1918 print("Channel A", render(t
->get_channel_a()));
1919 print("Channel B", render(t
->get_channel_b()));
1920 print("TxRx Mode", render(t
->get_txrx_mode()));
1921 print("Power", render(t
->get_power()));
1922 print("Adressed", render(t
->get_addressed()));
1923 if (t
->get_addressed()) {
1924 print("MMSI 1", render(t
->get_mmsi_1()));
1925 print("MMSI 2", render(t
->get_mmsi_2()));
1927 print("Position NE", render(t
->get_position_ne()));
1928 print("Position SW", render(t
->get_position_sw()));
1932 static void print_detail_message_23(const marnav::ais::message
* m
)
1934 const auto t
= marnav::ais::message_cast
<marnav::ais::message_23
>(m
);
1935 print("Repeat Indicator", render(t
->get_repeat_indicator()));
1936 print("MMSI", render(t
->get_mmsi()));
1937 print("Position NE", render(t
->get_position_ne()));
1938 print("Position SW", render(t
->get_position_sw()));
1939 print("Station Type", render(t
->get_station_type()));
1940 print("Ship Type", render(t
->get_shiptype()));
1941 print("TxRx Mode", render(t
->get_txrx_mode()));
1942 print("Report Interval", render(t
->get_interval()));
1943 print("Quiet Time", render(t
->get_quiet_time()));
1946 static void print_detail_message_24(const marnav::ais::message
* m
)
1948 const auto t
= marnav::ais::message_cast
<marnav::ais::message_24
>(m
);
1949 print("Repeat Indicator", render(t
->get_repeat_indicator()));
1950 print("MMSI", render(t
->get_mmsi()));
1951 print("Part", render(t
->get_part_number()));
1952 if (t
->get_part_number() == marnav::ais::message_24::part::A
) {
1953 print("Ship Name", render(t
->get_shipname()));
1955 print("Ship Type", render(t
->get_shiptype()));
1956 print("Vendor ID", render(t
->get_vendor_id()));
1957 print("Model", render(t
->get_model()));
1958 print("Serial", render(t
->get_serial()));
1959 print("Callsign", render(t
->get_callsign()));
1960 if (t
->is_auxiliary_vessel()) {
1961 print("Mothership MMSI", render(t
->get_mothership_mmsi()));
1963 print("Length", render(t
->get_vessel_dimension().length()));
1964 print("Width", render(t
->get_vessel_dimension().width()));
1972 marnav::nmea::sentence_id id
;
1973 std::function
<void(const marnav::nmea::sentence
*)> func
;
1976 static const std::vector
<nmea_entry
> & nmea_sentences()
1978 #define ADD_SENTENCE(s) \
1980 marnav::nmea::s::ID, detail::print_detail_##s \
1982 using container
= std::vector
<nmea_entry
>;
1984 static const container sentences
= {
2073 ADD_SENTENCE(pgrme
),
2074 ADD_SENTENCE(pgrmm
),
2075 ADD_SENTENCE(pgrmz
),
2083 static int dump_nmea(const std::string
& line
)
2085 using namespace marnav
;
2088 const auto & sentences
= nmea_sentences();
2089 auto s
= nmea::make_sentence(line
);
2090 auto i
= std::find_if(std::begin(sentences
), std::end(sentences
),
2091 [&s
](const nmea_entry
& item
) { return item
.id
== s
->id(); });
2092 if (i
== std::end(sentences
)) {
2093 fmt::printf("\t%s\n", detail::render(s
->id()));
2095 "%s%s%s\n\tnot implemented\n\n", terminal::magenta
, line
, terminal::normal
);
2097 fmt::printf("%s%s%s\n", terminal::green
, line
, terminal::normal
);
2098 fmt::printf("\tName : %s\n", detail::render(s
->id()));
2099 fmt::printf("\tTalker: %s\n", detail::render(s
->get_talker()));
2104 } catch (nmea::unknown_sentence
& error
) {
2105 fmt::printf("%s%s%s\n\terror: unknown sentence: %s\n\n", terminal::red
, line
,
2106 terminal::normal
, error
.what());
2107 } catch (nmea::checksum_error
& error
) {
2108 fmt::printf("%s%s%s\n\terror: checksum error: %s\n\n", terminal::red
, line
,
2109 terminal::normal
, error
.what());
2110 } catch (std::invalid_argument
& error
) {
2112 "%s%s%s\n\terror: %s\n\n", terminal::red
, line
, terminal::normal
, error
.what());
2117 static int dump_ais(const std::vector
<std::unique_ptr
<marnav::nmea::sentence
>> & sentences
)
2119 #define ADD_MESSAGE(m) \
2121 marnav::ais::m::ID, detail::print_detail_##m \
2124 marnav::ais::message_id id
;
2125 std::function
<void(const marnav::ais::message
*)> func
;
2127 using container
= std::vector
<entry
>;
2129 static const container messages
= {
2130 ADD_MESSAGE(message_01
),
2131 ADD_MESSAGE(message_02
),
2132 ADD_MESSAGE(message_03
),
2133 ADD_MESSAGE(message_04
),
2134 ADD_MESSAGE(message_05
),
2135 ADD_MESSAGE(message_06
),
2136 ADD_MESSAGE(message_07
),
2137 ADD_MESSAGE(message_08
),
2138 ADD_MESSAGE(message_09
),
2139 ADD_MESSAGE(message_10
),
2140 ADD_MESSAGE(message_11
),
2141 ADD_MESSAGE(message_12
),
2142 ADD_MESSAGE(message_13
),
2143 ADD_MESSAGE(message_14
),
2144 ADD_MESSAGE(message_17
),
2145 ADD_MESSAGE(message_18
),
2146 ADD_MESSAGE(message_19
),
2147 ADD_MESSAGE(message_20
),
2148 ADD_MESSAGE(message_21
),
2149 ADD_MESSAGE(message_22
),
2150 ADD_MESSAGE(message_23
),
2151 ADD_MESSAGE(message_24
)
2156 using namespace marnav
;
2159 auto m
= ais::make_message(nmea::collect_payload(sentences
.begin(), sentences
.end()));
2160 auto i
= std::find_if(std::begin(messages
), std::end(messages
),
2161 [&m
](const container::value_type
& item
) { return item
.id
== m
->type(); });
2162 if (i
== std::end(messages
)) {
2163 fmt::printf("\t%s\n", detail::render(m
->type()));
2164 fmt::printf("%smessage_%02u%s\n\tnot implemented\n\n", terminal::magenta
,
2165 static_cast<uint8_t>(m
->type()), terminal::normal
);
2167 fmt::printf("\t%s\n", detail::render(m
->type()));
2172 } catch (std::exception
& error
) {
2173 fmt::printf("\t%serror:%s %s\n\n", terminal::red
, terminal::normal
, error
.what());
2178 static int process(std::function
<bool(std::string
&)> source
)
2180 using namespace marnav
;
2183 std::vector
<std::unique_ptr
<nmea::sentence
>> sentences
;
2187 while (source(line
)) {
2194 if (line
[0] == nmea::sentence::start_token
) {
2195 result
+= dump_nmea(line
);
2196 } else if (line
[0] == nmea::sentence::start_token_ais
) {
2197 fmt::printf("%s%s%s\n", terminal::blue
, line
, terminal::normal
);
2198 auto s
= nmea::make_sentence(line
);
2200 nmea::vdm
* v
= nullptr; // VDM is the common denominator for AIS relevant messages
2202 if (s
->id() == nmea::sentence_id::VDO
) {
2203 v
= nmea::sentence_cast
<nmea::vdo
>(s
.get());
2204 } else if (s
->id() == nmea::sentence_id::VDM
) {
2205 v
= nmea::sentence_cast
<nmea::vdm
>(s
.get());
2207 // something strange happened, no VDM nor VDO
2208 fmt::printf("%s%s%s\n\terror: ignoring AIS sentence, dropping collection.\n\n",
2209 terminal::red
, line
, terminal::normal
);
2215 // check sentences if a discontuniation has occurred
2216 if (sentences
.size() && (sentences
.back()->id() != v
->id())) {
2217 sentences
.clear(); // there was a discontinuation, start over collecting
2219 "\t%swarning:%s dropping collection.\n", terminal::cyan
, terminal::normal
);
2222 // check if a previous message was not complete
2223 const auto n_fragments
= v
->get_n_fragments();
2224 const auto fragment
= v
->get_fragment();
2225 if (sentences
.size() >= fragment
) {
2228 "\t%swarning:%s dropping collection.\n", terminal::cyan
, terminal::normal
);
2231 sentences
.push_back(std::move(s
));
2232 if (fragment
== n_fragments
) {
2233 result
+= dump_ais(sentences
);
2237 fmt::printf("%s%s%s\n\terror: ignoring AIS sentence.\n\n", terminal::red
, line
,
2245 static bool parse_options(int argc
, char ** argv
)
2247 uint32_t port_speed
= 0;
2250 cxxopts::Options options
{argv
[0], "NMEA Dump"};
2251 options
.add_options()
2253 "Shows help information.")
2255 "Shows a list of supported NMEA sentences.")
2257 "Specifies the port to use.",
2258 cxxopts::value
<std::string
>(global
.config
.port
))
2260 "Specifies the port speed. Valid values: 4800, 38400",
2261 cxxopts::value
<uint32_t>(port_speed
))
2263 "Specifies the file to use.",
2264 cxxopts::value
<std::string
>(global
.config
.file
))
2267 cxxopts::value
<std::string
>(global
.config
.input_string
))
2271 const auto args
= options
.parse(argc
, argv
);
2273 if (args
.count("help")) {
2274 fmt::printf("%s\n", options
.help());
2275 fmt::printf("If no file or port is specified, stdin is used to read data from.\n\n");
2279 using namespace marnav
;
2281 if (args
.count("help-nmea-list")) {
2282 const auto is_impl
= [](nmea::sentence_id id
) {
2283 return std::find_if(begin(nmea_sentences()), end(nmea_sentences()),
2284 [id
](const nmea_entry
& entry
) {
2285 return id
== entry
.id
2286 // AIS data carrying NMEA sentences are decoded as AIS messages
2287 || id
== nmea::sentence_id::VDM
|| id
== nmea::sentence_id::VDO
;
2289 != end(nmea_sentences());
2292 for (const auto id
: nmea::get_supported_sentences_id()) {
2293 fmt::printf("%c %s %s\n", is_impl(id
) ? '-' : '*', to_string(id
), to_name(id
));
2301 static const std::vector
<uint32_t> valid_port_speeds
= {4800, 38400};
2303 if (args
.count("port") && args
.count("file"))
2304 throw std::runtime_error
{"specifying port and file is illegal"};
2305 if (args
.count("port") && !contains(valid_port_speeds
, port_speed
))
2306 throw std::runtime_error
{"invalid port speed"};
2308 switch (port_speed
) {
2310 global
.config
.speed
= io::serial::baud::baud_4800
;
2313 global
.config
.speed
= io::serial::baud::baud_38400
;
2323 int main(int argc
, char ** argv
)
2325 using namespace nmeadump
;
2327 if (parse_options(argc
, argv
))
2328 return EXIT_SUCCESS
;
2331 if (!global
.config
.file
.empty()) {
2332 std::ifstream ifs
{global
.config
.file
.c_str()};
2333 result
= process([&](std::string
& line
) { return !!std::getline(ifs
, line
); });
2334 } else if (!global
.config
.port
.empty()) {
2335 using namespace marnav
;
2336 using namespace marnav::io
;
2337 default_nmea_reader source
{
2338 utils::make_unique
<serial
>(global
.config
.port
, global
.config
.speed
,
2339 serial::databits::bit_8
, serial::stopbits::bit_1
, serial::parity::none
)};
2340 result
= process([&](std::string
& line
) { return source
.read_sentence(line
); });
2341 } else if (!global
.config
.input_string
.empty()) {
2342 std::istringstream
is(global
.config
.input_string
);
2343 result
= process([&](std::string
& line
) { return !!std::getline(is
, line
); });
2345 std::cin
.sync_with_stdio(false);
2346 result
= process([&](std::string
& line
) { return !!std::getline(std::cin
, line
); });