00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "packml_sm/state_machine.h"
00020 #include "packml_sm/transitions.h"
00021 #include "packml_sm/events.h"
00022
00023 namespace packml_sm
00024 {
00025
00026
00027 bool StateMachineInterface::start()
00028 {
00029 switch(StatesEnum(getCurrentState())) {
00030 case StatesEnum::IDLE:
00031 _start();
00032 return true;
00033 default:
00034 ROS_WARN_STREAM("Ignoring START command in current state: " << getCurrentState());
00035 return false;
00036 }
00037 }
00038
00039 bool StateMachineInterface::clear()
00040 {
00041 switch(StatesEnum(getCurrentState())) {
00042 case StatesEnum::ABORTED:
00043 _clear();
00044 return true;
00045 default:
00046 ROS_WARN_STREAM("Ignoring CLEAR command in current state: " << getCurrentState());
00047 return false;
00048 }
00049 }
00050
00051 bool StateMachineInterface::reset()
00052 {
00053 switch(StatesEnum(getCurrentState())) {
00054 case StatesEnum::COMPLETE:
00055 case StatesEnum::STOPPED:
00056 _reset();
00057 return true;
00058 default:
00059 ROS_WARN_STREAM("Ignoring RESET command in current state: " << getCurrentState());
00060 return false;
00061 }
00062 }
00063
00064 bool StateMachineInterface::hold()
00065 {
00066 switch(StatesEnum(getCurrentState())) {
00067 case StatesEnum::EXECUTE:
00068 _hold();
00069 return true;
00070 default:
00071 ROS_WARN_STREAM("Ignoring HOLD command in current state: " << getCurrentState());
00072 return false;
00073 }
00074 }
00075
00076
00077 bool StateMachineInterface::unhold()
00078 {
00079 switch(StatesEnum(getCurrentState())) {
00080 case StatesEnum::HELD:
00081 _unhold();
00082 return true;
00083 default:
00084 ROS_WARN_STREAM("Ignoring HELD command in current state: " << getCurrentState());
00085 return false;
00086 }
00087 }
00088
00089
00090 bool StateMachineInterface::suspend()
00091 {
00092 switch(StatesEnum(getCurrentState())) {
00093 case StatesEnum::EXECUTE:
00094 _suspend();
00095 return true;
00096 default:
00097 ROS_WARN_STREAM("Ignoring SUSPEND command in current state: " << getCurrentState());
00098 return false;
00099 }
00100 }
00101
00102 bool StateMachineInterface::unsuspend()
00103 {
00104 switch(StatesEnum(getCurrentState())) {
00105 case StatesEnum::SUSPENDED:
00106 _unsuspend();
00107 return true;
00108 default:
00109 ROS_WARN_STREAM("Ignoring UNSUSPEND command in current state: " << getCurrentState());
00110 return false;
00111 }
00112 }
00113
00114
00115 bool StateMachineInterface::stop()
00116 {
00117 switch(StatesEnum(getCurrentState())) {
00118 case StatesEnum::STOPPABLE:
00119 case StatesEnum::STARTING:
00120 case StatesEnum::IDLE:
00121 case StatesEnum::SUSPENDED:
00122 case StatesEnum::EXECUTE:
00123 case StatesEnum::HOLDING:
00124 case StatesEnum::HELD:
00125 case StatesEnum::SUSPENDING:
00126 case StatesEnum::UNSUSPENDING:
00127 case StatesEnum::UNHOLDING:
00128 case StatesEnum::COMPLETING:
00129 case StatesEnum::COMPLETE:
00130 _stop();
00131 return true;
00132 default:
00133 ROS_WARN_STREAM("Ignoring STOP command in current state: " << getCurrentState());
00134 return false;
00135 }
00136 }
00137
00138 bool StateMachineInterface::abort()
00139 {
00140 switch(StatesEnum(getCurrentState())) {
00141 case StatesEnum::ABORTABLE:
00142 case StatesEnum::STOPPED:
00143 case StatesEnum::STARTING:
00144 case StatesEnum::IDLE:
00145 case StatesEnum::SUSPENDED:
00146 case StatesEnum::EXECUTE:
00147 case StatesEnum::HOLDING:
00148 case StatesEnum::HELD:
00149 case StatesEnum::SUSPENDING:
00150 case StatesEnum::UNSUSPENDING:
00151 case StatesEnum::UNHOLDING:
00152 case StatesEnum::COMPLETING:
00153 case StatesEnum::COMPLETE:
00154 case StatesEnum::CLEARING:
00155 case StatesEnum::STOPPING:
00156 _abort();
00157 return true;
00158 default:
00159 ROS_WARN_STREAM("Ignoring ABORT command in current state: " << getCurrentState());
00160 return false;
00161 }
00162 }
00163
00164
00165
00166
00167
00168 QCoreApplication *a;
00169 void init(int argc, char *argv[])
00170 {
00171 if( NULL == QCoreApplication::instance() )
00172 {
00173 ROS_INFO_STREAM("Starting QCoreApplication");
00174 a = new QCoreApplication(argc, argv);
00175 }
00176 }
00177
00178
00179
00180
00181
00182
00183 std::shared_ptr<StateMachine> StateMachine::singleCyleSM()
00184 {
00185 return std::shared_ptr<StateMachine>(new SingleCycle());
00186 }
00187
00188
00189 std::shared_ptr<StateMachine> StateMachine::continuousCycleSM()
00190 {
00191 return std::shared_ptr<StateMachine>(new ContinuousCycle());
00192 }
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210 StateMachine::StateMachine()
00211 {
00212
00213 ROS_DEBUG_STREAM("State machine constructor");
00214
00215 ROS_DEBUG_STREAM("Constructiong super states");
00216 abortable_ = WaitState::Abortable();
00217 connect(abortable_, SIGNAL(stateEntered(int, QString)), this, SLOT(setState(int,QString)));
00218
00219 stoppable_ = WaitState::Stoppable(abortable_);
00220 connect(stoppable_, SIGNAL(stateEntered(int, QString)), this, SLOT(setState(int,QString)));
00221
00222 ROS_DEBUG_STREAM("Constructiong acting/wait states");
00223 unholding_ = ActingState::Unholding(stoppable_);
00224 connect(unholding_, SIGNAL(stateEntered(int, QString)), this, SLOT(setState(int,QString)));
00225
00226 held_ = WaitState::Held(stoppable_);
00227 connect(held_, SIGNAL(stateEntered(int, QString)), this, SLOT(setState(int,QString)));
00228
00229 holding_ = ActingState::Holding(stoppable_);
00230 connect(holding_, SIGNAL(stateEntered(int, QString)), this, SLOT(setState(int,QString)));
00231
00232 idle_ = WaitState::Idle(stoppable_);
00233 connect(idle_, SIGNAL(stateEntered(int, QString)), this, SLOT(setState(int,QString)));
00234
00235 starting_ = ActingState::Starting(stoppable_);
00236 connect(starting_, SIGNAL(stateEntered(int, QString)), this, SLOT(setState(int,QString)));
00237
00238 completing_ = ActingState::Completing(stoppable_);
00239 connect(completing_, SIGNAL(stateEntered(int, QString)), this, SLOT(setState(int,QString)));
00240
00241 complete_ = WaitState::Complete(stoppable_);
00242 connect(complete_, SIGNAL(stateEntered(int, QString)), this, SLOT(setState(int,QString)));
00243
00244 resetting_ = ActingState::Resetting(stoppable_);
00245 connect(resetting_, SIGNAL(stateEntered(int, QString)), this, SLOT(setState(int,QString)));
00246
00247 unsuspending_ = ActingState::Unsuspending(stoppable_);
00248 connect(unsuspending_, SIGNAL(stateEntered(int, QString)), this, SLOT(setState(int,QString)));
00249
00250 suspended_ = WaitState::Suspended(stoppable_);
00251 connect(suspended_, SIGNAL(stateEntered(int, QString)), this, SLOT(setState(int,QString)));
00252
00253 suspending_ = ActingState::Suspending(stoppable_);
00254 connect(suspending_, SIGNAL(stateEntered(int, QString)), this, SLOT(setState(int,QString)));
00255
00256 stopped_ = WaitState::Stopped(abortable_);
00257 connect(stopped_, SIGNAL(stateEntered(int, QString)), this, SLOT(setState(int,QString)));
00258
00259 stopping_ = ActingState::Stopping(abortable_);
00260 connect(stopping_, SIGNAL(stateEntered(int, QString)), this, SLOT(setState(int,QString)));
00261
00262 clearing_ = ActingState::Clearing(abortable_);
00263 connect(clearing_, SIGNAL(stateEntered(int, QString)), this, SLOT(setState(int,QString)));
00264
00265 aborted_ = WaitState::Aborted();
00266 connect(aborted_, SIGNAL(stateEntered(int, QString)), this, SLOT(setState(int,QString)));
00267
00268 aborting_ = ActingState::Aborting();
00269 connect(aborting_, SIGNAL(stateEntered(int, QString)), this, SLOT(setState(int,QString)));
00270
00271 execute_ = ActingState::Execute(stoppable_);
00272 connect(execute_, SIGNAL(stateEntered(int, QString)), this, SLOT(setState(int,QString)));
00273
00274 ROS_DEBUG_STREAM("Adding states to state machine");
00275 sm_internal_.addState(abortable_);
00276 sm_internal_.addState(aborted_);
00277 sm_internal_.addState(aborting_);
00278 }
00279
00280 StateMachine::~StateMachine()
00281 {
00282 }
00283
00284
00285 bool StateMachine::activate()
00286 {
00287 ROS_INFO_STREAM("Checking if QCore application is running");
00288 if( NULL == QCoreApplication::instance() )
00289 {
00290 ROS_ERROR_STREAM("QCore application is not running, QCoreApplication must"
00291 << " be created in main thread for state macine to run");
00292 return false;
00293 }
00294 else
00295 {
00296 ROS_INFO_STREAM("Moving state machine to Qcore thread");
00297 sm_internal_.moveToThread(QCoreApplication::instance()->thread());
00298 this->moveToThread(QCoreApplication::instance()->thread());
00299
00300 sm_internal_.start();
00301 ROS_INFO_STREAM("State machine thread created and started");
00302
00303 return true;
00304 }
00305 }
00306
00307
00308 bool StateMachine::deactivate()
00309 {
00310 ROS_DEBUG_STREAM("Deactivating state machine");
00311 sm_internal_.stop();
00312 }
00313
00314 void StateMachine::setState(int value, QString name)
00315 {
00316 ROS_DEBUG_STREAM("State changed(event) to: " << name.toStdString() <<
00317 "(" << value << ")");
00318 state_value_ = value;
00319 state_name_ = name;
00320 emit stateChanged(value, name);
00321 }
00322
00323
00324 bool StateMachine::setStarting(std::function<int ()> state_method)
00325 {
00326 ROS_INFO_STREAM("Initializing state machine with STARTING function pointer");
00327 return starting_->setOperationMethod(state_method);
00328 }
00329
00330 bool StateMachine::setCompleting(std::function<int ()> state_method)
00331 {
00332 ROS_INFO_STREAM("Initializing state machine with COMPLETING function pointer");
00333 return completing_->setOperationMethod(state_method);
00334 }
00335
00336 bool StateMachine::setAborting(std::function<int ()> state_method)
00337 {
00338 ROS_INFO_STREAM("Initializing state machine with ABORTING function pointer");
00339 return aborting_->setOperationMethod(state_method);
00340 }
00341
00342 bool StateMachine::setClearing(std::function<int ()> state_method)
00343 {
00344 ROS_INFO_STREAM("Initializing state machine with CLEARING function pointer");
00345 return clearing_->setOperationMethod(state_method);
00346 }
00347
00348 bool StateMachine::setStopping(std::function<int ()> state_method)
00349 {
00350 ROS_INFO_STREAM("Initializing state machine with STOPPING function pointer");
00351 return stopping_->setOperationMethod(state_method);
00352 }
00353
00354 bool StateMachine::setResetting(std::function<int ()> state_method)
00355 {
00356 ROS_INFO_STREAM("Initializing state machine with RESETTING function pointer");
00357 return resetting_->setOperationMethod(state_method);
00358 }
00359
00360 bool StateMachine::setSuspending(std::function<int ()> state_method)
00361 {
00362 ROS_INFO_STREAM("Initializing state machine with SUSPENDING function pointer");
00363 return suspending_->setOperationMethod(state_method);
00364 }
00365
00366 bool StateMachine::setUnsuspending(std::function<int ()> state_method)
00367 {
00368 ROS_INFO_STREAM("Initializing state machine with UNSUSPENDING function pointer");
00369 return unsuspending_->setOperationMethod(state_method);
00370 }
00371
00372 bool StateMachine::setHolding(std::function<int ()> state_method)
00373 {
00374 ROS_INFO_STREAM("Initializing state machine with HOLDING function pointer");
00375 return holding_->setOperationMethod(state_method);
00376 }
00377
00378 bool StateMachine::setUnholding(std::function<int ()> state_method)
00379 {
00380 ROS_INFO_STREAM("Initializing state machine with UNHOLDING function pointer");
00381 return unholding_->setOperationMethod(state_method);
00382 }
00383
00384 bool StateMachine::setExecute(std::function<int ()> state_method)
00385 {
00386 ROS_INFO_STREAM("Initializing state machine with EXECUTE function pointer");
00387 return execute_->setOperationMethod(state_method);
00388 }
00389
00390 void StateMachine::_start() {sm_internal_.postEvent(CmdEvent::start());}
00391 void StateMachine::_clear() {sm_internal_.postEvent(CmdEvent::clear());}
00392 void StateMachine::_reset() {sm_internal_.postEvent(CmdEvent::reset());}
00393 void StateMachine::_hold() {sm_internal_.postEvent(CmdEvent::hold());}
00394 void StateMachine::_unhold() {sm_internal_.postEvent(CmdEvent::unhold());}
00395 void StateMachine::_suspend() {sm_internal_.postEvent(CmdEvent::suspend());}
00396 void StateMachine::_unsuspend() {sm_internal_.postEvent(CmdEvent::unsuspend());}
00397 void StateMachine::_stop() {sm_internal_.postEvent(CmdEvent::stop());}
00398 void StateMachine::_abort() {sm_internal_.postEvent(CmdEvent::abort());}
00399
00400
00401 ContinuousCycle::ContinuousCycle()
00402 {
00403
00404 ROS_INFO_STREAM("Forming CONTINUOUS CYCLE state machine (states + transitions)");
00405
00406
00407
00408 CmdTransition* abortable_aborting_on_cmd = CmdTransition::abort(*abortable_, *aborting_);
00409 ErrorTransition* abortable_aborting_on_error = new ErrorTransition(*abortable_, *aborting_);
00410 StateCompleteTransition* aborting_aborted = new StateCompleteTransition(*aborting_, *aborted_);
00411 CmdTransition* aborted_clearing_ = CmdTransition::clear(*aborted_, *clearing_);
00412 StateCompleteTransition* clearing_stopped_ = new StateCompleteTransition(*clearing_, *stopped_);
00413 CmdTransition* stoppable_stopping_ = CmdTransition::stop(*stoppable_, *stopping_);
00414 StateCompleteTransition* stopping_stopped = new StateCompleteTransition(*stopping_, *stopped_);
00415 CmdTransition* stopped_resetting_ = CmdTransition::reset(*stopped_, *resetting_);
00416 StateCompleteTransition* unholding_execute_ = new StateCompleteTransition(*unholding_, *execute_);
00417 CmdTransition* held_unholding_ = CmdTransition::unhold(*held_, *unholding_);
00418 StateCompleteTransition* holding_held_ = new StateCompleteTransition(*holding_,*held_);
00419 CmdTransition* idle_starting_ = CmdTransition::start(*idle_, *starting_);
00420 StateCompleteTransition* starting_execute_ = new StateCompleteTransition(*starting_,*execute_);
00421 CmdTransition* execute_holding_ = CmdTransition::hold(*execute_,*holding_);
00422 StateCompleteTransition* execute_execute_ = new StateCompleteTransition(*execute_, *execute_);
00423 StateCompleteTransition* completing_complete = new StateCompleteTransition(*completing_, *complete_);
00424 CmdTransition* complete_resetting_ = CmdTransition::reset(*complete_, *resetting_);
00425 StateCompleteTransition* resetting_idle_ = new StateCompleteTransition(*resetting_, *idle_);
00426 CmdTransition* execute_suspending_ = CmdTransition::suspend(*execute_,*suspending_);
00427 StateCompleteTransition* suspending_suspended_ = new StateCompleteTransition(*suspending_,*suspended_);
00428 CmdTransition* suspended_unsuspending_ = CmdTransition::unsuspend(*suspended_, *unsuspending_);
00429 StateCompleteTransition* unsuspending_execute_ = new StateCompleteTransition(*unsuspending_, *execute_);
00430
00431
00432 abortable_->setInitialState(clearing_);
00433 stoppable_->setInitialState(resetting_);
00434 sm_internal_.setInitialState(aborted_);
00435 ROS_INFO_STREAM("State machine formed");
00436 }
00437
00438
00439 SingleCycle::SingleCycle()
00440 {
00441
00442 ROS_INFO_STREAM("Forming SINGLE CYCLE state machine (states + transitions)");
00443
00444
00445
00446 CmdTransition* abortable_aborting_on_cmd = CmdTransition::abort(*abortable_, *aborting_);
00447 ErrorTransition* abortable_aborting_on_error = new ErrorTransition(*abortable_, *aborting_);
00448 StateCompleteTransition* aborting_aborted = new StateCompleteTransition(*aborting_, *aborted_);
00449 CmdTransition* aborted_clearing_ = CmdTransition::clear(*aborted_, *clearing_);
00450 StateCompleteTransition* clearing_stopped_ = new StateCompleteTransition(*clearing_, *stopped_);
00451 CmdTransition* stoppable_stopping_ = CmdTransition::stop(*stoppable_, *stopping_);
00452 StateCompleteTransition* stopping_stopped = new StateCompleteTransition(*stopping_, *stopped_);
00453 CmdTransition* stopped_resetting_ = CmdTransition::reset(*stopped_, *resetting_);
00454 StateCompleteTransition* unholding_execute_ = new StateCompleteTransition(*unholding_, *execute_);
00455 CmdTransition* held_unholding_ = CmdTransition::unhold(*held_, *unholding_);
00456 StateCompleteTransition* holding_held_ = new StateCompleteTransition(*holding_,*held_);
00457 CmdTransition* idle_starting_ = CmdTransition::start(*idle_, *starting_);
00458 StateCompleteTransition* starting_execute_ = new StateCompleteTransition(*starting_,*execute_);
00459 CmdTransition* execute_holding_ = CmdTransition::hold(*execute_,*holding_);
00460 StateCompleteTransition* execute_completing_ = new StateCompleteTransition(*execute_,*completing_);
00461 StateCompleteTransition* completing_complete = new StateCompleteTransition(*completing_, *complete_);
00462 CmdTransition* complete_resetting_ = CmdTransition::reset(*complete_, *resetting_);
00463 StateCompleteTransition* resetting_idle_ = new StateCompleteTransition(*resetting_, *idle_);
00464 CmdTransition* execute_suspending_ = CmdTransition::suspend(*execute_,*suspending_);
00465 StateCompleteTransition* suspending_suspended_ = new StateCompleteTransition(*suspending_,*suspended_);
00466 CmdTransition* suspended_unsuspending_ = CmdTransition::unsuspend(*suspended_, *unsuspending_);
00467 StateCompleteTransition* unsuspending_execute_ = new StateCompleteTransition(*unsuspending_, *execute_);
00468
00469
00470 abortable_->setInitialState(clearing_);
00471 stoppable_->setInitialState(resetting_);
00472 sm_internal_.setInitialState(aborted_);
00473 ROS_INFO_STREAM("State machine formed");
00474 }
00475
00476
00477
00478 }