1 #include <marnav/ais/message_01.hpp>
2 #include <marnav/ais/angle.hpp>
7 constexpr message_id
message_01::ID
;
8 constexpr std::size_t message_01::SIZE_BITS
;
10 message_01::message_01()
15 message_01::message_01(message_id id
)
20 message_01::message_01(const raw
& bits
)
23 if (bits
.size() != SIZE_BITS
)
24 throw std::invalid_argument
{"invalid number of bits in ais/message_01"};
28 std::optional
<geo::longitude
> message_01::get_lon() const
30 if (longitude_minutes_
== longitude_not_available
)
31 return std::make_optional
<geo::longitude
>();
32 return to_geo_longitude(longitude_minutes_
, longitude_minutes_
.count
, angle_scale::I4
);
35 std::optional
<geo::latitude
> message_01::get_lat() const
37 if (latitude_minutes_
== latitude_not_available
)
38 return std::make_optional
<geo::latitude
>();
39 return to_geo_latitude(latitude_minutes_
, latitude_minutes_
.count
, angle_scale::I4
);
42 void message_01::set_lon_unavailable()
44 longitude_minutes_
= longitude_not_available
;
47 void message_01::set_lat_unavailable()
49 latitude_minutes_
= latitude_not_available
;
52 void message_01::set_lon(const geo::longitude
& t
)
54 longitude_minutes_
= to_longitude_minutes(t
, longitude_minutes_
.count
, angle_scale::I4
);
57 void message_01::set_lat(const geo::latitude
& t
)
59 latitude_minutes_
= to_latitude_minutes(t
, latitude_minutes_
.count
, angle_scale::I4
);
62 std::optional
<units::knots
> message_01::get_sog() const noexcept
64 // ignores special value of 1022 = 102.2 knots or faster
66 if (sog_
== sog_not_available
)
68 return units::knots
{0.1 * sog_
};
71 void message_01::set_sog_unavailable()
73 sog_
= sog_not_available
;
76 void message_01::set_sog(units::velocity t
)
79 throw std::invalid_argument
{"SOG less than zero"};
81 const auto v
= t
.get
<units::knots
>();
82 sog_
= std::min(sog_max
, static_cast<uint32_t>(round(v
* 10).value()));
85 /// Returns course over ground in degrees true north.
86 std::optional
<double> message_01::get_cog() const noexcept
88 if (cog_
== cog_not_available
)
93 void message_01::set_cog(std::optional
<double> t
) noexcept
95 cog_
= !t
? cog_not_available
: static_cast<uint32_t>(std::round(*t
/ 0.1));
98 /// Returns heading in degrees.
99 std::optional
<uint32_t> message_01::get_hdg() const noexcept
101 if (hdg_
== hdg_not_available
)
106 void message_01::set_hdg(std::optional
<uint32_t> t
) noexcept
108 hdg_
= !t
? hdg_not_available
: *t
;
111 rate_of_turn
message_01::get_rot() const noexcept
113 return rate_of_turn(rot_
);
116 void message_01::set_rot(rate_of_turn t
) noexcept
121 void message_01::read_data(const raw
& bits
)
123 get(bits
, repeat_indicator_
);
125 get(bits
, nav_status_
);
128 get(bits
, position_accuracy_
);
129 get(bits
, longitude_minutes_
);
130 get(bits
, latitude_minutes_
);
133 get(bits
, timestamp_
);
134 get(bits
, maneuver_indicator_
);
136 get(bits
, radio_status_
);
139 raw
message_01::get_data() const
143 bits
.set(type(), 0, 6);
144 set(bits
, repeat_indicator_
);
146 set(bits
, nav_status_
);
149 set(bits
, position_accuracy_
);
150 set(bits
, longitude_minutes_
);
151 set(bits
, latitude_minutes_
);
154 set(bits
, timestamp_
);
155 set(bits
, maneuver_indicator_
);
157 set(bits
, radio_status_
);