1 #include <marnav/nmea/mob.hpp>
2 #include <marnav/nmea/io.hpp>
13 static mob::mob_status
mob_status_mapping(
14 typename
std::underlying_type
<mob::mob_status
>::type value
)
18 return mob::mob_status::mob_activated
;
20 return mob::mob_status::test_mode
;
22 return mob::mob_status::manual_button
;
24 return mob::mob_status::mob_not_in_use
;
26 return mob::mob_status::error
;
28 throw std::invalid_argument
{"invaild value for conversion to mob::mob_status"};
31 static mob::mob_position_source
mob_position_source_mapping(
32 typename
std::underlying_type
<mob::mob_position_source
>::type value
)
36 return mob::mob_position_source::position_estimated
;
38 return mob::mob_position_source::position_reported
;
43 return mob::mob_position_source::reserved
;
45 return mob::mob_position_source::error
;
47 throw std::invalid_argument
{"invaild value for conversion to mob::mob_position_source"};
50 static mob::battery_status
battery_status_mapping(
51 typename
std::underlying_type
<mob::battery_status
>::type value
)
55 return mob::battery_status::good
;
57 return mob::battery_status::low
;
62 return mob::battery_status::reserved
;
64 return mob::battery_status::error
;
66 throw std::invalid_argument
{"invaild value for conversion to mob::battery_status"};
70 std::string
to_string(mob::mob_status value
)
73 case mob::mob_status::mob_activated
:
75 case mob::mob_status::test_mode
:
77 case mob::mob_status::manual_button
:
79 case mob::mob_status::mob_not_in_use
:
81 case mob::mob_status::error
:
84 throw std::invalid_argument
{"invaild value for conversion of mob::mob_status"};
87 std::string
to_string(mob::mob_position_source value
)
90 case mob::mob_position_source::position_estimated
:
92 case mob::mob_position_source::position_reported
:
94 case mob::mob_position_source::reserved
:
96 case mob::mob_position_source::error
:
99 throw std::invalid_argument
{"invaild value for conversion of mob::mob_position_source"};
102 std::string
to_string(mob::battery_status value
)
105 case mob::battery_status::good
:
107 case mob::battery_status::low
:
109 case mob::battery_status::reserved
:
111 case mob::battery_status::error
:
114 throw std::invalid_argument
{"invaild value for conversion of mob::battery_status"};
117 constexpr sentence_id
mob::ID
;
118 constexpr const char * mob::TAG
;
121 : sentence(ID
, TAG
, talker::integrated_navigation
)
125 mob::mob(talker talk
, fields::const_iterator first
, fields::const_iterator last
)
126 : sentence(ID
, TAG
, talk
)
128 if (std::distance(first
, last
) != 14)
129 throw std::invalid_argument
{"invalid number of fields in mob"};
131 read(*(first
+ 0), emitter_id_
);
132 read(*(first
+ 1), mob_status_
, mob_status_mapping
);
133 read(*(first
+ 2), mob_activation_utc_
);
134 read(*(first
+ 3), mob_position_source_
, mob_position_source_mapping
);
135 read(*(first
+ 4), position_date_
);
136 read(*(first
+ 5), position_utc_
);
137 read(*(first
+ 6), lat_
);
138 read(*(first
+ 7), lat_hem_
);
139 read(*(first
+ 8), lon_
);
140 read(*(first
+ 9), lon_hem_
);
141 read(*(first
+ 10), cog_
);
142 read(*(first
+ 11), sog_
);
143 read(*(first
+ 12), mmsi_
);
144 read(*(first
+ 13), battery_status_
, battery_status_mapping
);
146 // instead of reading data into temporary lat/lon, let's correct values afterwards
147 lat_
= correct_hemisphere(lat_
, lat_hem_
);
148 lon_
= correct_hemisphere(lon_
, lon_hem_
);
151 void mob::append_data_to(std::string
& s
) const
153 append(s
, to_string(emitter_id_
));
154 append(s
, to_string(mob_status_
));
155 append(s
, to_string(mob_activation_utc_
));
156 append(s
, to_string(mob_position_source_
));
157 append(s
, to_string(position_date_
));
158 append(s
, to_string(position_utc_
));
159 append(s
, to_string(lat_
));
160 append(s
, to_string(lat_hem_
));
161 append(s
, to_string(lon_
));
162 append(s
, to_string(lon_hem_
));
163 append(s
, to_string(cog_
));
164 append(s
, to_string(sog_
));
165 append(s
, format(mmsi_
, 9));
166 append(s
, to_string(battery_status_
));
169 geo::latitude
mob::get_lat() const
174 geo::longitude
mob::get_lon() const
179 utils::mmsi
mob::get_mmsi() const
181 return utils::mmsi
{static_cast<utils::mmsi::value_type
>(mmsi_
)};
184 void mob::set_emitter_id(const std::string
& t
)
191 if (t
.size() > emitter_id_max
)
192 throw std::invalid_argument("emitter id max 5 digits");
193 if (t
.find_first_not_of("0123456789abcdefABCDEF") != std::string::npos
)
194 throw std::invalid_argument("emitter id only hex digits allowed");
196 emitter_id_
= std::string(emitter_id_max
, '0');
197 std::transform(begin(t
), end(t
), next(begin(*emitter_id_
), emitter_id_max
- t
.size()),
198 [](std::string::value_type c
) -> std::string::value_type
{ return std::toupper(c
); });
201 void mob::set_lat(const geo::latitude
& t
)
204 lat_hem_
= convert_hemisphere(t
);
207 void mob::set_lon(const geo::longitude
& t
)
210 lon_hem_
= convert_hemisphere(t
);
213 void mob::set_mmsi(const utils::mmsi
& t
)