1 #include <marnav/nmea/rmb.hpp>
3 #include <marnav/nmea/io.hpp>
10 constexpr sentence_id
rmb::ID
;
11 constexpr const char * rmb::TAG
;
14 : sentence(ID
, TAG
, talker::global_positioning_system
)
18 rmb::rmb(talker talk
, fields::const_iterator first
, fields::const_iterator last
)
19 : sentence(ID
, TAG
, talk
)
21 // before and after NMEA 2.3
22 const auto size
= std::distance(first
, last
);
23 if ((size
< 13) || (size
> 14))
24 throw std::invalid_argument
{"invalid number of fields in rmb"};
26 read(*(first
+ 0), active_
);
27 read(*(first
+ 1), cross_track_error_
);
28 read(*(first
+ 2), steer_dir_
);
29 read(*(first
+ 3), waypoint_to_
);
30 read(*(first
+ 4), waypoint_from_
);
31 read(*(first
+ 5), lat_
);
32 read(*(first
+ 6), lat_hem_
);
33 read(*(first
+ 7), lon_
);
34 read(*(first
+ 8), lon_hem_
);
35 read(*(first
+ 9), range_
);
36 read(*(first
+ 10), bearing_
);
37 read(*(first
+ 11), dst_velocity_
);
38 read(*(first
+ 12), arrival_status_
);
42 read(*(first
+ 13), mode_ind_
);
44 // instead of reading data into temporary lat/lon, let's correct values afterwards
45 lat_
= correct_hemisphere(lat_
, lat_hem_
);
46 lon_
= correct_hemisphere(lon_
, lon_hem_
);
49 utils::optional
<geo::longitude
> rmb::get_lon() const
51 return (lon_
&& lon_hem_
) ? lon_
: utils::optional
<geo::longitude
>{};
54 utils::optional
<geo::latitude
> rmb::get_lat() const
56 return (lat_
&& lat_hem_
) ? lat_
: utils::optional
<geo::latitude
>{};
59 void rmb::set_lat(const geo::latitude
& t
)
62 lat_hem_
= convert_hemisphere(t
);
65 void rmb::set_lon(const geo::longitude
& t
)
68 lon_hem_
= convert_hemisphere(t
);
71 utils::optional
<units::velocity
> rmb::get_dst_velocity() const
75 return {*dst_velocity_
};
78 void rmb::set_dst_velocity(units::velocity t
)
81 throw std::invalid_argument
{"invalid argument, destination velocity less than zero"};
82 dst_velocity_
= t
.get
<units::knots
>();
85 utils::optional
<units::length
> rmb::get_range() const
92 void rmb::set_range(units::length t
)
95 throw std::invalid_argument
{"invalid argument, range less than zero"};
96 range_
= t
.get
<units::nautical_miles
>();
99 utils::optional
<units::length
> rmb::get_cross_track_error() const
101 if (!cross_track_error_
)
103 return {*cross_track_error_
};
106 void rmb::set_cross_track_error(units::length t
)
109 throw std::invalid_argument
{"invalid argument, cross track error less than zero"};
110 cross_track_error_
= t
.get
<units::nautical_miles
>();
113 void rmb::append_data_to(std::string
& s
) const
115 append(s
, to_string(active_
));
116 append(s
, to_string(cross_track_error_
));
117 append(s
, to_string(steer_dir_
));
118 append(s
, to_string(waypoint_to_
));
119 append(s
, to_string(waypoint_from_
));
120 append(s
, to_string(lat_
));
121 append(s
, to_string(lat_hem_
));
122 append(s
, to_string(lon_
));
123 append(s
, to_string(lon_hem_
));
124 append(s
, to_string(range_
));
125 append(s
, to_string(bearing_
));
126 append(s
, to_string(dst_velocity_
));
127 append(s
, to_string(arrival_status_
));
128 append(s
, to_string(mode_ind_
));