25 #ifndef GOBY_MOOS_MOOS_TRANSLATOR_H
26 #define GOBY_MOOS_MOOS_TRANSLATOR_H
38 #include <MOOS/libMOOS/Comms/MOOSMsg.h>
39 #include <MOOS/libMOOS/Utils/MOOSUtilityFunctions.h>
40 #include <boost/lexical_cast.hpp>
41 #include <boost/lexical_cast/bad_lexical_cast.hpp>
42 #include <google/protobuf/descriptor.h>
45 #include "dccl/dynamic_protobuf_manager.h"
56 namespace transitional
66 const std::vector<moos::transitional::DCCLMessageVal>& ref_vals);
70 const std::vector<moos::transitional::DCCLMessageVal>& ref_vals);
74 const std::vector<moos::transitional::DCCLMessageVal>& ref_vals);
95 goby::moos::protobuf::TranslatorEntry(),
96 double lat_origin = std::numeric_limits<double>::quiet_NaN(),
97 double lon_origin = std::numeric_limits<double>::quiet_NaN(),
98 const std::string& modem_id_lookup_path =
"")
100 initialize(lat_origin, lon_origin, modem_id_lookup_path);
101 if (entry.IsInitialized())
107 double lat_origin = std::numeric_limits<double>::quiet_NaN(),
108 double lon_origin = std::numeric_limits<double>::quiet_NaN(),
109 const std::string& modem_id_lookup_path =
"")
111 initialize(lat_origin, lon_origin, modem_id_lookup_path);
115 void clear_entry(
const std::string& protobuf_name) { dictionary_.erase(protobuf_name); }
117 void add_entry(
const goby::moos::protobuf::TranslatorEntry& entry)
119 if (dictionary_.count(entry.protobuf_name()))
120 throw(std::runtime_error(
"Duplicate translator entry for " + entry.protobuf_name()));
121 dictionary_[entry.protobuf_name()] = entry;
124 void add_entry(
const std::set<goby::moos::protobuf::TranslatorEntry>& entries)
126 for (
const auto& entry : entries) {
add_entry(entry); }
132 for (
const auto& entry : entries) {
add_entry(entry); }
136 template <
typename GoogleProtobufMessagePo
inter,
class StringCMOOSMsgMap>
137 GoogleProtobufMessagePointer
moos_to_protobuf(
const StringCMOOSMsgMap& moos_variables,
138 const std::string& protobuf_name);
140 std::multimap<std::string, CMOOSMsg>
144 std::multimap<std::string, CMOOSMsg>
147 const std::map<std::string, goby::moos::protobuf::TranslatorEntry>&
dictionary()
const
154 goby::moos::protobuf::TranslatorEntry::ParserSerializerTechnique technique,
155 const std::string& pb_name)
159 CMOOSMsg moos_msg(MOOS_NOTIFY, var,
str.size(),
str.data());
160 moos_msg.SetSourceAux(
162 goby::moos::protobuf::TranslatorEntry::ParserSerializerTechnique_Name(technique));
169 auto return_double = boost::lexical_cast<double>(
str);
170 return CMOOSMsg(MOOS_NOTIFY, var, return_double);
172 catch (boost::bad_lexical_cast&)
174 CMOOSMsg moos_msg(MOOS_NOTIFY, var,
str);
175 moos_msg.SetSourceAux(
177 goby::moos::protobuf::TranslatorEntry::ParserSerializerTechnique_Name(
187 void initialize(
double lat_origin = std::numeric_limits<double>::quiet_NaN(),
188 double lon_origin = std::numeric_limits<double>::quiet_NaN(),
189 const std::string& modem_id_lookup_path =
"");
192 const std::vector<moos::transitional::DCCLMessageVal>& ref_vals);
195 const std::vector<moos::transitional::DCCLMessageVal>& ref_vals);
198 const std::vector<moos::transitional::DCCLMessageVal>& ref_vals);
201 const std::vector<moos::transitional::DCCLMessageVal>& ref_vals);
208 std::map<std::string, goby::moos::protobuf::TranslatorEntry> dictionary_;
215 os <<
"= Begin MOOSTranslator =\n";
220 os <<
"== Begin Entry " << i <<
" ==\n"
221 << it.second.DebugString() <<
"== End Entry " << i <<
" ==\n";
226 os <<
"= End MOOSTranslator =";
232 inline bool operator<(
const protobuf::TranslatorEntry& a,
const protobuf::TranslatorEntry& b)
234 return a.protobuf_name() < b.protobuf_name();
241 inline std::multimap<std::string, CMOOSMsg>
244 std::map<std::string, goby::moos::protobuf::TranslatorEntry>::const_iterator it =
247 const std::string& pb_name = protobuf_msg.
GetDescriptor()->full_name();
249 if (it == dictionary_.end())
250 throw(std::runtime_error(
"No TranslatorEntry for Protobuf type: " + pb_name));
252 const goby::moos::protobuf::TranslatorEntry& entry = it->second;
254 std::multimap<std::string, CMOOSMsg> moos_msgs;
256 bool is_binary =
false;
258 for (
int i = 0, n = entry.publish_size(); i < n; ++i)
260 std::string return_string;
261 std::string moos_var = entry.publish(i).moos_var();
263 switch (entry.publish(i).technique())
265 case protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_TEXT_FORMAT:
267 protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_TEXT_FORMAT>::
268 serialize(&return_string, protobuf_msg);
271 case protobuf::TranslatorEntry::TECHNIQUE_PREFIXED_PROTOBUF_TEXT_FORMAT:
273 protobuf::TranslatorEntry::TECHNIQUE_PREFIXED_PROTOBUF_TEXT_FORMAT>::
274 serialize(&return_string, protobuf_msg);
277 case protobuf::TranslatorEntry::TECHNIQUE_PREFIXED_PROTOBUF_NATIVE_HEX:
279 protobuf::TranslatorEntry::TECHNIQUE_PREFIXED_PROTOBUF_NATIVE_HEX>::
280 serialize(&return_string, protobuf_msg);
283 case protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_NATIVE_HEX:
285 protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_NATIVE_HEX>::
286 serialize(&return_string, protobuf_msg);
289 case protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_NATIVE_ENCODED:
291 protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_NATIVE_ENCODED>::
292 serialize(&return_string, protobuf_msg);
296 case protobuf::TranslatorEntry::TECHNIQUE_PREFIXED_PROTOBUF_NATIVE_ENCODED:
298 protobuf::TranslatorEntry::TECHNIQUE_PREFIXED_PROTOBUF_NATIVE_ENCODED>::
299 serialize(&return_string, protobuf_msg);
303 case protobuf::TranslatorEntry::TECHNIQUE_COMMA_SEPARATED_KEY_EQUALS_VALUE_PAIRS:
305 protobuf::TranslatorEntry::TECHNIQUE_COMMA_SEPARATED_KEY_EQUALS_VALUE_PAIRS>::
306 serialize(&return_string, protobuf_msg, entry.publish(i).algorithm(),
307 entry.use_short_enum());
310 case protobuf::TranslatorEntry::TECHNIQUE_FORMAT:
313 &moos_var, protobuf_msg, entry.publish(i).algorithm(),
314 entry.publish(i).moos_var(), entry.publish(i).repeated_delimiter(),
315 entry.use_short_enum());
318 &return_string, protobuf_msg, entry.publish(i).algorithm(),
319 entry.publish(i).format(), entry.publish(i).repeated_delimiter(),
320 entry.use_short_enum());
325 std::make_pair(moos_var,
make_moos_msg(moos_var, return_string, is_binary,
326 entry.publish(i).technique(), pb_name)));
332 inline std::multimap<std::string, CMOOSMsg>
335 std::map<std::string, goby::moos::protobuf::TranslatorEntry>::const_iterator it =
338 const std::string& pb_name = protobuf_msg.
GetDescriptor()->full_name();
340 if (it == dictionary_.end())
341 throw(std::runtime_error(
"No TranslatorEntry for Protobuf type: " + pb_name));
343 const goby::moos::protobuf::TranslatorEntry& entry = it->second;
345 std::multimap<std::string, CMOOSMsg> moos_msgs;
347 bool is_binary =
false;
349 for (
int i = 0, n = entry.create_size(); i < n; ++i)
351 std::string return_string;
352 std::string moos_var = entry.create(i).moos_var();
354 switch (entry.create(i).technique())
356 case protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_TEXT_FORMAT:
358 goby::moos::protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_TEXT_FORMAT>::
359 serialize(&return_string, protobuf_msg);
362 case protobuf::TranslatorEntry::TECHNIQUE_PREFIXED_PROTOBUF_TEXT_FORMAT:
364 goby::moos::protobuf::TranslatorEntry::
365 TECHNIQUE_PREFIXED_PROTOBUF_TEXT_FORMAT>::serialize(&return_string,
369 case protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_NATIVE_HEX:
371 goby::moos::protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_NATIVE_HEX>::
372 serialize(&return_string, protobuf_msg);
375 case protobuf::TranslatorEntry::TECHNIQUE_PREFIXED_PROTOBUF_NATIVE_HEX:
377 goby::moos::protobuf::TranslatorEntry::TECHNIQUE_PREFIXED_PROTOBUF_NATIVE_HEX>::
378 serialize(&return_string, protobuf_msg);
381 case protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_NATIVE_ENCODED:
383 goby::moos::protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_NATIVE_ENCODED>::
384 serialize(&return_string, protobuf_msg);
388 case protobuf::TranslatorEntry::TECHNIQUE_PREFIXED_PROTOBUF_NATIVE_ENCODED:
390 goby::moos::protobuf::TranslatorEntry::
391 TECHNIQUE_PREFIXED_PROTOBUF_NATIVE_ENCODED>::serialize(&return_string,
396 case protobuf::TranslatorEntry::TECHNIQUE_COMMA_SEPARATED_KEY_EQUALS_VALUE_PAIRS:
400 protobuf::TranslatorEntry::PublishSerializer::Algorithm>
404 protobuf::TranslatorEntry::TECHNIQUE_COMMA_SEPARATED_KEY_EQUALS_VALUE_PAIRS>::
405 serialize(&return_string, protobuf_msg, empty_algorithms,
406 entry.use_short_enum());
410 case protobuf::TranslatorEntry::TECHNIQUE_FORMAT:
413 protobuf::TranslatorEntry::PublishSerializer::Algorithm>
417 &return_string, protobuf_msg, empty_algorithms, entry.create(i).format(),
418 entry.create(i).repeated_delimiter(), entry.use_short_enum());
424 std::make_pair(moos_var, make_moos_msg(moos_var, return_string, is_binary,
425 entry.create(i).technique(), pb_name)));
428 if (entry.trigger().type() == protobuf::TranslatorEntry::Trigger::TRIGGER_PUBLISH)
430 if (moos_msgs.count(entry.trigger().moos_var()))
433 typedef std::multimap<std::string, CMOOSMsg>::iterator It;
434 std::pair<It, It> p = moos_msgs.equal_range(entry.trigger().moos_var());
435 for (
auto it = p.first; it != p.second; ++it) it->second.m_dfTime = MOOSTime();
440 moos_msgs.insert(std::make_pair(entry.trigger().moos_var(),
441 CMOOSMsg(MOOS_NOTIFY, entry.trigger().moos_var(),
"")));
448 template <
typename GoogleProtobufMessagePo
inter,
class StringCMOOSMsgMap>
449 GoogleProtobufMessagePointer
451 const std::string& protobuf_name)
453 std::map<std::string, goby::moos::protobuf::TranslatorEntry>::const_iterator it =
454 dictionary_.find(protobuf_name);
456 if (it == dictionary_.end())
457 throw(std::runtime_error(
"No TranslatorEntry for Protobuf type: " + protobuf_name));
459 const goby::moos::protobuf::TranslatorEntry& entry = it->second;
461 GoogleProtobufMessagePointer
msg;
466 msg = dccl::DynamicProtobufManager::new_protobuf_message<GoogleProtobufMessagePointer>(
471 throw(std::runtime_error(
"Unknown Protobuf type: " + protobuf_name +
472 "; be sure it is compiled in or directly loaded into the "
473 "dccl::DynamicProtobufManager."));
475 for (
int i = 0, n = entry.create_size(); i < n; ++i)
477 auto it = moos_variables.find(entry.create(i).moos_var());
478 std::string source_string =
479 (it == moos_variables.end())
481 : (it->second.IsString() ? it->second.GetString()
482 : goby::util::as<std::string>(it->second.GetDouble()));
484 switch (entry.create(i).technique())
486 case protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_TEXT_FORMAT:
488 protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_TEXT_FORMAT>::parse(source_string,
492 case protobuf::TranslatorEntry::TECHNIQUE_PREFIXED_PROTOBUF_TEXT_FORMAT:
494 protobuf::TranslatorEntry::TECHNIQUE_PREFIXED_PROTOBUF_TEXT_FORMAT>::
495 parse(source_string, &*
msg);
498 case protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_NATIVE_HEX:
500 protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_NATIVE_HEX>::parse(source_string,
504 case protobuf::TranslatorEntry::TECHNIQUE_PREFIXED_PROTOBUF_NATIVE_HEX:
506 protobuf::TranslatorEntry::TECHNIQUE_PREFIXED_PROTOBUF_NATIVE_HEX>::
507 parse(source_string, &*
msg);
510 case protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_NATIVE_ENCODED:
512 protobuf::TranslatorEntry::TECHNIQUE_PROTOBUF_NATIVE_ENCODED>::
513 parse(source_string, &*
msg);
516 case protobuf::TranslatorEntry::TECHNIQUE_PREFIXED_PROTOBUF_NATIVE_ENCODED:
518 protobuf::TranslatorEntry::TECHNIQUE_PREFIXED_PROTOBUF_NATIVE_ENCODED>::
519 parse(source_string, &*
msg);
522 case protobuf::TranslatorEntry::TECHNIQUE_COMMA_SEPARATED_KEY_EQUALS_VALUE_PAIRS:
524 protobuf::TranslatorEntry::TECHNIQUE_COMMA_SEPARATED_KEY_EQUALS_VALUE_PAIRS>::
525 parse(source_string, &*
msg, entry.create(i).algorithm(),
526 entry.use_short_enum());
529 case protobuf::TranslatorEntry::TECHNIQUE_FORMAT:
531 source_string, &*
msg, entry.create(i).format(),
532 entry.create(i).repeated_delimiter(), entry.create(i).algorithm(),
533 entry.use_short_enum());
static CMOOSMsg make_moos_msg(const std::string &var, const std::string &str, bool is_binary, goby::moos::protobuf::TranslatorEntry::ParserSerializerTechnique technique, const std::string &pb_name)
std::multimap< std::string, CMOOSMsg > protobuf_to_inverse_moos(const google::protobuf::Message &protobuf_msg)
void add_entry(const std::set< goby::moos::protobuf::TranslatorEntry > &entries)
MOOSTranslator(const goby::moos::protobuf::TranslatorEntry &entry=goby::moos::protobuf::TranslatorEntry(), double lat_origin=std::numeric_limits< double >::quiet_NaN(), double lon_origin=std::numeric_limits< double >::quiet_NaN(), const std::string &modem_id_lookup_path="")
std::multimap< std::string, CMOOSMsg > protobuf_to_moos(const google::protobuf::Message &protobuf_msg)
MOOSTranslator(const google::protobuf::RepeatedPtrField< goby::moos::protobuf::TranslatorEntry > &entries, double lat_origin=std::numeric_limits< double >::quiet_NaN(), double lon_origin=std::numeric_limits< double >::quiet_NaN(), const std::string &modem_id_lookup_path="")
void update_utm_datum(double lat_origin, double lon_origin)
void add_entry(const google::protobuf::RepeatedPtrField< goby::moos::protobuf::TranslatorEntry > &entries)
const std::map< std::string, goby::moos::protobuf::TranslatorEntry > & dictionary() const
GoogleProtobufMessagePointer moos_to_protobuf(const StringCMOOSMsgMap &moos_variables, const std::string &protobuf_name)
void add_entry(const goby::moos::protobuf::TranslatorEntry &entry)
void clear_entry(const std::string &protobuf_name)
const Descriptor * GetDescriptor() const
Helpers for MOOS applications for serializing and parsed Google Protocol buffers messages.
bool operator<(const protobuf::TranslatorEntry &a, const protobuf::TranslatorEntry &b)
void alg_lon2hemisphere_initial(moos::transitional::DCCLMessageVal &val_to_mod)
void alg_to_upper(moos::transitional::DCCLMessageVal &val_to_mod)
std::mutex dynamic_parse_mutex
void alg_angle_0_360(moos::transitional::DCCLMessageVal &angle)
void alg_lon2nmea_lon(moos::transitional::DCCLMessageVal &val_to_mod)
void alg_lat2hemisphere_initial(moos::transitional::DCCLMessageVal &val_to_mod)
void alg_power_to_dB(moos::transitional::DCCLMessageVal &val_to_mod)
void alg_angle_n180_180(moos::transitional::DCCLMessageVal &angle)
std::ostream & operator<<(std::ostream &os, const CMOOSMsg &msg)
void alg_subtract(moos::transitional::DCCLMessageVal &val, const std::vector< moos::transitional::DCCLMessageVal > &ref_vals)
void alg_TSD_to_soundspeed(moos::transitional::DCCLMessageVal &val, const std::vector< moos::transitional::DCCLMessageVal > &ref_vals)
void alg_dB_to_power(moos::transitional::DCCLMessageVal &val_to_mod)
void alg_abs(moos::transitional::DCCLMessageVal &val_to_mod)
void alg_to_lower(moos::transitional::DCCLMessageVal &val_to_mod)
void alg_lat2nmea_lat(moos::transitional::DCCLMessageVal &val_to_mod)
void alg_add(moos::transitional::DCCLMessageVal &val, const std::vector< moos::transitional::DCCLMessageVal > &ref_vals)
void alg_unix_time2nmea_time(moos::transitional::DCCLMessageVal &val_to_mod)
std::string str(TimeType value=SystemClock::now< TimeType >())
Returns the provided time (or current time if omitted) as a human-readable string.
The global namespace for the Goby project.
extern ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< ::google::protobuf::MessageOptions, ::PROTOBUF_NAMESPACE_ID::internal::MessageTypeTraits< ::goby::GobyMessageOptions >, 11, false > msg