MOOS 0.2375
|
00001 00002 // 00003 // MOOS - Mission Oriented Operating Suite 00004 // 00005 // A suit of Applications and Libraries for Mobile Robotics Research 00006 // Copyright (C) 2001-2005 Massachusetts Institute of Technology and 00007 // Oxford University. 00008 // 00009 // This software was written by Paul Newman and others 00010 // at MIT 2001-2002 and Oxford University 2003-2005. 00011 // email: pnewman@robots.ox.ac.uk. 00012 // 00013 // This file is part of a MOOS Instrument. 00014 // 00015 // This program is free software; you can redistribute it and/or 00016 // modify it under the terms of the GNU General Public License as 00017 // published by the Free Software Foundation; either version 2 of the 00018 // License, or (at your option) any later version. 00019 // 00020 // This program is distributed in the hope that it will be useful, 00021 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00022 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00023 // General Public License for more details. 00024 // 00025 // You should have received a copy of the GNU General Public License 00026 // along with this program; if not, write to the Free Software 00027 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 00028 // 02111-1307, USA. 00029 // 00031 // MOOSJanitor.cpp: implementation of the CMOOSJanitor class. 00032 // 00034 #include <MOOSLIB/MOOSLib.h> 00035 #include <sstream> 00036 #include <cstring> 00037 #include <iomanip> 00038 #include "MOOSJanitor.h" 00039 #define GROUND_FAULT 100 00040 #define BLUEFIN_WATCHDOG_PERIOD 1.0 00041 #define DIAGNOSTIC_INTERVAL 5.0 00042 00044 // Construction/Destruction 00046 00047 using namespace std; 00048 00049 CMOOSJanitor::CMOOSJanitor() 00050 { 00051 m_sVehicleType="BLUEFIN"; 00052 m_dfLastWDHit = 0; 00053 m_dfLastDiagnostic = 0; 00054 m_bAutoWatchDog = false; 00055 } 00056 00057 CMOOSJanitor::~CMOOSJanitor() 00058 { 00059 00060 } 00061 00062 bool CMOOSJanitor::Iterate() 00063 { 00064 00065 if(m_bAutoWatchDog) 00066 { 00067 HitTailConeWD(); 00068 } 00069 00070 // DoDiagnostics(); 00071 00072 return true; 00073 } 00074 00075 00076 bool CMOOSJanitor::OnStartUp() 00077 { 00078 //call base class member first 00079 CMOOSInstrument::OnStartUp(); 00080 00081 m_MissionReader.GetValue("VEHICLETYPE",m_sVehicleType); 00082 00083 string sWD; 00084 m_MissionReader.GetValue("AUTOWATCHDOG",sWD); 00085 00086 m_bAutoWatchDog = MOOSStrCmp(sWD,"TRUE"); 00087 00088 if(IsSimulateMode()) 00089 { 00090 //not much to do... 00091 RegisterMOOSVariables(); 00092 } 00093 else 00094 { 00095 if(IsBluefinVehicle()) 00096 { 00097 //try to open 00098 if(!SetupPort()) 00099 { 00100 return false; 00101 } 00102 00103 if(!SetUpSwitches()) 00104 { 00105 return false; 00106 } 00107 00108 } 00109 } 00110 00111 00112 00113 return true; 00114 } 00115 00116 00117 00118 bool CMOOSJanitor::OnNewMail(MOOSMSG_LIST &NewMail) 00119 { 00120 CMOOSMsg Msg; 00121 00122 if(m_Comms.PeekMail(NewMail,"JANITOR_RESTART",Msg,true)) 00123 { 00124 SetUpSwitches(); 00125 } 00126 00127 if(m_Comms.PeekMail(NewMail,"ACTUATION_WD_HIT",Msg,true)) 00128 { 00129 if(IsBluefinVehicle()) 00130 { 00131 HitTailConeWD(); 00132 } 00133 } 00134 00135 while(m_Comms.PeekMail(NewMail,"JANITOR_SWITCH",Msg,true)) 00136 { 00137 if(IsBluefinVehicle()) 00138 { 00139 OnSwitch(Msg); 00140 } 00141 } 00142 00143 return UpdateMOOSVariables(NewMail); 00144 } 00145 00146 bool CMOOSJanitor::OnConnectToServer() 00147 { 00148 00149 //register for a restart signal 00150 m_Comms.Register("JANITOR_RESTART",0); 00151 00152 //register for explicit circuit control 00153 m_Comms.Register("JANITOR_SWITCH",0); 00154 00155 if(IsBluefinVehicle()) 00156 { 00157 //register for wathc dog hit from iACtuation... 00158 m_Comms.Register("ACTUATION_WD_HIT",3.0); 00159 } 00160 00161 return true; 00162 } 00163 00164 00165 00166 bool CMOOSJanitor::BootBluefinVehicle() 00167 { 00168 00169 return true; 00170 } 00171 00172 bool CMOOSJanitor::IsBluefinVehicle() 00173 { 00174 return MOOSStrCmp("BLUEFIN",m_sVehicleType); 00175 } 00176 00177 bool CMOOSJanitor::SetUpSwitches() 00178 { 00179 STRING_LIST sParams; 00180 00181 if(!m_MissionReader.GetConfiguration(GetAppName(),sParams)) 00182 { 00183 return false; 00184 } 00185 00186 STRING_LIST::iterator q; 00187 00188 bool bOK = true; 00189 00190 for(q = sParams.begin();q!=sParams.end();q++) 00191 { 00192 string sLine = *q; 00193 string sTok,sVal; 00194 if(m_MissionReader.GetTokenValPair(sLine,sTok,sVal)) 00195 { 00196 if(MOOSStrCmp("SWITCH",sTok)) 00197 { 00198 //this is a switch command... 00199 // eg Switch = GPS @ 1 : On 00200 00201 string sResourceName = MOOSChomp(sVal,"@"); 00202 string sCircuit = MOOSChomp(sVal,":"); 00203 string sInitial = sVal; 00204 00205 CResourceCircuit NewResource; 00206 00207 NewResource.m_bInitialState = MOOSStrCmp(sInitial,"ON"); 00208 NewResource.m_nCircuit = atoi(sCircuit.c_str()); 00209 NewResource.m_sConnectedResource = sResourceName; 00210 00211 m_Resources[sResourceName] = NewResource; 00212 00213 if(!SetSwitch(sResourceName,NewResource.m_bInitialState)) 00214 { 00215 MOOSTrace("Control of Switch %s failed...\n\a",sResourceName.c_str()); 00216 bOK = false; 00217 } 00218 00219 } 00220 } 00221 } 00222 00223 return bOK; 00224 } 00225 00226 bool CMOOSJanitor::SetSwitch(const string &sResource, bool bVal) 00227 { 00228 RESOURCEMAP::iterator p = m_Resources.find(sResource); 00229 00230 if(p!=m_Resources.end()) 00231 { 00232 CResourceCircuit & rResource = p->second; 00233 int nCircuit = rResource.m_nCircuit; 00234 00235 stringstream os; 00236 00237 if(nCircuit>15) 00238 return false; 00239 00240 //figure out stem of command 00241 char i2x[]="0123456789ABCDEF"; 00242 os<<(bVal==true?"N":"F")<<i2x[nCircuit]<<ends; 00243 00244 string sStem = os.str(); 00245 00246 //pre-pend # for command 00247 string sTx = "#"+sStem; 00248 00249 00250 00251 m_Port.Write((char *)sTx.c_str(),sTx.size()); 00252 00253 //send command 00254 string sReply; 00255 if(!m_Port.GetTelegram(sReply,2)) 00256 { 00257 MOOSTrace("CMOOSJanitor::SetSwitch() PowerBoard Not responding... \n"); 00258 return false; 00259 } 00260 00261 //now parse reply 00262 if(sReply.find("ERR")!=string::npos) 00263 { 00264 //gross error... 00265 MOOSTrace("CMOOSJanitor::SetSwitch() Power Board returns \"ERR\" to command \"%s\"...\n", 00266 sTx.c_str()); 00267 return false; 00268 } 00269 00270 string sExpected ="$"+sStem+" 1"; 00271 if(sReply.find(sExpected)!=string::npos) 00272 { 00273 //reply is good 00274 rResource.m_bCurrentState = bVal; 00275 MOOSTrace("CMOOSJanitor: Turning resource \"%s\" %s [circuit %d]\n", 00276 rResource.m_sConnectedResource.c_str(), 00277 bVal==true?"ON":"OFF", 00278 nCircuit); 00279 00280 00281 } 00282 else 00283 { 00284 MOOSTrace("CMOOSJanitor::SetSwitch() Power Board returns \"%s\" to command \"%s\"...\n", 00285 sReply.c_str(), 00286 sTx.c_str()); 00287 return false; 00288 } 00289 00290 } 00291 else 00292 { 00293 MOOSTrace("CMOOSJanitor::SetSwitch() Resource \"%s\" not found\n",sResource.c_str()); 00294 return false; 00295 } 00296 00297 return true; 00298 } 00299 00300 bool CMOOSJanitor::HitTailConeWD() 00301 { 00302 if(MOOSTime()-m_dfLastWDHit<BLUEFIN_WATCHDOG_PERIOD) 00303 return true; 00304 00305 //reset wathcdog on power board.. 00306 string sTx = "#TA"; 00307 m_Port.Write((char*)sTx.c_str(),sTx.size()); 00308 string sRx; 00309 00310 if(!m_Port.GetTelegram(sRx,1.0)) 00311 { 00312 MOOSTrace("PowerBoard not responding to wathcdog reset...\n"); 00313 return false; 00314 } 00315 else 00316 { 00317 m_dfLastWDHit = MOOSTime(); 00318 MOOSTrace("[%f] Tail Cone WD Hit.\n", 00319 m_dfLastWDHit-GetAppStartTime()); 00320 } 00321 00322 return true; 00323 } 00324 00325 bool CMOOSJanitor::OnSwitch(CMOOSMsg &Msg) 00326 { 00327 //now, what are we being asked to do? 00328 //Msg.m_sVal = "Resource : On" 00329 if(Msg.m_cDataType==MOOS_STRING) 00330 { 00331 string sStr = Msg.m_sVal; 00332 MOOSRemoveChars(sStr," "); 00333 string sResource = MOOSChomp(sStr,":"); 00334 string sState = sStr; 00335 bool bState = MOOSStrCmp(sState,"ON"); 00336 00337 return SetSwitch(sResource,bState); 00338 } 00339 00340 //wrong data type!!! 00341 return false; 00342 } 00343 00344 bool CMOOSJanitor::GetTemperature() 00345 { 00346 00347 00348 //ok so do it.. 00349 char sTx[]="#K1"; 00350 if(!m_Port.Write(sTx,strlen(sTx))) 00351 { 00352 return false; 00353 } 00354 00355 string sReply; 00356 if(!m_Port.GetTelegram(sReply,2.0)) 00357 { 00358 return false; 00359 } 00360 00361 //process reply 00362 MOOSChomp(sReply,"$K1 "); 00363 stringstream is(sReply.c_str()); 00364 is.flags(ios::hex); 00365 int nHex; 00366 is>>nHex; 00367 00368 m_dfTemperature = nHex*500.0/1024.0; 00369 00370 m_Comms.Notify("SPHERE_TEMP",m_dfTemperature); 00371 00372 bool bOn; 00373 00374 if(GetSwitchState("FAN",bOn)) 00375 { 00376 if(m_dfTemperature>30.0 && !bOn ) 00377 { 00378 MOOSDebugWrite("Its getting hot in here...turning fan on"); 00379 SetSwitch("FAN",true); 00380 } 00381 if(m_dfTemperature<27.0 && bOn) 00382 { 00383 MOOSDebugWrite("Its cool enough. Turning fan off"); 00384 SetSwitch("FAN",false); 00385 } 00386 } 00387 return true; 00388 } 00389 00390 bool CMOOSJanitor::GetSwitchState(const string &sResource, bool &bState) 00391 { 00392 RESOURCEMAP::iterator p = m_Resources.find(sResource); 00393 00394 if(p!=m_Resources.end()) 00395 { 00396 CResourceCircuit & rResource = p->second; 00397 bState = rResource.m_bCurrentState; 00398 return true; 00399 } 00400 00401 return false; 00402 } 00403 00404 bool CMOOSJanitor::GetGroundFaults() 00405 { 00406 //ok so do it.. 00407 vector<string> Names; 00408 Names.push_back("Bat Bus +"); 00409 Names.push_back("Bat Bus -"); 00410 Names.push_back("ISO 12V+"); 00411 Names.push_back("ISO 12V-"); 00412 00413 00414 bool bGroundFault = false; 00415 unsigned int i; 00416 for(i = 0;i<Names.size();i++) 00417 { 00418 string sTx = MOOSFormat("#G%d",i); 00419 if(m_Port.Write((char*)sTx.c_str(),sTx.size())) 00420 { 00421 string sReply; 00422 if(m_Port.GetTelegram(sReply,2.0)) 00423 { 00424 //process reply 00425 string sExpected = MOOSFormat("$G%d",i); 00426 00427 MOOSChomp(sReply,sExpected); 00428 if(!sReply.empty()) 00429 { 00430 stringstream is(sReply.c_str()); 00431 is.flags(ios::hex); 00432 int nHex; 00433 is>>nHex; 00434 00435 00436 if(nHex>GROUND_FAULT) 00437 { 00438 string sGF; 00439 if(i != 1) 00440 { 00441 sGF = MOOSFormat("JANITOR: Warning, suspected Ground fault in %s [%d]", 00442 Names[i].c_str(), 00443 nHex); 00444 } 00445 else 00446 { 00447 sGF = MOOSFormat("JANITOR: Warning, suspected Ground fault in %s [%d] is shore power on?", 00448 Names[i].c_str(), 00449 nHex); 00450 } 00451 MOOSDebugWrite(sGF); 00452 } 00453 } 00454 } 00455 } 00456 } 00457 00458 return true; 00459 } 00460 00461 bool CMOOSJanitor::GetLeaks() 00462 { 00463 //ok so do it.. 00464 vector<string> Names; 00465 Names.push_back("Sphere"); 00466 Names.push_back("Aft JBox"); 00467 Names.push_back("Forward JBox"); 00468 00469 unsigned int i; 00470 for(i = 0;i<Names.size();i++) 00471 { 00472 string sTx = MOOSFormat("#L%d",i); 00473 if(m_Port.Write((char*)sTx.c_str(),sTx.size())) 00474 { 00475 string sReply; 00476 if(m_Port.GetTelegram(sReply,2.0)) 00477 { 00478 //process reply 00479 string sExpected = MOOSFormat("$L%d",i); 00480 00481 MOOSChomp(sReply,sExpected); 00482 if(!sReply.empty()) 00483 { 00484 int nLeak = atoi(sReply.c_str()); 00485 if(nLeak !=0) 00486 { 00487 string sLeak = MOOSFormat("JANITOR: SEVERE!! Leak in %s",Names[i].c_str()); 00488 MOOSDebugWrite(sLeak); 00489 } 00490 } 00491 } 00492 } 00493 } 00494 00495 return true; 00496 } 00497 00498 bool CMOOSJanitor::DoDiagnostics() 00499 { 00500 00501 if(MOOSTime()-m_dfLastDiagnostic<DIAGNOSTIC_INTERVAL) 00502 { 00503 return true; 00504 } 00505 else 00506 { 00507 m_dfLastDiagnostic = MOOSTime(); 00508 } 00509 00510 GetTemperature(); 00511 GetGroundFaults(); 00512 GetLeaks(); 00513 00514 return true; 00515 00516 }