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 Basic (Common) Application. 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 00032 #ifdef _WIN32 00033 #pragma warning(disable : 4786) 00034 #pragma warning(disable : 4503) 00035 #endif 00036 00037 00038 00039 // HelmApp.cpp: implementation of the CHelmApp class. 00040 // 00042 #include <MOOSLIB/MOOSLib.h> 00043 #include <MOOSGenLib/MOOSGenLib.h> 00044 #include <MOOSTaskLib/MOOSTaskLib.h> 00045 00046 #include <iostream> 00047 #include <fstream> 00048 #include <sstream> 00049 #include <map> 00050 00051 00052 using namespace std; 00053 #include "HelmApp.h" 00054 00055 #define MAX_TASKS 200 00056 00058 // Construction/Destruction 00060 00061 CHelmApp::CHelmApp() 00062 { 00063 m_bInitialised = false; 00064 00065 m_dfCurrentElevator=0; 00066 m_dfCurrentRudder=0; 00067 m_dfCurrentThrust=0; 00068 00069 00070 //some sensible defaults (missionfile can overwrite this) 00071 SetAppFreq(5); 00072 SetCommsFreq(15); 00073 00074 m_bManualOverRide = true; 00075 00076 } 00077 00078 CHelmApp::~CHelmApp() 00079 { 00080 00081 TASK_LIST::iterator p; 00082 00083 for(p = m_Tasks.begin();p!=m_Tasks.end();p++) 00084 { 00085 delete *p; 00086 00087 } 00088 m_Tasks.clear(); 00089 00090 } 00091 00092 00093 bool CHelmApp::OnNewMail(MOOSMSG_LIST &NewMail) 00094 { 00095 00096 CMOOSMsg Msg; 00097 if(m_Comms.PeekMail(NewMail,"MOOS_MANUAL_OVERIDE",Msg)) 00098 { 00099 if(!Msg.IsSkewed(MOOSTime())) 00100 { 00101 if(MOOSStrCmp(Msg.m_sVal,"TRUE")) 00102 { 00103 MOOSTrace("Manual Overide is on\n"); 00104 MOOSDebugWrite("Manual Overide is on"); 00105 m_bManualOverRide = true; 00106 } 00107 else 00108 { 00109 MOOSTrace("Manual Overide is off\n"); 00110 MOOSDebugWrite("Manual Overide is off!"); 00111 m_bManualOverRide = false; 00112 } 00113 } 00114 } 00115 else if(m_Comms.PeekMail(NewMail,"RESTART_HELM",Msg)) 00116 { 00117 if(!Msg.IsSkewed(MOOSTime())) 00118 { 00119 if(MOOSStrCmp(Msg.m_sVal,"TRUE")) 00120 { 00121 RestartHelm(); 00122 } 00123 } 00124 } 00125 else if(m_Comms.PeekMail(NewMail,"THIRDPARTY_REQUEST",Msg)) 00126 { 00127 OnThirdPartyRequest(Msg); 00128 } 00129 else 00130 { 00131 //send to tasks... 00132 TASK_LIST::iterator p; 00133 00134 for(p = m_Tasks.begin();p!=m_Tasks.end();p++) 00135 { 00136 CMOOSBehaviour* pBehaviour = *p; 00137 00138 pBehaviour->OnNewMail(NewMail); 00139 } 00140 } 00141 return true; 00142 } 00143 00144 00145 bool CHelmApp::OnConnectToServer() 00146 { 00147 00148 string sWPs=MakeWayPointsString(); 00149 m_Comms.Notify("WAY_POINTS",sWPs); 00150 00151 m_Comms.Register("RESTART_HELM",0.1); 00152 m_Comms.Register("MOOS_MANUAL_OVERIDE",0.1); 00153 m_Comms.Register("THIRDPARTY_REQUEST",0.1); 00154 00155 00156 return true; 00157 } 00158 00159 00160 bool CHelmApp::Iterate() 00161 { 00162 if(m_bInitialised==false) 00163 { 00164 MOOSTrace("CHelmApp::Iterate() FAIL : Helm not initialised\n"); 00165 return false; 00166 } 00167 00168 00169 if(IsManualOveride()) 00170 { 00171 //we do nothing! 00172 return true; 00173 } 00174 00175 CPathAction DesiredAction; 00176 00177 OnPreIterate(); 00178 00179 TASK_LIST::iterator p; 00180 00181 double dfTimeNow = MOOSTime(); 00182 00183 for(p = m_Tasks.begin();p!=m_Tasks.end();p++) 00184 { 00185 CMOOSBehaviour* pBehaviour = *p; 00186 00187 pBehaviour->SetTime(dfTimeNow); 00188 00189 if(pBehaviour->ShouldRun()) 00190 { 00191 pBehaviour->Run(DesiredAction); 00192 } 00193 00194 } 00195 00196 OnPostIterate(); 00197 00198 if(m_Transaction.IsOpen()) 00199 { 00200 //if we are OneShot, just close down 00201 if(!m_Transaction.IsTPTaskRunning() && 00202 m_Transaction.IsOneShot()) 00203 { 00204 OnTransactionClose(m_Transaction.GetTransactingClient()); 00205 } 00206 00207 //otherwise just need to keep track of when the TPIT died 00208 //and close the transaction after the sessionTimeOut expires 00209 if(!m_Transaction.IsTPTaskRunning() && 00210 m_Transaction.GetTaskCompleteTime() == -1) 00211 { 00212 m_Transaction.SetTaskCompleteTime(MOOSTime()); 00213 } 00214 else if((m_Transaction.GetTaskCompleteTime() != -1) && 00215 (m_Transaction.IsTPTaskTimeOutExpired())) 00216 { 00217 OnTransactionClose(m_Transaction.GetTransactingClient()); 00218 } 00219 00220 00221 } 00222 00223 //desired is now where we want to go... 00224 double dfEl = DesiredAction.Get(ACTUATOR_ELEVATOR); 00225 SetElevator(dfEl); 00226 00227 double dfRudder = DesiredAction.Get(ACTUATOR_RUDDER); 00228 SetRudder(dfRudder); 00229 00230 double dfThrust = DesiredAction.Get(ACTUATOR_THRUST); 00231 SetThrust(dfThrust); 00232 00233 return true; 00234 } 00235 00236 bool CHelmApp::Initialise() 00237 { 00238 00239 m_bInitialised = false; 00240 00241 m_dfCurrentElevator=0; 00242 m_dfCurrentRudder=0; 00243 m_dfCurrentThrust=0; 00244 00245 00246 //we need to have talked to the DB to get our skew 00247 //time before this as tasks need a start time 00248 //this is unusual behaviour for a MOOS process but 00249 //does mean things are safe... 00250 int nCount = 0; 00251 while(!m_Comms.IsConnected()) 00252 { 00253 00254 MOOSPause(1000); 00255 if(nCount++>30) 00256 { 00257 MOOSTrace("Cannot initialise helm without connecting to Server\n"); 00258 MOOSTrace("Waited 30 seconds..quiting\n"); 00259 return false; 00260 } 00261 } 00262 00263 00264 if(!m_MissionReader.GetConfigurationParam("TASKFILE",m_sTaskFile)) 00265 { 00266 m_sTaskFile = m_sMissionFile; 00267 } 00268 00269 00270 InitialiseTransactors(); 00271 00272 00273 00274 //set up controller gains and limits 00275 if(!GetGains()) 00276 return false; 00277 00278 if(!m_TaskReader.Run( m_sTaskFile.c_str(), 00279 &m_MissionReader, 00280 m_Gains, 00281 m_Tasks)) 00282 { 00283 MOOSDebugWrite("Error in Mission File while making tasks. Helm quits"); 00284 MOOSPause(4000); 00285 return false; 00286 } 00287 00288 00289 00290 //not too many task allowed (ie hundreds...) 00291 if(m_Tasks.size()>MAX_TASKS) 00292 { 00293 MOOSTrace("no more than %d tasks can be run in parrallel %d were requested ! \n",MAX_TASKS,m_Tasks.size()); 00294 return false; 00295 } 00296 00297 //check that we have and EndMission as well as an OverallTimeOut 00298 if(!PassSafetyCheck()) 00299 { 00300 MOOSDebugWrite("Must have both EndMission and OverallTimeOut tasks for Helm to work"); 00301 return false; 00302 } 00303 //helpful to tell the world what waypoints have been made 00304 string sWPs=MakeWayPointsString(); 00305 m_Comms.Notify("WAY_POINTS",sWPs); 00306 00307 00308 //if we have got to here we are OK 00309 m_bInitialised = true; 00310 00311 return m_bInitialised; 00312 } 00313 00314 00315 bool CHelmApp::GetGains() 00316 { 00317 00318 bool bSuccess = true; 00319 00320 //get yaw gains.... 00321 if(!m_MissionReader.GetConfigurationParam("YAW_PID_KP",m_Gains.m_dfYawKp)) 00322 { 00323 MOOSDebugWrite("YAW_PID_KP not found in Mission File"); 00324 bSuccess&=false; 00325 } 00326 if(!m_MissionReader.GetConfigurationParam("YAW_PID_KD",m_Gains.m_dfYawKd)) 00327 { 00328 MOOSDebugWrite("YAW_PID_KD not found in Mission File"); 00329 bSuccess&=false; 00330 } 00331 if(!m_MissionReader.GetConfigurationParam("YAW_PID_KI",m_Gains.m_dfYawKi)) 00332 { 00333 MOOSDebugWrite("YAW_PID_KI not found in Mission File"); 00334 bSuccess&=false; 00335 } 00336 if(!m_MissionReader.GetConfigurationParam("YAW_PID_INTEGRAL_LIMIT",m_Gains.m_dfYawKiMax)) 00337 { 00338 MOOSDebugWrite("YAW_PID_INTEGRAL_LIMIT not found in Mission File"); 00339 bSuccess&=false; 00340 } 00341 00342 if(!m_MissionReader.GetConfigurationParam("Z_TO_PITCH_PID_KP",m_Gains.m_dfZToPitchKp)) 00343 { 00344 MOOSDebugWrite("Z_TO_PITCH_PID_KP not found in Mission File"); 00345 bSuccess&=false; 00346 } 00347 if(!m_MissionReader.GetConfigurationParam("Z_TO_PITCH_PID_KD",m_Gains.m_dfZToPitchKd)) 00348 { 00349 MOOSDebugWrite("Z_TO_PITCH_PID_KD not found in Mission File"); 00350 bSuccess&=false; 00351 } 00352 if(!m_MissionReader.GetConfigurationParam("Z_TO_PITCH_PID_KI",m_Gains.m_dfZToPitchKi)) 00353 { 00354 MOOSDebugWrite("Z_TO_PITCH_PID_KI not found in Mission File"); 00355 bSuccess&=false; 00356 } 00357 if(!m_MissionReader.GetConfigurationParam("Z_TO_PITCH_PID_INTEGRAL_LIMIT",m_Gains.m_dfZToPitchKiMax)) 00358 { 00359 MOOSDebugWrite("Z_TO_PITCH_PID_INTEGRAL_LIMIT not found in Mission File"); 00360 bSuccess&=false; 00361 } 00362 00363 if(!m_MissionReader.GetConfigurationParam("PITCH_PID_KP",m_Gains.m_dfPitchKp)) 00364 { 00365 MOOSDebugWrite("PITCH_PID_KP not found in Mission File"); 00366 bSuccess&=false; 00367 } 00368 if(!m_MissionReader.GetConfigurationParam("PITCH_PID_KD",m_Gains.m_dfPitchKd)) 00369 { 00370 MOOSDebugWrite("PITCH_PID_KD not found in Mission File"); 00371 bSuccess&=false; 00372 } 00373 if(!m_MissionReader.GetConfigurationParam("PITCH_PID_KI",m_Gains.m_dfPitchKi)) 00374 { 00375 MOOSDebugWrite("PITCH_PID_KI not found in Mission File"); 00376 bSuccess&=false; 00377 } 00378 if(!m_MissionReader.GetConfigurationParam("PITCH_PID_INTEGRAL_LIMIT",m_Gains.m_dfPitchKiMax)) 00379 { 00380 MOOSDebugWrite("PITCH_PID_INTEGRAL_LIMIT not found in Mission File"); 00381 bSuccess&=false; 00382 } 00383 00384 //end stops: 00385 if(!m_MissionReader.GetConfigurationParam("MAXPITCH",m_Gains.m_dfMaxPitch)) 00386 { 00387 MOOSDebugWrite("MAXPITCH not found in Mission File"); 00388 bSuccess&=false; 00389 } 00390 if(!m_MissionReader.GetConfigurationParam("MAXELEVATOR",m_Gains.m_dfMaxElevator)) 00391 { 00392 MOOSDebugWrite("MAXELEVATOR not found in Mission File"); 00393 bSuccess&=false; 00394 } 00395 if(!m_MissionReader.GetConfigurationParam("MAXRUDDER",m_Gains.m_dfMaxRudder)) 00396 { 00397 MOOSDebugWrite("MAXRUDDER not found in Mission File"); 00398 bSuccess&=false; 00399 } 00400 if(!m_MissionReader.GetConfigurationParam("MAXTHRUST",m_Gains.m_dfMaxThrust)) 00401 { 00402 MOOSDebugWrite("MAXTHRUST not found in Mission File"); 00403 bSuccess&=false; 00404 } 00405 00406 //now a few human to MOOS conversions 00407 m_Gains.m_dfMaxRudder = MOOSDeg2Rad(m_Gains.m_dfMaxRudder); 00408 m_Gains.m_dfMaxElevator = MOOSDeg2Rad(m_Gains.m_dfMaxElevator); 00409 m_Gains.m_dfMaxPitch = MOOSDeg2Rad(m_Gains.m_dfMaxPitch); 00410 00411 #ifdef VERBOSE 00412 MOOSDebugWrite(MOOSFormat("*** NEW CONTROLLER GAINS ARE:*******")); 00413 MOOSDebugWrite(MOOSFormat("YAW_PID_KP = %f",m_Gains.m_dfYawKp)); 00414 MOOSDebugWrite(MOOSFormat("YAW_PID_KD = %f",m_Gains.m_dfYawKd)); 00415 MOOSDebugWrite(MOOSFormat("YAW_PID_KI = %f",m_Gains.m_dfYawKi)); 00416 MOOSDebugWrite(MOOSFormat("YAW_PID_INTEGRAL_LIMIT = %f",m_Gains.m_dfYawKiMax)); 00417 00418 MOOSDebugWrite(MOOSFormat("Z_TO_PITCH_PID_KP = %f",m_Gains.m_dfZToPitchKp)); 00419 MOOSDebugWrite(MOOSFormat("Z_TO_PITCH_PID_KD = %f",m_Gains.m_dfZToPitchKd)); 00420 MOOSDebugWrite(MOOSFormat("Z_TO_PITCH_PID_KI = %f",m_Gains.m_dfZToPitchKi)); 00421 MOOSDebugWrite(MOOSFormat("Z_TO_PITCH_PID_KI_LIMIT= %f",m_Gains.m_dfZToPitchKiMax)); 00422 00423 MOOSDebugWrite(MOOSFormat("PITCH_PID_KP = %f",m_Gains.m_dfPitchKp)); 00424 MOOSDebugWrite(MOOSFormat("PITCH_PID_KD = %f",m_Gains.m_dfPitchKd)); 00425 MOOSDebugWrite(MOOSFormat("PITCH_PID_KI = %f",m_Gains.m_dfPitchKi)); 00426 MOOSDebugWrite(MOOSFormat("PITCH_PID_KI_LIMIT = %f",m_Gains.m_dfPitchKiMax)); 00427 #endif 00428 00429 00430 return bSuccess; 00431 } 00432 00433 #define UPDATE_INTERVAL 0.2 00434 00435 bool CHelmApp::OnPreIterate() 00436 { 00437 TASK_LIST::iterator p; 00438 00439 STRING_LIST NewResources; 00440 STRING_LIST::iterator q; 00441 00442 for(p = m_Tasks.begin();p!=m_Tasks.end();p++) 00443 { 00444 CMOOSBehaviour* pBehaviour = *p; 00445 00446 if(pBehaviour->HasNewRegistration()) 00447 { 00448 NewResources.clear(); 00449 00450 pBehaviour->GetRegistrations(NewResources); 00451 00452 for(q = NewResources.begin();q!=NewResources.end();q++) 00453 { 00454 if(m_Comms.IsConnected()) 00455 { 00456 m_Comms.Register(*q,UPDATE_INTERVAL); 00457 } 00458 } 00459 } 00460 } 00461 00462 return true; 00463 } 00464 00465 00466 bool CHelmApp::OnPostIterate() 00467 { 00468 TASK_LIST::iterator p; 00469 00470 MOOSMSG_LIST Notifications; 00471 00472 MOOSMSG_LIST::iterator q; 00473 00474 for(p = m_Tasks.begin();p!=m_Tasks.end();p++) 00475 { 00476 CMOOSBehaviour* pBehaviour = *p; 00477 00478 Notifications.clear(); 00479 00480 pBehaviour->GetNotifications(Notifications); 00481 00482 for(q = Notifications.begin();q!=Notifications.end();q++) 00483 { 00484 if(m_Comms.IsConnected()) 00485 { 00486 m_Comms.Post(*q); 00487 } 00488 } 00489 } 00490 00491 return true; 00492 } 00493 00494 00495 00496 00497 00498 bool CHelmApp::SetElevator(double dfAngleRadians) 00499 { 00500 00501 m_dfCurrentElevator=MOOSRad2Deg(dfAngleRadians); 00502 00503 MOOSAbsLimit(m_dfCurrentElevator,MOOSRad2Deg(m_Gains.m_dfMaxElevator)); 00504 00505 m_Comms.Notify("DESIRED_ELEVATOR",m_dfCurrentElevator); 00506 00507 return true; 00508 } 00509 00510 bool CHelmApp::SetRudder(double dfAngleRadians) 00511 { 00512 00513 m_dfCurrentRudder=MOOSRad2Deg(dfAngleRadians); 00514 00515 //the PID should have looked after saturation itself but can never be 00516 //too sure..! 00517 MOOSAbsLimit(m_dfCurrentRudder,MOOSRad2Deg(m_Gains.m_dfMaxRudder)); 00518 00519 m_Comms.Notify("DESIRED_RUDDER",m_dfCurrentRudder); 00520 00521 return true; 00522 } 00523 00524 00525 bool CHelmApp::SetThrust(double dfThrust) 00526 { 00527 00528 m_dfCurrentThrust=dfThrust; 00529 00530 MOOSAbsLimit(m_dfCurrentRudder,m_Gains.m_dfMaxThrust); 00531 00532 m_Comms.Notify("DESIRED_THRUST",m_dfCurrentThrust); 00533 00534 return true; 00535 } 00536 00537 string CHelmApp::MakeWayPointsString() 00538 { 00539 TASK_LIST::iterator p; 00540 00541 string sResult; 00542 for(p = m_Tasks.begin();p!=m_Tasks.end();p++) 00543 { 00544 CMOOSBehaviour * pTask = *p; 00545 00546 CGoToWayPoint* pGotoWpTask = dynamic_cast<CGoToWayPoint*>(pTask); 00547 00548 if(pGotoWpTask!=NULL) 00549 { 00550 ostringstream os; 00551 os <<pGotoWpTask->GetName().c_str() 00552 <<"="<<pGotoWpTask->m_sLocation.c_str() 00553 <<","<<pGotoWpTask->m_dfVicinityRadius<<";"<<ends; 00554 00555 sResult+=os.str(); 00556 00557 // os.rdbuf()->freeze(0); 00558 00559 /*sResult+= pGotoWpTask->GetName() 00560 +"=" 00561 +pGotoWpTask->m_sLocation 00562 +";";*/ 00563 } 00564 00565 } 00566 return sResult; 00567 } 00568 00569 bool CHelmApp::OnStartUp() 00570 { 00571 if(CHelmApp::Initialise()) 00572 { 00573 00574 00575 return true; 00576 } 00577 else 00578 { 00579 return false; 00580 } 00581 00582 00583 } 00584 00585 00586 bool CHelmApp::RestartHelm() 00587 { 00588 MOOSTrace("Helm restarting!!!!\n"); 00589 00590 //tell the system via debug... 00591 MOOSDebugWrite("Helm::Restart()"); 00592 00593 00594 //need to reload mission file 00595 m_MissionReader.SetFile(m_sMissionFile.c_str()); 00596 00597 00598 TASK_LIST::iterator p; 00599 00600 for(p = m_Tasks.begin();p!=m_Tasks.end();p++) 00601 { 00602 delete *p; 00603 00604 } 00605 m_Tasks.clear(); 00606 00607 return Initialise(); 00608 } 00609 00610 bool CHelmApp::IsManualOveride() 00611 { 00612 return m_bManualOverRide; 00613 } 00614 00615 bool CHelmApp::PassSafetyCheck() 00616 { 00617 bool bFoundEndMission = false; 00618 bool bFoundOverallTimeOut = false; 00619 TASK_LIST::iterator p; 00620 00621 for(p = m_Tasks.begin();p!=m_Tasks.end();p++) 00622 { 00623 CMOOSBehaviour * pTask = *p; 00624 00625 CEndMission* pEndMission = dynamic_cast<CEndMission*>(pTask); 00626 00627 if(pEndMission != NULL) 00628 { 00629 bFoundEndMission = true; 00630 } 00631 00632 COverallTimeOut* pOverallTimeOut = dynamic_cast<COverallTimeOut*>(pTask); 00633 00634 if(pOverallTimeOut != NULL) 00635 { 00636 bFoundOverallTimeOut = true; 00637 } 00638 00639 00640 } 00641 00642 return (bFoundEndMission && bFoundOverallTimeOut); 00643 } 00644 00647 bool CHelmApp::OnThirdPartyRequest(CMOOSMsg &Msg) 00648 { 00649 00650 if(m_bManualOverRide) 00651 { 00652 MOOSDebugWrite("Cannot launch Thirdparty Task in manual overide mode (press 'o' to relinquish manual control)"); 00653 return false; 00654 } 00655 00656 double dfTimeNow = MOOSTime(); 00657 //FORMAT is 00658 //JOBNAME@CLIENT:TASK=TASKNAME|Task Parameter 1|Task Parameter 2|etc... 00659 //JOBNAME@CLIENT:CLOSE 00660 string sInstruction = Msg.m_sVal; 00661 string sClient = MOOSChomp(Msg.m_sVal,":"); 00662 string sNotify; 00663 00664 if(m_Transaction.IsOpen()) 00665 { 00666 //check that another client is not requesting a transaction 00667 if(!m_Transaction.IsTransactingClient(sClient) || 00668 m_Transaction.IsOneShot()) 00669 { 00670 sNotify = sClient + 00671 " DENIED Access - Presently Transacting with " + 00672 m_Transaction.GetTransactingClient() + 00673 " [OneShot: " + (m_Transaction.IsOneShot() ? "true" : "false") + 00674 "]"; 00675 return OnTransactionError(sNotify, false); 00676 } 00677 else if(sInstruction.find("TASK") != string::npos) 00678 { 00679 //first close to remove the presently active Task 00680 OnTransactionClose(sClient, false); 00681 return OnTransaction(sInstruction, dfTimeNow); 00682 } 00683 else if(sInstruction.find("CLOSE")!=string::npos) 00684 { 00685 return OnTransactionClose(sClient); 00686 } 00687 else 00688 { 00689 sNotify = m_Transaction.GetTransactingClient() + 00690 " has ALREADY opened a transaction - command not understood"; 00691 return OnTransactionError(sNotify, false); 00692 } 00693 } 00694 else 00695 { 00696 if(sInstruction.find("TASK") != string::npos) 00697 { 00698 return OnTransaction(sInstruction, dfTimeNow); 00699 } 00700 else 00701 { 00702 sNotify = sClient + " Missing 'TASK=' in THIRDPARTY_REQUEST"; 00703 return OnTransactionError(sNotify, false); 00704 } 00705 } 00706 00707 } 00708 00709 bool CHelmApp::CTransaction::HasPermissions(string sRequest) 00710 { 00711 MOOSToUpper(sRequest); 00712 STRING_LIST AllowableTasks = m_PermissionsMap[m_sTransactingClient]; 00713 00714 STRING_LIST::iterator q; 00715 for(q = AllowableTasks.begin(); q != AllowableTasks.end(); q++) 00716 { 00717 //now see if the sRequest the m_sTransactingClient 00718 //wants to accomplish is within its list of permissable 00719 //tasks to spawn 00720 string sAllowedTask = *q; 00721 if(MOOSStrCmp(sRequest,sAllowedTask)) 00722 { 00723 return true; 00724 } 00725 } 00726 00727 00728 //the requesting client's task is not allowed to be launched by them 00729 return false; 00730 00731 } 00732 00733 00734 00735 bool CHelmApp::CTransaction::IsTransactingClient(string sClient) 00736 { 00737 return MOOSStrCmp(sClient,m_sTransactingClient); 00738 } 00739 00740 //add MOOSDbebug info to these methods 00741 bool CHelmApp::OnTransactionOpen(string sClient) 00742 { 00743 //FORMAT is 00744 //JOBNAME@CLIENT 00745 //check that this jobname@client has access 00746 MOOSToUpper(sClient); 00747 if(m_Transaction.HasAccess(sClient)) 00748 { 00749 m_Transaction.SetTransactionIsOpen(true); 00750 m_Transaction.SetTransactingClient(sClient); 00751 m_Transaction.SetTransactingTask(NULL); 00752 m_Transaction.SetTaskCompleteTime(-1); 00753 00754 m_Comms.Notify("CURRENT_THIRDPARTY", m_Transaction.GetTransactingClient()); 00755 00756 return true; 00757 } 00758 else 00759 { 00760 return false; 00761 } 00762 00763 } 00764 00765 bool CHelmApp::OnTransactionClose(string sClient, bool bAnnounce) 00766 { 00767 //search thru the tasks for this job@client and remove/delete the task 00768 TASK_LIST::iterator p; 00769 // MOOSTrace("Task List is %d big\n", m_Tasks.size()); 00770 string sJob = MOOSChomp(sClient,"@"); 00771 MOOSToUpper(sClient); 00772 00773 //can't call the Stop() method because this will cause the 00774 //task to publish FinishFlags, which we don't want to have happen 00775 if(m_Transaction.GetTransactingTask() != NULL) 00776 m_Tasks.remove(m_Transaction.GetTransactingTask()); 00777 00778 // MOOSTrace("After removal, Task List is %d big\n", m_Tasks.size()); 00779 00780 //time to close the connection down 00781 m_Transaction.SetTransactionIsOpen(false); 00782 m_Transaction.SetTransactingClient("NONE"); 00783 m_Transaction.SetTransactingTask(NULL); 00784 00785 if(bAnnounce) 00786 { 00787 m_Comms.Notify("CURRENT_THIRDPARTY", 00788 m_Transaction.GetTransactingClient()); 00789 } 00790 00791 return true; 00792 } 00793 00794 bool CHelmApp::OnTransactionError(string sError, bool bShouldClose) 00795 { 00796 if(bShouldClose) 00797 OnTransactionClose(m_Transaction.GetTransactingClient()); 00798 00799 //create a debug message and post to the DB 00800 MOOSDebugWrite(sError); 00801 00802 return false; 00803 } 00804 00805 bool CHelmApp::OnTransaction(string sInstruction, double dfTimeNow) 00806 { 00807 string sClient, 00808 sTaskName, 00809 sError; 00810 bool bError = false; 00811 00812 m_Transaction.ParseInstruction(sInstruction, sClient, sTaskName); 00813 00814 if(!OnTransactionOpen(sClient)) 00815 { 00816 sError = sClient + " is not ALLOWed to transact"; 00817 bError = true; 00818 } 00819 else if(!m_Transaction.HasPermissions(sTaskName)) 00820 { 00821 sError = m_Transaction.GetTransactingClient() + 00822 " Lacks Permissions for: " + 00823 sTaskName; 00824 bError = true; 00825 } 00826 00827 CMOOSBehaviour * pNewTask = NULL; 00828 pNewTask = m_TaskReader.MakeNewTask(sTaskName); 00829 00830 STRING_LIST ParameterList; 00831 if(pNewTask != NULL) 00832 { 00833 //task built correctly, now figure out its parameters 00834 m_Transaction.BuildParameterList(sInstruction, ParameterList); 00835 pNewTask->SetGains(m_Gains); 00836 pNewTask->SetName(sTaskName); 00837 00838 STRING_LIST::iterator p; 00839 for(p = ParameterList.begin(); p != ParameterList.end(); p++) 00840 { 00841 string sLine = *p; 00842 MOOSToUpper(sLine); 00843 00844 string sTok; 00845 string sVal; 00846 00847 if(m_MissionReader.GetTokenValPair(sLine,sTok,sVal)) 00848 { 00849 if(!pNewTask->SetParam(sTok, sVal)) 00850 { 00851 string sError = "THIRDPARTY parse fail on " + sLine; 00852 bError = true; 00853 } 00854 } 00855 00856 } 00857 } 00858 else 00859 { 00860 sError = "THIRDPARTY TASK creation FAIL"; 00861 bError = true; 00862 } 00863 00864 00865 00866 //let us know if we were successful 00867 if(!bError) 00868 { 00869 //keep track of this task with our pointer 00870 m_Transaction.SetTransactingTask(pNewTask); 00871 00872 //necessary? 00873 //pNewTask->SetMissionFileReader(pMissionFileReader); 00874 00875 //ask task about its priority - if(priority < 2) -> set to 2 00876 //only make tasks with max priority of 2 00877 if(pNewTask->GetPriority() < 2) 00878 pNewTask->SetPriority(2); 00879 00880 //always make the initialstate ON 00881 pNewTask->SetParam("INITIALSTATE", "ON"); 00882 m_Tasks.push_front(pNewTask); 00883 00884 return true; 00885 } 00886 else 00887 { 00888 delete pNewTask; 00889 return OnTransactionError(sError); 00890 } 00891 00892 } 00893 00894 bool CHelmApp::InitialiseTransactors() 00895 { 00896 //a CTransaction object is responsible for knowing about transactions 00897 m_Transaction.Initialise(); 00898 00899 //FORMAT is 00900 //ALLOW = JOBNAME@CLIENT:TASK1,TASK2|SessionTimeOut=value 00901 STRING_LIST Params; 00902 PERMISSIONS_MAP PermissionsMap; 00903 SESSION_TIMEOUT_MAP SessionTimeOutMap; 00904 00905 if(m_MissionReader.GetConfiguration(m_sAppName,Params)) 00906 { 00907 00908 STRING_LIST::iterator p; 00909 for(p=Params.begin();p!=Params.end();p++) 00910 { 00911 string sParam = *p; 00912 //get rid of the whitespace 00913 MOOSRemoveChars(sParam," "); 00914 00915 string sWhat = MOOSChomp(sParam,"="); 00916 MOOSToUpper(sWhat); 00917 00918 if(MOOSStrCmp(sWhat,"ALLOW")) 00919 { 00920 //Tasks that can be fired by the JOB@CLIENT 00921 string sClientInfo = MOOSChomp(sParam,"|"); 00922 string sWho = MOOSChomp(sClientInfo,":"); 00923 MOOSToUpper(sWho); 00924 00925 STRING_LIST Tasks; 00926 00927 while(!sClientInfo.empty()) 00928 { 00929 string sUpperParam = MOOSChomp(sClientInfo,","); 00930 MOOSToUpper(sUpperParam); 00931 Tasks.push_front(sUpperParam); 00932 } 00933 00934 PermissionsMap[sWho] = Tasks; 00935 00936 //SessionTimeOuts for these particular Tasks 00937 string sVar = MOOSChomp(sParam, "="); 00938 MOOSToUpper(sVar); 00939 if(MOOSStrCmp(sVar, "SESSIONTIMEOUT")) 00940 { 00941 double dfVal = atof(sParam.c_str()); 00942 if((dfVal > 0) && (dfVal < MAX_SESSION_TIMEOUT)) 00943 { 00944 SessionTimeOutMap[sWho] = dfVal; 00945 } 00946 else if((dfVal > 0) && (dfVal > MAX_SESSION_TIMEOUT)) 00947 { 00948 SessionTimeOutMap[sWho] = MAX_SESSION_TIMEOUT; 00949 } 00950 } 00951 } 00952 00953 } 00954 00955 //make sure the Transacation knows about these maps 00956 m_Transaction.SetPermissionsMap(PermissionsMap); 00957 m_Transaction.SetSessionTimeOutMap(SessionTimeOutMap); 00958 } 00959 00960 //we initially are not talking to anyone 00961 m_Comms.Notify("CURRENT_THIRDPARTY", "NONE"); 00962 00963 return true; 00964 } 00965 00966 bool CHelmApp::CTransaction::BuildParameterList(string sList, STRING_LIST &ParameterList) 00967 { 00968 //remove the whitespace 00969 MOOSRemoveChars(sList," "); 00970 //sList has format: 00971 //LOCATION=0,0,0|RADIUS=5 00972 while(!sList.empty()) 00973 { 00974 string sWhat = MOOSChomp(sList,"|"); 00975 MOOSToUpper(sWhat); 00976 ParameterList.push_front(sWhat); 00977 } 00978 00979 00980 return true; 00981 } 00982 00983 00984 bool CHelmApp::CTransaction::HasAccess(string sClient) 00985 { 00986 //although this method seems redundant, it is responsible for 00987 //being the first layer of security and prevents us from 00988 //opening a connection to a JOB that we should not be dealing 00989 //with in the first place 00990 00991 MOOSToUpper(sClient); 00992 PERMISSIONS_MAP::iterator p = m_PermissionsMap.find(sClient); 00993 00994 if(p != m_PermissionsMap.end()) 00995 { 00996 return true; 00997 } 00998 else 00999 return false; 01000 } 01001 01002 01003 bool CHelmApp::CTransaction::IsOpen() 01004 { 01005 return m_bTransactionIsOpen; 01006 } 01007 01008 bool CHelmApp::CTransaction::IsTPTaskRunning() 01009 { 01010 if(m_pTransactingTask != NULL) 01011 return m_pTransactingTask->ShouldRun(); 01012 else 01013 return false; 01014 } 01015 01016 bool CHelmApp::CTransaction::IsTPTaskTimeOutExpired() 01017 { 01018 return ((MOOSTime() - GetTaskCompleteTime()) > GetSessionTimeOut()); 01019 } 01020 01021 bool CHelmApp::CTransaction::IsOneShot() 01022 { 01023 return (m_dfSessionTimeOut == 0.0); 01024 } 01025 01026 01027 CHelmApp::CTransaction::CTransaction() 01028 { 01029 01030 } 01031 01032 CHelmApp::CTransaction::~CTransaction() 01033 { 01034 01035 } 01036 01037 bool CHelmApp::CTransaction::Initialise() 01038 { 01039 SetTransactingClient("NONE"); 01040 SetTransactionIsOpen(false); 01041 SetTransactingTask(NULL); 01042 SetSessionTimeOut(0.0);//assume OneShot 01043 SetTaskCompleteTime(-1); 01044 01045 return true; 01046 } 01047 01048 void CHelmApp::CTransaction::SetTaskCompleteTime(double dfCompleteTime) 01049 { 01050 m_dfTPTaskCompleteTime = dfCompleteTime; 01051 } 01052 01053 void CHelmApp::CTransaction::SetTransactingClient(string sClient) 01054 { 01055 m_sTransactingClient = sClient; 01056 01057 if(m_sTransactingClient != "NONE") 01058 SetSessionTimeOut(m_SessionTimeOutMap[m_sTransactingClient]); 01059 else 01060 SetSessionTimeOut(0.0); 01061 } 01062 01063 void CHelmApp::CTransaction::SetSessionTimeOut(double dfTimeOut) 01064 { 01065 m_dfSessionTimeOut = dfTimeOut; 01066 } 01067 01068 void CHelmApp::CTransaction::SetTransactingTask(CMOOSBehaviour *pNewTask) 01069 { 01070 m_pTransactingTask = pNewTask; 01071 } 01072 01073 void CHelmApp::CTransaction::SetTransactionIsOpen(bool bOpen) 01074 { 01075 m_bTransactionIsOpen = bOpen; 01076 } 01077 01078 CMOOSBehaviour * CHelmApp::CTransaction::GetTransactingTask() 01079 { 01080 return m_pTransactingTask; 01081 } 01082 01083 double CHelmApp::CTransaction::GetSessionTimeOut() 01084 { 01085 return m_dfSessionTimeOut; 01086 } 01087 01088 string CHelmApp::CTransaction::GetTransactingClient() 01089 { 01090 return m_sTransactingClient; 01091 } 01092 01093 double CHelmApp::CTransaction::GetTaskCompleteTime() 01094 { 01095 return m_dfTPTaskCompleteTime; 01096 } 01097 01098 bool CHelmApp::CTransaction::ParseInstruction(string &sInstruction, string &sClient, string &sTaskName) 01099 { 01100 //need a Transaction object that stores all this stuff once 01101 //FORMAT is 01102 //JOB@CLIENT:TASK=TASKNAME|Task Parameter 1|Task Parameter 2 01103 string sBeginning = MOOSChomp(sInstruction,"|"); 01104 01105 sClient = MOOSChomp(sBeginning,":"); 01106 01107 MOOSChomp(sBeginning,"="); 01108 01109 sTaskName = sBeginning; 01110 01111 return true; 01112 } 01113 01114 void CHelmApp::CTransaction::SetPermissionsMap(PERMISSIONS_MAP PermissionsMap) 01115 { 01116 m_PermissionsMap = PermissionsMap; 01117 } 01118 01119 void CHelmApp::CTransaction::SetSessionTimeOutMap(SESSION_TIMEOUT_MAP SessionMap) 01120 { 01121 m_SessionTimeOutMap = SessionMap; 01122 }