Goby3  3.1.4
2024.02.22
goby_moos_app.h
Go to the documentation of this file.
1 // Copyright 2011-2024:
2 // GobySoft, LLC (2013-)
3 // Massachusetts Institute of Technology (2007-2014)
4 // Community contributors (see AUTHORS file)
5 // File authors:
6 // Toby Schneider <toby@gobysoft.org>
7 // James D. Turner <james.turner@nrl.navy.mil>
8 // Shawn Dooley <shawn@shawndooley.net>
9 //
10 //
11 // This file is part of the Goby Underwater Autonomy Project Libraries
12 // ("The Goby Libraries").
13 //
14 // The Goby Libraries are free software: you can redistribute them and/or modify
15 // them under the terms of the GNU Lesser General Public License as published by
16 // the Free Software Foundation, either version 2.1 of the License, or
17 // (at your option) any later version.
18 //
19 // The Goby Libraries are distributed in the hope that they will be useful,
20 // but WITHOUT ANY WARRANTY; without even the implied warranty of
21 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 // GNU Lesser General Public License for more details.
23 //
24 // You should have received a copy of the GNU Lesser General Public License
25 // along with Goby. If not, see <http://www.gnu.org/licenses/>.
26 
27 #ifndef GOBY_MOOS_GOBY_MOOS_APP_H
28 #define GOBY_MOOS_GOBY_MOOS_APP_H
29 
30 #include <chrono> // for system...
31 #include <cstdio> // for remove
32 #include <cstdlib> // for exit
33 #include <deque> // for deque
34 #include <iomanip> // for operat...
35 #include <iostream> // for operat...
36 #include <map> // for map
37 #include <memory> // for allocator
38 #include <stdexcept> // for runtim...
39 #include <string> // for string
40 #include <unistd.h> // for symlink
41 #include <utility> // for pair
42 #include <vector> // for vector
43 
44 #include <MOOS/libMOOS/App/MOOSApp.h> // for CMOOSApp
45 #include <MOOS/libMOOS/Comms/CommsTypes.h> // for MOOSMS...
46 #include <MOOS/libMOOS/Comms/MOOSMsg.h> // for CMOOSMsg
47 #include <MOOS/libMOOS/Utils/MOOSFileReader.h> // for CMOOSF...
48 #include <MOOS/libMOOS/Utils/MOOSUtilityFunctions.h> // for MOOSTime
49 #include <boost/algorithm/string/erase.hpp> // for erase_...
50 #include <boost/algorithm/string/find.hpp> // for ifind_...
51 #include <boost/algorithm/string/predicate.hpp> // for iequals
52 #include <boost/algorithm/string/replace.hpp> // for replac...
53 #include <boost/algorithm/string/trim.hpp> // for trim_copy
54 #include <boost/bind/bind.hpp> // for bind, _1
55 #include <boost/date_time/posix_time/posix_time_config.hpp> // for posix_...
56 #include <boost/date_time/posix_time/posix_time_types.hpp> // for second...
57 #include <boost/date_time/posix_time/time_formatters.hpp> // for to_iso...
58 #include <boost/filesystem.hpp> // for path
59 #include <boost/function.hpp> // for function
60 #include <boost/lexical_cast/bad_lexical_cast.hpp> // for bad_le...
61 #include <boost/program_options/options_description.hpp> // for operat...
62 #include <boost/program_options/parsers.hpp> // for basic_...
63 #include <boost/program_options/positional_options.hpp> // for positi...
64 #include <boost/program_options/value_semantic.hpp> // for value
65 #include <boost/program_options/variables_map.hpp> // for variab...
66 #include <boost/range/iterator_range_core.hpp> // for iterat...
67 #include <boost/signals2/signal.hpp> // for signal
68 #include <boost/smart_ptr/shared_ptr.hpp> // for shared...
69 #include <boost/units/quantity.hpp> // for operator/
70 #include <boost/units/systems/si/time.hpp> // for seconds
71 #include <google/protobuf/descriptor.h> // for FieldD...
72 #include <google/protobuf/descriptor.pb.h> // for FieldO...
73 #include <google/protobuf/message.h> // for Reflec...
74 #include <google/protobuf/text_format.h> // for TextFo...
75 
77 #include "goby/moos/moos_protobuf_helpers.h" // for set_mo...
78 #include "goby/moos/moos_translator.h" // for MOOSTr...
79 #include "goby/moos/protobuf/goby_moos_app.pb.h" // for GobyMO...
80 #include "goby/moos/protobuf/translator.pb.h" // for Transl...
81 #include "goby/protobuf/option_extensions.pb.h" // for GobyFi...
82 #include "goby/time/convert.h" // for System...
83 #include "goby/time/simulation.h" // for Simula...
84 #include "goby/time/system_clock.h" // for System...
85 #include "goby/time/types.h" // for SITime
86 #include "goby/util/as.h" // for as
87 #include "goby/util/debug_logger/flex_ostream.h" // for operat...
88 #include "goby/util/debug_logger/flex_ostreambuf.h" // for WARN
89 #include "goby/util/debug_logger/term_color.h" // for esc_no...
90 #include "goby/util/protobuf/debug_logger.pb.h" // for GLogCo...
91 
92 #include "dynamic_moos_vars.h" // for Dynami...
93 
94 namespace goby
95 {
96 namespace moos
97 {
99 
100 template <typename App> int run(int argc, char* argv[]);
101 
102 template <typename ProtobufMessage>
103 inline void protobuf_inbox(const CMOOSMsg& msg,
104  boost::function<void(const ProtobufMessage& msg)> handler)
105 {
106  ProtobufMessage pb_msg;
107  parse_for_moos(msg.GetString(), &pb_msg);
108  handler(pb_msg);
109 }
110 
111 // shell implementation so we can call superclass methods for when
112 // using AppCastingMOOSApp
113 class MOOSAppShell : public CMOOSApp
114 {
115  protected:
116  bool Iterate() override { return true; }
117  bool OnStartUp() override { return true; }
118  bool OnConnectToServer() override { return true; }
119  bool OnNewMail(MOOSMSG_LIST& /*NewMail*/) override { return true; }
121  void PostReport() {}
122 };
123 
124 template <class MOOSAppType = MOOSAppShell> class GobyMOOSAppSelector : public MOOSAppType
125 {
126  protected:
127  typedef boost::function<void(const CMOOSMsg& msg)> InboxFunc;
128 
129  template <typename ProtobufConfig>
130  explicit GobyMOOSAppSelector(ProtobufConfig* cfg)
131  : start_time_(MOOSTime()),
132  configuration_read_(false),
133  cout_cleared_(false),
134  connected_(false),
135  started_up_(false),
136  ignore_stale_(true),
137  dynamic_moos_vars_enabled_(true)
138  {
139  using goby::glog;
140 
141  read_configuration(cfg);
142 
143  // keep a copy for ourselves
144  common_cfg_ = cfg->common();
145  configuration_read_ = true;
146 
147  process_configuration();
148 
149  glog.is(goby::util::logger::DEBUG2) && glog << cfg->DebugString() << std::endl;
150  }
151 
152  ~GobyMOOSAppSelector() override = default;
153 
154  template <typename ProtobufMessage>
155  void publish_pb(const std::string& key, const ProtobufMessage& msg)
156  {
157  std::string serialized;
158  bool is_binary = serialize_for_moos(&serialized, msg);
160  key, serialized, is_binary, goby::moos::moos_technique,
161  msg.GetDescriptor()->full_name());
162  publish(moos_msg);
163  }
164 
166  {
167  if (connected_ && started_up_)
168  MOOSAppType::m_Comms.Post(msg);
169  else
170  msg_buffer_.push_back(msg);
171  }
172 
173  void publish(const std::string& key, const std::string& value)
174  {
175  CMOOSMsg msg(MOOS_NOTIFY, key, value);
176  publish(msg);
177  }
178 
179  void publish(const std::string& key, double value)
180  {
181  CMOOSMsg msg(MOOS_NOTIFY, key, value);
182  publish(msg);
183  }
184 
185  goby::moos::DynamicMOOSVars& dynamic_vars() { return dynamic_vars_; }
186  double start_time() const { return start_time_; }
187 
188  void subscribe(const std::string& var, const InboxFunc& handler = InboxFunc(),
189  double blackout = 0);
190 
191  template <typename V, typename A1>
192  void subscribe(const std::string& var, void (V::*mem_func)(A1), V* obj, double blackout = 0)
193  {
194  subscribe(var, boost::bind(mem_func, obj, boost::placeholders::_1), blackout);
195  }
196 
197  // wildcard
198  void subscribe(const std::string& var_pattern, const std::string& app_pattern,
199  const InboxFunc& handler = InboxFunc(), double blackout = 0);
200 
201  template <typename V, typename A1>
202  void subscribe(const std::string& var_pattern, const std::string& app_pattern,
203  void (V::*mem_func)(A1), V* obj, double blackout = 0)
204  {
205  subscribe(var_pattern, app_pattern, boost::bind(mem_func, obj, boost::placeholders::_1),
206  blackout);
207  }
208 
209  template <typename V, typename ProtobufMessage>
210  void subscribe_pb(const std::string& var, void (V::*mem_func)(const ProtobufMessage&), V* obj,
211  double blackout = 0)
212  {
213  subscribe_pb<ProtobufMessage>(var, boost::bind(mem_func, obj, boost::placeholders::_1),
214  blackout);
215  }
216 
217  template <typename ProtobufMessage>
218  void subscribe_pb(const std::string& var,
219  boost::function<void(const ProtobufMessage& msg)> handler,
220  double blackout = 0)
221  {
222  subscribe(var,
223  boost::bind(&goby::moos::protobuf_inbox<ProtobufMessage>, boost::placeholders::_1,
224  handler),
225  blackout);
226  }
227 
228  void register_timer(int period_seconds, const boost::function<void()>& handler)
229  {
230  int now = (goby::time::SystemClock::now<goby::time::SITime>() / boost::units::si::seconds) /
231  period_seconds;
232  now *= period_seconds;
233 
234  SynchronousLoop new_loop;
235  new_loop.unix_next = now + period_seconds;
236  new_loop.period_seconds = period_seconds;
237  new_loop.handler = handler;
238  synchronous_loops_.push_back(new_loop);
239  }
240 
241  template <typename V> void register_timer(int period_seconds, void (V::*mem_func)(), V* obj)
242  {
243  register_timer(period_seconds, boost::bind(mem_func, obj));
244  }
245 
246  template <typename App> friend int ::goby::moos::run(int argc, char* argv[]);
247 
248  virtual void loop() = 0;
249 
250  bool ignore_stale() { return ignore_stale_; }
251  void set_ignore_stale(bool b) { ignore_stale_ = b; }
252 
253  bool dynamic_moos_vars_enabled() { return dynamic_moos_vars_enabled_; }
254  void set_dynamic_moos_vars_enabled(bool b) { dynamic_moos_vars_enabled_ = b; }
255 
256  std::pair<std::string, goby::moos::protobuf::TranslatorEntry::ParserSerializerTechnique>
257  parse_type_technique(const std::string& type_and_technique)
258  {
259  std::string protobuf_type;
261  if (!type_and_technique.empty())
262  {
263  std::string::size_type colon_pos = type_and_technique.find(':');
264 
265  if (colon_pos != std::string::npos)
266  {
267  protobuf_type = type_and_technique.substr(0, colon_pos);
268  std::string str_technique = type_and_technique.substr(colon_pos + 1);
269 
271  str_technique, &technique))
272  throw(std::runtime_error("Invalid technique string"));
273  }
274  else
275  {
276  throw std::runtime_error("Missing colon (:)");
277  }
278  return std::make_pair(protobuf_type, technique);
279  }
280  else
281  {
282  throw std::runtime_error("Empty technique string");
283  }
284  }
285 
286  private:
287  // from CMOOSApp
288  bool Iterate() override;
289  bool OnStartUp() override;
290  bool OnConnectToServer() override;
291  bool OnDisconnectFromServer() override;
292  bool OnNewMail(MOOSMSG_LIST& NewMail) override;
293  void try_subscribing();
294  void do_subscriptions();
295 
296  int fetch_moos_globals(google::protobuf::Message* msg, CMOOSFileReader& moos_file_reader);
297 
298  void read_configuration(google::protobuf::Message* cfg);
299  void process_configuration();
300 
301  private:
302  // when we started (seconds since UNIX)
303  double start_time_;
304 
305  // have we read the configuration file fully?
306  bool configuration_read_;
307  bool cout_cleared_;
308 
309  std::ofstream fout_;
310 
311  // allows direct reading of newest publish to a given MOOS variable
312  goby::moos::DynamicMOOSVars dynamic_vars_;
313 
314  std::map<std::string, std::shared_ptr<boost::signals2::signal<void(const CMOOSMsg& msg)>>>
315  mail_handlers_;
316 
317  std::map<std::pair<std::string, std::string>,
318  std::shared_ptr<boost::signals2::signal<void(const CMOOSMsg& msg)>>>
319  wildcard_mail_handlers_;
320 
321  // CMOOSApp::OnConnectToServer()
322  bool connected_;
323  // CMOOSApp::OnStartUp()
324  bool started_up_;
325 
326  std::deque<CMOOSMsg> msg_buffer_;
327 
328  // MOOS Variable name, blackout time
329  std::deque<std::pair<std::string, double>> pending_subscriptions_;
330  std::deque<std::pair<std::string, double>> existing_subscriptions_;
331 
332  // MOOS Variable pattern, MOOS App pattern, blackout time
333  std::deque<std::pair<std::pair<std::string, std::string>, double>>
334  wildcard_pending_subscriptions_;
335  std::deque<std::pair<std::pair<std::string, std::string>, double>>
336  wildcard_existing_subscriptions_;
337 
338  struct SynchronousLoop
339  {
340  double unix_next;
341  int period_seconds;
342  boost::function<void()> handler;
343  };
344 
345  std::vector<SynchronousLoop> synchronous_loops_;
346 
347  protobuf::GobyMOOSAppConfig common_cfg_;
348 
349  bool ignore_stale_;
350 
351  bool dynamic_moos_vars_enabled_;
352 
353  static int argc_;
354  static char** argv_;
355  static std::string mission_file_;
356  static std::string application_name_;
357 };
358 
360 {
361  public:
362  template <typename ProtobufConfig>
363  explicit GobyMOOSApp(ProtobufConfig* cfg) : GobyMOOSAppSelector<>(cfg)
364  {
365  }
366 };
367 } // namespace moos
368 } // namespace goby
369 
370 template <class MOOSAppType>
372 
373 template <class MOOSAppType>
375 
376 template <class MOOSAppType> int goby::moos::GobyMOOSAppSelector<MOOSAppType>::argc_ = 0;
377 template <class MOOSAppType> char** goby::moos::GobyMOOSAppSelector<MOOSAppType>::argv_ = nullptr;
378 
379 template <class MOOSAppType> bool goby::moos::GobyMOOSAppSelector<MOOSAppType>::Iterate()
380 {
381  MOOSAppType::Iterate();
382 
383  if (!configuration_read_)
384  return true;
385 
386  // clear out MOOSApp cout for ncurses "scope" mode
387  // MOOS has stopped talking by first Iterate()
388  if (!cout_cleared_)
389  {
391  cout_cleared_ = true;
392  }
393 
394  while (!msg_buffer_.empty() && (connected_ && started_up_))
395  {
397  goby::glog << "writing from buffer: " << msg_buffer_.front().GetKey() << ": "
398  << msg_buffer_.front().GetAsString() << std::endl;
399 
400  MOOSAppType::m_Comms.Post(msg_buffer_.front());
401  msg_buffer_.pop_front();
402  }
403 
404  loop();
405 
406  if (synchronous_loops_.size())
407  {
408  double now = goby::time::SystemClock::now<goby::time::SITime>() / boost::units::si::seconds;
409  for (typename std::vector<SynchronousLoop>::iterator it = synchronous_loops_.begin(),
410  end = synchronous_loops_.end();
411  it != end; ++it)
412  {
413  SynchronousLoop& loop = *it;
414  if (loop.unix_next <= now)
415  {
416  loop.handler();
417  loop.unix_next += loop.period_seconds;
418 
419  // fix jumps forward in time
420  if (loop.unix_next < now)
421  loop.unix_next = now + loop.period_seconds;
422  }
423 
424  // fix jumps backwards in time
425  if (loop.unix_next > (now + 2 * loop.period_seconds))
426  loop.unix_next = now + loop.period_seconds;
427  }
428  }
429 
430  return true;
431 }
432 
433 template <class MOOSAppType>
435 {
436  // for AppCasting (otherwise no-op)
437  MOOSAppType::OnNewMail(NewMail);
438 
439  for (const auto& msg : NewMail)
440  {
442  goby::glog << "Received mail: " << msg.GetKey() << ", time: " << std::setprecision(15)
443  << msg.GetTime() << std::endl;
444 
445  // update dynamic moos variables - do this inside the loop so the newest is
446  // also the one referenced in the call to inbox()
447  if (dynamic_moos_vars_enabled_)
448  dynamic_vars().update_moos_vars(msg);
449 
450  if (msg.GetTime() < start_time_ && ignore_stale_)
451  {
453  goby::glog << "ignoring normal mail from " << msg.GetKey()
454  << " from before we started (dynamics still updated)" << std::endl;
455  }
456  else if (mail_handlers_.count(msg.GetKey()))
457  (*mail_handlers_[msg.GetKey()])(msg);
458 
459  for (auto& wildcard_mail_handler : wildcard_mail_handlers_)
460  {
461  if (MOOSWildCmp(wildcard_mail_handler.first.first, msg.GetKey()) &&
462  MOOSWildCmp(wildcard_mail_handler.first.second, msg.GetSource()))
463  (*(wildcard_mail_handler.second))(msg);
464  }
465  }
466 
467  return true;
468 }
469 
470 template <class MOOSAppType>
472 {
473  std::cout << MOOSAppType::m_MissionReader.GetAppName() << ", disconnected from server."
474  << std::endl;
475  connected_ = false;
476  pending_subscriptions_.insert(pending_subscriptions_.end(), existing_subscriptions_.begin(),
477  existing_subscriptions_.end());
478  existing_subscriptions_.clear();
479  wildcard_pending_subscriptions_.insert(wildcard_pending_subscriptions_.end(),
480  wildcard_existing_subscriptions_.begin(),
481  wildcard_existing_subscriptions_.end());
482  wildcard_existing_subscriptions_.clear();
483  return true;
484 }
485 
486 template <class MOOSAppType> bool goby::moos::GobyMOOSAppSelector<MOOSAppType>::OnConnectToServer()
487 {
488  std::cout << MOOSAppType::m_MissionReader.GetAppName() << ", connected to server." << std::endl;
489  connected_ = true;
490  try_subscribing();
491 
492  for (const auto& ini : common_cfg_.initializer())
493  {
494  if (ini.has_global_cfg_var())
495  {
496  std::string result;
497  if (MOOSAppType::m_MissionReader.GetValue(ini.global_cfg_var(), result))
498  {
499  if (ini.type() == protobuf::GobyMOOSAppConfig::Initializer::INI_DOUBLE)
500  publish(ini.moos_var(), goby::util::as<double>(result));
501  else if (ini.type() == protobuf::GobyMOOSAppConfig::Initializer::INI_STRING)
502  publish(ini.moos_var(), ini.trim() ? boost::trim_copy(result) : result);
503  }
504  }
505  else
506  {
507  if (ini.type() == protobuf::GobyMOOSAppConfig::Initializer::INI_DOUBLE)
508  publish(ini.moos_var(), ini.dval());
509  else if (ini.type() == protobuf::GobyMOOSAppConfig::Initializer::INI_STRING)
510  publish(ini.moos_var(), ini.trim() ? boost::trim_copy(ini.sval()) : ini.sval());
511  }
512  }
513 
514  return true;
515 }
516 
517 template <class MOOSAppType> bool goby::moos::GobyMOOSAppSelector<MOOSAppType>::OnStartUp()
518 {
519  MOOSAppType::OnStartUp();
520 
521  std::cout << MOOSAppType::m_MissionReader.GetAppName() << ", starting ..." << std::endl;
522  CMOOSApp::SetCommsFreq(common_cfg_.comm_tick());
523  CMOOSApp::SetAppFreq(common_cfg_.app_tick());
524  started_up_ = true;
525  try_subscribing();
526  return true;
527 }
528 
529 template <class MOOSAppType>
531  const InboxFunc& handler,
532  double blackout /* = 0 */)
533 {
535  goby::glog << "subscribing for MOOS variable: " << var << " @ " << blackout << std::endl;
536 
537  pending_subscriptions_.emplace_back(var, blackout);
538  try_subscribing();
539 
540  if (!mail_handlers_[var])
541  mail_handlers_[var].reset(new boost::signals2::signal<void(const CMOOSMsg& msg)>);
542 
543  if (handler)
544  mail_handlers_[var]->connect(handler);
545 }
546 
547 template <class MOOSAppType>
549  const std::string& app_pattern,
550  const InboxFunc& handler,
551  double blackout /* = 0 */)
552 {
554  goby::glog << "wildcard subscribing for MOOS variable pattern: " << var_pattern
555  << ", app pattern: " << app_pattern << " @ " << blackout << std::endl;
556 
557  std::pair<std::string, std::string> key = std::make_pair(var_pattern, app_pattern);
558  wildcard_pending_subscriptions_.emplace_back(key, blackout);
559  try_subscribing();
560 
561  if (!wildcard_mail_handlers_.count(key))
562  wildcard_mail_handlers_.insert(std::make_pair(
563  key, std::make_shared<boost::signals2::signal<void(const CMOOSMsg& msg)>>()));
564 
565  if (handler)
566  wildcard_mail_handlers_[key]->connect(handler);
567 }
568 
569 template <class MOOSAppType> void goby::moos::GobyMOOSAppSelector<MOOSAppType>::try_subscribing()
570 {
571  if (connected_ && started_up_)
572  do_subscriptions();
573 }
574 
575 template <class MOOSAppType> void goby::moos::GobyMOOSAppSelector<MOOSAppType>::do_subscriptions()
576 {
577  MOOSAppType::RegisterVariables();
578 
579  while (!pending_subscriptions_.empty())
580  {
581  // variable name, blackout
582  if (MOOSAppType::m_Comms.Register(pending_subscriptions_.front().first,
583  pending_subscriptions_.front().second))
584  {
586  goby::glog << "subscribed for: " << pending_subscriptions_.front().first
587  << std::endl;
588  }
589  else
590  {
592  goby::glog << "failed to subscribe for: " << pending_subscriptions_.front().first
593  << std::endl;
594  }
595  existing_subscriptions_.push_back(pending_subscriptions_.front());
596  pending_subscriptions_.pop_front();
597  }
598 
599  while (!wildcard_pending_subscriptions_.empty())
600  {
601  // variable name, blackout
602  if (MOOSAppType::m_Comms.Register(wildcard_pending_subscriptions_.front().first.first,
603  wildcard_pending_subscriptions_.front().first.second,
604  wildcard_pending_subscriptions_.front().second))
605  {
607  goby::glog << "subscribed for: "
608  << wildcard_pending_subscriptions_.front().first.first << ":"
609  << wildcard_pending_subscriptions_.front().first.second << std::endl;
610  }
611  else
612  {
614  goby::glog << "failed to subscribe for: "
615  << wildcard_pending_subscriptions_.front().first.first << ":"
616  << wildcard_pending_subscriptions_.front().first.second << std::endl;
617  }
618 
619  wildcard_existing_subscriptions_.push_back(wildcard_pending_subscriptions_.front());
620  wildcard_pending_subscriptions_.pop_front();
621  }
622 }
623 
624 template <class MOOSAppType>
626  google::protobuf::Message* msg, CMOOSFileReader& moos_file_reader)
627 {
628  int globals = 0;
629  const google::protobuf::Descriptor* desc = msg->GetDescriptor();
630  const google::protobuf::Reflection* refl = msg->GetReflection();
631 
632  for (int i = 0, n = desc->field_count(); i < n; ++i)
633  {
634  const google::protobuf::FieldDescriptor* field_desc = desc->field(i);
635 
636  // we don't support repeated fields or oneof fields containing MOOS globals
637  if (field_desc->is_repeated() || field_desc->containing_oneof())
638  continue;
639 
640  std::string moos_global = field_desc->options().GetExtension(goby::field).moos_global();
641 
642  switch (field_desc->cpp_type())
643  {
644  case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE:
645  {
646  bool message_was_empty = !refl->HasField(*msg, field_desc);
647  int set_globals =
648  fetch_moos_globals(refl->MutableMessage(msg, field_desc), moos_file_reader);
649  if (set_globals == 0 && message_was_empty)
650  refl->ClearField(msg, field_desc);
651 
652  break;
653  }
654 
655  case google::protobuf::FieldDescriptor::CPPTYPE_INT32:
656  {
657  int result;
658  if (moos_file_reader.GetValue(moos_global, result))
659  {
660  refl->SetInt32(msg, field_desc, result);
661  ++globals;
662  }
663 
664  break;
665  }
666 
667  case google::protobuf::FieldDescriptor::CPPTYPE_INT64:
668  {
669  int result;
670  if (moos_file_reader.GetValue(moos_global, result))
671  {
672  refl->SetInt64(msg, field_desc, result);
673  ++globals;
674  }
675  break;
676  }
677 
678  case google::protobuf::FieldDescriptor::CPPTYPE_UINT32:
679  {
680  unsigned result;
681  if (moos_file_reader.GetValue(moos_global, result))
682  {
683  refl->SetUInt32(msg, field_desc, result);
684  ++globals;
685  }
686 
687  break;
688  }
689 
690  case google::protobuf::FieldDescriptor::CPPTYPE_UINT64:
691  {
692  unsigned result;
693  if (moos_file_reader.GetValue(moos_global, result))
694  {
695  refl->SetUInt64(msg, field_desc, result);
696  ++globals;
697  }
698  break;
699  }
700 
701  case google::protobuf::FieldDescriptor::CPPTYPE_BOOL:
702  {
703  enum Result
704  {
705  RESULT_TRUE = 1,
706  RESULT_FALSE = 0,
707  RESULT_UNSPECIFIED = -1
708  };
709 
710  Result result = RESULT_UNSPECIFIED;
711  // avoid parsing pLogger "LOG = some string" as "log = false"
712  std::string svalue;
713  if (moos_file_reader.GetValue(moos_global, svalue))
714  {
715  if (MOOSStrCmp(svalue, "TRUE"))
716  result = RESULT_TRUE;
717  else if (MOOSStrCmp(svalue, "FALSE"))
718  result = RESULT_FALSE;
719  else if (MOOSIsNumeric(svalue))
720  result = atof(svalue.c_str()) > 0 ? RESULT_TRUE : RESULT_FALSE;
721  }
722  if (result != RESULT_UNSPECIFIED)
723  {
724  refl->SetBool(msg, field_desc, result);
725  ++globals;
726  }
727  break;
728  }
729 
730  case google::protobuf::FieldDescriptor::CPPTYPE_STRING:
731  {
732  std::string result;
733  if (moos_file_reader.GetValue(moos_global, result))
734  {
735  refl->SetString(msg, field_desc, result);
736  ++globals;
737  }
738 
739  break;
740  }
741 
742  case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT:
743  {
744  float result;
745  if (moos_file_reader.GetValue(moos_global, result))
746  {
747  refl->SetFloat(msg, field_desc, result);
748  ++globals;
749  }
750 
751  break;
752  }
753 
754  case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE:
755  {
756  double result;
757  if (moos_file_reader.GetValue(moos_global, result))
758  {
759  refl->SetDouble(msg, field_desc, result);
760  ++globals;
761  }
762  break;
763  }
764 
765  case google::protobuf::FieldDescriptor::CPPTYPE_ENUM:
766  {
767  std::string result;
768  if (moos_file_reader.GetValue(moos_global, result))
769  {
770  const google::protobuf::EnumValueDescriptor* enum_desc =
771  refl->GetEnum(*msg, field_desc)->type()->FindValueByName(result);
772  if (!enum_desc)
773  throw(std::runtime_error(std::string("invalid enumeration " + result +
774  " for field " + field_desc->name())));
775 
776  refl->SetEnum(msg, field_desc, enum_desc);
777  ++globals;
778  }
779  break;
780  }
781  }
782  }
783  return globals;
784 }
785 
786 template <class MOOSAppType>
789 {
790  boost::filesystem::path launch_path(argv_[0]);
791 
792 #if BOOST_FILESYSTEM_VERSION == 3
793  std::string binary_name = launch_path.filename().string();
794 #else
795  std::string binary_name = launch_path.filename();
796 #endif
797  application_name_ = binary_name;
798 
799  //
800  // READ CONFIGURATION
801  //
802 
803  boost::program_options::options_description od_all;
804  boost::program_options::variables_map var_map, po_env_var_map;
805  try
806  {
807  boost::program_options::options_description od_cli_only(
808  "Options given on command line only");
809  od_cli_only.add_options()("help,h", "writes this help message")(
810  "moos_file,c", boost::program_options::value<std::string>(&mission_file_),
811  "path to .moos file")("moos_name,a",
812  boost::program_options::value<std::string>(&application_name_),
813  "name to register with MOOS")(
814  "example_config,e", "writes an example .moos ProcessConfig block")(
815  "version,V", "writes the current version");
816 
818  boost::program_options::options_description>
819  od_map;
820 
821  std::string od_pb_always_desc =
822  "Options typically given in the .moos file, but may be specified on the command line";
823  std::string od_pb_never_desc = "Hidden options";
824  std::string od_pb_advanced_desc = "Advanced options";
825  std::string od_pb_developer_desc = "Developer options";
826  od_map.insert(
828  boost::program_options::options_description(od_pb_always_desc.c_str())));
829  od_map.insert(std::make_pair(
831  boost::program_options::options_description(od_pb_advanced_desc.c_str())));
832  od_map.insert(std::make_pair(
834  boost::program_options::options_description(od_pb_developer_desc.c_str())));
835  od_map.insert(
837  boost::program_options::options_description(od_pb_never_desc.c_str())));
838 
839  std::map<std::string, std::string> environmental_var_map;
841  environmental_var_map);
842  std::vector<goby::middleware::ConfigReader::PositionalOption> positional_options;
844  positional_options);
845 
846  for (const auto& od_p : od_map) od_all.add(od_p.second);
847  od_all.add(od_cli_only);
848 
849  boost::program_options::positional_options_description p;
850  p.add("moos_file", 1);
851  p.add("moos_name", 1);
852  for (const auto& po : positional_options) { p.add(po.name.c_str(), po.position_max_count); }
853 
854  boost::program_options::store(boost::program_options::command_line_parser(argc_, argv_)
855  .options(od_all)
856  .positional(p)
857  .run(),
858  var_map);
859 
860  if (!environmental_var_map.empty())
861  {
862  boost::program_options::store(
863  boost::program_options::parse_environment(
864  od_all,
865  [&environmental_var_map](const std::string& i_env_var) -> std::string {
866  return environmental_var_map.count(i_env_var)
867  ? environmental_var_map.at(i_env_var)
868  : "";
869  }),
870  po_env_var_map);
871  }
872 
873  boost::program_options::notify(var_map);
874  boost::program_options::notify(po_env_var_map);
875 
876  if (var_map.count("help"))
877  {
878  std::cerr << "Usage: " << binary_name << " [options] moos_file [moos_name]"
879  << std::endl;
880 
881  std::cerr << od_map[goby::GobyFieldOptions::ConfigurationOptions::ALWAYS] << "\n";
882  std::cerr << od_cli_only << "\n";
883  exit(EXIT_SUCCESS);
884  }
885  else if (var_map.count("example_config"))
886  {
887  std::cout << "ProcessConfig = " << application_name_ << "\n{";
889  std::cout << "}" << std::endl;
890  exit(EXIT_SUCCESS);
891  }
892  else if (var_map.count("version"))
893  {
895  exit(EXIT_SUCCESS);
896  }
897 
898  goby::glog.set_name(application_name_);
900 
901  std::string protobuf_text;
902  std::ifstream fin;
903  fin.open(mission_file_.c_str());
904  if (fin.is_open())
905  {
906  std::string line;
907  bool in_process_config = false;
908  while (getline(fin, line))
909  {
910  std::string no_blanks_line = boost::algorithm::erase_all_copy(line, " ");
911  if (boost::algorithm::iequals(no_blanks_line, "PROCESSCONFIG=" + application_name_))
912  {
913  in_process_config = true;
914  }
915  else if (in_process_config &&
916  !boost::algorithm::ifind_first(line, "PROCESSCONFIG").empty())
917  {
918  break;
919  }
920 
921  if (in_process_config)
922  protobuf_text += line + "\n";
923  }
924 
925  if (!in_process_config)
926  {
928  goby::glog << "no ProcessConfig block for " << application_name_ << std::endl;
929  }
930 
931  // trim off "ProcessConfig = __ {"
932  protobuf_text.erase(0, protobuf_text.find_first_of('{') + 1);
933 
934  // trim off last "}" and anything that follows
935  protobuf_text.erase(protobuf_text.find_last_of('}'));
936 
937  // convert "//" to "#" for comments
938  boost::algorithm::replace_all(protobuf_text, "//", "#");
939 
940  google::protobuf::TextFormat::Parser parser;
941  goby::util::FlexOStreamErrorCollector error_collector(protobuf_text);
942  parser.RecordErrorsTo(&error_collector);
943  parser.AllowPartialMessage(true);
944  parser.ParseFromString(protobuf_text, cfg);
945 
946  if (error_collector.has_errors() || error_collector.has_warnings())
947  {
949  goby::glog << "fatal configuration errors (see above)" << std::endl;
950  }
951  }
952  else
953  {
954  goby::glog.is(goby::util::logger::WARN) && goby::glog << "failed to open "
955  << mission_file_ << std::endl;
956  }
957 
958  fin.close();
959 
960  CMOOSFileReader moos_file_reader;
961  moos_file_reader.SetFile(mission_file_);
962  fetch_moos_globals(cfg, moos_file_reader);
963 
964  // add any environmental variable options that don't exist in the cfg file
965  for (const auto& p : po_env_var_map)
966  {
967  // let protobuf deal with the defaults
968  if (!p.second.defaulted())
970  p.second, false);
971  }
972 
973  // add / overwrite any options that are specified in the cfg file with those given on the command line
974  for (const auto& p : var_map)
975  {
976  if (!p.second.defaulted())
978  p.second, true);
979  }
980 
981  // now the proto message must have all required fields
982  if (!cfg->IsInitialized())
983  {
984  std::vector<std::string> errors;
985  cfg->FindInitializationErrors(&errors);
986 
987  std::stringstream err_msg;
988  err_msg << "Configuration is missing required parameters: \n";
989  for (const std::string& s : errors)
990  err_msg << goby::util::esc_red << s << "\n" << goby::util::esc_nocolor;
991 
992  err_msg << "Make sure you specified a proper .moos file";
993  throw(goby::middleware::ConfigException(err_msg.str()));
994  }
995  }
997  {
998  // output all the available command line options
999  std::cerr << od_all << "\n";
1000  std::cerr << "Problem parsing command-line configuration: \n" << e.what() << "\n";
1001 
1002  throw;
1003  }
1004 }
1005 
1006 template <class MOOSAppType>
1008 {
1009  //
1010  // PROCESS CONFIGURATION
1011  //
1012  goby::glog.add_stream(common_cfg_.verbosity(), &std::cout);
1013  if (common_cfg_.show_gui())
1014  {
1016  }
1017 
1018  if (common_cfg_.log())
1019  {
1020  if (!common_cfg_.has_log_path())
1021  {
1023  goby::glog << "logging all terminal output to default directory ("
1024  << common_cfg_.log_path() << ")."
1025  << "set log_path for another path " << std::endl;
1026  }
1027 
1028  if (!common_cfg_.log_path().empty())
1029  {
1030  using namespace boost::posix_time;
1031  std::string file_name_base = boost::replace_all_copy(application_name_, "/", "_") +
1032  "_" + common_cfg_.community();
1033 
1034  std::string file_name =
1035  file_name_base + "_" + to_iso_string(second_clock::universal_time()) + ".txt";
1036 
1037  std::string file_symlink = file_name_base + "_latest.txt";
1038 
1040  goby::glog << "logging output to file: " << file_name << std::endl;
1041 
1042  fout_.open(std::string(common_cfg_.log_path() + "/" + file_name).c_str());
1043 
1044  // symlink to "latest.txt"
1045  remove(std::string(common_cfg_.log_path() + "/" + file_symlink).c_str());
1046  symlink(file_name.c_str(),
1047  std::string(common_cfg_.log_path() + "/" + file_symlink).c_str());
1048 
1049  // if fails, try logging to this directory
1050  if (!fout_.is_open())
1051  {
1052  fout_.open(std::string("./" + file_name).c_str());
1054  goby::glog
1055  << "logging to current directory because given directory is unwritable!"
1056  << std::endl;
1057  }
1058  // if still no go, quit
1059  if (!fout_.is_open())
1060  {
1062  goby::glog << "cannot write to current directory, so cannot log." << std::endl;
1063  }
1064 
1065  goby::glog.add_stream(common_cfg_.log_verbosity(), &fout_);
1066  }
1067  }
1068 
1069  goby::moos::set_moos_technique(common_cfg_);
1070 
1071  if (common_cfg_.time_warp_multiplier() != 1)
1072  {
1073  goby::time::SimulatorSettings::warp_factor = common_cfg_.time_warp_multiplier();
1076  std::chrono::system_clock::time_point(std::chrono::seconds(0));
1077  start_time_ *= common_cfg_.time_warp_multiplier();
1078  }
1079 }
1080 
1081 // designed to run CMOOSApp derived applications
1082 // using the MOOS "convention" of argv[1] == mission file, argv[2] == alternative name
1083 template <typename App> int goby::moos::run(int argc, char* argv[])
1084 {
1085  App::argc_ = argc;
1086  App::argv_ = argv;
1087 
1088  try
1089  {
1090  App* app = App::get_instance();
1091  app->Run(App::application_name_.c_str(), App::mission_file_.c_str());
1092  }
1094  {
1095  // no further warning as the ApplicationBase Ctor handles this
1096  return 1;
1097  }
1098  catch (std::exception& e)
1099  {
1100  // some other exception
1101  goby::glog.is(goby::util::logger::DIE) && goby::glog << "uncaught exception: " << e.what()
1102  << std::endl;
1103  return 2;
1104  }
1105 
1106  return 0;
1107 }
1108 
1109 #endif
goby::moos::run
int run(int argc, char *argv[])
Shorthand for goby::run for Configurators that have a constructor that simply takes argc,...
Definition: goby_moos_app.h:1083
goby::moos::GobyMOOSAppSelector::subscribe
void subscribe(const std::string &var, const InboxFunc &handler=InboxFunc(), double blackout=0)
Definition: goby_moos_app.h:530
goby::moos::set_moos_technique
void set_moos_technique(const goby::moos::protobuf::GobyMOOSAppConfig &cfg)
Definition: moos_protobuf_helpers.h:1518
goby::moos::GobyMOOSAppSelector::publish
void publish(const std::string &key, double value)
Definition: goby_moos_app.h:179
google::protobuf::Reflection::SetUInt32
virtual void SetUInt32(Message *message, const FieldDescriptor *field, uint32 value) const =0
goby::moos::moos_technique
goby::moos::protobuf::TranslatorEntry::ParserSerializerTechnique moos_technique
goby::moos::protobuf_inbox
void protobuf_inbox(const CMOOSMsg &msg, boost::function< void(const ProtobufMessage &msg)> handler)
Definition: goby_moos_app.h:103
goby::util::protobuf::GLogConfig::VERBOSE
static const Verbosity VERBOSE
Definition: debug_logger.pb.h:381
goby::moos::write_version_message
void write_version_message()
goby::moos::GobyMOOSAppSelector::set_ignore_stale
void set_ignore_stale(bool b)
Definition: goby_moos_app.h:251
goby::moos::MOOSAppShell
Definition: goby_moos_app.h:113
system_clock.h
google::protobuf::Message::FindInitializationErrors
void FindInitializationErrors(std::vector< string > *errors) const
goby::moos::protobuf::TranslatorEntry_ParserSerializerTechnique
TranslatorEntry_ParserSerializerTechnique
Definition: translator.pb.h:111
SynchronousLoop
goby::util::FlexOstream::is
bool is(goby::util::logger::Verbosity verbosity)
types.h
goby
The global namespace for the Goby project.
Definition: acomms_constants.h:33
goby::util::logger::DEBUG2
@ DEBUG2
Definition: flex_ostreambuf.h:78
goby::moos::MOOSAppShell::PostReport
void PostReport()
Definition: goby_moos_app.h:121
as.h
goby::middleware::ConfigReader::get_positional_options
static void get_positional_options(const google::protobuf::Descriptor *desc, std::vector< PositionalOption > &positional_options)
goby::GobyFieldOptions_ConfigurationOptions::NEVER
static const ConfigAction NEVER
Definition: option_extensions.pb.h:345
goby::util::FlexOstream::enable_gui
void enable_gui()
Definition: flex_ostream.h:73
goby::moos::GobyMOOSAppSelector::publish_pb
void publish_pb(const std::string &key, const ProtobufMessage &msg)
Definition: goby_moos_app.h:155
term_color.h
goby::util::logger::WARN
@ WARN
Definition: flex_ostreambuf.h:74
goby::util::e
constexpr T e
Definition: constants.h:35
serialize_for_moos
bool serialize_for_moos(std::string *out, const google::protobuf::Message &msg)
Converts the Google Protocol Buffers message msg into a suitable (human readable) string out for send...
Definition: moos_protobuf_helpers.h:1538
goby::moos::MOOSAppShell::RegisterVariables
void RegisterVariables()
Definition: goby_moos_app.h:120
google::protobuf::Reflection
Definition: message.h:412
moos_protobuf_helpers.h
goby::moos::GobyMOOSAppSelector::dynamic_vars
goby::moos::DynamicMOOSVars & dynamic_vars()
Definition: goby_moos_app.h:185
goby::moos::GobyMOOSAppSelector::InboxFunc
boost::function< void(const CMOOSMsg &msg)> InboxFunc
Definition: goby_moos_app.h:127
goby::moos::GobyMOOSAppSelector::subscribe
void subscribe(const std::string &var_pattern, const std::string &app_pattern, void(V::*mem_func)(A1), V *obj, double blackout=0)
Definition: goby_moos_app.h:202
flex_ostreambuf.h
goby::util::logger::VERBOSE
@ VERBOSE
Definition: flex_ostreambuf.h:75
goby::moos::protobuf::TranslatorEntry::ParserSerializerTechnique_Parse
static bool ParserSerializerTechnique_Parse(const ::std::string &name, ParserSerializerTechnique *value)
Definition: translator.pb.h:1118
goby::middleware::ConfigException
indicates a problem with the runtime command line or .cfg file configuration (or –help was given)
Definition: configuration_reader.h:56
goby::GobyFieldOptions_ConfigurationOptions::ADVANCED
static const ConfigAction ADVANCED
Definition: option_extensions.pb.h:339
goby::util::FlexOstream::add_stream
void add_stream(logger::Verbosity verbosity=logger::VERBOSE, std::ostream *os=nullptr)
Attach a stream object (e.g. std::cout, std::ofstream, ...) to the logger with desired verbosity.
Definition: flex_ostream.h:89
detail::void
j template void())
Definition: json.hpp:4822
google::protobuf::Reflection::HasField
virtual bool HasField(const Message &message, const FieldDescriptor *field) const =0
google::protobuf::Reflection::SetDouble
virtual void SetDouble(Message *message, const FieldDescriptor *field, double value) const =0
CMOOSMsg
goby::moos::GobyMOOSAppSelector::ignore_stale
bool ignore_stale()
Definition: goby_moos_app.h:250
goby::moos::GobyMOOSAppSelector::subscribe
void subscribe(const std::string &var, void(V::*mem_func)(A1), V *obj, double blackout=0)
Definition: goby_moos_app.h:192
moos_translator.h
CMOOSApp
google::protobuf::Reflection::SetFloat
virtual void SetFloat(Message *message, const FieldDescriptor *field, float value) const =0
goby::middleware::ConfigReader::set_protobuf_program_option
static void set_protobuf_program_option(const boost::program_options::variables_map &vm, google::protobuf::Message &message, const std::string &full_name, const boost::program_options::variable_value &value, bool overwrite_if_exists)
google::protobuf::Reflection::ClearField
virtual void ClearField(Message *message, const FieldDescriptor *field) const =0
goby::field
extern ::google::protobuf::internal::ExtensionIdentifier< ::google::protobuf::FieldOptions, ::google::protobuf::internal::MessageTypeTraits< ::goby::GobyFieldOptions >, 11, false > field
Definition: option_extensions.pb.h:1323
parse_for_moos
void parse_for_moos(const std::string &in, google::protobuf::Message *msg)
Parses the string in to Google Protocol Buffers message msg. All errors are written to the goby::util...
Definition: moos_protobuf_helpers.h:1584
goby::moos::MOOSAppShell::OnStartUp
bool OnStartUp() override
Definition: goby_moos_app.h:117
goby::moos::GobyMOOSAppSelector::~GobyMOOSAppSelector
~GobyMOOSAppSelector() override=default
message.h
goby_moos_app.pb.h
goby::moos::GobyMOOSAppSelector::GobyMOOSAppSelector
GobyMOOSAppSelector(ProtobufConfig *cfg)
Definition: goby_moos_app.h:130
goby::moos::GobyMOOSAppSelector::publish
void publish(const std::string &key, const std::string &value)
Definition: goby_moos_app.h:173
goby::moos::GobyMOOSApp::GobyMOOSApp
GobyMOOSApp(ProtobufConfig *cfg)
Definition: goby_moos_app.h:363
google::protobuf::Reflection::MutableMessage
virtual Message * MutableMessage(Message *message, const FieldDescriptor *field, MessageFactory *factory=NULL) const =0
goby::time::SimulatorSettings::reference_time
static std::chrono::system_clock::time_point reference_time
Reference time when calculating SystemClock::now(). If this is unset, the default is 1 January of the...
Definition: simulation.h:42
goby::GobyFieldOptions_ConfigurationOptions::DEVELOPER
static const ConfigAction DEVELOPER
Definition: option_extensions.pb.h:341
goby::util::logger::DIE
@ DIE
Definition: flex_ostreambuf.h:80
goby::moos::GobyMOOSAppSelector::publish
void publish(CMOOSMsg &msg)
Definition: goby_moos_app.h:165
goby::util::logger::DEBUG3
@ DEBUG3
Definition: flex_ostreambuf.h:79
goby::util::FlexOStreamErrorCollector
Definition: flex_ostream.h:216
goby::moos::GobyMOOSAppSelector
Definition: goby_moos_app.h:124
goby::middleware::ConfigReader::get_protobuf_program_options
static void get_protobuf_program_options(std::map< goby::GobyFieldOptions::ConfigurationOptions::ConfigAction, boost::program_options::options_description > &od_map, const google::protobuf::Descriptor *desc, std::map< std::string, std::string > &environmental_var_map)
flex_ostream.h
goby::moos::DynamicMOOSVars
Definition: dynamic_moos_vars.h:34
goby::msg
extern ::google::protobuf::internal::ExtensionIdentifier< ::google::protobuf::MessageOptions, ::google::protobuf::internal::MessageTypeTraits< ::goby::GobyMessageOptions >, 11, false > msg
Definition: option_extensions.pb.h:1327
google::protobuf::Reflection::SetUInt64
virtual void SetUInt64(Message *message, const FieldDescriptor *field, uint64 value) const =0
goby::time::SimulatorSettings::using_sim_time
static bool using_sim_time
Enables simulation time if true (if false, none of the remaining parameters are used)
Definition: simulation.h:38
goby::time::SimulatorSettings::warp_factor
static int warp_factor
Warp factor to speed up (or slow time) the time values returned by SteadyClock::now() and SystemClock...
Definition: simulation.h:40
translator.pb.h
convert.h
debug_logger.pb.h
google::protobuf::Message
Definition: message.h:189
goby::moos::MOOSAppShell::OnConnectToServer
bool OnConnectToServer() override
Definition: goby_moos_app.h:118
google::protobuf::Message::GetDescriptor
const Descriptor * GetDescriptor() const
Definition: message.h:336
goby::util::esc_nocolor
const std::string esc_nocolor
Definition: term_color.h:51
goby::acomms::bind
void bind(ModemDriverBase &driver, QueueManager &queue_manager)
binds the driver link-layer callbacks to the QueueManager
Definition: bind.h:45
dynamic_moos_vars.h
goby::moos::GobyMOOSAppSelector::set_dynamic_moos_vars_enabled
void set_dynamic_moos_vars_enabled(bool b)
Definition: goby_moos_app.h:254
google::protobuf::Reflection::SetInt32
virtual void SetInt32(Message *message, const FieldDescriptor *field, int32 value) const =0
google::protobuf::Reflection::SetString
virtual void SetString(Message *message, const FieldDescriptor *field, const string &value) const =0
goby::moos::GobyMOOSAppSelector::loop
virtual void loop()=0
goby::util::esc_red
const std::string esc_red
Definition: term_color.h:37
goby::moos::MOOSAppShell::Iterate
bool Iterate() override
Definition: goby_moos_app.h:116
configuration_reader.h
goby::moos::GobyMOOSAppSelector::subscribe_pb
void subscribe_pb(const std::string &var, void(V::*mem_func)(const ProtobufMessage &), V *obj, double blackout=0)
Definition: goby_moos_app.h:210
goby::GobyFieldOptions_ConfigurationOptions::ConfigAction
GobyFieldOptions_ConfigurationOptions_ConfigAction ConfigAction
Definition: option_extensions.pb.h:336
goby::moos::GobyMOOSAppSelector::register_timer
void register_timer(int period_seconds, void(V::*mem_func)(), V *obj)
Definition: goby_moos_app.h:241
goby::GobyFieldOptions_ConfigurationOptions::ALWAYS
static const ConfigAction ALWAYS
Definition: option_extensions.pb.h:337
goby::util::FlexOstream::refresh
void refresh()
Definition: flex_ostream.h:150
goby::moos::GobyMOOSAppSelector::parse_type_technique
std::pair< std::string, goby::moos::protobuf::TranslatorEntry::ParserSerializerTechnique > parse_type_technique(const std::string &type_and_technique)
Definition: goby_moos_app.h:257
goby::moos::GobyMOOSAppSelector::start_time
double start_time() const
Definition: goby_moos_app.h:186
google::protobuf::Message::IsInitialized
virtual bool IsInitialized() const
httplib::detail::trim_copy
std::string trim_copy(const std::string &s)
Definition: httplib.h:2479
goby::moos::GobyMOOSApp
Definition: goby_moos_app.h:359
simulation.h
option_extensions.pb.h
google::protobuf::Reflection::SetBool
virtual void SetBool(Message *message, const FieldDescriptor *field, bool value) const =0
google::protobuf::Reflection::SetEnum
virtual void SetEnum(Message *message, const FieldDescriptor *field, const EnumValueDescriptor *value) const =0
google::protobuf::Reflection::GetEnum
virtual const EnumValueDescriptor * GetEnum(const Message &message, const FieldDescriptor *field) const =0
time.hpp
goby::glog
util::FlexOstream glog
Access the Goby logger through this object.
goby::moos::MOOSTranslator::make_moos_msg
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)
Definition: moos_translator.h:153
goby::moos::GobyMOOSAppSelector::dynamic_moos_vars_enabled
bool dynamic_moos_vars_enabled()
Definition: goby_moos_app.h:253
goby::moos::GobyMOOSAppSelector::subscribe_pb
void subscribe_pb(const std::string &var, boost::function< void(const ProtobufMessage &msg)> handler, double blackout=0)
Definition: goby_moos_app.h:218
google::protobuf::Reflection::SetInt64
virtual void SetInt64(Message *message, const FieldDescriptor *field, int64 value) const =0
goby::util::FlexOstream::set_name
void set_name(const std::string &s)
Set the name of the application that the logger is serving.
Definition: flex_ostream.h:67
goby::moos::GobyMOOSAppSelector::register_timer
void register_timer(int period_seconds, const boost::function< void()> &handler)
Definition: goby_moos_app.h:228
goby::moos::MOOSAppShell::OnNewMail
bool OnNewMail(MOOSMSG_LIST &) override
Definition: goby_moos_app.h:119
goby::middleware::ConfigReader::get_example_cfg_file
static void get_example_cfg_file(google::protobuf::Message *message, std::ostream *human_desc_ss, const std::string &indent="", goby::GobyFieldOptions::ConfigurationOptions::ConfigAction action=goby::GobyFieldOptions::ConfigurationOptions::ALWAYS)