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/nmea.hpp>
25 #include <marnav/nmea/ais_helper.hpp>
26 #include <marnav/nmea/checksum.hpp>
27 #include <marnav/nmea/sentence.hpp>
28 #include <marnav/nmea/waypoint.hpp>
29 #include <marnav/nmea/name.hpp>
30 #include <marnav/nmea/string.hpp>
32 #include <marnav/nmea/aam.hpp>
33 #include <marnav/nmea/alm.hpp>
34 #include <marnav/nmea/apa.hpp>
35 #include <marnav/nmea/apb.hpp>
36 #include <marnav/nmea/bec.hpp>
37 #include <marnav/nmea/bod.hpp>
38 #include <marnav/nmea/bwc.hpp>
39 #include <marnav/nmea/bwr.hpp>
40 #include <marnav/nmea/bww.hpp>
41 #include <marnav/nmea/dbt.hpp>
42 #include <marnav/nmea/dpt.hpp>
43 //#include <marnav/nmea/dsc.hpp>
44 //#include <marnav/nmea/dse.hpp>
45 #include <marnav/nmea/dtm.hpp>
46 #include <marnav/nmea/fsi.hpp>
47 #include <marnav/nmea/gbs.hpp>
48 #include <marnav/nmea/gga.hpp>
49 #include <marnav/nmea/glc.hpp>
50 #include <marnav/nmea/gll.hpp>
51 #include <marnav/nmea/gns.hpp>
52 #include <marnav/nmea/grs.hpp>
53 #include <marnav/nmea/gsa.hpp>
54 #include <marnav/nmea/gst.hpp>
55 #include <marnav/nmea/gsv.hpp>
56 #include <marnav/nmea/gtd.hpp>
57 #include <marnav/nmea/hdg.hpp>
58 #include <marnav/nmea/hfb.hpp>
59 #include <marnav/nmea/hdm.hpp>
60 #include <marnav/nmea/hdt.hpp>
61 #include <marnav/nmea/hsc.hpp>
62 #include <marnav/nmea/its.hpp>
63 #include <marnav/nmea/lcd.hpp>
64 #include <marnav/nmea/mob.hpp>
65 #include <marnav/nmea/msk.hpp>
66 #include <marnav/nmea/mss.hpp>
67 #include <marnav/nmea/mtw.hpp>
68 #include <marnav/nmea/mwd.hpp>
69 #include <marnav/nmea/mwv.hpp>
70 #include <marnav/nmea/osd.hpp>
71 #include <marnav/nmea/r00.hpp>
72 #include <marnav/nmea/rma.hpp>
73 #include <marnav/nmea/rmb.hpp>
74 #include <marnav/nmea/rmc.hpp>
75 #include <marnav/nmea/rot.hpp>
76 #include <marnav/nmea/rpm.hpp>
77 #include <marnav/nmea/rsa.hpp>
78 #include <marnav/nmea/rsd.hpp>
79 #include <marnav/nmea/rte.hpp>
80 #include <marnav/nmea/sfi.hpp>
81 #include <marnav/nmea/stn.hpp>
82 #include <marnav/nmea/tds.hpp>
83 #include <marnav/nmea/tfi.hpp>
84 #include <marnav/nmea/tll.hpp>
85 #include <marnav/nmea/tpc.hpp>
86 #include <marnav/nmea/tpr.hpp>
87 #include <marnav/nmea/tpt.hpp>
88 #include <marnav/nmea/ttm.hpp>
89 #include <marnav/nmea/vbw.hpp>
90 #include <marnav/nmea/vdm.hpp>
91 #include <marnav/nmea/vdo.hpp>
92 #include <marnav/nmea/vdr.hpp>
93 #include <marnav/nmea/vhw.hpp>
94 #include <marnav/nmea/vlw.hpp>
95 #include <marnav/nmea/vpw.hpp>
96 #include <marnav/nmea/vtg.hpp>
97 #include <marnav/nmea/vwr.hpp>
98 #include <marnav/nmea/wcv.hpp>
99 #include <marnav/nmea/wnc.hpp>
100 #include <marnav/nmea/wpl.hpp>
101 #include <marnav/nmea/xdr.hpp>
102 #include <marnav/nmea/xte.hpp>
103 #include <marnav/nmea/xtr.hpp>
104 #include <marnav/nmea/zda.hpp>
105 #include <marnav/nmea/zdl.hpp>
106 #include <marnav/nmea/zfo.hpp>
107 #include <marnav/nmea/ztg.hpp>
108 #include <marnav/nmea/pgrme.hpp>
109 #include <marnav/nmea/pgrmm.hpp>
110 #include <marnav/nmea/pgrmz.hpp>
111 #include <marnav/nmea/stalk.hpp>
113 #include <marnav/ais/ais.hpp>
114 #include <marnav/ais/name.hpp>
116 #include <marnav/ais/message_01.hpp>
117 #include <marnav/ais/message_02.hpp>
118 #include <marnav/ais/message_03.hpp>
119 #include <marnav/ais/message_04.hpp>
120 #include <marnav/ais/message_05.hpp>
121 #include <marnav/ais/message_06.hpp>
122 #include <marnav/ais/message_07.hpp>
123 #include <marnav/ais/message_08.hpp>
124 #include <marnav/ais/message_09.hpp>
125 #include <marnav/ais/message_10.hpp>
126 #include <marnav/ais/message_11.hpp>
127 #include <marnav/ais/message_12.hpp>
128 #include <marnav/ais/message_13.hpp>
129 #include <marnav/ais/message_14.hpp>
130 #include <marnav/ais/message_17.hpp>
131 #include <marnav/ais/message_18.hpp>
132 #include <marnav/ais/message_19.hpp>
133 #include <marnav/ais/message_20.hpp>
134 #include <marnav/ais/message_21.hpp>
135 #include <marnav/ais/message_22.hpp>
136 #include <marnav/ais/message_23.hpp>
137 #include <marnav/ais/message_24.hpp>
138 #include <marnav/ais/binary_001_11.hpp>
139 #include <marnav/ais/binary_200_10.hpp>
141 #include <marnav/io/default_nmea_reader.hpp>
142 #include <marnav/io/serial.hpp>
144 #include <marnav/units/units.hpp>
146 #include <marnav/utils/unique.hpp>
147 #include <marnav/utils/mmsi_country.hpp>
149 #include <cxxopts.hpp>
151 #include <fmt/format.h>
152 #include <fmt/printf.h>
163 static constexpr const char * normal
= "\033[0m";
164 static constexpr const char * black
= "\033[30m";
165 static constexpr const char * red
= "\033[31m";
166 static constexpr const char * green
= "\033[32m";
167 static constexpr const char * yellow
= "\033[33m";
168 static constexpr const char * blue
= "\033[34m";
169 static constexpr const char * magenta
= "\033[35m";
170 static constexpr const char * cyan
= "\033[36m";
171 static constexpr const char * white
= "\033[37m";
176 template <class Container
>
177 static bool contains(
178 const Container
& container
, const typename
Container::value_type
& element
)
180 return std::find(std::begin(container
), std::end(container
), element
)
181 != std::end(container
);
188 marnav::io::serial::baud speed
;
190 std::string input_string
;
194 static bool parse_options(int argc
, char ** argv
)
196 uint32_t port_speed
= 0;
199 cxxopts::Options options
{argv
[0], "NMEA Dump"};
200 options
.add_options()
202 "Shows help information.")
204 "Specifies the port to use.",
205 cxxopts::value
<std::string
>(global
.config
.port
))
207 "Specifies the port speed. Valid values: 4800, 38400",
208 cxxopts::value
<uint32_t>(port_speed
))
210 "Specifies the file to use.",
211 cxxopts::value
<std::string
>(global
.config
.file
))
214 cxxopts::value
<std::string
>(global
.config
.input_string
))
218 const auto args
= options
.parse(argc
, argv
);
220 if (args
.count("help")) {
221 fmt::printf("%s\n", options
.help());
222 fmt::printf("If no file or port is specified, stdin is used to read data from.\n\n");
228 static const std::vector
<uint32_t> valid_port_speeds
= {4800, 38400};
230 if (args
.count("port") && args
.count("file"))
231 throw std::runtime_error
{"specifying port and file is illegal"};
232 if (args
.count("port") && !contains(valid_port_speeds
, port_speed
))
233 throw std::runtime_error
{"invalid port speed"};
235 switch (port_speed
) {
237 global
.config
.speed
= marnav::io::serial::baud::baud_4800
;
240 global
.config
.speed
= marnav::io::serial::baud::baud_38400
;
249 static std::string
trim(const std::string
& s
)
251 static const char * whitespace
= "\n\r\t ";
252 const auto begin
= s
.find_first_not_of(whitespace
);
253 const auto end
= s
.find_last_not_of(whitespace
);
254 return begin
!= std::string::npos
? s
.substr(begin
, end
- begin
+ 1) : "";
260 template <typename T
> static std::string
render(const T
& t
)
262 return marnav::nmea::to_string(t
);
265 static std::string
render(const std::string
& t
)
270 static std::string
render(bool t
)
272 return t
? "true" : "false";
275 static std::string
render(char t
)
277 return fmt::sprintf("%c", t
);
280 static std::string
render(const uint32_t t
)
282 return fmt::sprintf("%u", t
);
285 static std::string
render(const int32_t t
)
287 return fmt::sprintf("%d", t
);
290 static std::string
render(const uint8_t t
)
292 return fmt::sprintf("%u", t
);
295 static std::string
render(const double t
)
297 return fmt::sprintf("%-8.3f", t
);
300 static std::string
render(const marnav::utils::mmsi
& t
)
302 const auto country
= mmsi_country(t
).name
;
303 if (!country
.empty())
305 "%09u (%s)", static_cast<marnav::utils::mmsi::value_type
>(t
), country
);
306 return fmt::sprintf("%09u", static_cast<marnav::utils::mmsi::value_type
>(t
));
309 static std::string
render(const marnav::nmea::time
& t
)
311 return fmt::sprintf("%02u:%02u:%02u", t
.hour(), t
.minutes(), t
.seconds());
314 static std::string
render(const marnav::geo::latitude
& t
)
316 using namespace marnav::nmea
;
318 " %02u\u00b0%02u'%04.1f%s", t
.degrees(), t
.minutes(), t
.seconds(), to_string(t
.hem()));
321 static std::string
render(const marnav::geo::longitude
& t
)
323 using namespace marnav::nmea
;
325 "%03u\u00b0%02u'%04.1f%s", t
.degrees(), t
.minutes(), t
.seconds(), to_string(t
.hem()));
328 static std::string
render(const marnav::geo::position
& p
)
330 using namespace marnav::nmea
;
331 return fmt::sprintf("%s %s", render(p
.lat()), render(p
.lon()));
334 static std::string
render(const marnav::ais::message_23::report_interval t
)
337 case marnav::ais::message_23::report_interval::autonomous_mode
:
338 return "Autonomous Mode";
339 case marnav::ais::message_23::report_interval::minutes_10
:
341 case marnav::ais::message_23::report_interval::minutes_06
:
343 case marnav::ais::message_23::report_interval::minutes_03
:
345 case marnav::ais::message_23::report_interval::minutes_01
:
347 case marnav::ais::message_23::report_interval::seconds_30
:
349 case marnav::ais::message_23::report_interval::seconds_15
:
351 case marnav::ais::message_23::report_interval::seconds_10
:
353 case marnav::ais::message_23::report_interval::seconds_05
:
355 case marnav::ais::message_23::report_interval::next_shorter
:
356 return "Next Shorter";
357 case marnav::ais::message_23::report_interval::next_longer
:
358 return "Next Longer";
363 static std::string
render(const marnav::ais::message_24::part t
)
366 case marnav::ais::message_24::part::A
:
368 case marnav::ais::message_24::part::B
:
374 static std::string
render(const marnav::ais::binary_001_11::trend t
)
377 case marnav::ais::binary_001_11::trend::steady
:
379 case marnav::ais::binary_001_11::trend::decreasing
:
380 return "decreasing ";
381 case marnav::ais::binary_001_11::trend::increasing
:
383 case marnav::ais::binary_001_11::trend::not_available
:
384 return "not available";
389 static std::string
render(const marnav::ais::binary_001_11::ice t
)
392 case marnav::ais::binary_001_11::ice::no
:
394 case marnav::ais::binary_001_11::ice::yes
:
396 case marnav::ais::binary_001_11::ice::not_available
:
397 return "not available";
402 static std::string
render(const marnav::ais::binary_001_11::precipitation t
)
405 case marnav::ais::binary_001_11::precipitation::rain
:
407 case marnav::ais::binary_001_11::precipitation::thunderstorm
:
408 return "thunderstorm";
409 case marnav::ais::binary_001_11::precipitation::freezing_rain
:
410 return "freezing_rain";
411 case marnav::ais::binary_001_11::precipitation::mixed_ice
:
413 case marnav::ais::binary_001_11::precipitation::snow
:
415 case marnav::ais::binary_001_11::precipitation::not_available
:
416 return "not available";
421 static std::string
render(const marnav::ais::binary_200_10::loaded_state t
)
424 case marnav::ais::binary_200_10::loaded_state::not_available
:
425 return "not available";
426 case marnav::ais::binary_200_10::loaded_state::unloaded
:
428 case marnav::ais::binary_200_10::loaded_state::loaded
:
434 static std::string
render(const marnav::ais::rate_of_turn t
)
437 return "not available";
438 if (t
.is_not_turning())
439 return "not turning";
440 if (t
.is_more_5deg30s_right())
441 return "more 5deg/30s right";
442 if (t
.is_more_5deg30s_left())
443 return "more 5deg/30s left";
444 return fmt::sprintf("%f", t
.value());
447 static std::string
render(const marnav::ais::ship_type t
)
449 return marnav::ais::to_name(t
);
452 static std::string
render(const marnav::ais::epfd_fix_type t
)
454 return marnav::ais::to_name(t
);
457 static std::string
render(const marnav::ais::off_position_indicator t
)
459 return marnav::ais::to_name(t
);
462 static std::string
render(const marnav::ais::virtual_aid t
)
464 return marnav::ais::to_name(t
);
467 static std::string
render(const marnav::ais::aid_type_id t
)
469 return marnav::ais::to_name(t
);
472 static std::string
render(const marnav::ais::message_id t
)
474 return marnav::ais::to_name(t
);
477 static std::string
render(const marnav::ais::maneuver_indicator_id t
)
479 return marnav::ais::to_name(t
);
482 static std::string
render(const marnav::ais::data_terminal t
)
484 return marnav::ais::to_name(t
);
487 static std::string
render(const marnav::ais::navigation_status t
)
489 return marnav::ais::to_name(t
);
492 static std::string
render(const marnav::nmea::mob::mob_status t
)
495 case marnav::nmea::mob::mob_status::mob_activated
:
496 return "mob activated";
497 case marnav::nmea::mob::mob_status::test_mode
:
499 case marnav::nmea::mob::mob_status::manual_button
:
500 return "manual button";
501 case marnav::nmea::mob::mob_status::mob_not_in_use
:
502 return "mob not in use";
503 case marnav::nmea::mob::mob_status::error
:
509 static std::string
render(const marnav::nmea::mob::mob_position_source t
)
512 case marnav::nmea::mob::mob_position_source::position_estimated
:
513 return "position estimated";
514 case marnav::nmea::mob::mob_position_source::position_reported
:
515 return "position reported";
516 case marnav::nmea::mob::mob_position_source::reserved
:
518 case marnav::nmea::mob::mob_position_source::error
:
524 static std::string
render(const marnav::nmea::mob::battery_status t
)
527 case marnav::nmea::mob::battery_status::good
:
529 case marnav::nmea::mob::battery_status::low
:
531 case marnav::nmea::mob::battery_status::reserved
:
533 case marnav::nmea::mob::battery_status::error
:
539 static std::string
render(const marnav::nmea::tfi::state t
)
542 case marnav::nmea::tfi::state::off
:
544 case marnav::nmea::tfi::state::on
:
546 case marnav::nmea::tfi::state::no_answer
:
552 static std::string
render(const marnav::nmea::sentence_id t
)
554 return marnav::nmea::to_name(t
);
557 static std::string
render(const marnav::nmea::talker t
)
559 return marnav::nmea::to_name(t
);
562 static std::string
render(const marnav::nmea::unit::distance t
)
564 return marnav::nmea::to_name(t
);
567 static std::string
render(const marnav::nmea::unit::temperature t
)
569 return marnav::nmea::to_name(t
);
572 static std::string
render(const marnav::nmea::unit::velocity t
)
574 return marnav::nmea::to_name(t
);
577 static std::string
render(const marnav::nmea::side t
)
579 return marnav::nmea::to_name(t
);
582 static std::string
render(const marnav::nmea::reference t
)
584 return marnav::nmea::to_name(t
);
587 static std::string
render(const marnav::nmea::quality t
)
589 return marnav::nmea::to_name(t
);
592 static std::string
render(const marnav::nmea::direction t
)
594 return marnav::nmea::to_string(t
);
597 static std::string
render(const marnav::nmea::selection_mode t
)
599 return marnav::nmea::to_name(t
);
602 static std::string
render(const marnav::nmea::status t
)
604 return marnav::nmea::to_name(t
);
607 static std::string
render(const marnav::nmea::route t
)
609 return marnav::nmea::to_name(t
);
612 static std::string
render(const marnav::nmea::waypoint
& t
)
617 static std::string
render(const marnav::nmea::mode_indicator t
)
619 return marnav::nmea::to_name(t
);
622 static std::string
render(const std::vector
<uint8_t> & t
)
625 s
.reserve(t
.size() * 3 - 1);
626 for (auto i
= begin(t
); i
!= end(t
); ++i
)
627 s
.append(fmt::sprintf(((i
== begin(t
)) ? "%02x" : " %02x"), *i
));
631 static std::string
render(const marnav::units::nautical_miles
& t
)
633 return fmt::sprintf("%s %s", render(t
.value()), render(marnav::nmea::unit::distance::nm
));
636 static std::string
render(const marnav::units::knots
& t
)
638 return fmt::sprintf("%s %s", render(t
.value()), render(marnav::nmea::unit::velocity::knot
));
641 static std::string
render(const marnav::units::meters
& t
)
644 "%s %s", render(t
.value()), render(marnav::nmea::unit::distance::meter
));
647 static std::string
render(const marnav::units::feet
& t
)
649 return fmt::sprintf("%s %s", render(t
.value()), render(marnav::nmea::unit::distance::feet
));
652 static std::string
render(const marnav::units::meters_per_second
& t
)
654 return fmt::sprintf("%s %s", render(t
.value()), render(marnav::nmea::unit::velocity::mps
));
657 static std::string
render(const marnav::units::celsius
& t
)
660 "%s %s", render(t
.value()), render(marnav::nmea::unit::temperature::celsius
));
663 static std::string
render(const marnav::units::length
& t
)
665 // all lengths are rendered in meters by default
666 return render(t
.get
<marnav::units::meters
>());
669 static std::string
render(const marnav::units::velocity
& t
)
671 // all velocities are rendered in knots by default
672 return render(t
.get
<marnav::units::knots
>());
675 static std::string
render(const marnav::units::temperature
& t
)
677 // all temperatures are rendered in celsius by default
678 return render(t
.get
<marnav::units::celsius
>());
681 template <typename T
> static std::string
render(const marnav::utils::optional
<T
> & t
)
688 static void print(const std::string
& name
, const std::string
& value
)
690 fmt::printf("\t%-30s : %s\n", name
, value
);
693 static void print(const std::string
& title
)
695 fmt::printf("\t%s\n", title
);
698 static void print_detail_hdg(const marnav::nmea::sentence
* s
)
700 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::hdg
>(s
);
701 print("Heading", render(t
->get_heading()));
702 print("Magn Deviation",
703 fmt::sprintf("%s %s", render(t
->get_magn_dev()), render(t
->get_magn_dev_hem())));
704 print("Magn Variation",
705 fmt::sprintf("%s %s", render(t
->get_magn_var()), render(t
->get_magn_var_hem())));
708 static void print_detail_hfb(const marnav::nmea::sentence
* s
)
710 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::hfb
>(s
);
711 print("Distance Head Foot [m]", render(t
->get_distance_head_foot()));
712 print("Distance Head Bottom [m]", render(t
->get_distance_head_bottom()));
715 static void print_detail_hdm(const marnav::nmea::sentence
* s
)
717 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::hdm
>(s
);
718 print("Heading", render(t
->get_heading()));
721 static void print_detail_hdt(const marnav::nmea::sentence
* s
)
723 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::hdt
>(s
);
724 print("Heading", render(t
->get_heading()));
727 static void print_detail_hsc(const marnav::nmea::sentence
* s
)
729 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::hsc
>(s
);
730 print("Heading True", render(t
->get_heading_true()));
731 print("Heading Magnetic", render(t
->get_heading_mag()));
734 static void print_detail_its(const marnav::nmea::sentence
* s
)
736 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::its
>(s
);
737 print("Distance [m]", render(t
->get_distance()));
740 static void print_detail_lcd(const marnav::nmea::sentence
* s
)
742 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::lcd
>(s
);
743 print("GRI microseconds", render(t
->get_gri()));
744 print("Master", fmt::sprintf("SNR:%d ECD:%d", t
->get_master().snr
, t
->get_master().ecd
));
745 for (int i
= 0; i
< marnav::nmea::lcd::max_differences
; ++i
) {
746 const auto diff
= t
->get_time_diff(i
);
748 print(fmt::sprintf("Time Diff %d", i
),
749 fmt::sprintf("SNR:%d ECD:%d", diff
->snr
, diff
->ecd
));
754 static void print_detail_mob(const marnav::nmea::sentence
* s
)
756 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::mob
>(s
);
757 print("MOB Emitter ID", render(t
->get_emitter_id()));
758 print("MOB Status", render(t
->get_mob_status()));
759 print("MOB Time UTC", render(t
->get_mob_activation_utc()));
760 print("MOB Position Source", render(t
->get_mob_position_source()));
761 print("Date of Position", render(t
->get_position_date()));
762 print("Time of Position", render(t
->get_position_time()));
763 print("Latitude", render(t
->get_lat()));
764 print("Longitude", render(t
->get_lon()));
765 print("COG", render(t
->get_cog()));
766 print("SOG", render(t
->get_sog()));
767 print("MMSI", render(t
->get_mmsi()));
768 print("Battery Status", render(t
->get_battery_status()));
771 static void print_detail_msk(const marnav::nmea::sentence
* s
)
773 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::msk
>(s
);
774 print("Frequency to use", render(t
->get_frequency()));
775 print("Frequency Mode", render(t
->get_frequency_mode()));
776 print("Beacon Bit Rate", render(t
->get_bitrate()));
777 print("Beacon Mode", render(t
->get_bitrate_mode()));
778 print("Frequency for MSS message status", render(t
->get_frequency_mss_status()));
781 static void print_detail_rmb(const marnav::nmea::sentence
* s
)
783 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::rmb
>(s
);
784 print("Active", render(t
->get_active()));
785 print("Cross Track Error", render(t
->get_cross_track_error()));
786 print("Waypoint From", render(t
->get_waypoint_from()));
787 print("Waypoint To", render(t
->get_waypoint_to()));
788 print("Latitude", render(t
->get_lat()));
789 print("Longitude", render(t
->get_lon()));
790 print("Range", render(t
->get_range()));
791 print("Bearing", render(t
->get_bearing()));
792 print("Dest. Velocity", render(t
->get_dst_velocity()));
793 print("Arrival Status", render(t
->get_arrival_status()));
794 print("Mode Indicator", render(t
->get_mode_ind()));
797 static void print_detail_rmc(const marnav::nmea::sentence
* s
)
799 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::rmc
>(s
);
800 print("Time UTC", render(t
->get_time_utc()));
801 print("Status", render(t
->get_status()));
802 print("Latitude", render(t
->get_lat()));
803 print("Longitude", render(t
->get_lon()));
804 print("SOG", render(t
->get_sog()));
805 print("Heading", render(t
->get_heading()));
806 print("Date", render(t
->get_date()));
807 print("Magn Dev", fmt::sprintf("%s %s", render(t
->get_mag()), render(t
->get_mag_hem())));
808 print("Mode Ind ", render(t
->get_mode_ind()));
811 static void print_detail_rot(const marnav::nmea::sentence
* s
)
813 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::rot
>(s
);
814 print("Rate of Turn", render(t
->get_deg_per_minute()));
815 print("Status", render(t
->get_data_valid()));
818 static void print_detail_rpm(const marnav::nmea::sentence
* s
)
820 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::rpm
>(s
);
821 print("Source", render(t
->get_source()));
822 print("Source Number", render(t
->get_source_number()));
823 print("RPM", render(t
->get_revolutions()));
824 print("Propeller Pitch", render(t
->get_propeller_pitch()));
825 print("Status", render(t
->get_data_valid()));
828 static void print_detail_rsa(const marnav::nmea::sentence
* s
)
830 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::rsa
>(s
);
831 print("Starbord Angle", render(t
->get_rudder1()));
832 print("Starbord Status", render(t
->get_rudder1_valid()));
833 print("Port Angle", render(t
->get_rudder2()));
834 print("Port Status", render(t
->get_rudder2_valid()));
837 static void print_detail_rsd(const marnav::nmea::sentence
* s
)
839 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::rsd
>(s
);
840 print("Cursor Range from own ship", render(t
->get_cursor_range()));
841 print("Cursor Bearing from own ship", render(t
->get_cursor_bearing()));
842 print("Range Scale", render(t
->get_range_scale()));
843 print("Range Units", render(t
->get_range_unit()));
846 static void print_detail_vtg(const marnav::nmea::sentence
* s
)
848 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::vtg
>(s
);
849 print("Track True", render(t
->get_track_true()));
850 print("Track Magn", render(t
->get_track_magn()));
851 print("Speed Knots", render(t
->get_speed_kn()));
852 print("Speed kmh", render(t
->get_speed_kmh()));
853 print("Mode Indicator", render(t
->get_mode_ind()));
856 static void print_detail_gll(const marnav::nmea::sentence
* s
)
858 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::gll
>(s
);
859 print("Latitude", render(t
->get_lat()));
860 print("Longitude", render(t
->get_lon()));
861 print("Time UTC", render(t
->get_time_utc()));
862 print("Status", render(t
->get_data_valid()));
863 print("Mode Indicator", render(t
->get_mode_ind()));
866 static void print_detail_gns(const marnav::nmea::sentence
* s
)
868 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::gns
>(s
);
869 print("Time UTC", render(t
->get_time_utc()));
870 print("Latitude", render(t
->get_lat()));
871 print("Longitude", render(t
->get_lon()));
872 print("Mode Indicator", render(t
->get_mode_ind()));
873 print("Number of Satellites", render(t
->get_number_of_satellites()));
874 print("HDROP", render(t
->get_hdrop()));
875 print("Antenna Altitude [m]", render(t
->get_antenna_altitude()));
876 print("Geoidal Separation [m]", render(t
->get_geodial_separation()));
877 print("Age of differential Data", render(t
->get_age_of_differential_data()));
878 print("Differential Ref Station ID", render(t
->get_differential_ref_station_id()));
881 static void print_detail_grs(const marnav::nmea::sentence
* s
)
883 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::grs
>(s
);
884 print("UTC time associated with GGA", render(t
->get_time_utc()));
885 print("Status", render(t
->get_usage()));
886 for (int i
= 0; i
< marnav::nmea::grs::num_satellite_residuals
; ++i
) {
887 const auto residual
= t
->get_sat_residual(i
);
889 print(fmt::sprintf("Sat %02d Residual [m]", i
), render(*residual
));
893 static void print_detail_bec(const marnav::nmea::sentence
* s
)
895 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::bec
>(s
);
896 print("Time UTC", render(t
->get_time_utc()));
897 print("Bearing True", render(t
->get_bearing_true()));
898 print("Bearing Magn", render(t
->get_bearing_magn()));
899 print("Distance [nm]", render(t
->get_distance().get
<marnav::units::nautical_miles
>()));
900 print("Waypoint", render(t
->get_waypoint()));
903 static void print_detail_bod(const marnav::nmea::sentence
* s
)
905 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::bod
>(s
);
906 print("Bearing True", render(t
->get_bearing_true()));
907 print("Bearing Magn", render(t
->get_bearing_magn()));
908 print("Waypoint To", render(t
->get_waypoint_to()));
909 print("Waypoint From", render(t
->get_waypoint_from()));
912 static void print_detail_bwc(const marnav::nmea::sentence
* s
)
914 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::bwc
>(s
);
915 print("Time UTC", render(t
->get_time_utc()));
916 print("Bearing True", render(t
->get_bearing_true()));
917 print("Bearing Magnetic", render(t
->get_bearing_mag()));
918 print("Distance", fmt::sprintf("%s %s", render(t
->get_distance()),
919 render(marnav::nmea::unit::distance::nm
)));
920 print("Waypoint", render(t
->get_waypoint_id()));
921 print("Mode Indicator", render(t
->get_mode_ind()));
924 static void print_detail_bwr(const marnav::nmea::sentence
* s
)
926 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::bwr
>(s
);
927 print("Time UTC", render(t
->get_time_utc()));
928 print("Latitude", render(t
->get_lat()));
929 print("Longitude", render(t
->get_lon()));
930 print("Bearing True", render(t
->get_bearing_true()));
931 print("Bearing Magnetic", render(t
->get_bearing_mag()));
932 print("Distance NM", render(t
->get_distance()));
933 print("Waypoint", render(t
->get_waypoint_id()));
934 print("Mode Indicator", render(t
->get_mode_ind()));
937 static void print_detail_bww(const marnav::nmea::sentence
* s
)
939 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::bww
>(s
);
940 print("Bearing True", render(t
->get_bearing_true()));
941 print("Bearing Magnetic", render(t
->get_bearing_magn()));
942 print("Waypoint To", render(t
->get_waypoint_to()));
943 print("Waypoint From", render(t
->get_waypoint_from()));
946 static void print_detail_gsa(const marnav::nmea::sentence
* s
)
948 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::gsa
>(s
);
949 print("Selection Mode", render(t
->get_sel_mode()));
950 print("Mode", render(t
->get_mode()));
951 for (auto i
= 0; i
< marnav::nmea::gsa::max_satellite_ids
; ++i
) {
952 print(fmt::sprintf("Satellite %02u", i
), render(t
->get_satellite_id(i
)));
954 print("PDOP", render(t
->get_pdop()));
955 print("HDOP", render(t
->get_hdop()));
956 print("VDOP", render(t
->get_vdop()));
959 static void print_detail_gst(const marnav::nmea::sentence
* s
)
961 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::gst
>(s
);
962 print("Time UTC", render(t
->get_time_utc()));
963 print("Total RMS", render(t
->get_total_rms()));
964 print("Std Dev Semi-Major Axis", render(t
->get_dev_semi_major()));
965 print("Std Dev Semi-Minor Axis", render(t
->get_dev_semi_minor()));
966 print("Orientation Semi-Major Axis", render(t
->get_orientation()));
967 print("Std Dev. Latitude Error", render(t
->get_dev_lat()));
968 print("Std Dev. Longitude Error", render(t
->get_dev_lon()));
969 print("Std Dev. Altitude Error", render(t
->get_dev_alt()));
972 static void print_detail_glc(const marnav::nmea::sentence
* s
)
974 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::glc
>(s
);
975 print("GRI", render(t
->get_gri()));
976 print("Master TOA", fmt::sprintf("DIFF:%s STATUS:%s", render(t
->get_master().diff
),
977 render(t
->get_master().status
)));
978 for (int i
= 0; i
< marnav::nmea::glc::max_differences
; ++i
) {
979 const auto & td
= t
->get_time_diff(i
);
981 print(fmt::sprintf("Time Diff %d", i
),
982 fmt::sprintf("DIFF:%s STATUS:%s", render(td
->diff
), render(td
->status
)));
987 static void print_detail_gga(const marnav::nmea::sentence
* s
)
989 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::gga
>(s
);
990 print("Time", render(t
->get_time()));
991 print("Latitude", render(t
->get_lat()));
992 print("Longitude", render(t
->get_lon()));
993 print("Quality Ind", render(t
->get_quality_indicator()));
994 print("Num Satellites", render(t
->get_n_satellites()));
995 print("Horiz Dilution", render(t
->get_hor_dilution()));
996 print("Altitude", render(t
->get_altitude()));
997 print("Geodial Sep", render(t
->get_geodial_separation()));
998 print("DGPS Age", render(t
->get_dgps_age()));
999 print("DGPS Ref", render(t
->get_dgps_ref()));
1002 static void print_detail_osd(const marnav::nmea::sentence
* s
)
1004 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::osd
>(s
);
1005 print("Heading", render(t
->get_heading()));
1006 print("Status", render(t
->get_data_valid()));
1007 print("Vessel Course True", render(t
->get_course()));
1008 print("Vessel Speed",
1009 fmt::sprintf("%s %s", render(t
->get_speed()), render(t
->get_speed_unit())));
1010 print("Vessel Set", render(t
->get_vessel_set()));
1011 print("Vessel Drift",
1012 fmt::sprintf("%s %s", render(t
->get_vessel_drift()), render(t
->get_speed_unit())));
1015 static void print_detail_r00(const marnav::nmea::sentence
* s
)
1017 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::r00
>(s
);
1018 for (int i
= 0; i
< marnav::nmea::r00::max_waypoint_ids
; ++i
) {
1019 const auto & wp
= t
->get_waypoint_id(i
);
1021 print("Waypoint", render(*wp
));
1026 static void print_detail_rma(const marnav::nmea::sentence
* s
)
1028 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::rma
>(s
);
1029 print("Blink Warning", render(t
->get_blink_warning()));
1030 print("Latitude", render(t
->get_lat()));
1031 print("Longitude", render(t
->get_lon()));
1032 print("Time Diff A", render(t
->get_time_diff_a()));
1033 print("Time Diff B", render(t
->get_time_diff_b()));
1034 print("SOG [kn]", render(t
->get_sog()));
1035 print("Track made good", render(t
->get_track()));
1036 print("Magnetic Variation", fmt::sprintf("%s %s", render(t
->get_magnetic_var()),
1037 render(t
->get_magnetic_var_hem())));
1040 static void print_detail_mwv(const marnav::nmea::sentence
* s
)
1042 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::mwv
>(s
);
1043 print("Angle", fmt::sprintf("%s %s", render(t
->get_angle()), render(t
->get_angle_ref())));
1044 print("Speed", fmt::sprintf("%s %s", render(t
->get_speed()), render(t
->get_speed_unit())));
1045 print("Data Valid", render(t
->get_data_valid()));
1048 static void print_detail_gsv(const marnav::nmea::sentence
* s
)
1050 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::gsv
>(s
);
1051 print("Num Messages", render(t
->get_n_messages()));
1052 print("Messages Number", render(t
->get_message_number()));
1053 print("Num Sat in View", render(t
->get_n_satellites_in_view()));
1054 for (int i
= 0; i
< 4; ++i
) {
1055 const auto sat
= t
->get_sat(i
);
1057 print("Sat", fmt::sprintf("PRN:%02u ELEV:%02u AZIMUTH:%03u SNR:%s", sat
->prn
,
1058 sat
->elevation
, sat
->azimuth
, render(sat
->snr
)));
1063 static void print_detail_gtd(const marnav::nmea::sentence
* s
)
1065 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::gtd
>(s
);
1066 for (int i
= 0; i
< marnav::nmea::gtd::max_time_diffs
; ++i
)
1067 print(fmt::sprintf("Time Diff %d", i
), render(t
->get_time_diff(i
)));
1070 static void print_detail_zda(const marnav::nmea::sentence
* s
)
1072 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::zda
>(s
);
1073 print("Time UTC", render(t
->get_time_utc()));
1074 print("Date", render(t
->get_date()));
1075 print("Local Zone Hours", render(t
->get_local_zone_hours()));
1076 print("Local Zone Min", render(t
->get_local_zone_minutes()));
1079 static void print_detail_zdl(const marnav::nmea::sentence
* s
)
1081 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::zdl
>(s
);
1082 print("Time to Point", render(t
->get_time_to_point()));
1083 print("Distance to Point NM", render(t
->get_distance()));
1084 print("Type of Point", render(t
->get_type_point()));
1087 static void print_detail_zfo(const marnav::nmea::sentence
* s
)
1089 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::zfo
>(s
);
1090 print("Time UTC", render(t
->get_time_utc()));
1091 print("Elapsed Time", render(t
->get_time_elapsed()));
1092 print("Origin Waypoint", render(t
->get_waypoint_id()));
1095 static void print_detail_ztg(const marnav::nmea::sentence
* s
)
1097 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::ztg
>(s
);
1098 print("Time UTC", render(t
->get_time_utc()));
1099 print("Time Remaining", render(t
->get_time_remaining()));
1100 print("Destination Waypoint", render(t
->get_waypoint_id()));
1103 static void print_detail_dtm(const marnav::nmea::sentence
* s
)
1105 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::dtm
>(s
);
1106 print("Ref", render(t
->get_ref()));
1107 print("Subcode", render(t
->get_subcode()));
1108 print("Latitude Offset", render(t
->get_lat_offset()));
1109 print("Latitude Hem", render(t
->get_lat_hem()));
1110 print("Longitude Offset", render(t
->get_lon_offset()));
1111 print("Longitude Hem", render(t
->get_lon_hem()));
1112 print("Altitude", render(t
->get_altitude().get
<marnav::units::meters
>()));
1113 print("Name", render(t
->get_name()));
1116 static void print_detail_fsi(const marnav::nmea::sentence
* s
)
1118 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::fsi
>(s
);
1119 print("Tx Freuency 100 Hz", render(t
->get_tx_frequency()));
1120 print("Rx Freuency 100 Hz", render(t
->get_rx_frequency()));
1121 print("Mode of Operation", render(t
->get_communications_mode()));
1122 print("Power Level", render(t
->get_power_level()));
1123 print("Sentence Status Flag", render(t
->get_sentence_status()));
1126 static void print_detail_gbs(const marnav::nmea::sentence
* s
)
1128 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::gbs
>(s
);
1129 print("Time UTC", render(t
->get_time_utc()));
1130 print("Error Latitude", render(t
->get_err_lat().get
<marnav::units::meters
>()));
1131 print("Error Longitude", render(t
->get_err_lon().get
<marnav::units::meters
>()));
1132 print("Error Altitude", render(t
->get_err_alt().get
<marnav::units::meters
>()));
1133 print("Satellite PRN", render(t
->get_satellite()));
1134 print("Probability", render(t
->get_probability()));
1135 print("Bias", render(t
->get_bias().get
<marnav::units::meters
>()));
1136 print("Standard Deviation of bias", render(t
->get_bias_dev()));
1139 static void print_detail_aam(const marnav::nmea::sentence
* s
)
1141 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::aam
>(s
);
1142 print("Arrival Circle Entred", render(t
->get_arrival_circle_entered()));
1143 print("Perpendicular Passed", render(t
->get_perpendicualar_passed()));
1144 print("Arrival Circle Radius",
1145 render(t
->get_arrival_circle_radius().get
<marnav::units::nautical_miles
>()));
1146 print("Waypoint", render(t
->get_waypoint_id()));
1149 static void print_detail_alm(const marnav::nmea::sentence
* s
)
1151 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::alm
>(s
);
1152 print("Number of Messages", render(t
->get_number_of_messages()));
1153 print("Message Number", render(t
->get_message_number()));
1154 print("Satellite PRN", render(t
->get_satellite_prn()));
1155 print("GPS Week Number", render(t
->get_gps_week_number()));
1156 print("SV Health", render(t
->get_sv_health()));
1157 print("Eccentricity", render(t
->get_eccentricity()));
1158 print("Almanac Reference Time", render(t
->get_almanac_reference_time()));
1159 print("Inclination Angle", render(t
->get_inclination_angle()));
1160 print("Rate of right ascension", render(t
->get_rate_of_right_ascension()));
1161 print("Root of Semimajor Axis", render(t
->get_root_of_semimajor_axis()));
1162 print("Argument of perigee", render(t
->get_argument_of_perigee()));
1163 print("Longitude of ascension node", render(t
->get_longitude_of_ascension_node()));
1164 print("Mean Anomaly", render(t
->get_mean_anomaly()));
1165 print("F0 clock parameter", render(t
->get_f0_clock_parameter()));
1166 print("F1 clock parameter", render(t
->get_f1_clock_parameter()));
1169 static void print_detail_apa(const marnav::nmea::sentence
* s
)
1171 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::apa
>(s
);
1172 print("Lorac C Blink Warning", render(t
->get_loran_c_blink_warning()));
1173 print("Lorac C Cycle Lock Warning", render(t
->get_loran_c_cycle_lock_warning()));
1174 print("Magnitude of Cross Track Error", render(t
->get_cross_track_error_magnitude()));
1175 print("Direction to Steer", render(t
->get_direction_to_steer()));
1176 print("Cross Track Units", render(t
->get_cross_track_unit()));
1177 print("Status Arrival", render(t
->get_status_arrival()));
1178 print("Status Perpendicular Passed", render(t
->get_status_perpendicular_passing()));
1179 print("Bearing Origin to Dest", render(t
->get_bearing_origin_to_destination()));
1180 print("Bearing Origin to Dest Ref", render(t
->get_bearing_origin_to_destination_ref()));
1181 print("Destination Waypoint", render(t
->get_waypoint_id()));
1184 static void print_detail_rte(const marnav::nmea::sentence
* s
)
1186 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::rte
>(s
);
1187 print("Number of Messages", render(t
->get_n_messages()));
1188 print("Message Number", render(t
->get_message_number()));
1189 print("Message Mode", render(t
->get_message_mode()));
1190 for (int i
= 0; i
< marnav::nmea::rte::max_waypoints
; ++i
) {
1191 const auto wp
= t
->get_waypoint_id(i
);
1193 print(fmt::sprintf("Waypoint %i", i
), render(wp
));
1197 static void print_detail_sfi(const marnav::nmea::sentence
* s
)
1199 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::sfi
>(s
);
1200 print("Number of Messages", render(t
->get_n_messages()));
1201 print("Message Number", render(t
->get_message_number()));
1202 for (const auto & f
: t
->get_frequencies())
1203 print("Frequency [kHz]", fmt::sprintf("%s %s", render(f
.frequency
), render(f
.mode
)));
1206 static void print_detail_stn(const marnav::nmea::sentence
* s
)
1208 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::stn
>(s
);
1209 print("Number ID", render(t
->get_number()));
1212 static void print_detail_tds(const marnav::nmea::sentence
* s
)
1214 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::tds
>(s
);
1215 print("Distance [m]", render(t
->get_distance()));
1218 static void print_detail_tfi(const marnav::nmea::sentence
* s
)
1220 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::tfi
>(s
);
1221 print("Sensor #1", render(t
->get_sensor(0)));
1222 print("Sensor #2", render(t
->get_sensor(1)));
1223 print("Sensor #3", render(t
->get_sensor(2)));
1226 static void print_detail_tll(const marnav::nmea::sentence
* s
)
1228 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::tll
>(s
);
1229 print("Target Number", render(t
->get_number()));
1230 print("Latitude", render(t
->get_lat()));
1231 print("Longitude", render(t
->get_lon()));
1232 print("Target Name", render(t
->get_name()));
1233 print("Time UTC", render(t
->get_time_utc()));
1234 print("Target Status", render(t
->get_status()));
1235 print("Reference Target", render(t
->get_reference_target()));
1238 static void print_detail_tpc(const marnav::nmea::sentence
* s
)
1240 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::tpc
>(s
);
1241 print("Horiz. Range from Center Line [m]", render(t
->get_distance_centerline()));
1242 print("Horiz. dist from Transd. along [m]", render(t
->get_distance_transducer()));
1243 print("Depth [m]", render(t
->get_depth()));
1246 static void print_detail_tpr(const marnav::nmea::sentence
* s
)
1248 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::tpr
>(s
);
1249 print("Horizontal Range [m]", render(t
->get_range()));
1250 print("Bearing to Target to Vessel", render(t
->get_bearing()));
1251 print("Depth [m]", render(t
->get_depth()));
1254 static void print_detail_tpt(const marnav::nmea::sentence
* s
)
1256 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::tpt
>(s
);
1257 print("Horizontal Range [m]", render(t
->get_range()));
1258 print("Bearing to Target True", render(t
->get_bearing()));
1259 print("Depth [m]", render(t
->get_depth()));
1262 static void print_detail_ttm(const marnav::nmea::sentence
* s
)
1264 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::ttm
>(s
);
1265 print("Target Number", render(t
->get_target_number()));
1266 print("Target Distance", render(t
->get_target_distance()));
1267 print("Bearing from own ship", render(t
->get_bearing_from_ownship()));
1268 print("Bearing from own ship Ref", render(t
->get_bearing_from_ownship_ref()));
1269 print("Target Speed", render(t
->get_target_speed()));
1270 print("Target Course", render(t
->get_target_course()));
1271 print("Target Course Ref", render(t
->get_target_course_ref()));
1272 print("CPA", render(t
->get_distance_cpa()));
1273 print("TCPA", render(t
->get_tcpa()));
1274 print("Unknown", render(t
->get_unknown()));
1275 print("Target Name", render(t
->get_target_name()));
1276 print("Target Status", render(t
->get_target_status()));
1277 print("Reference Target", render(t
->get_reference_target()));
1280 static void print_detail_vbw(const marnav::nmea::sentence
* s
)
1282 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::vbw
>(s
);
1283 print("Longitudinal Water Speed", render(t
->get_water_speed_longitudinal()));
1284 print("Transverse Water Speed", render(t
->get_water_speed_transveral()));
1285 print("Status", render(t
->get_water_speed_status()));
1286 print("Longitudinal Ground Speed", render(t
->get_ground_speed_longitudinal()));
1287 print("Transverse Ground Speed", render(t
->get_ground_speed_transveral()));
1288 print("Status", render(t
->get_ground_speed_status()));
1291 static void print_detail_vdr(const marnav::nmea::sentence
* s
)
1293 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::vdr
>(s
);
1294 print("Degrees True", render(t
->get_degrees_true()));
1295 print("Degrees Magnetic", render(t
->get_degrees_magn()));
1296 print("Speed of Current", render(t
->get_speed()));
1299 static void print_detail_mss(const marnav::nmea::sentence
* s
)
1301 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::mss
>(s
);
1302 print("Signal Strength [dB 1uV]", render(t
->get_signal_strength()));
1303 print("Signal to Noise Ratio (dB)", render(t
->get_signal_to_noise_ratio()));
1304 print("Beacon Frequency [kHz]", render(t
->get_beacon_frequency()));
1305 print("Beacon Data Rate BPS", render(t
->get_beacon_datarate()));
1306 print("unknown", render(t
->get_unknown()));
1309 static void print_detail_mtw(const marnav::nmea::sentence
* s
)
1311 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::mtw
>(s
);
1312 print("Water Temperature", render(t
->get_temperature()));
1315 static void print_detail_mwd(const marnav::nmea::sentence
* s
)
1317 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::mwd
>(s
);
1318 print("Direction True", render(t
->get_direction_true()));
1319 print("Direction Magnetic", render(t
->get_direction_mag()));
1320 print("Speed kn", render(t
->get_speed_kn()));
1321 print("Speed m/s", render(t
->get_speed_ms()));
1324 static void print_detail_dbt(const marnav::nmea::sentence
* s
)
1326 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::dbt
>(s
);
1327 print("Depth Feet", render(t
->get_depth_feet()));
1328 print("Depth Meter", render(t
->get_depth_meter()));
1329 print("Depth Fathom", render(t
->get_depth_fathom()));
1332 static void print_detail_dpt(const marnav::nmea::sentence
* s
)
1334 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::dpt
>(s
);
1335 print("Depth", render(t
->get_depth_meter().get
<marnav::units::meters
>()));
1336 print("Offset from Transducer",
1337 render(t
->get_transducer_offset().get
<marnav::units::meters
>()));
1338 print("Max Depth", render(t
->get_max_depth()));
1341 static void print_detail_apb(const marnav::nmea::sentence
* s
)
1343 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::apb
>(s
);
1344 print("Loran C blink warn", render(t
->get_loran_c_blink_warning()));
1345 print("Loran C cycle lock warn", render(t
->get_loran_c_cycle_lock_warning()));
1346 print("Cross Track Error Magnitude", render(t
->get_cross_track_error_magnitude()));
1347 print("Direction to Steer", render(t
->get_direction_to_steer()));
1348 print("Cross Track Unit", render(t
->get_cross_track_unit()));
1349 print("Status Arrival", render(t
->get_status_arrival()));
1350 print("Status Perpendicular Pass", render(t
->get_status_perpendicular_passing()));
1351 print("Bearing Org to Dest", render(t
->get_bearing_origin_to_destination()));
1352 print("Bearing Org to Dest Ref", render(t
->get_bearing_origin_to_destination_ref()));
1353 print("Waypoint", render(t
->get_waypoint_id()));
1354 print("Bearing Pos to Dest", render(t
->get_bearing_pos_to_destination()));
1355 print("Bearing Pos to Dest Ref", render(t
->get_bearing_pos_to_destination_ref()));
1356 print("Heading to Steer to Dest", render(t
->get_heading_to_steer_to_destination()));
1357 print("Heading to Steer to Dest Ref", render(t
->get_heading_to_steer_to_destination_ref()));
1358 print("Mode Indicator", render(t
->get_mode_ind()));
1361 static void print_detail_pgrme(const marnav::nmea::sentence
* s
)
1363 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::pgrme
>(s
);
1364 print("HPE", render(t
->get_horizontal_position_error()));
1365 print("VPE", render(t
->get_vertical_position_error()));
1366 print("O.sph.eq.pos err", render(t
->get_overall_spherical_equiv_position_error()));
1369 static void print_detail_pgrmm(const marnav::nmea::sentence
* s
)
1371 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::pgrmm
>(s
);
1372 print("Map Datum", render(t
->get_map_datum()));
1375 static void print_detail_pgrmz(const marnav::nmea::sentence
* s
)
1377 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::pgrmz
>(s
);
1378 print("Altitude", render(t
->get_altitude()));
1379 print("Fix Type", render(t
->get_fix()));
1382 static void print_detail_stalk(const marnav::nmea::sentence
* s
)
1384 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::stalk
>(s
);
1385 print("Data", render(t
->get_data()));
1388 static void print_detail_vwr(const marnav::nmea::sentence
* s
)
1390 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::vwr
>(s
);
1391 print("Angle", fmt::sprintf("%s %s", render(t
->get_angle()), render(t
->get_angle_side())));
1392 print("Speed kn", render(t
->get_speed_knots()));
1393 print("Speed m/s", render(t
->get_speed_mps()));
1394 print("Speed km/h", render(t
->get_speed_kmh()));
1397 static void print_detail_wcv(const marnav::nmea::sentence
* s
)
1399 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::wcv
>(s
);
1400 print("Speed kn", render(t
->get_speed()));
1401 print("Waypoint", render(t
->get_waypoint_id()));
1404 static void print_detail_wnc(const marnav::nmea::sentence
* s
)
1406 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::wnc
>(s
);
1407 print("Distnace NM", render(t
->get_distance_nm()));
1408 print("Distnace km", render(t
->get_distance_km()));
1409 print("Waypoint To", render(t
->get_waypoint_to()));
1410 print("Waypoint From", render(t
->get_waypoint_from()));
1413 static void print_detail_wpl(const marnav::nmea::sentence
* s
)
1415 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::wpl
>(s
);
1416 print("Latitude", render(t
->get_lat()));
1417 print("Longitude", render(t
->get_lon()));
1418 print("Waypoint", render(t
->get_waypoint_id()));
1421 static void print_detail_xdr(const marnav::nmea::sentence
* s
)
1423 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::xdr
>(s
);
1424 for (auto i
= 0; i
< marnav::nmea::xdr::max_transducer_info
; ++i
) {
1425 const auto info
= t
->get_info(i
);
1427 print("Transducer Info",
1428 fmt::sprintf("Type:%c Data:%f Unit:%c Name:%s", info
->transducer_type
,
1429 info
->measurement_data
, info
->units_of_measurement
, info
->name
));
1434 static void print_detail_xte(const marnav::nmea::sentence
* s
)
1436 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::xte
>(s
);
1437 print("Status 1", render(t
->get_status1()));
1438 print("Status 2", render(t
->get_status2()));
1439 print("Cross Track Error Magnitude", render(t
->get_cross_track_error_magnitude()));
1440 print("Direction to Steer", render(t
->get_direction_to_steer()));
1441 print("Mode Indicator", render(t
->get_mode_ind()));
1444 static void print_detail_xtr(const marnav::nmea::sentence
* s
)
1446 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::xtr
>(s
);
1447 print("Cross Track Error Magnitude", render(t
->get_cross_track_error_magnitude()));
1448 print("Direction to Steer", render(t
->get_direction_to_steer()));
1451 static void print_detail_vlw(const marnav::nmea::sentence
* s
)
1453 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::vlw
>(s
);
1454 print("Distance Cumulative NM", render(t
->get_distance_cum()));
1455 print("Distance since Rest NM", render(t
->get_distance_reset()));
1458 static void print_detail_vpw(const marnav::nmea::sentence
* s
)
1460 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::vpw
>(s
);
1461 print("Speed kn", render(t
->get_speed_knots()));
1462 print("Speed m/s", render(t
->get_speed_meters_per_second()));
1465 static void print_detail_vhw(const marnav::nmea::sentence
* s
)
1467 const auto t
= marnav::nmea::sentence_cast
<marnav::nmea::vhw
>(s
);
1468 print("Heading True", render(t
->get_heading_true()));
1469 print("Heading Magn", render(t
->get_heading_magn()));
1470 print("Speed kn", render(t
->get_speed_knots()));
1471 print("Speed km/h", render(t
->get_speed_kmh()));
1474 static void print_detail_message_01_common(const marnav::ais::message_01
* t
)
1476 print("Repeat Indicator", render(t
->get_repeat_indicator()));
1477 print("MMSI", render(t
->get_mmsi()));
1478 print("Nav Status", render(t
->get_nav_status()));
1479 print("ROT", render(t
->get_rot()));
1480 print("SOG", render(t
->get_sog()));
1481 print("Pos Accuracy", render(t
->get_position_accuracy()));
1482 print("Latitude", render(t
->get_lat()));
1483 print("Longitude", render(t
->get_lon()));
1484 print("COG", render(t
->get_cog()));
1485 print("HDG", render(t
->get_hdg()));
1486 print("Time Stamp", render(t
->get_timestamp()));
1487 print("Maneuver Indicator", render(t
->get_maneuver_indicator()));
1488 print("RAIM", render(t
->get_raim()));
1489 print("Radio Status", render(t
->get_radio_status()));
1492 static void print_detail_message_01(const marnav::ais::message
* m
)
1494 print_detail_message_01_common(marnav::ais::message_cast
<marnav::ais::message_01
>(m
));
1497 static void print_detail_message_02(const marnav::ais::message
* m
)
1499 print_detail_message_01_common(marnav::ais::message_cast
<marnav::ais::message_02
>(m
));
1502 static void print_detail_message_03(const marnav::ais::message
* m
)
1504 print_detail_message_01_common(marnav::ais::message_cast
<marnav::ais::message_03
>(m
));
1507 static void print_detail_message_04_common(const marnav::ais::message_04
* t
)
1509 print("Repeat Indicator", render(t
->get_repeat_indicator()));
1510 print("MMSI", render(t
->get_mmsi()));
1511 print("Year", render(t
->get_year()));
1512 print("Month", render(t
->get_month()));
1513 print("Day", render(t
->get_day()));
1514 print("Hour", render(t
->get_hour()));
1515 print("Minute", render(t
->get_minute()));
1516 print("Second", render(t
->get_second()));
1517 print("Pos Accuracy", render(t
->get_position_accuracy()));
1518 print("Latitude", render(t
->get_lat()));
1519 print("Longitude", render(t
->get_lon()));
1520 print("EPFD Fix", render(t
->get_epfd_fix()));
1521 print("RAIM", render(t
->get_raim()));
1522 print("Radio Status", render(t
->get_radio_status()));
1525 static void print_detail_message_04(const marnav::ais::message
* m
)
1527 print_detail_message_04_common(marnav::ais::message_cast
<marnav::ais::message_04
>(m
));
1530 static void print_detail_message_11(const marnav::ais::message
* m
)
1532 print_detail_message_04_common(marnav::ais::message_cast
<marnav::ais::message_11
>(m
));
1535 static void print_detail_message_12(const marnav::ais::message
* m
)
1537 const auto t
= marnav::ais::message_cast
<marnav::ais::message_12
>(m
);
1538 print("Repeat Indicator", render(t
->get_repeat_indicator()));
1539 print("MMSI", render(t
->get_mmsi()));
1540 print("Seqence Number", render(t
->get_seqno()));
1541 print("Destination MMSI", render(t
->get_dest_mmsi()));
1542 print("Retransmit", render(t
->get_retransmit()));
1543 print("Text", render(t
->get_text()));
1546 static void print_detail_message_13(const marnav::ais::message
* m
)
1548 const auto t
= marnav::ais::message_cast
<marnav::ais::message_13
>(m
);
1549 print("Repeat Indicator", render(t
->get_repeat_indicator()));
1550 print("MMSI", render(t
->get_mmsi()));
1551 print("MMSI_1", render(t
->get_mmsi_1()));
1552 print("MMSI_2", render(t
->get_mmsi_2()));
1553 print("MMSI_3", render(t
->get_mmsi_3()));
1554 print("MMSI_4", render(t
->get_mmsi_4()));
1557 static void print_detail_message_14(const marnav::ais::message
* m
)
1559 const auto t
= marnav::ais::message_cast
<marnav::ais::message_14
>(m
);
1560 print("Repeat Indicator", render(t
->get_repeat_indicator()));
1561 print("MMSI", render(t
->get_mmsi()));
1562 print("Text", render(t
->get_text()));
1565 static void print_detail_message_05(const marnav::ais::message
* m
)
1567 const auto t
= marnav::ais::message_cast
<marnav::ais::message_05
>(m
);
1568 print("Repeat Indicator", render(t
->get_repeat_indicator()));
1569 print("MMSI", render(t
->get_mmsi()));
1570 print("AIS Version", render(t
->get_ais_version()));
1571 print("IMO", render(t
->get_imo_number()));
1572 print("Callsign", render(t
->get_callsign()));
1573 print("Shipname", render(t
->get_shipname()));
1574 print("Shiptype", render(t
->get_shiptype()));
1575 print("Length", render(t
->get_vessel_dimension().length()));
1576 print("Width", render(t
->get_vessel_dimension().width()));
1577 print("Draught", render(t
->get_draught()));
1578 print("EPFD Fix", render(t
->get_epfd_fix()));
1579 print("ETA Month", render(t
->get_eta_month()));
1580 print("ETA Day", render(t
->get_eta_day()));
1581 print("ETA Hour", render(t
->get_eta_hour()));
1582 print("ETA Minute", render(t
->get_eta_minute()));
1583 print("Destination", render(t
->get_destination()));
1584 print("DTE", render(t
->get_dte()));
1587 static void print_detail_message_06(const marnav::ais::message
* m
)
1589 const auto t
= marnav::ais::message_cast
<marnav::ais::message_06
>(m
);
1590 print("Repeat Indicator", render(t
->get_repeat_indicator()));
1591 print("MMSI", render(t
->get_mmsi()));
1592 print("Sequence No", render(t
->get_sequnce_no()));
1593 print("Destination MMSI", render(t
->get_dest_mmsi()));
1594 print("Retransmit Flag", render(t
->get_retransmit_flag()));
1595 print("DAC", render(t
->get_dac()));
1596 print("FID", render(t
->get_fid()));
1598 fmt::printf("\n\twarning: message 06: decoding of payload not implemented: %03d/%02d\n",
1599 t
->get_dac(), t
->get_fid());
1602 static void print_detail_message_07(const marnav::ais::message
* m
)
1604 const auto t
= marnav::ais::message_cast
<marnav::ais::message_07
>(m
);
1605 print("Repeat Indicator", render(t
->get_repeat_indicator()));
1606 print("MMSI", render(t
->get_mmsi()));
1607 print("MMSI_1", render(t
->get_mmsi_1()));
1608 print("MMSI_2", render(t
->get_mmsi_2()));
1609 print("MMSI_3", render(t
->get_mmsi_3()));
1610 print("MMSI_4", render(t
->get_mmsi_4()));
1613 static void print_detail_message_08(const marnav::ais::message
* m
)
1615 const auto t
= marnav::ais::message_cast
<marnav::ais::message_08
>(m
);
1616 print("Repeat Indicator", render(t
->get_repeat_indicator()));
1617 print("MMSI", render(t
->get_mmsi()));
1618 print("DAC", render(t
->get_dac()));
1619 print("FID", render(t
->get_fid()));
1621 if (t
->get_dac() == 1 && t
->get_fid() == 11) {
1622 marnav::ais::binary_001_11 b
;
1625 print("Meteological and Hydrological Data (001/11) IMO236");
1626 print("Position", render(b
.get_position()));
1627 print("Day", render(b
.get_day()));
1628 print("Hour", render(b
.get_hour()));
1629 print("Minute", render(b
.get_minute()));
1630 print("Wind Speed 10min avg [kn]", render(b
.get_wind_speed_avg()));
1631 print("Wind Gust [kn]", render(b
.get_wind_gust()));
1632 print("Wind Direction", render(b
.get_wind_direction()));
1633 print("Wind Gust Direction", render(b
.get_wind_gust_direction()));
1634 print("Temperature [C]", render(b
.get_temperature()));
1635 print("Humidity [%]", render(b
.get_humidity()));
1636 print("Dew Point [%]", render(b
.get_dew_point()));
1637 print("Air Pressure [hPa]", render(b
.get_pressure()));
1638 print("Air Pressure Trend", render(b
.get_pressure_trend()));
1639 print("Visibility [NM]", render(b
.get_visibility()));
1640 print("Water Level [m]", render(b
.get_water_level()));
1641 print("Water Level Trend", render(b
.get_water_level_trend()));
1642 print("Sufrace Current Speed [kn]", render(b
.get_surface_current_speed()));
1643 print("Sufrace Current Direction", render(b
.get_surface_current_direction()));
1644 print("Current 2 Speed [kn]", render(b
.get_current_2_speed()));
1645 print("Current 2 Direction", render(b
.get_current_2_direction()));
1646 print("Current 2 Depth [m]", render(b
.get_current_2_depth()));
1647 print("Current 3 Speed [kn]", render(b
.get_current_3_speed()));
1648 print("Current 3 Direction", render(b
.get_current_3_direction()));
1649 print("Current 3 Depth [m]", render(b
.get_current_3_depth()));
1650 print("Wave Height [m]", render(b
.get_wave_height()));
1651 print("Wave Period [s]", render(b
.get_wave_period()));
1652 print("Wave Direction", render(b
.get_wave_direction()));
1653 print("Swell Height [m]", render(b
.get_swell_height()));
1654 print("Swell Period [s]", render(b
.get_swell_period()));
1655 print("Swell Direction", render(b
.get_swell_direction()));
1656 print("Sea State", render(b
.get_sea_state()));
1657 print("Water Temperature [C]", render(b
.get_water_temperature()));
1658 print("Precipitation", render(b
.get_precipitation()));
1659 print("Salinity [%]", render(b
.get_salinity()));
1660 print("Ice", render(b
.get_ice()));
1661 } else if (t
->get_dac() == 200 && t
->get_fid() == 10) {
1662 marnav::ais::binary_200_10 b
;
1665 print("Inland ship static and voyage related data (200/10)");
1666 print("Vessel ID", render(b
.get_vessel_id()));
1667 print("Length [m]", render(b
.get_length()));
1668 print("Beam [m]", render(b
.get_beam()));
1669 print("Shiptype", render(b
.get_shiptype()));
1670 print("Hazard", render(b
.get_hazard()));
1671 print("Draught [m]", render(b
.get_draught()));
1672 print("Loaded", render(b
.get_loaded()));
1673 print("Speed quality", render(b
.get_speed_q()));
1674 print("Course quality", render(b
.get_course_q()));
1675 print("Heading quality", render(b
.get_heading_q()));
1677 fmt::printf("\n\twarning: message 08: decoding of payload not implemented: %03d/%02d\n",
1678 t
->get_dac(), t
->get_fid());
1682 static void print_detail_message_09(const marnav::ais::message
* m
)
1684 const auto t
= marnav::ais::message_cast
<marnav::ais::message_09
>(m
);
1685 print("Repeat Indicator", render(t
->get_repeat_indicator()));
1686 print("MMSI", render(t
->get_mmsi()));
1687 print("Altitude", render(t
->get_altitude()));
1688 print("Speed", render(t
->get_speed()));
1689 print("Pos Accuracy", render(t
->get_position_accuracy()));
1690 print("COG", render(t
->get_course()));
1691 print("UTC Second", render(t
->get_utc_second()));
1692 print("DTE", render(t
->get_dte()));
1693 print("RAIM", render(t
->get_raim()));
1694 print("Radio Status", render(t
->get_radio_status()));
1697 static void print_detail_message_10(const marnav::ais::message
* m
)
1699 const auto t
= marnav::ais::message_cast
<marnav::ais::message_10
>(m
);
1700 print("Repeat Indicator", render(t
->get_repeat_indicator()));
1701 print("MMSI", render(t
->get_mmsi()));
1702 print("Destination MMSI", render(t
->get_dest_mmsi()));
1705 static void print_detail_message_17(const marnav::ais::message
* m
)
1707 const auto t
= marnav::ais::message_cast
<marnav::ais::message_17
>(m
);
1708 print("Repeat Indicator", render(t
->get_repeat_indicator()));
1709 print("MMSI", render(t
->get_mmsi()));
1710 print("Latitude", render(t
->get_lat()));
1711 print("Longitude", render(t
->get_lon()));
1713 // TODO: print payload as hex string
1716 static void print_detail_message_18(const marnav::ais::message
* m
)
1718 const auto t
= marnav::ais::message_cast
<marnav::ais::message_18
>(m
);
1719 print("Repeat Indicator", render(t
->get_repeat_indicator()));
1720 print("MMSI", render(t
->get_mmsi()));
1721 print("SOG", render(t
->get_sog()));
1722 print("Pos Accuracy", render(t
->get_position_accuracy()));
1723 print("Latitude", render(t
->get_lat()));
1724 print("Longitude", render(t
->get_lon()));
1725 print("COG", render(t
->get_cog()));
1726 print("HDG", render(t
->get_hdg()));
1727 print("Time Stamp", render(t
->get_timestamp()));
1728 print("CS Unit", render(t
->get_cs_unit()));
1729 print("Display Flag", render(t
->get_display_flag()));
1730 print("DSC Flag", render(t
->get_dsc_flag()));
1731 print("Band Flag", render(t
->get_band_flag()));
1732 print("Message 22 Flag", render(t
->get_message_22_flag()));
1733 print("Assigned", render(t
->get_assigned()));
1734 print("RAIM", render(t
->get_raim()));
1735 print("Radio Status", render(t
->get_radio_status()));
1738 static void print_detail_message_19(const marnav::ais::message
* m
)
1740 const auto t
= marnav::ais::message_cast
<marnav::ais::message_19
>(m
);
1741 print("Repeat Indicator", render(t
->get_repeat_indicator()));
1742 print("MMSI", render(t
->get_mmsi()));
1743 print("SOG", render(t
->get_sog()));
1744 print("Pos Accuracy", render(t
->get_position_accuracy()));
1745 print("Latitude", render(t
->get_lat()));
1746 print("Longitude", render(t
->get_lon()));
1747 print("COG", render(t
->get_cog()));
1748 print("HDG", render(t
->get_hdg()));
1749 print("Time Stamp", render(t
->get_timestamp()));
1750 print("Ship Name", render(t
->get_shipname()));
1751 print("Ship Type", render(t
->get_shiptype()));
1752 print("Length", render(t
->get_vessel_dimension().length()));
1753 print("Width", render(t
->get_vessel_dimension().width()));
1754 print("EPFD Fix", render(t
->get_epfd_fix()));
1755 print("RAIM", render(t
->get_raim()));
1756 print("DTE", render(t
->get_dte()));
1757 print("Assigned", render(t
->get_assigned()));
1760 static void print_detail_message_20(const marnav::ais::message
* m
)
1762 const auto t
= marnav::ais::message_cast
<marnav::ais::message_20
>(m
);
1763 print("Repeat Indicator", render(t
->get_repeat_indicator()));
1764 print("MMSI", render(t
->get_mmsi()));
1765 for (int i
= 0; i
< 3; ++i
) {
1766 const auto entry
= t
->get_entry(i
);
1767 print(fmt::sprintf("Entry %d", i
+ 1),
1768 fmt::sprintf("Offset:%4u Slots:%1u Timeout:%1u Increment:%4u", entry
.offset
,
1769 entry
.slots
, entry
.timeout
, entry
.increment
));
1773 static void print_detail_message_21(const marnav::ais::message
* m
)
1775 const auto t
= marnav::ais::message_cast
<marnav::ais::message_21
>(m
);
1776 print("Repeat Indicator", render(t
->get_repeat_indicator()));
1777 print("MMSI", render(t
->get_mmsi()));
1778 print("Aid Type", render(t
->get_aid_type()));
1779 print("Name", render(t
->get_name()));
1780 print("Pos Accuracy", render(t
->get_position_accuracy()));
1781 print("Latitude", render(t
->get_lat()));
1782 print("Longitude", render(t
->get_lon()));
1783 print("Length", render(t
->get_vessel_dimension().length()));
1784 print("Width", render(t
->get_vessel_dimension().width()));
1785 print("EPFD Fix", render(t
->get_epfd_fix()));
1786 print("UTC Second", render(t
->get_utc_second()));
1787 print("Off Pos Indicator", render(t
->get_off_position()));
1788 print("Regional", render(t
->get_regional()));
1789 print("RAIM", render(t
->get_raim()));
1790 print("Virtual Aid Flag", render(t
->get_virtual_aid_flag()));
1791 print("Assigned", render(t
->get_assigned()));
1792 print("Name Extension", render(t
->get_name_extension()));
1795 static void print_detail_message_22(const marnav::ais::message
* m
)
1797 const auto t
= marnav::ais::message_cast
<marnav::ais::message_22
>(m
);
1798 print("Repeat Indicator", render(t
->get_repeat_indicator()));
1799 print("MMSI", render(t
->get_mmsi()));
1800 print("Channel A", render(t
->get_channel_a()));
1801 print("Channel B", render(t
->get_channel_b()));
1802 print("TxRx Mode", render(t
->get_txrx_mode()));
1803 print("Power", render(t
->get_power()));
1804 print("Adressed", render(t
->get_addressed()));
1805 if (t
->get_addressed()) {
1806 print("MMSI 1", render(t
->get_mmsi_1()));
1807 print("MMSI 2", render(t
->get_mmsi_2()));
1809 print("Position NE", render(t
->get_position_ne()));
1810 print("Position SW", render(t
->get_position_sw()));
1814 static void print_detail_message_23(const marnav::ais::message
* m
)
1816 const auto t
= marnav::ais::message_cast
<marnav::ais::message_23
>(m
);
1817 print("Repeat Indicator", render(t
->get_repeat_indicator()));
1818 print("MMSI", render(t
->get_mmsi()));
1819 print("Position NE", render(t
->get_position_ne()));
1820 print("Position SW", render(t
->get_position_sw()));
1821 print("Station Type", render(t
->get_station_type()));
1822 print("Ship Type", render(t
->get_shiptype()));
1823 print("TxRx Mode", render(t
->get_txrx_mode()));
1824 print("Report Interval", render(t
->get_interval()));
1825 print("Quiet Time", render(t
->get_quiet_time()));
1828 static void print_detail_message_24(const marnav::ais::message
* m
)
1830 const auto t
= marnav::ais::message_cast
<marnav::ais::message_24
>(m
);
1831 print("Repeat Indicator", render(t
->get_repeat_indicator()));
1832 print("MMSI", render(t
->get_mmsi()));
1833 print("Part", render(t
->get_part_number()));
1834 if (t
->get_part_number() == marnav::ais::message_24::part::A
) {
1835 print("Ship Name", render(t
->get_shipname()));
1837 print("Ship Type", render(t
->get_shiptype()));
1838 print("Vendor ID", render(t
->get_vendor_id()));
1839 print("Model", render(t
->get_model()));
1840 print("Serial", render(t
->get_serial()));
1841 print("Callsign", render(t
->get_callsign()));
1842 if (t
->is_auxiliary_vessel()) {
1843 print("Mothership MMSI", render(t
->get_mothership_mmsi()));
1845 print("Length", render(t
->get_vessel_dimension().length()));
1846 print("Width", render(t
->get_vessel_dimension().width()));
1853 static void dump_nmea(const std::string
& line
)
1855 #define ADD_SENTENCE(s) \
1857 marnav::nmea::s::ID, detail::print_detail_##s \
1860 marnav::nmea::sentence_id id
;
1861 std::function
<void(const marnav::nmea::sentence
*)> func
;
1863 using container
= std::vector
<entry
>;
1865 static const container sentences
= {
1941 ADD_SENTENCE(pgrme
),
1942 ADD_SENTENCE(pgrmm
),
1943 ADD_SENTENCE(pgrmz
),
1949 using namespace marnav
;
1952 auto s
= nmea::make_sentence(line
);
1953 auto i
= std::find_if(std::begin(sentences
), std::end(sentences
),
1954 [&s
](const container::value_type
& item
) { return item
.id
== s
->id(); });
1955 if (i
== std::end(sentences
)) {
1956 fmt::printf("\t%s\n", detail::render(s
->id()));
1958 "%s%s%s\n\tnot implemented\n\n", terminal::magenta
, line
, terminal::normal
);
1960 fmt::printf("%s%s%s\n", terminal::green
, line
, terminal::normal
);
1961 fmt::printf("\tName : %s\n", detail::render(s
->id()));
1962 fmt::printf("\tTalker: %s\n", detail::render(s
->get_talker()));
1966 } catch (nmea::unknown_sentence
& error
) {
1967 fmt::printf("%s%s%s\n\terror: unknown sentence: %s\n\n", terminal::red
, line
,
1968 terminal::normal
, error
.what());
1969 } catch (nmea::checksum_error
& error
) {
1970 fmt::printf("%s%s%s\n\terror: checksum error: %s\n\n", terminal::red
, line
,
1971 terminal::normal
, error
.what());
1972 } catch (std::invalid_argument
& error
) {
1974 "%s%s%s\n\terror: %s\n\n", terminal::red
, line
, terminal::normal
, error
.what());
1978 static void dump_ais(const std::vector
<std::unique_ptr
<marnav::nmea::sentence
>> & sentences
)
1980 #define ADD_MESSAGE(m) \
1982 marnav::ais::m::ID, detail::print_detail_##m \
1985 marnav::ais::message_id id
;
1986 std::function
<void(const marnav::ais::message
*)> func
;
1988 using container
= std::vector
<entry
>;
1990 static const container messages
= {
1991 ADD_MESSAGE(message_01
),
1992 ADD_MESSAGE(message_02
),
1993 ADD_MESSAGE(message_03
),
1994 ADD_MESSAGE(message_04
),
1995 ADD_MESSAGE(message_05
),
1996 ADD_MESSAGE(message_06
),
1997 ADD_MESSAGE(message_07
),
1998 ADD_MESSAGE(message_08
),
1999 ADD_MESSAGE(message_09
),
2000 ADD_MESSAGE(message_10
),
2001 ADD_MESSAGE(message_11
),
2002 ADD_MESSAGE(message_12
),
2003 ADD_MESSAGE(message_13
),
2004 ADD_MESSAGE(message_14
),
2005 ADD_MESSAGE(message_17
),
2006 ADD_MESSAGE(message_18
),
2007 ADD_MESSAGE(message_19
),
2008 ADD_MESSAGE(message_20
),
2009 ADD_MESSAGE(message_21
),
2010 ADD_MESSAGE(message_22
),
2011 ADD_MESSAGE(message_23
),
2012 ADD_MESSAGE(message_24
)
2017 using namespace marnav
;
2020 auto m
= ais::make_message(nmea::collect_payload(sentences
.begin(), sentences
.end()));
2021 auto i
= std::find_if(std::begin(messages
), std::end(messages
),
2022 [&m
](const container::value_type
& item
) { return item
.id
== m
->type(); });
2023 if (i
== std::end(messages
)) {
2024 fmt::printf("\t%s\n", detail::render(m
->type()));
2025 fmt::printf("%smessage_%02u%s\n\tnot implemented\n\n", terminal::magenta
,
2026 static_cast<uint8_t>(m
->type()), terminal::normal
);
2028 fmt::printf("\t%s\n", detail::render(m
->type()));
2032 } catch (std::exception
& error
) {
2033 fmt::printf("\t%serror:%s %s\n\n", terminal::red
, terminal::normal
, error
.what());
2037 static void process(std::function
<bool(std::string
&)> source
)
2039 using namespace marnav
;
2042 std::vector
<std::unique_ptr
<nmea::sentence
>> sentences
;
2044 while (source(line
)) {
2051 if (line
[0] == nmea::sentence::start_token
) {
2053 } else if (line
[0] == nmea::sentence::start_token_ais
) {
2054 fmt::printf("%s%s%s\n", terminal::blue
, line
, terminal::normal
);
2055 auto s
= nmea::make_sentence(line
);
2057 nmea::vdm
* v
= nullptr; // VDM is the common denominator for AIS relevant messages
2059 if (s
->id() == nmea::sentence_id::VDO
) {
2060 v
= nmea::sentence_cast
<nmea::vdo
>(s
.get());
2061 } else if (s
->id() == nmea::sentence_id::VDM
) {
2062 v
= nmea::sentence_cast
<nmea::vdm
>(s
.get());
2064 // something strange happened, no VDM nor VDO
2065 fmt::printf("%s%s%s\n\terror: ignoring AIS sentence, dropping collection.\n\n",
2066 terminal::red
, line
, terminal::normal
);
2071 // check sentences if a discontuniation has occurred
2072 if (sentences
.size() && (sentences
.back()->id() != v
->id())) {
2073 sentences
.clear(); // there was a discontinuation, start over collecting
2075 "\t%swarning:%s dropping collection.\n", terminal::cyan
, terminal::normal
);
2078 // check if a previous message was not complete
2079 const auto n_fragments
= v
->get_n_fragments();
2080 const auto fragment
= v
->get_fragment();
2081 if (sentences
.size() >= fragment
) {
2084 "\t%swarning:%s dropping collection.\n", terminal::cyan
, terminal::normal
);
2087 sentences
.push_back(std::move(s
));
2088 if (fragment
== n_fragments
) {
2089 dump_ais(sentences
);
2093 fmt::printf("%s%s%s\n\terror: ignoring AIS sentence.\n\n", terminal::red
, line
,
2100 int main(int argc
, char ** argv
)
2102 using namespace nmeadump
;
2104 if (parse_options(argc
, argv
))
2105 return EXIT_SUCCESS
;
2107 if (!global
.config
.file
.empty()) {
2108 std::ifstream ifs
{global
.config
.file
.c_str()};
2109 process([&](std::string
& line
) { return !!std::getline(ifs
, line
); });
2110 } else if (!global
.config
.port
.empty()) {
2111 using namespace marnav
;
2112 using namespace marnav::io
;
2113 default_nmea_reader source
{
2114 utils::make_unique
<serial
>(global
.config
.port
, global
.config
.speed
,
2115 serial::databits::bit_8
, serial::stopbits::bit_1
, serial::parity::none
)};
2116 process([&](std::string
& line
) { return source
.read_sentence(line
); });
2117 } else if (!global
.config
.input_string
.empty()) {
2118 std::istringstream
is(global
.config
.input_string
);
2119 process([&](std::string
& line
){ return !!std::getline(is
, line
); });
2121 std::cin
.sync_with_stdio(false);
2122 process([&](std::string
& line
) { return !!std::getline(std::cin
, line
); });
2125 return EXIT_SUCCESS
;