- Main Page
- Namespaces
- Classes
- Files
- Related Pages

# /Users/fpy/titan-1-5-MBARI/Mers/Interfaces/ExecutionInterface.cpp

    00001
    00002 //
    00003 // Copyright (c) 2004           Model-based Embedded and Robotic Systems Group
    00004 // All Rights Reserved          Massachusetts Institute of Technology
    00005 //
    00006 // This software is provided as is. Model-based Embedded and Robotic Systems
    00007 // (MERS) group does not assume any responsibility.
    00008 //
    00009 // Organization:        Model-based Embedded and Robotic Systems Group
    00010 //                                      Massachusetts Institute of Technology
    00011 //
    00013
    00014 #define PREFIX "ExecutionInterface : "
    00015 #define TRACE(x) { LOG4CPLUS_TRACE( mLogger, PREFIX << x ); }
    00016 #define DEBUG(x) { LOG4CPLUS_DEBUG( mLogger, PREFIX << x ); }
    00017 #define INFO(x)  { LOG4CPLUS_INFO ( mLogger, PREFIX << x ); }
    00018 #define ERROR(x) { LOG4CPLUS_ERROR( mLogger, std::endl << " *** " << PREFIX << x << " ***" << std::endl ); }
    00019
    00020 #include "ExecutionInterface.h"
    00021
    00022 #include <Mers/Interfaces/Task.h>
    00023 #include <Mers/Interfaces/TaskFactory.h>
    00024
    00026
    00027 using Mers::Interfaces::ExecutionInterface;
    00028 using Mers::Interfaces::Task;
    00029 using Mers::Utils::Lang::String;
    00030 using std::set;
    00031 using std::vector;
    00032 using log4cplus::Logger;
    00033
    00035
    00036 Logger ExecutionInterface::mLogger
    00037         (Logger::getInstance("Mers.Interfaces.ExecutionInterface"));
    00038
    00040
    00041 ExecutionInterface::ExecutionInterface( TaskFactory *pTaskFactory ) :
    00042         ExecutionInterfaceBase( pTaskFactory ),
    00043         Mutex( "ExecutionInterface" )
    00044 {
    00045         mFailedTasks.clear();
    00046         completedTasks.clear();
    00047   currentTasks.clear();
    00048   recentlyFailedTasks.clear();
    00049         recentlyCompletedTasks.clear();
    00050         tasksToStart.clear();
    00051         tasksToStop.clear();
    00052 }
    00053
    00055
    00056 ExecutionInterface::~ExecutionInterface()
    00057 {
    00058 }
    00059
    00061
    00062 bool ExecutionInterface::start(TaskIdentifier taskID)
    00063 {
    00064         // Schedule the task to be started by the next call to step(...)
    00065         t_TaskSharedPointer pTask = getTask( taskID );
    00066         if( !pTask ) {
    00067                 ERROR( "start(...) : Task ID " << taskID << " not found" );
    00068                 return false;
    00069         }
    00070         LockMutex();
    00071         if( find( currentTasks.begin(), currentTasks.end(), taskID ) != currentTasks.end() ) {
    00072                 TRACE( "start(...) : Task ID " << taskID << " ( " << pTask->toString() << " ) is already running - ignoring start request" );
    00073         }
    00074         else if( find( completedTasks.begin(), completedTasks.end(), taskID ) != completedTasks.end() ) {
    00075                 TRACE( "start(...) : Task ID " << taskID << " ( " << pTask->toString() << " ) has already been executed - ignoring start request" );
    00076         }
    00077         else {
    00078                 TRACE( "start(...) : Scheduling task ID " << taskID << " ( " << pTask->toString() << " ) for starting" );
    00079                 tasksToStart.insert( taskID );
    00080         }
    00081         UnlockMutex();
    00082         return true;
    00083 }
    00084
    00086
    00087 bool ExecutionInterface::stop()
    00088 {
    00089         // Schedule all active tasks to be stopped by the next call to step(...)
    00090         // Only valid IDs ever make it to the currentTasks list, so we don't need to check them
    00091         LockMutex();
    00092         for( set<TaskIdentifier>::iterator iter = currentTasks.begin(); iter!=currentTasks.end(); iter++ ) {
    00093                 TRACE( "stop() : Scheduling task ID " << *iter << " for stopping" );
    00094     tasksToStop.insert( *iter );
    00095         }
    00096         UnlockMutex();
    00097         return true;
    00098 }
    00099
    00101
    00102 bool ExecutionInterface::stop(TaskIdentifier taskID)
    00103 {
    00104         // Schedule the task to be stopped by the next call to step(...)
    00105         t_TaskSharedPointer pTask = getTask( taskID );
    00106         if( !pTask ) {
    00107                 ERROR( "stop(...) : Task ID " << taskID << " not found" );
    00108                 return false;
    00109         }
    00110         LockMutex();
    00111         if( find( currentTasks.begin(), currentTasks.end(), taskID ) == currentTasks.end() ) {
    00112                 TRACE( "stop(...) : Task ID " << taskID << " ( " << pTask->toString() << " )  is not currently executing - ignoring stop request" );
    00113         }
    00114         else if( find( completedTasks.begin(), completedTasks.end(), taskID ) != completedTasks.end() ) {
    00115                 TRACE( "stop(...) : Task ID " << taskID << " ( " << pTask->toString() << " )  has already completed - ignoring stop request" );
    00116         }
    00117         else {
    00118                 TRACE( "stop(...) : Scheduling task ID " << taskID << " ( " << pTask->toString() << " )  for stopping" );
    00119                 tasksToStop.insert( taskID );
    00120         }
    00121         UnlockMutex();
    00122         return true;
    00123 }
    00124
    00126
    00127 int ExecutionInterface::step(bool)
    00128 {
    00129         LockMutex();
    00130
    00131         recentlyFailedTasks.clear();
    00132         recentlyCompletedTasks.clear();
    00133
    00134         // Check for recently completed and failed tasks
    00135         // Must do this before we try to stop any tasks
    00136         TRACE( "step(...) : Checking for completed and failed tasks" );
    00137         set<TaskIdentifier>::iterator iter = currentTasks.begin();
    00138         while( iter!=currentTasks.end() ) {
    00139
    00140                 TaskIdentifier taskID = *iter;
    00141                 t_TaskSharedPointer pTask = getTask( taskID );
    00142
    00143                 if( pTask->Completed() || pTask->Failed() ) {
    00144
    00145                         if( pTask->Completed() ) {
    00146                                 TRACE( "Task ID " << taskID << " ( " << pTask->toString() << " ) has completed" );
    00147                                 recentlyCompletedTasks.insert( taskID );
    00148                                 completedTasks.insert( taskID );
    00149                         }
    00150
    00151                         if( pTask->Failed() ) {
    00152                                 TRACE( "Task ID " << taskID << " ( " << pTask->toString() << " ) has failed" );
    00153                                 recentlyFailedTasks.insert( taskID );
    00154                                 mFailedTasks.insert( taskID );
    00155                         }
    00156
    00157                         // only remove it from the currentTasks list once!
    00158                         // once we call erase, the iterator is invalid, so take a copy and increment before we erase
    00159                         set<TaskIdentifier>::iterator nextIter = iter;
    00160                         nextIter++;
    00161                         currentTasks.erase( iter );
    00162                         iter = nextIter;
    00163
    00164                 }
    00165                 else {
    00166                         // increment iterator
    00167                         iter++;
    00168                 }
    00169
    00170         }
    00171
    00172         // Stop tasks
    00173         TRACE( "step(...) : Stopping " << tasksToStop.size() << " tasks" );
    00174         while( !tasksToStop.empty() ) {
    00175                 TaskIdentifier taskID = *tasksToStop.begin();
    00176                 t_TaskSharedPointer pTask = getTask( taskID );
    00177
    00178                 // If task has recently completed it will not be in the currentTasks list but will be in the recentlyCompletedTasks list
    00179                 if( find( currentTasks.begin(), currentTasks.end(), taskID ) == currentTasks.end() ) {
    00180                         if( find( recentlyCompletedTasks.begin(), recentlyCompletedTasks.end(), taskID ) != recentlyCompletedTasks.end() ) {
    00181                                 TRACE( "step(...) : Task ID "  << taskID << " ( " << pTask->toString() << " ) has recently completed - no need to stop" );
    00182                                 tasksToStop.erase( taskID );
    00183                                 continue;
    00184                         }
    00185                         else {
    00186                                 // The task is scheduled to be stopped, but isn't running and hasn't recently completed - error!
    00187                                 ERROR( "Logic error : Task ID " << taskID << " ( " << pTask->toString() << " ) is scheduled to be stopped, but isn't running and hasn't recently completed!" );
    00188                                 UnlockMutex();
    00189                                 return 2;
    00190                         }
    00191                 }
    00192                 if( pTask->Stop() ) {
    00193                         currentTasks.erase( taskID );
    00194                         TRACE( "step(...) : Stopped task ID " << taskID << " ( " << pTask->toString() << " )" );
    00195                 }
    00196                 else {
    00197                  // Failure to start or stop is not an error - we handle this
    00198                         TRACE( "step(...) : Failed to stop task ID " << taskID << " ( " << pTask->toString() << " )" );
    00199                         recentlyFailedTasks.insert( taskID );
    00200                         mFailedTasks.insert( taskID );
    00201                 }
    00202                 tasksToStop.erase( taskID );
    00203         }
    00204
    00205         // Start tasks
    00206         TRACE( "step(...) : Starting " << tasksToStart.size() << " tasks" );
    00207         while( !tasksToStart.empty() ) {
    00208                 TaskIdentifier taskID = *tasksToStart.begin();
    00209                 t_TaskSharedPointer pTask = getTask( taskID );
    00210
    00211                 if( pTask->Start() ) { // Failure to start or stop is not an error - we handle this
    00212                         TRACE( "step(...) : Started task ID " << taskID << " ( " << pTask->toString() << " )"  );
    00213                         currentTasks.insert( taskID );
    00214                 }
    00215                 else {
    00216                         TRACE( "step(...) : Failed to start task ID " << taskID << " ( " << pTask->toString() << " )"  );
    00217                         recentlyFailedTasks.insert( taskID );
    00218                         mFailedTasks.insert( taskID );
    00219                 }
    00220                 tasksToStart.erase( taskID );
    00221         }
    00222
    00223         UnlockMutex();
    00224         return 0;
    00225 }
    00226
    00228
    00229 bool ExecutionInterface::isDone()
    00230 {
    00231         // Return true if all tasks have completed
    00232         return completedTasks.size() == mTasks.size();
    00233 }
    00234
    00236
    00237 bool ExecutionInterface::isDone(TaskIdentifier taskID)
    00238 {
    00239         // Return true of this task has completed
    00240         t_TaskSharedPointer pTask = getTask( taskID );
    00241         if( !pTask ) {
    00242                 ERROR( "isDone(...) : Task ID " << taskID << " not found" );
    00243                 return false;
    00244         }
    00245         return find( completedTasks.begin(), completedTasks.end(), taskID ) != completedTasks.end();
    00246 }
    00247
    00249
    00250 String
    00251 ExecutionInterface::getTasksString()
    00252 {
    00253   String buf;
    00254   // Print all the tasks.
    00255   set<TaskIdentifier>::iterator iSet;
    00256   for( iSet=mTasks.begin(); iSet!=mTasks.end(); iSet++ )
    00257     buf += (*iSet)->toString() + '\n';
    00258   return buf;
    00259 }
    00260
    00262
    00263 String
    00264 ExecutionInterface::getActiveTasksString()
    00265 {
    00266   String buf;
    00267   // Print all the active tasks.
    00268   set<TaskIdentifier>::iterator iSet;
    00269   for( iSet=currentTasks.begin(); iSet!=currentTasks.end(); iSet++ )
    00270     buf += (*iSet)->toString() + '\n';
    00271   return buf;
    00272 }
    00273
    00275
    00276 set<ExecutionInterface::TaskIdentifier>
    00277 ExecutionInterface::getRecentlyFailedTasks()
    00278 {
    00279         return recentlyFailedTasks;
    00280 }
    00281
    00283
    00284 set<ExecutionInterface::TaskIdentifier>
    00285 ExecutionInterface::getRecentlyCompletedTasks()
    00286 {
    00287         return recentlyCompletedTasks;
    00288 }
    00289