MOOS 0.2375
/home/toby/moos-ivp/MOOS-2375-Oct0611/NavigationAndControl/pHelm/HelmApp.cpp
Go to the documentation of this file.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines