state_machine_interface.h
Go to the documentation of this file.
00001 /*
00002  * Copyright 2013 Southwest Research Institute
00003 
00004    Licensed under the Apache License, Version 2.0 (the "License");
00005    you may not use this file except in compliance with the License.
00006    You may obtain a copy of the License at
00007 
00008      http://www.apache.org/licenses/LICENSE-2.0
00009 
00010    Unless required by applicable law or agreed to in writing, software
00011    distributed under the License is distributed on an "AS IS" BASIS,
00012    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013    See the License for the specific language governing permissions and
00014    limitations under the License.
00015  */
00016 
00017 #ifndef STATE_MACHINE_INTERFACE_H_
00018 #define STATE_MACHINE_INTERFACE_H_
00019 
00020 #include <boost/shared_ptr.hpp>
00021 #include <boost/thread/mutex.hpp>
00022 #include <boost/thread/thread.hpp>
00023 #include <boost/assign/list_of.hpp>
00024 #include <boost/assign/list_inserter.hpp>
00025 #include <ros/ros.h>
00026 
00027 namespace mtconnect_cnc_robot_example { namespace state_machine {
00028 
00029         namespace states
00030         {
00031                 enum State
00032                 {
00033 
00034                         EXIT = int(-5),
00035                         ROBOT_FAULT,
00036                         CNC_FAULT,
00037                         GRIPPER_FAULT,
00038                         EMPTY,// = int(-1),
00039                         DISPLAY_STATES = int(0),
00040                         STARTUP,// = int(1),
00041                         READY,
00042                         ROBOT_RESET,
00043                         CNC_RESET,
00044                         PERIPHERALS_RESET,
00045                         ROBOT_MOVING,
00046                         CNC_MOVING,
00047                         GRIPPER_MOVING,
00048                         MATERIAL_LOAD_STARTED,
00049                         MATERIAL_LOAD_COMPLETED,
00050                         MATERIAL_UNLOAD_STARTED,
00051                         MATERIAL_UNLOAD_COMPLETED,
00052                         TEST_TASK_STARTED,
00053                         TEST_TASK_COMPLETED,
00054                         DISPLAY_TASKS
00055                 };
00056 
00057                 static std::map<int,std::string> STATE_MAP =
00058                                 boost::assign::map_list_of(DISPLAY_STATES,"DISPLAY_STATES")
00059                                 (EMPTY,"EMPTY")
00060                                 (STARTUP,"STARTUP")
00061                                 (READY,"READY")
00062                                 (ROBOT_RESET,"ROBOT_RESET")
00063                                 (CNC_RESET,"CNC_RESET")
00064                                 (PERIPHERALS_RESET,"PERIPHERALS_RESET")
00065                                 (ROBOT_FAULT,"ROBOT_FAULT")
00066                                 (CNC_FAULT,"CNC_FAULT")
00067                                 (GRIPPER_FAULT,"GRIPPER_FAULT")
00068                                 (ROBOT_MOVING,"ROBOT_MOVING")
00069                                 (CNC_MOVING,"CNC_MOVING")
00070                                 (GRIPPER_MOVING,"GRIPPER_MOVING")
00071                                 (MATERIAL_LOAD_STARTED,"MATERIAL_LOAD_STARTED")
00072                                 (MATERIAL_LOAD_COMPLETED,"MATERIAL_LOAD_COMPLETED")
00073                                 (MATERIAL_UNLOAD_STARTED,"MATERIAL_UNLOAD_STARTED")
00074                                 (MATERIAL_UNLOAD_COMPLETED,"MATERIAL_UNLOAD_COMPLETED")
00075                                 (TEST_TASK_STARTED,"TEST_TASK_STARTED")
00076                                 (TEST_TASK_COMPLETED,"TEST_TASK_COMPLETED")
00077                                 (DISPLAY_TASKS,"DISPLAY_TASKS")
00078                                 (EXIT,"EXIT");
00079 
00080         }
00081 
00082 
00083         class StateMachineInterface
00084         {
00085 
00086         public:
00087 
00088                 typedef boost::shared_ptr<StateMachineInterface> Ptr;
00089 
00090         public:
00091                 StateMachineInterface(){}
00092                 virtual ~StateMachineInterface(){}
00093 
00094                 virtual void run()
00095                 {
00096                         ros::NodeHandle nh;
00097                         ros::AsyncSpinner spinner(2);
00098                         spinner.start();
00099 
00100                         ros::Duration loop_pause(0.5f);
00101                         set_active_state(states::STARTUP);
00102 
00103                         int last_state = states::EMPTY;
00104                         int active_state = get_active_state();
00105                         print_current_state();
00106                         while(ros::ok() && process_transition())
00107                         {
00108                                 // getting externally entered state
00109                                 get_param_state_override();
00110 
00111                                 // printing new state info
00112                                 active_state = get_active_state();
00113                                 if(active_state != last_state)
00114                                 {
00115                                         last_state = active_state;
00116                                         print_current_state();
00117                                 }
00118                         }
00119                 }
00120 
00121                 // state set and get thread safe methods
00122                 void set_active_state(int state)
00123                 {
00124                         boost::mutex::scoped_lock lock(active_state_mutex_);
00125                         previous_state_ = active_state_;
00126                         active_state_ = state;
00127                 }
00128 
00129                 int get_active_state()
00130                 {
00131                         boost::mutex::scoped_lock lock(active_state_mutex_);
00132                         return active_state_;
00133                 }
00134 
00135                 int get_previous_state()
00136                 {
00137                         boost::mutex::scoped_lock lock(active_state_mutex_);
00138                         return previous_state_;
00139                 }
00140 
00141                 // related state machine methods
00142                 void get_param_state_override(std::string name_space = "state_override")
00143                 {
00144                         ros::NodeHandle nh("~");
00145                         int state = states::EMPTY;
00146                         if(nh.getParam(name_space,state) && state != states::EMPTY)
00147                         {
00148                                 set_active_state(state);
00149                                 // setting back to empty state
00150                                 nh.setParam(name_space,states::EMPTY);
00151                         }
00152                 }
00153 
00154 
00155                 void print_current_state()
00156                 {
00157                         using namespace mtconnect_cnc_robot_example::state_machine::states;
00158                         std::cout<<"\t" <<STATE_MAP[get_active_state()]<<" state active"<<std::endl;
00159                 }
00160 
00161                 void print_state_list()
00162                 {
00163                         using namespace mtconnect_cnc_robot_example::state_machine::states;
00164                         std::map<int,std::string>::iterator i;
00165                         std::cout<<"\tState List\n";
00166                         for(i = STATE_MAP.begin(); i != STATE_MAP.end(); i++)
00167                         {
00168                                 std::cout<<"\t- ("<<i->first<<") \t"<< i->second<<"\n";
00169                         }
00170                 }
00171 
00172         protected:
00173 
00174                 // transition actions
00175                 virtual bool on_startup(){return true;}
00176                 virtual bool on_ready(){return true;}
00177                 virtual bool on_robot_reset(){return true;}
00178                 virtual bool on_material_load_started(){return true;}
00179                 virtual bool on_material_load_completed(){return true;}
00180                 virtual bool on_material_unload_started(){return true;}
00181                 virtual bool on_material_unload_completed(){return true;}
00182                 virtual bool on_cnc_reset(){return true;}
00183                 virtual bool on_peripherals_reset(){return true;}
00184                 virtual bool on_robot_fault(){return true;}
00185                 virtual bool on_cnc_fault(){return true;}
00186                 virtual bool on_gripper_fault(){return true;}
00187                 virtual bool on_robot_moving(){return true;}
00188                 virtual bool on_cnc_moving(){return true;}
00189                 virtual bool on_gripper_moving(){return true;}
00190                 virtual bool on_display_states(){print_state_list(); return true;}
00191                 virtual bool on_test_task_started(){return true;}
00192                 virtual bool on_test_task_completed(){return true;}
00193                 virtual bool on_display_tasks(){ return true;}
00194 
00195                 // process state machine transition
00196                 virtual bool process_transition()
00197                 {
00198                         switch(get_active_state())
00199                         {
00200                         case states::STARTUP:
00201 
00202                                 if(on_startup())
00203                                 {
00204                                         set_active_state(states::ROBOT_RESET);
00205                                 }
00206 
00207                                 break;
00208                         case states::READY:
00209 
00210                                 on_ready();
00211 
00212                                 break;
00213 
00214                         case states::ROBOT_RESET:
00215 
00216                                 if(on_robot_reset())
00217                                 {
00218                                         set_active_state(states::READY);
00219                                 }
00220 
00221                                 break;
00222 
00223                         case states::CNC_RESET:
00224 
00225                                 if(on_cnc_reset())
00226                                 {
00227                                         set_active_state(states::ROBOT_RESET);
00228                                 }
00229 
00230                                 break;
00231 
00232                         case states::PERIPHERALS_RESET:
00233 
00234                                 if(on_peripherals_reset())
00235                                 {
00236                                         set_active_state(states::CNC_RESET);
00237                                 }
00238 
00239                                 break;
00240 
00241                         case states::ROBOT_MOVING:
00242 
00243                                 on_robot_moving();
00244                                 break;
00245 
00246                         case states::CNC_MOVING:
00247 
00248                                 on_cnc_moving();
00249                                 break;
00250 
00251                         case states::GRIPPER_MOVING:
00252 
00253                                 on_gripper_moving();
00254                                 break;
00255 
00256                         case states::ROBOT_FAULT:
00257 
00258                                 if(on_robot_fault())
00259                                 {
00260                                         //set_active_state(states::READY);
00261                                 }
00262 
00263                                 break;
00264 
00265                         case states::CNC_FAULT:
00266 
00267                                 if(on_cnc_fault())
00268                                 {
00269                                         set_active_state(states::ROBOT_FAULT);
00270                                 }
00271                                 break;
00272 
00273                         case states::GRIPPER_FAULT:
00274 
00275                                 if(on_gripper_fault())
00276                                 {
00277                                         set_active_state(states::CNC_FAULT);
00278                                 }
00279 
00280                                 break;
00281 
00282                         case states::MATERIAL_LOAD_STARTED:
00283 
00284                                 on_material_load_started();
00285 
00286                                 break;
00287                         case states::MATERIAL_LOAD_COMPLETED:
00288 
00289                                 if(on_material_load_completed())
00290                                 {
00291                                         set_active_state(states::ROBOT_RESET);
00292                                 }
00293 
00294                                 break;
00295 
00296                         case states::MATERIAL_UNLOAD_STARTED:
00297 
00298                                 on_material_unload_started();
00299 
00300                                 break;
00301                         case states::MATERIAL_UNLOAD_COMPLETED:
00302 
00303                                 if(on_material_unload_completed())
00304                                 {
00305                                         set_active_state(states::ROBOT_RESET);
00306                                 }
00307 
00308                                 break;
00309 
00310                         case states::DISPLAY_STATES:
00311 
00312                                 if(on_display_states())
00313                                 {
00314                                         set_active_state(get_previous_state());
00315                                 }
00316 
00317                                 break;
00318 
00319                         case states::TEST_TASK_STARTED:
00320 
00321                                 on_test_task_started();
00322 
00323                                 break;
00324 
00325                         case states::TEST_TASK_COMPLETED:
00326 
00327                                 if(on_test_task_completed())
00328                                 {
00329                                         set_active_state(states::ROBOT_FAULT);
00330                                 }
00331 
00332                                 break;
00333 
00334                         case states::DISPLAY_TASKS:
00335 
00336                                 on_display_tasks();
00337                                 set_active_state(get_previous_state());
00338                                 break;
00339 
00340                         case states::EXIT:
00341 
00342                                 return false;
00343                         }
00344 
00345                         return true;
00346                 }
00347 
00348         protected:
00349 
00350                 // state members
00351                 int active_state_;
00352                 int previous_state_;
00353 
00354                 // threading members
00355                 boost::mutex active_state_mutex_;
00356 
00357         };
00358 
00359 }}
00360 
00361 #endif /* STATE_MACHINE_INTERFACE_H_ */


mtconnect_cnc_robot_example
Author(s): Jnicho
autogenerated on Mon Jan 6 2014 11:31:45