00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
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,
00039 DISPLAY_STATES = int(0),
00040 STARTUP,
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
00109 get_param_state_override();
00110
00111
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
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
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
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
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
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
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
00351 int active_state_;
00352 int previous_state_;
00353
00354
00355 boost::mutex active_state_mutex_;
00356
00357 };
00358
00359 }}
00360
00361 #endif