27#ifndef GOBY_MOOS_GOBY_MOOS_APP_H 
   28#define GOBY_MOOS_GOBY_MOOS_APP_H 
   44#include <MOOS/libMOOS/App/MOOSApp.h>                        
   45#include <MOOS/libMOOS/Comms/CommsTypes.h>                   
   46#include <MOOS/libMOOS/Comms/MOOSMsg.h>                      
   47#include <MOOS/libMOOS/Utils/MOOSFileReader.h>               
   48#include <MOOS/libMOOS/Utils/MOOSUtilityFunctions.h>         
   49#include <boost/algorithm/string/erase.hpp>                  
   50#include <boost/algorithm/string/find.hpp>                   
   51#include <boost/algorithm/string/predicate.hpp>              
   52#include <boost/algorithm/string/replace.hpp>                
   53#include <boost/algorithm/string/trim.hpp>                   
   54#include <boost/bind/bind.hpp>                               
   55#include <boost/date_time/posix_time/posix_time_config.hpp>  
   56#include <boost/date_time/posix_time/posix_time_types.hpp>   
   57#include <boost/date_time/posix_time/time_formatters.hpp>    
   58#include <boost/filesystem.hpp>                              
   59#include <boost/function.hpp>                                
   60#include <boost/lexical_cast/bad_lexical_cast.hpp>           
   61#include <boost/program_options/options_description.hpp>     
   62#include <boost/program_options/parsers.hpp>                 
   63#include <boost/program_options/positional_options.hpp>      
   64#include <boost/program_options/value_semantic.hpp>          
   65#include <boost/program_options/variables_map.hpp>           
   66#include <boost/range/iterator_range_core.hpp>               
   67#include <boost/signals2/signal.hpp>                         
   68#include <boost/smart_ptr/shared_ptr.hpp>                    
   69#include <boost/units/quantity.hpp>                          
   71#include <google/protobuf/descriptor.h>                      
   72#include <google/protobuf/descriptor.pb.h>                   
   74#include <google/protobuf/text_format.h>                     
  100template <
typename App> 
int run(
int argc, 
char* argv[]);
 
  102template <
typename ProtobufMessage>
 
  104                           boost::function<
void(
const ProtobufMessage& 
msg)> handler)
 
  106    ProtobufMessage pb_msg;
 
 
  119    bool OnNewMail(MOOSMSG_LIST& )
 override { 
return true; }
 
 
  129    template <
typename ProtobufConfig>
 
  131        : start_time_(MOOSTime()),
 
  132          configuration_read_(false),
 
  133          cout_cleared_(false),
 
  137          dynamic_moos_vars_enabled_(true)
 
  141        read_configuration(cfg);
 
  144        common_cfg_ = cfg->common();
 
  145        configuration_read_ = 
true;
 
  147        process_configuration();
 
 
  154    template <
typename ProtobufMessage>
 
  157        std::string serialized;
 
  161            msg.GetDescriptor()->full_name());
 
 
  167        if (connected_ && started_up_)
 
  168            MOOSAppType::m_Comms.Post(
msg);
 
  170            msg_buffer_.push_back(
msg);
 
 
  173    void publish(
const std::string& key, 
const std::string& value)
 
  175        CMOOSMsg 
msg(MOOS_NOTIFY, key, value);
 
 
  179    void publish(
const std::string& key, 
double value)
 
  181        CMOOSMsg 
msg(MOOS_NOTIFY, key, value);
 
 
  189                   double blackout = 0);
 
  191    template <
typename V, 
typename A1>
 
  192    void subscribe(
const std::string& var, 
void (V::*mem_func)(A1), V* obj, double blackout = 0)
 
  194        subscribe(var, boost::bind(mem_func, obj, boost::placeholders::_1), blackout);
 
 
  198    void subscribe(
const std::string& var_pattern, 
const std::string& app_pattern,
 
  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)
 
  205        subscribe(var_pattern, app_pattern, boost::bind(mem_func, obj, boost::placeholders::_1),
 
 
  209    template <
typename V, 
typename ProtobufMessage>
 
  210    void subscribe_pb(
const std::string& var, 
void (V::*mem_func)(const ProtobufMessage&), V* obj,
 
  213        subscribe_pb<ProtobufMessage>(var, boost::bind(mem_func, obj, boost::placeholders::_1),
 
 
  217    template <
typename ProtobufMessage>
 
  219                      boost::function<
void(
const ProtobufMessage& 
msg)> handler,
 
  223                  boost::bind(&goby::moos::protobuf_inbox<ProtobufMessage>, boost::placeholders::_1,
 
 
  230        int now = (goby::time::SystemClock::now<goby::time::SITime>() / boost::units::si::seconds) /
 
  232        now *= period_seconds;
 
  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);
 
 
  241    template <
typename V> 
void register_timer(
int period_seconds, 
void (V::*mem_func)(), V* obj)
 
 
  246    template <
typename App> 
friend int ::goby::moos::run(
int argc, 
char* argv[]);
 
  256    std::pair<std::string, goby::moos::protobuf::TranslatorEntry::ParserSerializerTechnique>
 
  259        std::string protobuf_type;
 
  261        if (!type_and_technique.empty())
 
  263            std::string::size_type colon_pos = type_and_technique.find(
':');
 
  265            if (colon_pos != std::string::npos)
 
  267                protobuf_type = type_and_technique.substr(0, colon_pos);
 
  268                std::string str_technique = type_and_technique.substr(colon_pos + 1);
 
  271                        str_technique, &technique))
 
  272                    throw(std::runtime_error(
"Invalid technique string"));
 
  276                throw std::runtime_error(
"Missing colon (:)");
 
  278            return std::make_pair(protobuf_type, technique);
 
  282            throw std::runtime_error(
"Empty technique string");
 
 
  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();
 
  299    void process_configuration();
 
  306    bool configuration_read_;
 
  314    std::map<std::string, std::shared_ptr<boost::signals2::signal<void(
const CMOOSMsg& 
msg)>>>
 
  317    std::map<std::pair<std::string, std::string>,
 
  318             std::shared_ptr<boost::signals2::signal<void(
const CMOOSMsg& 
msg)>>>
 
  319        wildcard_mail_handlers_;
 
  326    std::deque<CMOOSMsg> msg_buffer_;
 
  329    std::deque<std::pair<std::string, double>> pending_subscriptions_;
 
  330    std::deque<std::pair<std::string, double>> existing_subscriptions_;
 
  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_;
 
  338    struct SynchronousLoop
 
  342        boost::function<void()> handler;
 
  345    std::vector<SynchronousLoop> synchronous_loops_;
 
  347    protobuf::GobyMOOSAppConfig common_cfg_;
 
  351    bool dynamic_moos_vars_enabled_;
 
  355    static std::string mission_file_;
 
  356    static std::string application_name_;
 
 
  362    template <
typename ProtobufConfig>
 
 
  370template <
class MOOSAppType>
 
  373template <
class MOOSAppType>
 
  381    MOOSAppType::Iterate();
 
  383    if (!configuration_read_)
 
  391        cout_cleared_ = 
true;
 
  394    while (!msg_buffer_.empty() && (connected_ && started_up_))
 
  397            goby::glog << 
"writing from buffer: " << msg_buffer_.front().GetKey() << 
": " 
  398                       << msg_buffer_.front().GetAsString() << std::endl;
 
  400        MOOSAppType::m_Comms.Post(msg_buffer_.front());
 
  401        msg_buffer_.pop_front();
 
  406    if (synchronous_loops_.size())
 
  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();
 
  413            SynchronousLoop& loop = *it;
 
  414            if (loop.unix_next <= now)
 
  417                loop.unix_next += loop.period_seconds;
 
  420                if (loop.unix_next < now)
 
  421                    loop.unix_next = now + loop.period_seconds;
 
  425            if (loop.unix_next > (now + 2 * loop.period_seconds))
 
  426                loop.unix_next = now + loop.period_seconds;
 
  433template <
class MOOSAppType>
 
  437    MOOSAppType::OnNewMail(NewMail);
 
  439    for (
const auto& msg : NewMail)
 
  442            goby::glog << 
"Received mail: " << 
msg.GetKey() << 
", time: " << std::setprecision(15)
 
  443                       << 
msg.GetTime() << std::endl;
 
  447        if (dynamic_moos_vars_enabled_)
 
  448            dynamic_vars().update_moos_vars(msg);
 
  450        if (
msg.GetTime() < start_time_ && ignore_stale_)
 
  454                           << 
" from before we started (dynamics still updated)" << std::endl;
 
  456        else if (mail_handlers_.count(
msg.GetKey()))
 
  457            (*mail_handlers_[
msg.GetKey()])(msg);
 
  459        for (
auto& wildcard_mail_handler : wildcard_mail_handlers_)
 
  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);
 
  470template <
class MOOSAppType>
 
  473    std::cout << MOOSAppType::m_MissionReader.GetAppName() << 
", disconnected from server." 
  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();
 
  488    std::cout << MOOSAppType::m_MissionReader.GetAppName() << 
", connected to server." << std::endl;
 
  492    for (
const auto& ini : common_cfg_.initializer())
 
  494        if (ini.has_global_cfg_var())
 
  497            if (MOOSAppType::m_MissionReader.GetValue(ini.global_cfg_var(), result))
 
  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);
 
  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());
 
  519    MOOSAppType::OnStartUp();
 
  521    std::cout << MOOSAppType::m_MissionReader.GetAppName() << 
", starting ..." << std::endl;
 
  522    CMOOSApp::SetCommsFreq(common_cfg_.comm_tick());
 
  523    CMOOSApp::SetAppFreq(common_cfg_.app_tick());
 
  529template <
class MOOSAppType>
 
  535        goby::glog << 
"subscribing for MOOS variable: " << var << 
" @ " << blackout << std::endl;
 
  537    pending_subscriptions_.emplace_back(var, blackout);
 
  540    if (!mail_handlers_[var])
 
  541        mail_handlers_[var].reset(
new boost::signals2::signal<
void(
const CMOOSMsg& 
msg)>);
 
  544        mail_handlers_[var]->connect(handler);
 
 
  547template <
class MOOSAppType>
 
  549                                                             const std::string& app_pattern,
 
  554        goby::glog << 
"wildcard subscribing for MOOS variable pattern: " << var_pattern
 
  555                   << 
", app pattern: " << app_pattern << 
" @ " << blackout << std::endl;
 
  557    std::pair<std::string, std::string> key = std::make_pair(var_pattern, app_pattern);
 
  558    wildcard_pending_subscriptions_.emplace_back(key, blackout);
 
  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)>>()));
 
  566        wildcard_mail_handlers_[key]->connect(handler);
 
 
  571    if (connected_ && started_up_)
 
  577    MOOSAppType::RegisterVariables();
 
  579    while (!pending_subscriptions_.empty())
 
  582        if (MOOSAppType::m_Comms.Register(pending_subscriptions_.front().first,
 
  583                                          pending_subscriptions_.front().second))
 
  586                goby::glog << 
"subscribed for: " << pending_subscriptions_.front().first
 
  592                goby::glog << 
"failed to subscribe for: " << pending_subscriptions_.front().first
 
  595        existing_subscriptions_.push_back(pending_subscriptions_.front());
 
  596        pending_subscriptions_.pop_front();
 
  599    while (!wildcard_pending_subscriptions_.empty())
 
  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))
 
  608                           << wildcard_pending_subscriptions_.front().first.first << 
":" 
  609                           << wildcard_pending_subscriptions_.front().first.second << std::endl;
 
  615                           << wildcard_pending_subscriptions_.front().first.first << 
":" 
  616                           << wildcard_pending_subscriptions_.front().first.second << std::endl;
 
  619        wildcard_existing_subscriptions_.push_back(wildcard_pending_subscriptions_.front());
 
  620        wildcard_pending_subscriptions_.pop_front();
 
  624template <
class MOOSAppType>
 
  629    const google::protobuf::Descriptor* desc = 
msg->GetDescriptor();
 
  632    for (
int i = 0, n = desc->field_count(); i < n; ++i)
 
  634        const google::protobuf::FieldDescriptor* field_desc = desc->field(i);
 
  637        if (field_desc->is_repeated() || field_desc->containing_oneof())
 
  640        std::string moos_global = field_desc->options().GetExtension(
goby::field).moos_global();
 
  642        switch (field_desc->cpp_type())
 
  644            case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE:
 
  646                bool message_was_empty = !refl->
HasField(*msg, field_desc);
 
  648                    fetch_moos_globals(refl->
MutableMessage(msg, field_desc), moos_file_reader);
 
  649                if (set_globals == 0 && message_was_empty)
 
  655            case google::protobuf::FieldDescriptor::CPPTYPE_INT32:
 
  658                if (moos_file_reader.GetValue(moos_global, result))
 
  660                    refl->
SetInt32(msg, field_desc, result);
 
  667            case google::protobuf::FieldDescriptor::CPPTYPE_INT64:
 
  670                if (moos_file_reader.GetValue(moos_global, result))
 
  672                    refl->
SetInt64(msg, field_desc, result);
 
  678            case google::protobuf::FieldDescriptor::CPPTYPE_UINT32:
 
  681                if (moos_file_reader.GetValue(moos_global, result))
 
  683                    refl->
SetUInt32(msg, field_desc, result);
 
  690            case google::protobuf::FieldDescriptor::CPPTYPE_UINT64:
 
  693                if (moos_file_reader.GetValue(moos_global, result))
 
  695                    refl->
SetUInt64(msg, field_desc, result);
 
  701            case google::protobuf::FieldDescriptor::CPPTYPE_BOOL:
 
  707                    RESULT_UNSPECIFIED = -1
 
  710                Result result = RESULT_UNSPECIFIED;
 
  713                if (moos_file_reader.GetValue(moos_global, svalue))
 
  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;
 
  722                if (result != RESULT_UNSPECIFIED)
 
  724                    refl->
SetBool(msg, field_desc, result);
 
  730            case google::protobuf::FieldDescriptor::CPPTYPE_STRING:
 
  733                if (moos_file_reader.GetValue(moos_global, result))
 
  735                    refl->
SetString(msg, field_desc, result);
 
  742            case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT:
 
  745                if (moos_file_reader.GetValue(moos_global, result))
 
  747                    refl->
SetFloat(msg, field_desc, result);
 
  754            case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE:
 
  757                if (moos_file_reader.GetValue(moos_global, result))
 
  759                    refl->
SetDouble(msg, field_desc, result);
 
  765            case google::protobuf::FieldDescriptor::CPPTYPE_ENUM:
 
  768                if (moos_file_reader.GetValue(moos_global, result))
 
  770                    const google::protobuf::EnumValueDescriptor* enum_desc =
 
  771                        refl->
GetEnum(*msg, field_desc)->type()->FindValueByName(result);
 
  773                        throw(std::runtime_error(std::string(
"invalid enumeration " + result +
 
  774                                                             " for field " + field_desc->name())));
 
  776                    refl->
SetEnum(msg, field_desc, enum_desc);
 
  786template <
class MOOSAppType>
 
  790    boost::filesystem::path launch_path(argv_[0]);
 
  792#if BOOST_FILESYSTEM_VERSION == 3 
  793    std::string binary_name = launch_path.filename().string();
 
  795    std::string binary_name = launch_path.filename();
 
  797    application_name_ = binary_name;
 
  803    boost::program_options::options_description od_all;
 
  804    boost::program_options::variables_map var_map, po_env_var_map;
 
  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");
 
  818                 boost::program_options::options_description>
 
  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";
 
  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())));
 
  837                           boost::program_options::options_description(od_pb_never_desc.c_str())));
 
  839        std::map<std::string, std::string> environmental_var_map;
 
  841                                                                     environmental_var_map);
 
  842        std::vector<goby::middleware::ConfigReader::PositionalOption> positional_options;
 
  846        for (
const auto& od_p : od_map) od_all.add(od_p.second);
 
  847        od_all.add(od_cli_only);
 
  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); }
 
  854        boost::program_options::store(boost::program_options::command_line_parser(argc_, argv_)
 
  860        if (!environmental_var_map.empty())
 
  862            boost::program_options::store(
 
  863                boost::program_options::parse_environment(
 
  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)
 
  873        boost::program_options::notify(var_map);
 
  874        boost::program_options::notify(po_env_var_map);
 
  876        if (var_map.count(
"help"))
 
  878            std::cerr << 
"Usage: " << binary_name << 
" [options] moos_file [moos_name]" 
  882            std::cerr << od_cli_only << 
"\n";
 
  885        else if (var_map.count(
"example_config"))
 
  887            std::cout << 
"ProcessConfig = " << application_name_ << 
"\n{";
 
  889            std::cout << 
"}" << std::endl;
 
  892        else if (var_map.count(
"version"))
 
  901        std::string protobuf_text;
 
  903        fin.open(mission_file_.c_str());
 
  907            bool in_process_config = 
false;
 
  908            while (getline(fin, line))
 
  910                std::string no_blanks_line = boost::algorithm::erase_all_copy(line, 
" ");
 
  911                if (boost::algorithm::iequals(no_blanks_line, 
"PROCESSCONFIG=" + application_name_))
 
  913                    in_process_config = 
true;
 
  915                else if (in_process_config &&
 
  916                         !boost::algorithm::ifind_first(line, 
"PROCESSCONFIG").empty())
 
  921                if (in_process_config)
 
  922                    protobuf_text += line + 
"\n";
 
  925            if (!in_process_config)
 
  928                    goby::glog << 
"no ProcessConfig block for " << application_name_ << std::endl;
 
  932            protobuf_text.erase(0, protobuf_text.find_first_of(
'{') + 1);
 
  935            protobuf_text.erase(protobuf_text.find_last_of(
'}'));
 
  938            boost::algorithm::replace_all(protobuf_text, 
"//", 
"#");
 
  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);
 
  946            if (error_collector.has_errors() || error_collector.has_warnings())
 
  949                    goby::glog << 
"fatal configuration errors (see above)" << std::endl;
 
  955                                                                  << mission_file_ << std::endl;
 
  960        CMOOSFileReader moos_file_reader;
 
  961        moos_file_reader.SetFile(mission_file_);
 
  962        fetch_moos_globals(cfg, moos_file_reader);
 
  965        for (
const auto& p : po_env_var_map)
 
  968            if (!p.second.defaulted())
 
  974        for (
const auto& p : var_map)
 
  976            if (!p.second.defaulted())
 
  984            std::vector<std::string> errors;
 
  987            std::stringstream err_msg;
 
  988            err_msg << 
"Configuration is missing required parameters: \n";
 
  989            for (
const std::string& s : errors)
 
  992            err_msg << 
"Make sure you specified a proper .moos file";
 
  999        std::cerr << od_all << 
"\n";
 
 1000        std::cerr << 
"Problem parsing command-line configuration: \n" << 
e.what() << 
"\n";
 
 1006template <
class MOOSAppType>
 
 1013    if (common_cfg_.show_gui())
 
 1018    if (common_cfg_.log())
 
 1020        if (!common_cfg_.has_log_path())
 
 1023                goby::glog << 
"logging all terminal output to default directory (" 
 1024                           << common_cfg_.log_path() << 
")." 
 1025                           << 
"set log_path for another path " << std::endl;
 
 1028        if (!common_cfg_.log_path().empty())
 
 1030            using namespace boost::posix_time;
 
 1031            std::string file_name_base = boost::replace_all_copy(application_name_, 
"/", 
"_") +
 
 1032                                         "_" + common_cfg_.community();
 
 1034            std::string file_name =
 
 1036                (common_cfg_.log_omit_file_timestamp()
 
 1038                     : std::string(
"_") + to_iso_string(second_clock::universal_time())) +
 
 1042                goby::glog << 
"logging output to file: " << file_name << std::endl;
 
 1044            fout_.open(std::string(common_cfg_.log_path() + 
"/" + file_name).c_str());
 
 1046            if (!common_cfg_.log_omit_latest_symlink())
 
 1048                std::string file_symlink = file_name_base + 
"_latest.txt";
 
 1050                remove(std::string(common_cfg_.log_path() + 
"/" + file_symlink).c_str());
 
 1051                symlink(file_name.c_str(),
 
 1052                        std::string(common_cfg_.log_path() + 
"/" + file_symlink).c_str());
 
 1056            if (!fout_.is_open())
 
 1058                fout_.open(std::string(
"./" + file_name).c_str());
 
 1061                        << 
"logging to current directory because given directory is unwritable!" 
 1065            if (!fout_.is_open())
 
 1068                    goby::glog << 
"cannot write to current directory, so cannot log." << std::endl;
 
 1077    if (common_cfg_.time_warp_multiplier() != 1)
 
 1082            std::chrono::system_clock::time_point(std::chrono::seconds(0));
 
 1083        start_time_ *= common_cfg_.time_warp_multiplier();
 
 1096        App* app = App::get_instance();
 
 1097        app->Run(App::application_name_.c_str(), App::mission_file_.c_str());
 
 1104    catch (std::exception& e)
 
 
static constexpr ConfigAction NEVER
 
static constexpr ConfigAction DEVELOPER
 
GobyFieldOptions_ConfigurationOptions_ConfigAction ConfigAction
 
static constexpr ConfigAction ADVANCED
 
static constexpr ConfigAction ALWAYS
 
indicates a problem with the runtime command line or .cfg file configuration (or –help was given)
 
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)
 
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)
 
static void get_positional_options(const google::protobuf::Descriptor *desc, std::vector< PositionalOption > &positional_options)
 
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)
 
void publish(const std::string &key, double value)
 
void subscribe(const std::string &var, void(V::*mem_func)(A1), V *obj, double blackout=0)
 
boost::function< void(const CMOOSMsg &msg)> InboxFunc
 
void publish(const std::string &key, const std::string &value)
 
void subscribe_pb(const std::string &var, boost::function< void(const ProtobufMessage &msg)> handler, double blackout=0)
 
void register_timer(int period_seconds, void(V::*mem_func)(), V *obj)
 
GobyMOOSAppSelector(ProtobufConfig *cfg)
 
void subscribe(const std::string &var_pattern, const std::string &app_pattern, void(V::*mem_func)(A1), V *obj, double blackout=0)
 
void subscribe_pb(const std::string &var, void(V::*mem_func)(const ProtobufMessage &), V *obj, double blackout=0)
 
void publish(CMOOSMsg &msg)
 
void subscribe(const std::string &var, const InboxFunc &handler=InboxFunc(), double blackout=0)
 
goby::moos::DynamicMOOSVars & dynamic_vars()
 
void set_dynamic_moos_vars_enabled(bool b)
 
std::pair< std::string, goby::moos::protobuf::TranslatorEntry::ParserSerializerTechnique > parse_type_technique(const std::string &type_and_technique)
 
~GobyMOOSAppSelector() override=default
 
bool dynamic_moos_vars_enabled()
 
void set_ignore_stale(bool b)
 
void publish_pb(const std::string &key, const ProtobufMessage &msg)
 
void register_timer(int period_seconds, const boost::function< void()> &handler)
 
double start_time() const
 
GobyMOOSApp(ProtobufConfig *cfg)
 
bool OnStartUp() override
 
bool OnNewMail(MOOSMSG_LIST &) override
 
bool OnConnectToServer() override
 
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)
 
static bool ParserSerializerTechnique_Parse(::PROTOBUF_NAMESPACE_ID::ConstStringParam name, ParserSerializerTechnique *value)
 
bool is(goby::util::logger::Verbosity verbosity)
 
void set_name(const std::string &s)
Set the name of the application that the logger is serving.
 
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.
 
static constexpr Verbosity VERBOSE
 
const Descriptor * GetDescriptor() const
 
void FindInitializationErrors(std::vector< std::string > *errors) const
 
bool IsInitialized() const override
 
void SetUInt32(Message *message, const FieldDescriptor *field, uint32_t value) const
 
void ClearField(Message *message, const FieldDescriptor *field) const
 
Message * MutableMessage(Message *message, const FieldDescriptor *field, MessageFactory *factory=nullptr) const
 
void SetInt64(Message *message, const FieldDescriptor *field, int64_t value) const
 
bool HasField(const Message &message, const FieldDescriptor *field) const
 
void SetInt32(Message *message, const FieldDescriptor *field, int32_t value) const
 
void SetDouble(Message *message, const FieldDescriptor *field, double value) const
 
void SetFloat(Message *message, const FieldDescriptor *field, float value) const
 
const EnumValueDescriptor * GetEnum(const Message &message, const FieldDescriptor *field) const
 
void SetString(Message *message, const FieldDescriptor *field, std::string value) const
 
void SetUInt64(Message *message, const FieldDescriptor *field, uint64_t value) const
 
void SetEnum(Message *message, const FieldDescriptor *field, const EnumValueDescriptor *value) const
 
void SetBool(Message *message, const FieldDescriptor *field, bool value) const
 
Helpers for MOOS applications for serializing and parsed Google Protocol buffers messages.
 
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...
 
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...
 
TranslatorEntry_ParserSerializerTechnique
 
void write_version_message()
 
void protobuf_inbox(const CMOOSMsg &msg, boost::function< void(const ProtobufMessage &msg)> handler)
 
void set_moos_technique(const goby::moos::protobuf::GobyMOOSAppConfig &cfg)
 
goby::moos::protobuf::TranslatorEntry::ParserSerializerTechnique moos_technique
 
int run(int argc, char *argv[])
 
const std::string esc_red
 
const std::string esc_nocolor
 
The global namespace for the Goby project.
 
extern ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< ::PROTOBUF_NAMESPACE_ID::FieldOptions, ::PROTOBUF_NAMESPACE_ID::internal::MessageTypeTraits< ::goby::GobyFieldOptions >, 11, false > field
 
extern ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< ::PROTOBUF_NAMESPACE_ID::MessageOptions, ::PROTOBUF_NAMESPACE_ID::internal::MessageTypeTraits< ::goby::GobyMessageOptions >, 11, false > msg
 
util::FlexOstream glog
Access the Goby logger through this object.
 
int run(const goby::middleware::ConfiguratorInterface< typename App::ConfigType > &cfgtor)
Run a Goby application using the provided Configurator.
 
static bool using_sim_time
Enables simulation time if true (if false, none of the remaining parameters are used)
 
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...
 
static int warp_factor
Warp factor to speed up (or slow time) the time values returned by SteadyClock::now() and SystemClock...