00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <mtconnect_state_machine/state_machine.h>
00018 #include <mtconnect_state_machine/utilities.h>
00019 #include <industrial_robot_client/utils.h>
00020
00021 using namespace mtconnect_state_machine;
00022
00023 static const std::string PARAM_TASK_DESCRIPTION = "task_description";
00024 static const std::string PARAM_FORCE_FAULT_STATE = "force_fault";
00025 static const std::string PARAM_STATE_OVERRIDE = "state_override";
00026 static const std::string PARAM_LOOP_RATE = "loop_rate";
00027 static const std::string PARAM_CHECK_ENABLED = "home_check";
00028 static const std::string PARAM_HOME_TOL = "home_tol";
00029 static const std::string PARAM_MAT_STATE = "material_state";
00030 static const std::string KEY_HOME_POSITION = "home";
00031
00032
00033 static const std::string KEY_JM_HOME_TO_APPROACH = "JM_HOME_TO_APPROACH";
00034 static const std::string KEY_JM_APPROACH_TO_PICK = "JM_APPROACH_TO_PICK";
00035 static const std::string KEY_JM_PICK_TO_CHUCK = "JM_PICK_TO_CHUCK";
00036 static const std::string KEY_JM_CHUCK_TO_DOOR = "JM_CHUCK_TO_DOOR";
00037 static const std::string KEY_JM_DOOR_TO_HOME = "JM_DOOR_TO_HOME";
00038
00039
00040 static const std::string KEY_JM_HOME_TO_DOOR = "JM_HOME_TO_DOOR";
00041 static const std::string KEY_JM_DOOR_TO_CHUCK = "JM_DOOR_TO_CHUCK";
00042 static const std::string KEY_JM_CHUCK_TO_DROP = "JM_CHUCK_TO_DROP";
00043 static const std::string KEY_JM_DROP_TO_HOME = "JM_DROP_TO_HOME";
00044
00045 static const std::string DEFAULT_GRASP_ACTION = "gripper_action_service";
00046 static const std::string DEFAULT_VISE_ACTION = "vise_action_service";
00047 static const std::string DEFAULT_MATERIAL_LOAD_ACTION = "material_load_action";
00048 static const std::string DEFAULT_MATERIAL_UNLOAD_ACTION = "material_unload_action";
00049 static const std::string DEFAULT_CNC_OPEN_DOOR_ACTION = "cnc_open_door_action";
00050 static const std::string DEFAULT_CNC_CLOSE_DOOR_ACTION = "cnc_close_door_action";
00051 static const std::string DEFAULT_CNC_OPEN_CHUCK_ACTION = "cnc_open_chuck_action";
00052 static const std::string DEFAULT_CNC_CLOSE_CHUCK_ACTION = "cnc_close_chuck_action";
00053 static const std::string DEFAULT_JOINT_TRAJ_ACTION = "joint_trajectory_action";
00054 static const std::string DEFAULT_ROBOT_STATES_TOPIC = "robot_states";
00055 static const std::string DEFAULT_ROBOT_SPINDLE_TOPIC = "robot_spindle";
00056 static const std::string DEFAULT_ROBOT_STATUS_TOPIC = "robot_status";
00057 static const std::string DEFAULT_JOINT_STATE_TOPIC = "joint_states";
00058 static const std::string DEFAULT_SM_STATUS_TOPIC = "state_machine_status";
00059 static const std::string DEFAULT_EXTERNAL_COMMAND_SERVICE = "external_command";
00060 static const std::string DEFAULT_MATERIAL_LOAD_SET_STATE_SERVICE = "/MaterialLoad/set_mtconnect_state";
00061 static const std::string DEFAULT_MATERIAL_UNLOAD_SET_STATE_SERVICE = "/MaterialUnload/set_mtconnect_state";
00062 static const std::string DEFAULT_TRAJECTORY_FILTER_SERVICE = "filter_trajectory_with_constraints";
00063
00064 static const std::string MTCONNECT_ACTION_ACTIVE_FLAG = "ACTIVE";
00065
00066
00067 typedef mtconnect_msgs::SetMTConnectState::Request MtConnectState;
00068
00069 StateMachine::StateMachine() :
00070 nh_()
00071 {
00072
00073 state_ = StateTypes::INVALID;
00074 loop_rate_ = 0;
00075 home_check_ = false;
00076 home_tol_ = 0.0;
00077 cycle_stop_req_= false;
00078 material_state_ = false;
00079 material_load_state_ = mtconnect_msgs::SetMTConnectState::Request::NOT_READY;
00080 }
00081
00082 StateMachine::~StateMachine()
00083 {
00084
00085 }
00086
00087 bool StateMachine::init()
00088 {
00089 ros::NodeHandle ph("~");
00090 std::string task_desc;
00091
00092 if (!ph.getParam(PARAM_LOOP_RATE, loop_rate_))
00093 {
00094 ROS_WARN_STREAM("Param: " << PARAM_LOOP_RATE << " not set, using default");
00095 loop_rate_ = 10;
00096 }
00097 if (!ph.getParam(PARAM_CHECK_ENABLED, home_check_))
00098 {
00099 ROS_WARN_STREAM("Param: " << PARAM_CHECK_ENABLED << "not set, setting enabled");
00100 home_check_ = true;
00101 }
00102 if (!ph.getParam(PARAM_HOME_TOL, home_tol_))
00103 {
00104 ROS_WARN_STREAM("Param: " << PARAM_HOME_TOL << " not set, using default");
00105 home_tol_ = 0.1;
00106 }
00107 if (!ph.getParam(PARAM_TASK_DESCRIPTION, task_desc))
00108 {
00109 ROS_ERROR("Failed to load task description parameter");
00110 return false;
00111 }
00112
00113 std::map<std::string, boost::shared_ptr<mtconnect::JointPoint> > points;
00114 if (!parseTaskXml(task_desc, joint_paths_, points))
00115 {
00116 ROS_ERROR("Failed to parse xml");
00117 return false;
00118 }
00119
00120 if (points.empty())
00121 {
00122 ROS_ERROR("Failed to find defined points");
00123 return false;
00124 }
00125
00126 ROS_INFO_STREAM("Adding home position from task description");
00127 home_ = points[KEY_HOME_POSITION];
00128 if (home_->values_.empty())
00129 {
00130 ROS_ERROR("Home position is empty, failed to load home");
00131 return false;
00132 }
00133
00134
00135 material_load_server_ptr_ = MaterialLoadServerPtr(new MaterialLoadServer(nh_, DEFAULT_MATERIAL_LOAD_ACTION, false));
00136 material_load_server_ptr_->registerGoalCallback(boost::bind(&StateMachine::materialLoadGoalCB, this));
00137 material_unload_server_ptr_ = MaterialUnloadServerPtr(
00138 new MaterialUnloadServer(nh_, DEFAULT_MATERIAL_UNLOAD_ACTION, false));
00139 material_unload_server_ptr_->registerGoalCallback(boost::bind(&StateMachine::materialUnloadGoalCB, this));
00140
00141
00142 open_door_client_ptr_ = CncOpenDoorClientPtr(new CncOpenDoorClient(DEFAULT_CNC_OPEN_DOOR_ACTION, false));
00143 close_door_client_ptr_ = CncCloseDoorClientPtr(new CncCloseDoorClient(DEFAULT_CNC_CLOSE_DOOR_ACTION, false));
00144 open_chuck_client_ptr_ = CncOpenChuckClientPtr(new CncOpenChuckClient(DEFAULT_CNC_OPEN_CHUCK_ACTION, false));
00145 close_chuck_client_ptr_ = CncCloseChuckClientPtr(new CncCloseChuckClient(DEFAULT_CNC_CLOSE_CHUCK_ACTION, false));
00146 grasp_action_client_ptr_ = GraspActionClientPtr(new GraspActionClient(DEFAULT_GRASP_ACTION, false));
00147 vise_action_client_ptr_ = GraspActionClientPtr(new GraspActionClient(DEFAULT_VISE_ACTION, false));
00148 joint_traj_client_ptr_ = JointTractoryClientPtr(new JointTractoryClient(DEFAULT_JOINT_TRAJ_ACTION, false));
00149
00150
00151 robot_states_pub_ = nh_.advertise<mtconnect_msgs::RobotStates>(DEFAULT_ROBOT_STATES_TOPIC, 1);
00152 robot_spindle_pub_ = nh_.advertise<mtconnect_msgs::RobotSpindle>(DEFAULT_ROBOT_SPINDLE_TOPIC, 1);
00153 state_machine_pub_ = nh_.advertise<mtconnect_example_msgs::StateMachineStatus>(DEFAULT_SM_STATUS_TOPIC, 1);
00154
00155
00156 robot_status_sub_ = nh_.subscribe(DEFAULT_ROBOT_STATUS_TOPIC, 1, &StateMachine::robotStatusCB, this);
00157 joint_states_sub_ = nh_.subscribe(DEFAULT_JOINT_STATE_TOPIC, 1, &StateMachine::jointStatesCB, this);
00158
00159
00160 external_command_srv_ = nh_.advertiseService(DEFAULT_EXTERNAL_COMMAND_SERVICE, &StateMachine::externalCommandCB,
00161 this);
00162
00163
00164 material_load_set_state_client_ = nh_.serviceClient<mtconnect_msgs::SetMTConnectState>(
00165 DEFAULT_MATERIAL_LOAD_SET_STATE_SERVICE);
00166 material_unload_set_state_client_ = nh_.serviceClient<mtconnect_msgs::SetMTConnectState>(
00167 DEFAULT_MATERIAL_UNLOAD_SET_STATE_SERVICE);
00168
00169 trajectory_filter_client_ = nh_.serviceClient<arm_navigation_msgs::FilterJointTrajectoryWithConstraints>(
00170 DEFAULT_TRAJECTORY_FILTER_SERVICE);
00171
00172
00173 material_load_server_ptr_->start();
00174 material_unload_server_ptr_->start();
00175
00176 setState(StateTypes::IDLE);
00177
00178 return true;
00179
00180 }
00181
00182 void StateMachine::run()
00183 {
00184 ROS_INFO_STREAM("Entering blocking run");
00185 ros::Rate r(loop_rate_);
00186 while (ros::ok())
00187 {
00188
00189 runOnce();
00190 callPublishers();
00191 ros::spinOnce();
00192 errorChecks();
00193 overrideChecks();
00194
00195 r.sleep();
00196 }
00197
00198 }
00199
00200 void StateMachine::runOnce()
00201 {
00202
00203 MaterialLoadServer::Result load_res;
00204 MaterialUnloadServer::Result unload_res;
00205
00206 switch (state_)
00207 {
00208 case StateTypes::IDLE:
00209 break;
00210
00211 case StateTypes::INITING:
00212 setState(StateTypes::CHECK_HOME);
00213 break;
00214
00215 case StateTypes::CHECK_HOME:
00216 if ( isHome())
00217 {
00218 ROS_INFO_STREAM("Robot start home check passed");
00219 setState(StateTypes::WAIT_FOR_ACTIONS);
00220 }
00221 else
00222 {
00223 ROS_ERROR_STREAM("Robot not in home state on start");
00224 setState(StateTypes::ABORTING);
00225 }
00226 break;
00227
00228 case StateTypes::WAIT_FOR_ACTIONS:
00229 if (areActionsReady())
00230 {
00231 setState(StateTypes::WAIT_FOR_SERVICES);
00232 }
00233 else
00234 {
00235 ROS_INFO_STREAM_THROTTLE(20, "Waiting for actions to be ready");
00236 }
00237 break;
00238
00239 case StateTypes::WAIT_FOR_SERVICES:
00240 if (areServicesReady())
00241 {
00242 setState(StateTypes::SET_MAT_ACTIONS_READY);
00243 }
00244 else
00245 {
00246 ROS_INFO_STREAM_THROTTLE(20, "Waiting for services to be ready");
00247 }
00248 break;
00249
00250 case StateTypes::SET_MAT_ACTIONS_READY:
00251 if (setMatActionsReady())
00252 {
00253 setState(StateTypes::WAITING);
00254 }
00255 else
00256 {
00257 ROS_ERROR("Failed to set actions ready, aborting");
00258 setState(StateTypes::ABORTING);
00259 }
00260 break;
00261
00262 case StateTypes::WAITING:
00263 ROS_INFO_STREAM_THROTTLE(20, "Waiting for request");
00264 if(cycle_stop_req_)
00265 {
00266 cycle_stop_req_ = false;
00267 setState(StateTypes::STOPPING);
00268 }
00269 if(material_state_)
00270 {
00271 if(material_load_state_ != mtconnect_msgs::SetMTConnectState::Request::READY)
00272 {
00273 ROS_INFO_STREAM("Material present, updating material load to READY");
00274 setMatLoad(mtconnect_msgs::SetMTConnectState::Request::READY);
00275 }
00276 }
00277 else
00278 {
00279 if(material_load_state_ != mtconnect_msgs::SetMTConnectState::Request::NOT_READY)
00280 {
00281 ROS_INFO_STREAM("Material no present, updating material load to NOT READY");
00282 setMatLoad(mtconnect_msgs::SetMTConnectState::Request::NOT_READY);
00283 }
00284 }
00285 break;
00286
00287 case StateTypes::MATERIAL_LOADING:
00288 ROS_INFO_STREAM("++++++++++++++++++++++++ LOADING MATERIAL ++++++++++++++++++++++++");
00289 setState(StateTypes::ML_MOVE_PICK_APPROACH);
00290 break;
00291
00292 case StateTypes::ML_MOVE_PICK_APPROACH:
00293 moveArm(KEY_JM_HOME_TO_APPROACH);
00294 openGripper();
00295 openDoor();
00296 setState(StateTypes::ML_WAIT_MOVE_PICK_APPROACH);
00297 break;
00298
00299 case StateTypes::ML_WAIT_MOVE_PICK_APPROACH:
00300 if (isMoveDone() && isGripperOpened())
00301 {
00302 setState(StateTypes::ML_MOVE_PICK);
00303 }
00304 break;
00305
00306 case StateTypes::ML_MOVE_PICK:
00307 moveArm(KEY_JM_APPROACH_TO_PICK);
00308 setState(StateTypes::ML_WAIT_MOVE_PICK);
00309 break;
00310
00311 case StateTypes::ML_WAIT_MOVE_PICK:
00312 if (isMoveDone())
00313 {
00314 setState(StateTypes::ML_PICK);
00315 }
00316 break;
00317
00318 case StateTypes::ML_PICK:
00319 if(material_state_)
00320 {
00321 closeGripper();
00322 setState(StateTypes::ML_WAIT_PICK);
00323 }
00324 else
00325 {
00326 ROS_ERROR_STREAM("Unexpected out of material during pick, aborting");
00327 setState(StateTypes::ABORTING);
00328 }
00329 break;
00330
00331 case StateTypes::ML_WAIT_PICK:
00332 if (isGripperClosed() && isDoorOpened())
00333 {
00334 setState(StateTypes::ML_MOVE_CHUCK);
00335 }
00336 break;
00337
00338 case StateTypes::ML_MOVE_CHUCK:
00339 moveArm(KEY_JM_PICK_TO_CHUCK);
00340 setState(StateTypes::ML_WAIT_MOVE_CHUCK);
00341 break;
00342
00343 case StateTypes::ML_WAIT_MOVE_CHUCK:
00344 if (isMoveDone())
00345 {
00346 setState(StateTypes::ML_CLOSE_CHUCK);
00347 }
00348 break;
00349
00350 case StateTypes::ML_CLOSE_CHUCK:
00351 closeChuck();
00352 setState(StateTypes::ML_WAIT_CLOSE_CHUCK);
00353 break;
00354
00355 case StateTypes::ML_WAIT_CLOSE_CHUCK:
00356 if (isChuckClosed())
00357 {
00358 setState(StateTypes::ML_RELEASE_PART);
00359 }
00360 break;
00361
00362 case StateTypes::ML_RELEASE_PART:
00363 openGripper();
00364 setState(StateTypes::ML_WAIT_RELEASE_PART);
00365 break;
00366
00367 case StateTypes::ML_WAIT_RELEASE_PART:
00368 if (isGripperOpened())
00369 {
00370 setState(StateTypes::ML_MOVE_DOOR);
00371 }
00372 break;
00373
00374 case StateTypes::ML_MOVE_DOOR:
00375 moveArm(KEY_JM_CHUCK_TO_DOOR);
00376 setState(StateTypes::ML_WAIT_MOVE_DOOR);
00377 break;
00378
00379 case StateTypes::ML_WAIT_MOVE_DOOR:
00380 if (isMoveDone())
00381 {
00382 setState(StateTypes::ML_MOVE_HOME);
00383 }
00384 break;
00385
00386 case StateTypes::ML_MOVE_HOME:
00387 moveArm(KEY_JM_DOOR_TO_HOME);
00388 closeDoor();
00389 setState(StateTypes::ML_WAIT_MOVE_HOME);
00390 break;
00391
00392 case StateTypes::ML_WAIT_MOVE_HOME:
00393 if (isMoveDone() && isDoorClosed())
00394 {
00395 setState(StateTypes::MATERIAL_LOADED);
00396 }
00397 break;
00398
00399 case StateTypes::MATERIAL_LOADED:
00400 ROS_INFO_STREAM("Material loaded");
00401 load_res.load_state = "Succeeded";
00402 material_load_server_ptr_->setSucceeded(load_res);
00403 setState(StateTypes::WAITING);
00404 break;
00405
00406
00407
00408
00409 case StateTypes::MATERIAL_UNLOADING:
00410 ROS_INFO_STREAM("++++++++++++++++++++++++ UNLOADING MATERIAL ++++++++++++++++++++++++");
00411 setState(StateTypes::MU_MOVE_DOOR);
00412 break;
00413
00414 case StateTypes::MU_MOVE_DOOR:
00415 moveArm(KEY_JM_HOME_TO_DOOR);
00416 openDoor();
00417 setState(StateTypes::MU_WAIT_MOVE_DOOR);
00418 break;
00419
00420 case StateTypes::MU_WAIT_MOVE_DOOR:
00421 if(isMoveDone() && isDoorOpened())
00422 {
00423 setState(StateTypes::MU_MOVE_CHUCK);
00424 }
00425 break;
00426
00427 case StateTypes::MU_MOVE_CHUCK:
00428 moveArm(KEY_JM_DOOR_TO_CHUCK);
00429 setState(StateTypes::MU_WAIT_MOVE_CHUCK);
00430 break;
00431
00432 case StateTypes::MU_WAIT_MOVE_CHUCK:
00433 if(isMoveDone())
00434 {
00435 setState(StateTypes::MU_PICK_PART);
00436 }
00437 break;
00438
00439 case StateTypes::MU_PICK_PART:
00440 closeGripper();
00441 setState(StateTypes::MU_WAIT_PICK_PART);
00442 break;
00443
00444 case StateTypes::MU_WAIT_PICK_PART:
00445 if(isGripperClosed())
00446 {
00447 setState(StateTypes::MU_OPEN_CHUCK);
00448 }
00449 break;
00450
00451 case StateTypes::MU_OPEN_CHUCK:
00452 openChuck();
00453 setState(StateTypes::MU_WAIT_OPEN_CHUCK);
00454 break;
00455
00456 case StateTypes::MU_WAIT_OPEN_CHUCK:
00457 if(isChuckOpened())
00458 {
00459 setState(StateTypes::MU_MOVE_DROP);
00460 }
00461 break;
00462
00463 case StateTypes::MU_MOVE_DROP:
00464 moveArm(KEY_JM_CHUCK_TO_DROP);
00465 setState(StateTypes::MU_WAIT_MOVE_DROP);
00466 break;
00467
00468 case StateTypes::MU_WAIT_MOVE_DROP:
00469 if(isMoveDone())
00470 {
00471 setState(StateTypes::MU_DROP);
00472 }
00473 break;
00474
00475 case StateTypes::MU_DROP:
00476 openGripper();
00477 setState(StateTypes::MU_WAIT_DROP);
00478 break;
00479
00480 case StateTypes::MU_WAIT_DROP:
00481 if(isGripperOpened())
00482 {
00483 setState(StateTypes::MU_MOVE_HOME);
00484 }
00485 break;
00486
00487 case StateTypes::MU_MOVE_HOME:
00488 moveArm(KEY_JM_DROP_TO_HOME);
00489 setState(StateTypes::MU_WAIT_MOVE_HOME);
00490 break;
00491
00492 case StateTypes::MU_WAIT_MOVE_HOME:
00493 if(isMoveDone())
00494 {
00495 setState(StateTypes::MATERIAL_UNLOADED);
00496 }
00497 break;
00498
00499 case StateTypes::MATERIAL_UNLOADED:
00500 ROS_INFO_STREAM("Material unloaded");
00501 unload_res.unload_state = "Succeeded";
00502 material_unload_server_ptr_->setSucceeded(unload_res);
00503 setState(StateTypes::WAITING);
00504 break;
00505
00506
00507
00508 case StateTypes::ABORTING:
00509 ROS_ERROR("Entering state machine abort sequence");
00510 setState(StateTypes::ABORT_GOALS);
00511 break;
00512
00513 case StateTypes::ABORT_GOALS:
00514 ROS_INFO_STREAM("Aborting goals");
00515 abortActionServers();
00516 setState(StateTypes::CANCEL_REQUESTS);
00517 break;
00518
00519 case StateTypes::CANCEL_REQUESTS:
00520 ROS_INFO_STREAM("Canceling requests");
00521 cancelActionClients();
00522 setState(StateTypes::ABORTED);
00523 break;
00524
00525 case StateTypes::ABORTED:
00526 ROS_INFO_STREAM_THROTTLE(30, "Robot in ABORTED state");
00527 break;
00528
00529 case StateTypes::STOPPING:
00530 ROS_INFO_STREAM("Beginning system stop");
00531 setState(StateTypes::S_SET_MAT_ACTIONS_NOT_READY);
00532 break;
00533
00534 case StateTypes::S_SET_MAT_ACTIONS_NOT_READY:
00535 setMatActionsNotReady();
00536 setState(StateTypes::STOPPED);
00537 break;
00538
00539 case StateTypes::STOPPED:
00540 ROS_INFO_STREAM("Completing stop");
00541 setState(StateTypes::IDLE);
00542 break;
00543
00544 case StateTypes::RESETTING:
00545 setState(StateTypes::R_WAIT_FOR_HOME);
00546 break;
00547
00548 case StateTypes::R_WAIT_FOR_HOME:
00549 if( isHome())
00550 {
00551 setState(StateTypes::R_SET_MAT_ACTIONS_NOT_READY);
00552 }
00553 else
00554 {
00555 ROS_ERROR_STREAM("Robot not in home state for FAULT RESET");
00556 setState(StateTypes::ABORTING);
00557 }
00558 break;
00559
00560 case StateTypes::R_SET_MAT_ACTIONS_NOT_READY:
00561 setMatActionsNotReady();
00562 setState(StateTypes::IDLE);
00563 break;
00564
00565 default:
00566 ROS_ERROR_STREAM("Unhandled state: " << state_ << ", setting state to aborted");
00567 setState(StateTypes::ABORTING);
00568 break;
00569 }
00570 }
00571
00572 bool StateMachine::areActionsReady()
00573 {
00574 return open_door_client_ptr_->isServerConnected() && close_door_client_ptr_->isServerConnected()
00575 && open_chuck_client_ptr_->isServerConnected() && close_chuck_client_ptr_->isServerConnected()
00576 && grasp_action_client_ptr_->isServerConnected() && vise_action_client_ptr_->isServerConnected()
00577 && joint_traj_client_ptr_->isServerConnected();
00578 }
00579
00580 bool StateMachine::areServicesReady()
00581 {
00582 return material_load_set_state_client_.exists() && material_unload_set_state_client_.exists()
00583 && trajectory_filter_client_.exists();
00584 }
00585
00586 void StateMachine::abortActionServers()
00587 {
00588 ROS_INFO_STREAM("Checking material load action server");
00589 if (material_load_server_ptr_->isActive())
00590 {
00591 MaterialLoadServer::Result res;
00592 res.load_state = "Failed";
00593 material_load_server_ptr_->setAborted(res);
00594 ROS_INFO_STREAM("Material Load goal aborted");
00595 }
00596
00597 ROS_INFO_STREAM("Checking material unload action server");
00598 if (material_unload_server_ptr_->isActive())
00599 {
00600 MaterialUnloadServer::Result res;
00601 res.unload_state = "Failed";
00602 material_unload_server_ptr_->setAborted(res);
00603 ROS_INFO_STREAM("Material Unload goal aborted");
00604 }
00605 }
00606
00607 void StateMachine::cancelActionClients()
00608 {
00609 ROS_INFO_STREAM("Canceling all action clients");
00610 joint_traj_client_ptr_->cancelAllGoals();
00611
00612 open_door_client_ptr_->cancelAllGoals();
00613 open_chuck_client_ptr_->cancelAllGoals();
00614 close_door_client_ptr_->cancelAllGoals();
00615 close_chuck_client_ptr_->cancelAllGoals();
00616
00617 grasp_action_client_ptr_->cancelAllGoals();
00618 vise_action_client_ptr_->cancelAllGoals();
00619 }
00620
00621 bool StateMachine::setMatActionsReady()
00622 {
00623 return setMatLoad(mtconnect_msgs::SetMTConnectState::Request::READY)
00624 && setMatUnload(mtconnect_msgs::SetMTConnectState::Request::READY);
00625 }
00626
00627 bool StateMachine::setMatActionsNotReady()
00628 {
00629 return setMatLoad(mtconnect_msgs::SetMTConnectState::Request::NOT_READY)
00630 && setMatUnload(mtconnect_msgs::SetMTConnectState::Request::NOT_READY);
00631 }
00632
00633 bool StateMachine::setMatLoad(int state)
00634 {
00635 bool rtn = false;
00636 mat_load_set_state_.request.state_flag = state;
00637
00638 if (material_load_set_state_client_.call(mat_load_set_state_))
00639 {
00640 if (mat_load_set_state_.response.accepted)
00641 {
00642 material_load_state_ = state;
00643 ROS_INFO_STREAM("Material load set to: " << state);
00644 rtn = true;
00645 }
00646 else
00647 {
00648 ROS_WARN_STREAM("Material load failed to set to: " << state);
00649 rtn = false;
00650 }
00651 }
00652 else
00653 {
00654 ROS_WARN_STREAM("Material load service call failed");
00655 rtn = false;
00656 }
00657
00658 return rtn;
00659 }
00660
00661 bool StateMachine::setMatUnload(int state)
00662 {
00663 bool rtn = false;
00664 mat_unload_set_state_.request.state_flag = state;
00665
00666 if (material_unload_set_state_client_.call(mat_unload_set_state_))
00667 {
00668 if (mat_unload_set_state_.response.accepted)
00669 {
00670 ROS_INFO_STREAM("Material unload set to: " << state);
00671 rtn = true;
00672 }
00673 else
00674 {
00675 ROS_WARN_STREAM("Material unload failed to set to: " << state);
00676 rtn = false;
00677 }
00678 }
00679 else
00680 {
00681 ROS_WARN_STREAM("Material unload service call failed");
00682 rtn = false;
00683 }
00684
00685 return rtn;
00686 }
00687
00688 void StateMachine::errorChecks()
00689 {
00690 using namespace industrial_msgs;
00691 bool error = false;
00692
00693 if (robot_status_msg_.e_stopped.val == TriState::TRUE)
00694 {
00695 ROS_ERROR_STREAM_THROTTLE(5, "Robot estopped(" << robot_status_msg_.e_stopped << " aborting");
00696 error = true;
00697 }
00698 if (robot_status_msg_.in_error.val == TriState::TRUE)
00699 {
00700 ROS_ERROR_STREAM_THROTTLE(5, "General robot error(" << robot_status_msg_.in_error << " aborting");
00701 error = true;
00702 }
00703
00704 if (error && !(StateTypes::ABORTING >= state_ && state_ <= StateTypes::ABORTED))
00705 {
00706 ROS_INFO_STREAM("One or more general errors detected, aborting");
00707 setState(StateTypes::ABORTING);
00708 }
00709 }
00710
00711 void StateMachine::overrideChecks()
00712 {
00713 ros::NodeHandle ph("~");
00714 int state_override = StateTypes::INVALID;
00715 ph.getParamCached(PARAM_STATE_OVERRIDE, state_override);
00716
00717 int force_fault_state = StateTypes::INVALID;
00718 ph.getParamCached(PARAM_FORCE_FAULT_STATE, force_fault_state);
00719
00720 if (state_override != StateTypes::INVALID)
00721 {
00722 ROS_WARN_STREAM("Overriding state to: " << StateTypes::STATE_MAP[state_override]);
00723 setState(StateType(state_override));
00724 ph.setParam(PARAM_STATE_OVERRIDE, StateTypes::INVALID);
00725 }
00726 if (state_ == force_fault_state)
00727 {
00728 ROS_ERROR_STREAM("Forcing fault from state: "<< StateTypes::STATE_MAP[state_]);
00729 setState(StateTypes::ABORTING);
00730 ph.setParam(PARAM_FORCE_FAULT_STATE, StateTypes::INVALID);
00731 }
00732
00733
00734 bool mat_param_state = false;
00735 ph.getParamCached(PARAM_MAT_STATE, mat_param_state);
00736
00737 if (material_state_ != mat_param_state)
00738 {
00739 ROS_INFO_STREAM("Detected change in material state, from " << material_state_ << " to " << mat_param_state);
00740 material_state_ = mat_param_state;
00741 }
00742 }
00743
00744
00745 void StateMachine::callPublishers()
00746 {
00747 robotStatusPublisher();
00748 robotSpindlePublisher();
00749 stateMachineStatusPublisher();
00750 }
00751 void StateMachine::robotStatusPublisher()
00752 {
00753 using namespace industrial_msgs;
00754
00755 robot_state_msg_.header.stamp = ros::Time::now();
00756
00757
00758 if ((state_ != StateTypes::IDLE) && (state_ != StateTypes::ABORTED))
00759 {
00760 robot_state_msg_.avail.val = TriState::ENABLED;
00761 robot_state_msg_.mode.val = RobotMode::AUTO;
00762 }
00763 else
00764 {
00765 robot_state_msg_.avail.val = TriState::DISABLED;
00766 robot_state_msg_.mode.val = RobotMode::MANUAL;
00767 }
00768
00769
00770
00771
00772
00773
00774
00775 robot_state_msg_.rexec.val = TriState::HIGH;
00776
00777
00778 robot_states_pub_.publish(robot_state_msg_);
00779 }
00780
00781 void StateMachine::robotSpindlePublisher()
00782 {
00783 using namespace industrial_msgs;
00784 robot_spindle_msg_.header.stamp = ros::Time::now();
00785
00786
00787 robot_spindle_msg_.c_unclamp.val = TriState::HIGH;
00788 robot_spindle_msg_.s_inter.val = TriState::HIGH;
00789
00790 robot_spindle_pub_.publish(robot_spindle_msg_);
00791 }
00792
00793
00794 void StateMachine::stateMachineStatusPublisher()
00795 {
00796 state_machine_stat_msg_.header.stamp = ros::Time::now();
00797 state_machine_stat_msg_.state = state_;
00798 state_machine_stat_msg_.state_name = StateTypes::STATE_MAP[state_];
00799
00800 state_machine_pub_.publish(state_machine_stat_msg_);
00801 }
00802
00803
00804
00805 void StateMachine::materialLoadGoalCB()
00806 {
00807 switch (state_)
00808 {
00809 case StateTypes::WAITING:
00810 ROS_INFO_STREAM("Accepting material load request");
00811 material_load_server_ptr_->acceptNewGoal();
00812
00813 setState(StateTypes::MATERIAL_LOADING);
00814 break;
00815 default:
00816 ROS_WARN_STREAM("Material load request received in wrong state: " << state_);
00817 MaterialLoadServer::Result res;
00818 res.load_state = "Failed";
00819 material_load_server_ptr_->acceptNewGoal();
00820 material_load_server_ptr_->setAborted(res);
00821 break;
00822 }
00823 }
00824 void StateMachine::materialUnloadGoalCB()
00825 {
00826 switch (state_)
00827 {
00828 case StateTypes::WAITING:
00829 ROS_INFO_STREAM("Accepting material unload request");
00830 material_unload_server_ptr_->acceptNewGoal();
00831
00832 setState(StateTypes::MATERIAL_UNLOADING);
00833 break;
00834 default:
00835 ROS_WARN_STREAM("Material unload request received in wrong state: " << state_);
00836 MaterialUnloadServer::Result res;
00837 res.unload_state = "Failed";
00838 material_unload_server_ptr_->acceptNewGoal();
00839 material_unload_server_ptr_->setAborted(res);
00840 break;
00841 }
00842 }
00843 void StateMachine::robotStatusCB(const industrial_msgs::RobotStatusConstPtr &msg)
00844 {
00845 robot_status_msg_ = *msg;
00846 }
00847
00848 void StateMachine::jointStatesCB(const sensor_msgs::JointStateConstPtr &msg)
00849 {
00850 joint_state_msg_ = *msg;
00851 }
00852
00853 bool StateMachine::externalCommandCB(mtconnect_example_msgs::StateMachineCmd::Request &req,
00854 mtconnect_example_msgs::StateMachineCmd::Response &res)
00855 {
00856 using namespace mtconnect_example_msgs;
00857
00858 switch (req.command)
00859 {
00860 case StateMachineCmd::Request::STOP:
00861 if (state_ >= StateTypes::CYCLE_BEGIN && state_ <= StateTypes::CYCLE_END)
00862 {
00863 ROS_INFO_STREAM("External command STOP, setting stop request flag");
00864 cycle_stop_req_ = true;
00865 res.accepted = true;
00866 }
00867 else
00868 {
00869 ROS_WARN_STREAM("External command STOP ignored, wrong state: " << state_);
00870 res.accepted = false;
00871 }
00872 break;
00873
00874 case StateMachineCmd::Request::FAULT_RESET:
00875 if (state_ == StateTypes::ABORTED)
00876 {
00877 ROS_INFO_STREAM("External command FAULT_RESET executing");
00878 setState(StateTypes::RESETTING);
00879 res.accepted = true;
00880 }
00881 else
00882 {
00883 ROS_WARN_STREAM("External command FAULT_RESET ignored, wrong state: " << state_);
00884 res.accepted = false;
00885 }
00886 break;
00887 case StateMachineCmd::Request::START:
00888 if (state_ == StateTypes::IDLE)
00889 {
00890 ROS_INFO_STREAM("External command START executing");
00891 setState(StateTypes::INITING);
00892 res.accepted = true;
00893 }
00894 else
00895 {
00896 ROS_WARN_STREAM("External command START ignored, wrong state: " << state_);
00897 res.accepted = false;
00898 }
00899 break;
00900
00901 default:
00902 ROS_WARN_STREAM("External command: ignored");
00903 res.accepted = false;
00904 break;
00905 }
00906 return true;
00907 }
00908
00909 bool StateMachine::isActionComplete(int action_state)
00910 {
00911 bool rtn = false;
00912 switch (action_state)
00913 {
00914 case actionlib::SimpleClientGoalState::PENDING:
00915
00916 break;
00917
00918 case actionlib::SimpleClientGoalState::ACTIVE:
00919
00920 break;
00921
00922 case actionlib::SimpleClientGoalState::SUCCEEDED:
00923 rtn = true;
00924 break;
00925
00926 case actionlib::SimpleClientGoalState::PREEMPTED:
00927 case actionlib::SimpleClientGoalState::LOST:
00928 case actionlib::SimpleClientGoalState::REJECTED:
00929 case actionlib::SimpleClientGoalState::ABORTED:
00930
00931 ROS_ERROR_STREAM("Bad action state: " << action_state);
00932 setState(StateTypes::ABORTING);
00933 break;
00934
00935 default:
00936 ROS_ERROR_STREAM("Unrecognized action state: " << action_state);
00937 setState(StateTypes::ABORTING);
00938 break;
00939 }
00940
00941 return rtn;
00942 }
00943
00944 bool StateMachine::moveArm(const std::string & move_name)
00945 {
00946 joint_traj_goal_.trajectory = *joint_paths_[move_name];
00947
00948 trajectory_filter_.request.trajectory = joint_traj_goal_.trajectory;
00949 if (!joint_traj_goal_.trajectory.points.empty())
00950 {
00951 if (trajectory_filter_client_.call(trajectory_filter_))
00952 {
00953 if (trajectory_filter_.response.error_code.val == trajectory_filter_.response.error_code.SUCCESS)
00954 {
00955 ROS_INFO_STREAM("======================== MOVING ROBOT ========================");
00956
00957 joint_traj_goal_.trajectory = trajectory_filter_.response.trajectory;
00958
00959 joint_traj_client_ptr_->sendGoal(joint_traj_goal_);
00960 }
00961 else
00962 {
00963 ROS_ERROR("Failed to process filter trajectory, entering fault state");
00964 setState(StateTypes::ABORTING);
00965 }
00966 }
00967
00968 else
00969 {
00970 ROS_ERROR("Failed to call filter trajectory, entering fault state");
00971 setState(StateTypes::ABORTING);
00972 }
00973 }
00974 else
00975 {
00976 ROS_ERROR_STREAM(move_name << " trajectory is empty, failing");
00977 setState(StateTypes::ABORTING);
00978 }
00979
00980 return true;
00981 }
00982
00983 bool StateMachine::isMoveDone()
00984 {
00985 return isActionComplete(joint_traj_client_ptr_->getState().state_);
00986 }
00987
00988 void StateMachine::openDoor()
00989 {
00990 ROS_INFO_STREAM("======================== OPENING DOOR ========================");
00991 mtconnect_msgs::OpenDoorGoal goal;
00992 goal.open_door = MTCONNECT_ACTION_ACTIVE_FLAG;
00993 open_door_client_ptr_->sendGoal(goal);
00994 }
00995
00996 bool StateMachine::isDoorOpened()
00997 {
00998 return isActionComplete(open_door_client_ptr_->getState().state_);
00999 }
01000
01001 void StateMachine::closeDoor()
01002 {
01003 ROS_INFO_STREAM("======================== CLOSING_DOOR ========================");
01004 mtconnect_msgs::CloseDoorGoal goal;
01005 goal.close_door = MTCONNECT_ACTION_ACTIVE_FLAG;
01006 close_door_client_ptr_->sendGoal(goal);
01007 }
01008
01009 bool StateMachine::isDoorClosed()
01010 {
01011 return isActionComplete(close_door_client_ptr_->getState().state_);
01012 }
01013
01014 void StateMachine::openChuck()
01015 {
01016 ROS_INFO_STREAM("======================== OPENING CHUCK ========================");
01017
01018 mtconnect_msgs::OpenChuckGoal chuck_goal;
01019 chuck_goal.open_chuck = MTCONNECT_ACTION_ACTIVE_FLAG;
01020 open_chuck_client_ptr_->sendGoal(chuck_goal);
01021
01022
01023 object_manipulation_msgs::GraspHandPostureExecutionGoal vise_goal;
01024 vise_goal.goal = object_manipulation_msgs::GraspHandPostureExecutionGoal::RELEASE;
01025 vise_action_client_ptr_->sendGoal(vise_goal);
01026 }
01027
01028 bool StateMachine::isChuckOpened()
01029 {
01030 return isActionComplete(open_chuck_client_ptr_->getState().state_);
01031 }
01032
01033 void StateMachine::closeChuck()
01034 {
01035 ROS_INFO_STREAM("======================== CLOSING CHUCK ========================");
01036
01037 mtconnect_msgs::CloseChuckGoal chuck_goal;
01038 chuck_goal.close_chuck = MTCONNECT_ACTION_ACTIVE_FLAG;
01039 close_chuck_client_ptr_->sendGoal(chuck_goal);
01040
01041
01042 object_manipulation_msgs::GraspHandPostureExecutionGoal vise_goal;
01043 vise_goal.goal = object_manipulation_msgs::GraspHandPostureExecutionGoal::GRASP;
01044 vise_action_client_ptr_->sendGoal(vise_goal);
01045 }
01046
01047 bool StateMachine::isChuckClosed()
01048 {
01049 return isActionComplete(close_chuck_client_ptr_->getState().state_)
01050 && isActionComplete(grasp_action_client_ptr_->getState().state_);
01051 }
01052
01053 void StateMachine::openGripper()
01054 {
01055 ROS_INFO_STREAM("======================== OPENING GRIPPER ========================");
01056 object_manipulation_msgs::GraspHandPostureExecutionGoal goal;
01057 goal.goal = object_manipulation_msgs::GraspHandPostureExecutionGoal::RELEASE;
01058 grasp_action_client_ptr_->sendGoal(goal);
01059 }
01060
01061 bool StateMachine::isGripperOpened()
01062 {
01063 return isActionComplete(grasp_action_client_ptr_->getState().state_);
01064 }
01065
01066 void StateMachine::closeGripper()
01067 {
01068 ROS_INFO_STREAM("======================== CLOSING GRIPPER ========================");
01069 object_manipulation_msgs::GraspHandPostureExecutionGoal goal;
01070 goal.goal = object_manipulation_msgs::GraspHandPostureExecutionGoal::GRASP;
01071 grasp_action_client_ptr_->sendGoal(goal);
01072 }
01073
01074 bool StateMachine::isGripperClosed()
01075 {
01076 return isActionComplete(grasp_action_client_ptr_->getState().state_);
01077 }
01078
01079 bool StateMachine::isHome()
01080 {
01081 bool rtn = false;
01082
01083 if( home_check_ )
01084 {
01085 ROS_INFO_STREAM("Home checking ENABLED, returning range check");
01086 rtn = industrial_robot_client::utils::isWithinRange(home_->group_->joint_names_, home_->values_,
01087 joint_state_msg_.name, joint_state_msg_.position, home_tol_);
01088 }
01089 else
01090 {
01091 ROS_WARN_STREAM("Home checking DISABLED, returning true");
01092 rtn = true;
01093 }
01094
01095 return rtn;
01096 }