Goby Underwater Autonomy Project
Series: 1.1, revision: 163, released on 2013-02-06 14:23:27 -0500
|
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 }