23 #ifndef MOOS_TRANSLATOR_H 24 #define MOOS_TRANSLATOR_H 26 #include "goby/moos/moos_header.h" 27 #include "moos_geodesy.h" 32 #include "goby/moos/modem_id_convert.h" 34 #include "goby/moos/protobuf/translator.pb.h" 35 #include "goby/moos/transitional/message_algorithms.h" 36 #include "goby/util/dynamic_protobuf_manager.h" 42 void alg_power_to_dB(transitional::DCCLMessageVal& val_to_mod);
43 void alg_dB_to_power(transitional::DCCLMessageVal& val_to_mod);
46 void alg_TSD_to_soundspeed(transitional::DCCLMessageVal& val,
47 const std::vector<transitional::DCCLMessageVal>& ref_vals);
50 void alg_subtract(transitional::DCCLMessageVal& val,
51 const std::vector<transitional::DCCLMessageVal>& ref_vals);
54 void alg_add(transitional::DCCLMessageVal& val,
55 const std::vector<transitional::DCCLMessageVal>& ref_vals);
57 void alg_angle_0_360(transitional::DCCLMessageVal& angle);
58 void alg_angle_n180_180(transitional::DCCLMessageVal& angle);
60 void alg_to_upper(transitional::DCCLMessageVal& val_to_mod);
61 void alg_to_lower(transitional::DCCLMessageVal& val_to_mod);
63 void alg_abs(transitional::DCCLMessageVal& val_to_mod);
64 void alg_lat2hemisphere_initial(transitional::DCCLMessageVal& val_to_mod);
65 void alg_lon2hemisphere_initial(transitional::DCCLMessageVal& val_to_mod);
67 void alg_unix_time2nmea_time(transitional::DCCLMessageVal& val_to_mod);
69 void alg_lat2nmea_lat(transitional::DCCLMessageVal& val_to_mod);
70 void alg_lon2nmea_lon(transitional::DCCLMessageVal& val_to_mod);
77 double lat_origin = std::numeric_limits<double>::quiet_NaN(),
78 double lon_origin = std::numeric_limits<double>::quiet_NaN(),
79 const std::string& modem_id_lookup_path =
"")
81 initialize(lat_origin, lon_origin, modem_id_lookup_path);
82 if (entry.IsInitialized())
87 const google::protobuf::RepeatedPtrField<goby::moos::protobuf::TranslatorEntry>& entries,
88 double lat_origin = std::numeric_limits<double>::quiet_NaN(),
89 double lon_origin = std::numeric_limits<double>::quiet_NaN(),
90 const std::string& modem_id_lookup_path =
"")
92 initialize(lat_origin, lon_origin, modem_id_lookup_path);
96 void clear_entry(
const std::string& protobuf_name) { dictionary_.erase(protobuf_name); }
100 if (dictionary_.count(entry.protobuf_name()))
101 throw(std::runtime_error(
"Duplicate translator entry for " + entry.protobuf_name()));
102 dictionary_[entry.protobuf_name()] = entry;
105 void add_entry(
const std::set<goby::moos::protobuf::TranslatorEntry>& entries)
107 for (std::set<goby::moos::protobuf::TranslatorEntry>::const_iterator it = entries.begin(),
110 { add_entry(*it); } }
113 const google::protobuf::RepeatedPtrField<goby::moos::protobuf::TranslatorEntry>& entries)
115 for (google::protobuf::RepeatedPtrField<
119 { add_entry(*it); } }
122 template <
typename GoogleProtobufMessagePo
inter,
class StringCMOOSMsgMap>
123 GoogleProtobufMessagePointer moos_to_protobuf(
const StringCMOOSMsgMap& moos_variables,
124 const std::string& protobuf_name);
126 std::multimap<std::string, CMOOSMsg>
130 std::multimap<std::string, CMOOSMsg>
133 const std::map<std::string, goby::moos::protobuf::TranslatorEntry>& dictionary()
const 139 make_moos_msg(
const std::string& var,
const std::string& str,
bool is_binary,
140 goby::moos::protobuf::TranslatorEntry::ParserSerializerTechnique technique,
141 const std::string& pb_name)
145 CMOOSMsg moos_msg(MOOS_NOTIFY, var, str.size(), str.data());
146 moos_msg.SetSourceAux(
148 goby::moos::protobuf::TranslatorEntry::ParserSerializerTechnique_Name(technique));
155 double return_double = boost::lexical_cast<
double>(str);
156 return CMOOSMsg(MOOS_NOTIFY, var, return_double);
158 catch (boost::bad_lexical_cast&)
160 CMOOSMsg moos_msg(MOOS_NOTIFY, var, str);
161 moos_msg.SetSourceAux(
163 goby::moos::protobuf::TranslatorEntry::ParserSerializerTechnique_Name(
171 void initialize(
double lat_origin = std::numeric_limits<double>::quiet_NaN(),
172 double lon_origin = std::numeric_limits<double>::quiet_NaN(),
173 const std::string& modem_id_lookup_path =
"");
176 const std::vector<transitional::DCCLMessageVal>& ref_vals);
179 const std::vector<transitional::DCCLMessageVal>& ref_vals);
182 const std::vector<transitional::DCCLMessageVal>& ref_vals);
185 const std::vector<transitional::DCCLMessageVal>& ref_vals);
192 std::map<std::string, goby::moos::protobuf::TranslatorEntry> dictionary_;
197 inline std::ostream& operator<<(std::ostream& os,
const MOOSTranslator& tl)
199 os <<
"= Begin MOOSTranslator =\n";
202 for (std::map<std::string, goby::moos::protobuf::TranslatorEntry>::const_iterator
203 it = tl.dictionary().begin(),
204 n = tl.dictionary().end();
207 os <<
"== Begin Entry " << i <<
" ==\n" 208 << it->second.DebugString() <<
"== End Entry " << i <<
" ==\n";
213 os <<
"= End MOOSTranslator =";
221 return a.protobuf_name() < b.protobuf_name();
228 inline std::multimap<std::string, CMOOSMsg>
231 std::map<std::string, goby::moos::protobuf::TranslatorEntry>::const_iterator it =
232 dictionary_.find(protobuf_msg.GetDescriptor()->full_name());
234 const std::string& pb_name = protobuf_msg.GetDescriptor()->full_name();
236 if (it == dictionary_.end())
237 throw(std::runtime_error(
"No TranslatorEntry for Protobuf type: " + pb_name));
241 std::multimap<std::string, CMOOSMsg> moos_msgs;
243 bool is_binary =
false;
245 for (
int i = 0, n = entry.publish_size(); i < n; ++i)
247 std::string return_string;
248 std::string moos_var = entry.publish(i).moos_var();
250 switch (entry.publish(i).technique())
252 case protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_TEXT_FORMAT:
254 protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_TEXT_FORMAT>::
255 serialize(&return_string, protobuf_msg);
258 case protobuf::TranslatorEntry::TECHNIQUE_PREFIXED_PROTOBUF_TEXT_FORMAT:
260 protobuf::TranslatorEntry::TECHNIQUE_PREFIXED_PROTOBUF_TEXT_FORMAT>::
261 serialize(&return_string, protobuf_msg);
264 case protobuf::TranslatorEntry::TECHNIQUE_PREFIXED_PROTOBUF_NATIVE_HEX:
266 protobuf::TranslatorEntry::TECHNIQUE_PREFIXED_PROTOBUF_NATIVE_HEX>::
267 serialize(&return_string, protobuf_msg);
270 case protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_NATIVE_HEX:
272 protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_NATIVE_HEX>::
273 serialize(&return_string, protobuf_msg);
276 case protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_NATIVE_ENCODED:
278 protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_NATIVE_ENCODED>::
279 serialize(&return_string, protobuf_msg);
283 case protobuf::TranslatorEntry::TECHNIQUE_PREFIXED_PROTOBUF_NATIVE_ENCODED:
285 protobuf::TranslatorEntry::TECHNIQUE_PREFIXED_PROTOBUF_NATIVE_ENCODED>::
286 serialize(&return_string, protobuf_msg);
290 case protobuf::TranslatorEntry::TECHNIQUE_COMMA_SEPARATED_KEY_EQUALS_VALUE_PAIRS:
292 protobuf::TranslatorEntry::TECHNIQUE_COMMA_SEPARATED_KEY_EQUALS_VALUE_PAIRS>::
293 serialize(&return_string, protobuf_msg, entry.publish(i).algorithm(),
294 entry.use_short_enum());
297 case protobuf::TranslatorEntry::TECHNIQUE_FORMAT:
300 &moos_var, protobuf_msg, entry.publish(i).algorithm(),
301 entry.publish(i).moos_var(), entry.publish(i).repeated_delimiter(),
302 entry.use_short_enum());
305 &return_string, protobuf_msg, entry.publish(i).algorithm(),
306 entry.publish(i).format(), entry.publish(i).repeated_delimiter(),
307 entry.use_short_enum());
312 std::make_pair(moos_var, make_moos_msg(moos_var, return_string, is_binary,
313 entry.publish(i).technique(), pb_name)));
319 inline std::multimap<std::string, CMOOSMsg>
322 std::map<std::string, goby::moos::protobuf::TranslatorEntry>::const_iterator it =
323 dictionary_.find(protobuf_msg.GetDescriptor()->full_name());
325 const std::string& pb_name = protobuf_msg.GetDescriptor()->full_name();
327 if (it == dictionary_.end())
328 throw(std::runtime_error(
"No TranslatorEntry for Protobuf type: " + pb_name));
332 std::multimap<std::string, CMOOSMsg> moos_msgs;
334 bool is_binary =
false;
336 for (
int i = 0, n = entry.create_size(); i < n; ++i)
338 std::string return_string;
339 std::string moos_var = entry.create(i).moos_var();
341 switch (entry.create(i).technique())
343 case protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_TEXT_FORMAT:
345 goby::moos::protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_TEXT_FORMAT>::
346 serialize(&return_string, protobuf_msg);
349 case protobuf::TranslatorEntry::TECHNIQUE_PREFIXED_PROTOBUF_TEXT_FORMAT:
351 goby::moos::protobuf::TranslatorEntry::
352 TECHNIQUE_PREFIXED_PROTOBUF_TEXT_FORMAT>::serialize(&return_string,
356 case protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_NATIVE_HEX:
358 goby::moos::protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_NATIVE_HEX>::
359 serialize(&return_string, protobuf_msg);
362 case protobuf::TranslatorEntry::TECHNIQUE_PREFIXED_PROTOBUF_NATIVE_HEX:
364 goby::moos::protobuf::TranslatorEntry::TECHNIQUE_PREFIXED_PROTOBUF_NATIVE_HEX>::
365 serialize(&return_string, protobuf_msg);
368 case protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_NATIVE_ENCODED:
370 goby::moos::protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_NATIVE_ENCODED>::
371 serialize(&return_string, protobuf_msg);
375 case protobuf::TranslatorEntry::TECHNIQUE_PREFIXED_PROTOBUF_NATIVE_ENCODED:
377 goby::moos::protobuf::TranslatorEntry::
378 TECHNIQUE_PREFIXED_PROTOBUF_NATIVE_ENCODED>::serialize(&return_string,
383 case protobuf::TranslatorEntry::TECHNIQUE_COMMA_SEPARATED_KEY_EQUALS_VALUE_PAIRS:
386 google::protobuf::RepeatedPtrField<
391 protobuf::TranslatorEntry::TECHNIQUE_COMMA_SEPARATED_KEY_EQUALS_VALUE_PAIRS>::
392 serialize(&return_string, protobuf_msg, empty_algorithms,
393 entry.use_short_enum());
397 case protobuf::TranslatorEntry::TECHNIQUE_FORMAT:
399 google::protobuf::RepeatedPtrField<
404 &return_string, protobuf_msg, empty_algorithms, entry.create(i).format(),
405 entry.create(i).repeated_delimiter(), entry.use_short_enum());
411 std::make_pair(moos_var, make_moos_msg(moos_var, return_string, is_binary,
412 entry.create(i).technique(), pb_name)));
415 if (entry.trigger().type() == protobuf::TranslatorEntry::Trigger::TRIGGER_PUBLISH)
417 if (moos_msgs.count(entry.trigger().moos_var()))
420 typedef std::multimap<std::string, CMOOSMsg>::iterator It;
421 std::pair<It, It> p = moos_msgs.equal_range(entry.trigger().moos_var());
422 for (It it = p.first; it != p.second; ++it) it->second.m_dfTime = MOOSTime();
427 moos_msgs.insert(std::make_pair(entry.trigger().moos_var(),
428 CMOOSMsg(MOOS_NOTIFY, entry.trigger().moos_var(),
"")));
435 template <
typename GoogleProtobufMessagePo
inter,
class StringCMOOSMsgMap>
436 GoogleProtobufMessagePointer
437 goby::moos::MOOSTranslator::moos_to_protobuf(
const StringCMOOSMsgMap& moos_variables,
438 const std::string& protobuf_name)
440 std::map<std::string, goby::moos::protobuf::TranslatorEntry>::const_iterator it =
441 dictionary_.find(protobuf_name);
443 if (it == dictionary_.end())
444 throw(std::runtime_error(
"No TranslatorEntry for Protobuf type: " + protobuf_name));
448 GoogleProtobufMessagePointer msg =
449 goby::util::DynamicProtobufManager::new_protobuf_message<GoogleProtobufMessagePointer>(
453 throw(std::runtime_error(
"Unknown Protobuf type: " + protobuf_name +
454 "; be sure it is compiled in or directly loaded into the " 455 "goby::util::DynamicProtobufManager."));
457 for (
int i = 0, n = entry.create_size(); i < n; ++i)
459 std::multimap<std::string, CMOOSMsg>::const_iterator it =
460 moos_variables.find(entry.create(i).moos_var());
461 std::string source_string =
462 (it == moos_variables.end())
464 : (it->second.IsString() ? it->second.GetString()
465 : goby::util::as<std::string>(it->second.GetDouble()));
467 switch (entry.create(i).technique())
469 case protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_TEXT_FORMAT:
471 protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_TEXT_FORMAT>::parse(source_string,
475 case protobuf::TranslatorEntry::TECHNIQUE_PREFIXED_PROTOBUF_TEXT_FORMAT:
477 protobuf::TranslatorEntry::TECHNIQUE_PREFIXED_PROTOBUF_TEXT_FORMAT>::
478 parse(source_string, &*msg);
481 case protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_NATIVE_HEX:
483 protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_NATIVE_HEX>::parse(source_string,
487 case protobuf::TranslatorEntry::TECHNIQUE_PREFIXED_PROTOBUF_NATIVE_HEX:
489 protobuf::TranslatorEntry::TECHNIQUE_PREFIXED_PROTOBUF_NATIVE_HEX>::
490 parse(source_string, &*msg);
493 case protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_NATIVE_ENCODED:
495 protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_NATIVE_ENCODED>::
496 parse(source_string, &*msg);
499 case protobuf::TranslatorEntry::TECHNIQUE_PREFIXED_PROTOBUF_NATIVE_ENCODED:
501 protobuf::TranslatorEntry::TECHNIQUE_PREFIXED_PROTOBUF_NATIVE_ENCODED>::
502 parse(source_string, &*msg);
505 case protobuf::TranslatorEntry::TECHNIQUE_COMMA_SEPARATED_KEY_EQUALS_VALUE_PAIRS:
507 protobuf::TranslatorEntry::TECHNIQUE_COMMA_SEPARATED_KEY_EQUALS_VALUE_PAIRS>::
508 parse(source_string, &*msg, entry.create(i).algorithm(),
509 entry.use_short_enum());
512 case protobuf::TranslatorEntry::TECHNIQUE_FORMAT:
514 source_string, &*msg, entry.create(i).format(),
515 entry.create(i).repeated_delimiter(), entry.create(i).algorithm(),
516 entry.use_short_enum());
Helpers for MOOS applications for serializing and parsed Google Protocol buffers messages.
The global namespace for the Goby project.