Note: Goby version 1 (shown here) is now considered obsolete. Please use version 2 for new projects, and consider upgrading old projects.

Goby Underwater Autonomy Project  Series: 1.1, revision: 163, released on 2013-02-06 14:23:27 -0500
moos/libmoos_util/tes_moos_app.cpp
00001 // t. schneider tes@mit.edu 07.26.10
00002 // ocean engineering graudate student - mit / whoi joint program
00003 // massachusetts institute of technology (mit)
00004 // laboratory for autonomous marine sensing systems (lamss)      
00005 // 
00006 // This program is free software: you can redistribute it and/or modify
00007 // it under the terms of the GNU General Public License as published by
00008 // the Free Software Foundation, either version 3 of the License, or
00009 // (at your option) any later version.
00010 //
00011 // This software is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU General Public License
00017 // along with this software.  If not, see <http://www.gnu.org/licenses/>.
00018 
00019 
00020 #include "tes_moos_app.h"
00021 
00022 #include <boost/foreach.hpp>
00023 #include <boost/bind.hpp>
00024 
00025 #include "goby/util/string.h"
00026 
00027 using goby::util::glogger;
00028 using goby::util::as;
00029 
00030 std::string TesMoosApp::mission_file_;
00031 std::string TesMoosApp::application_name_;
00032 
00033 int TesMoosApp::argc_ = 0;
00034 char** TesMoosApp::argv_ = 0;
00035 
00036 bool TesMoosApp::Iterate()
00037 {
00038     if(!configuration_read_) return true;
00039 
00040     // clear out MOOSApp cout for ncurses "scope" mode
00041     // MOOS has stopped talking by first Iterate()
00042     if(!cout_cleared_)
00043     {
00044         glogger().refresh();
00045         cout_cleared_ = true;
00046     }
00047 
00048     while(connected_ && !msg_buffer_.empty())
00049     {
00050         glogger() << "writing from buffer: " << msg_buffer_.front().GetKey() << ": " << msg_buffer_.front().GetAsString() << std::endl;
00051         m_Comms.Post(msg_buffer_.front());
00052         msg_buffer_.pop_front();
00053     }
00054     
00055     
00056     loop();
00057     return true;
00058 }    
00059 
00060 bool TesMoosApp::OnNewMail(MOOSMSG_LIST &NewMail)
00061 {
00062     BOOST_FOREACH(const CMOOSMsg& msg, NewMail)
00063     {
00064         // update dynamic moos variables - do this inside the loop so the newest is
00065         // also the one referenced in the call to inbox()
00066         dynamic_vars().update_moos_vars(msg);   
00067 
00068         if(msg.GetTime() < start_time_ && ignore_stale_)
00069             glogger() << warn << "ignoring normal mail from " << msg.GetKey()
00070                   << " from before we started (dynamics still updated)"
00071                   << std::endl;
00072         else if(mail_handlers_.count(msg.GetKey()))
00073             mail_handlers_[msg.GetKey()](msg);
00074         else
00075             glogger() << die << "received mail that we have no handler for!" << std::endl;
00076     }
00077     
00078     return true;    
00079 }
00080 
00081 bool TesMoosApp::OnConnectToServer()
00082 {
00083     std::cout << m_MissionReader.GetAppName() << ", connected to server." << std::endl;
00084     connected_ = true;
00085     try_subscribing();
00086     
00087     BOOST_FOREACH(const TesMoosAppConfig::Initializer& ini,
00088                   common_cfg_.initializer())
00089     {   
00090         if(ini.has_global_cfg_var())
00091         {
00092             std::string result;
00093             if(m_MissionReader.GetValue(ini.global_cfg_var(), result))
00094             {
00095                 if(ini.type() == TesMoosAppConfig::Initializer::INI_DOUBLE)
00096                     publish(ini.moos_var(), as<double>(result));
00097                 else if(ini.type() == TesMoosAppConfig::Initializer::INI_STRING)
00098                     publish(ini.moos_var(), result);
00099             }
00100         }
00101         else
00102         {
00103             if(ini.type() == TesMoosAppConfig::Initializer::INI_DOUBLE)
00104                 publish(ini.moos_var(), ini.dval());
00105             else if(ini.type() == TesMoosAppConfig::Initializer::INI_STRING)
00106                 publish(ini.moos_var(), ini.sval());            
00107         }        
00108     }
00109     
00110     return true;
00111 }
00112 
00113 bool TesMoosApp::OnStartUp()
00114 {
00115     std::cout << m_MissionReader.GetAppName () << ", starting ..." << std::endl;
00116     CMOOSApp::SetCommsFreq(common_cfg_.comm_tick());
00117     CMOOSApp::SetAppFreq(common_cfg_.app_tick());
00118     started_up_ = true;
00119     try_subscribing();
00120     return true;
00121 }
00122 
00123 
00124 void TesMoosApp::subscribe(const std::string& var,  InboxFunc handler, int blackout /* = 0 */ )
00125 {
00126     glogger() << "subscribing for MOOS variable: " << var << " @ " << blackout << std::endl;
00127     
00128     pending_subscriptions_.push_back(std::make_pair(var, blackout));
00129     try_subscribing();
00130     mail_handlers_[var] = handler;
00131 }
00132 
00133 void TesMoosApp::try_subscribing()
00134 {
00135     if (connected_ && started_up_)
00136         do_subscriptions();
00137 }
00138 
00139 void TesMoosApp::do_subscriptions()
00140 {
00141     while(!pending_subscriptions_.empty())
00142     {
00143         // variable name, blackout
00144         m_Comms.Register(pending_subscriptions_.front().first,
00145                          pending_subscriptions_.front().second);
00146         glogger() << "subscribed for: " << pending_subscriptions_.front().first << std::endl;
00147         pending_subscriptions_.pop_front();
00148     }
00149 }
00150 
00151 
00152 void TesMoosApp::fetch_moos_globals(google::protobuf::Message* msg,
00153                                     CMOOSFileReader& moos_file_reader)
00154 {
00155     const google::protobuf::Descriptor* desc = msg->GetDescriptor();
00156     const google::protobuf::Reflection* refl = msg->GetReflection();
00157 
00158     for(int i = 0, n = desc->field_count(); i < n; ++i)
00159     {
00160         const google::protobuf::FieldDescriptor* field_desc = desc->field(i);
00161         if(field_desc->is_repeated())
00162             continue;
00163         
00164         std::string moos_global = field_desc->options().GetExtension(::moos_global);
00165         
00166         switch(field_desc->cpp_type())
00167         {
00168             case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE:
00169                 fetch_moos_globals(refl->MutableMessage(msg, field_desc), moos_file_reader);
00170                 break;    
00171                     
00172             case google::protobuf::FieldDescriptor::CPPTYPE_INT32:
00173             {
00174                 int result;
00175                 if(moos_file_reader.GetValue(moos_global, result))
00176                     refl->SetInt32(msg, field_desc, result);
00177                 break;
00178             }
00179             
00180             case google::protobuf::FieldDescriptor::CPPTYPE_INT64:
00181             {
00182                 int result;
00183                 if(moos_file_reader.GetValue(moos_global, result))
00184                     refl->SetInt64(msg, field_desc, result);
00185                 break;
00186             }
00187 
00188             case google::protobuf::FieldDescriptor::CPPTYPE_UINT32:
00189             {
00190                 unsigned result;
00191                 if(moos_file_reader.GetValue(moos_global, result))
00192                     refl->SetUInt32(msg, field_desc, result);
00193                 break;
00194             }
00195 
00196             case google::protobuf::FieldDescriptor::CPPTYPE_UINT64:
00197             {
00198                 unsigned result;
00199                 if(moos_file_reader.GetValue(moos_global, result))
00200                     refl->SetUInt64(msg, field_desc, result);
00201                 break;
00202             }
00203                         
00204             case google::protobuf::FieldDescriptor::CPPTYPE_BOOL:
00205             {
00206                 bool result;
00207                 if(moos_file_reader.GetValue(moos_global, result))
00208                     refl->SetBool(msg, field_desc, result);
00209                 break;
00210             }
00211                     
00212             case google::protobuf::FieldDescriptor::CPPTYPE_STRING:
00213             {
00214                 std::string result;
00215                 if(moos_file_reader.GetValue(moos_global, result))
00216                     refl->SetString(msg, field_desc, result);
00217                 break;
00218             }
00219                 
00220             case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT:
00221             {
00222                 float result;
00223                 if(moos_file_reader.GetValue(moos_global, result))
00224                     refl->SetFloat(msg, field_desc, result);
00225                 break;
00226             }
00227 
00228             case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE:
00229             {
00230                 double result;
00231                 if(moos_file_reader.GetValue(moos_global, result))
00232                     refl->SetDouble(msg, field_desc, result);
00233                 break;
00234             }
00235                 
00236             case google::protobuf::FieldDescriptor::CPPTYPE_ENUM:
00237             {
00238                 std::string result;
00239                 if(moos_file_reader.GetValue(moos_global, result))
00240                 {                
00241                     const google::protobuf::EnumValueDescriptor* enum_desc =
00242                         refl->GetEnum(*msg, field_desc)->type()->FindValueByName(result);
00243                     if(!enum_desc)
00244                         throw(std::runtime_error(std::string("invalid enumeration " +
00245                                                              result + " for field " +
00246                                                              field_desc->name())));
00247                     
00248                     refl->SetEnum(msg, field_desc, enum_desc);
00249                 }
00250                 break;
00251             }
00252         }
00253     }
00254 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends