00001 #include "robodyn_mechanisms/GripperSupervisor.h" 00002 #include <iostream> 00003 00004 GripperSupervisor::GripperSupervisor(): setpoint("null"), motcomLimit(30), pendingTimer(0) 00005 { 00006 } 00007 00008 GripperSupervisor::~GripperSupervisor() 00009 { 00010 } 00011 00012 void GripperSupervisor::initializeMaps(const std::vector<std::string>& grippers) 00013 { 00014 // Initialize zeros in the right ways 00015 EndEffectorData zeroData; 00016 zeroData.locked = false; 00017 zeroData.loaded = false; 00018 zeroData.verified = false; 00019 00020 GripperControlModes initMode; 00021 initMode.state = r2_msgs::JointControlMode::IGNORE; 00022 initMode.coeffs = r2_msgs::JointControlCoeffState::NOTLOADED; 00023 00024 for (unsigned int i = 0; i < grippers.size(); i++) 00025 { 00026 endEffectorMap[grippers[i]] = zeroData; 00027 errorStates[grippers[i]] = false; 00028 stateMap[grippers[i]] = IDLE; 00029 gripperJointModeMap[grippers[i]] = initMode; 00030 gripperDriveApprovedMap[grippers[i]] = false; 00031 } 00032 00033 return; 00034 00035 } 00036 00037 void GripperSupervisor::populateGripperStateInfo(const r2_msgs::GripperPositionState& eefState) 00038 { 00039 // Iterate through all end effectors in message 00040 if (eefState.name.size() == eefState.locked.size() && eefState.name.size() == eefState.loaded.size()) 00041 { 00042 for (unsigned int i = 0; i < eefState.name.size(); i++) 00043 { 00044 if ((eefIt = endEffectorMap.find(eefState.name[i])) != endEffectorMap.end()) 00045 { 00046 eefIt->second.locked = eefState.locked[i]; 00047 eefIt->second.loaded = eefState.loaded[i]; 00048 } 00049 } 00050 } 00051 00052 return; 00053 00054 } 00055 00056 void GripperSupervisor::populateBaseFrameInfo(const r2_msgs::StringArray& baseFrames) 00057 { 00058 baseFrameList = baseFrames.data; 00059 00060 return; 00061 } 00062 00063 void GripperSupervisor::populateGoalStatus(const actionlib_msgs::GoalStatusArray& goalStats) 00064 { 00065 for (unsigned int i = 0; i < goalStats.status_list.size(); i++) 00066 { 00067 // clear this vector after using it in transitions 00068 if (goalStats.status_list[i].status == actionlib_msgs::GoalStatus::ABORTED || 00069 goalStats.status_list[i].status == actionlib_msgs::GoalStatus::SUCCEEDED) 00070 { 00071 goalStatuses.status_list.push_back(goalStats.status_list[i]); 00072 } 00073 } 00074 00075 return; 00076 } 00077 00078 void GripperSupervisor::populateGripperCommandsIn(const r2_msgs::GripperPositionCommand& gripCmd) 00079 { 00080 // clear this vector after using it in transitions 00081 gripperCmds = gripCmd; 00082 00083 actionlib_msgs::GoalStatus gStat; 00084 gStat.goal_id.stamp = gripperCmds.header.stamp; 00085 gStat.status = actionlib_msgs::GoalStatus::PENDING; 00086 gStat.text = "Command pending"; 00087 00088 for (unsigned int i = 0; i < gripperCmds.name.size(); i++) 00089 { 00090 gStat.goal_id.id = gripperCmds.name[i]; 00091 goalStatusesOut.status_list.push_back(gStat); 00092 } 00093 00094 return; 00095 } 00096 00097 void GripperSupervisor::populateJointControlMode(const r2_msgs::JointControlDataArray& jntMode) 00098 { 00099 if (jntMode.joint.size() == jntMode.data.size()) 00100 { 00101 for (unsigned int i = 0; i < jntMode.joint.size(); i++) 00102 { 00103 if ((intIt = gripperJointModeMap.find(jntMode.joint[i])) != gripperJointModeMap.end()) 00104 { 00105 intIt->second.state = jntMode.data[i].controlMode.state; 00106 intIt->second.coeffs = jntMode.data[i].coeffState.state; 00107 } 00108 } 00109 } 00110 00111 return; 00112 } 00113 00114 void GripperSupervisor::populateDriveRequestMsg(r2_msgs::StringArray& requestOut) 00115 { 00116 requestOut = driveRequest; 00117 requestOut.header.stamp = ros::Time::now(); 00118 00119 driveRequest.data.clear(); 00120 return; 00121 } 00122 00123 void GripperSupervisor::populateJointControlCommandMsg(r2_msgs::JointControlDataArray& modeCmdOut) 00124 { 00125 modeCmdOut = jointModeCommands; 00126 modeCmdOut.header.stamp = ros::Time::now(); 00127 00128 jointModeCommands.joint.clear(); 00129 jointModeCommands.data.clear(); 00130 return; 00131 } 00132 00133 void GripperSupervisor::populateGoalStatusMsg(actionlib_msgs::GoalStatusArray& statusOut) 00134 { 00135 statusOut = goalStatusesOut; 00136 goalStatusesOut.status_list.clear(); 00137 return; 00138 } 00139 00140 void GripperSupervisor::populateGripperCommandMsg(r2_msgs::GripperPositionCommand& cmdOut) 00141 { 00142 // put all commands into one message 00143 cmdOut = gripperCmdOut; 00144 cmdOut.header.stamp = ros::Time::now(); 00145 00146 gripperCmdOut.name.clear(); 00147 gripperCmdOut.setpoint.clear(); 00148 gripperCmdOut.command.clear(); 00149 gripperCmdOut.dutyCycle.clear(); 00150 00151 return; 00152 } 00153 00154 void GripperSupervisor::populateCheckedGrippers(const bool override) 00155 { 00156 for (reqIt = gripperDriveApprovedMap.begin(); reqIt != gripperDriveApprovedMap.end(); ++reqIt) 00157 { 00158 reqIt->second = override; 00159 } 00160 } 00161 00162 void GripperSupervisor::populateCheckedGrippers(const r2_msgs::StringArray& grippers) 00163 { 00164 for (reqIt = gripperDriveApprovedMap.begin(); reqIt != gripperDriveApprovedMap.end(); ++reqIt) 00165 { 00166 reqIt->second = false; 00167 } 00168 00169 for (unsigned int i = 0; i < grippers.data.size(); ++i) 00170 { 00171 reqIt = gripperDriveApprovedMap.find(grippers.data[i]); 00172 00173 if (reqIt != gripperDriveApprovedMap.end()) 00174 { 00175 reqIt->second = true; 00176 } 00177 } 00178 } 00179 00180 void GripperSupervisor::checkTransitions(int baseOverride) 00181 { 00183 for (errIt = errorStates.begin(); errIt != errorStates.end(); ++errIt) 00184 { 00185 if ((intIt = gripperJointModeMap.find(errIt->first)) != gripperJointModeMap.end()) 00186 { 00187 if (intIt->second.coeffs == r2_msgs::JointControlCoeffState::LOADED) 00188 { 00189 int change = detectChangeInErrorState(errIt->first); 00190 00191 if (change > 0 && !errIt->second) 00192 { 00193 updateErrorState(errIt->first); 00194 transToFault(errIt->first); 00195 } 00196 else if (change > 0 && errIt->second) 00197 { 00198 if (transToIdle(errIt->first)) 00199 { 00200 updateErrorState(errIt->first); 00201 } 00202 } 00203 } 00204 } 00205 } 00206 00208 for (unsigned int i = 0; i < goalStatuses.status_list.size(); i++) 00209 { 00210 std::string name = goalStatuses.status_list[i].goal_id.id; 00211 00212 if (stateMap.find(name) != stateMap.end() && (intIt = gripperJointModeMap.find(name)) != gripperJointModeMap.end()) 00213 { 00214 if (intIt->second.state != r2_msgs::JointControlMode::FAULTED) 00215 { 00216 if (goalStatuses.status_list[i].status == actionlib_msgs::GoalStatus::ABORTED) 00217 { 00218 transToFailure(name); 00219 00220 // send warning via status message 00221 actionlib_msgs::GoalStatus gStat; 00222 gStat.goal_id.stamp = gripperCmds.header.stamp; 00223 gStat.goal_id.id = name; 00224 gStat.status = actionlib_msgs::GoalStatus::ABORTED; 00225 gStat.text = "Transition to failure"; 00226 goalStatusesOut.status_list.push_back(gStat); 00227 } 00228 else 00229 { 00230 // will send multiple park commands after time out in state machine if this doesn't work 00231 transToIdle(name); 00232 00233 // send warning via status message 00234 actionlib_msgs::GoalStatus gStat; 00235 gStat.goal_id.stamp = gripperCmds.header.stamp; 00236 gStat.goal_id.id = name; 00237 gStat.status = actionlib_msgs::GoalStatus::SUCCEEDED; 00238 gStat.text = "Command succeeded"; 00239 goalStatusesOut.status_list.push_back(gStat); 00240 } 00241 } 00242 } 00243 00244 runStateMachine(name); 00245 } 00246 00247 goalStatuses.status_list.clear(); 00248 00250 for (unsigned int i = 0; i < gripperCmds.name.size(); i++) 00251 { 00252 std::string name = gripperCmds.name[i]; 00253 00254 if ((stateIt = stateMap.find(name)) != stateMap.end() && (intIt = gripperJointModeMap.find(name)) != gripperJointModeMap.end()) 00255 { 00256 if (intIt->second.coeffs == r2_msgs::JointControlCoeffState::LOADED) 00257 { 00258 if (gripperCmds.command[i] == "cancel") 00259 { 00260 // add command to cancel this gripper 00261 gripperCmdOut.name.push_back(gripperCmds.name[i]); 00262 gripperCmdOut.setpoint.push_back(gripperCmds.setpoint[i]); 00263 gripperCmdOut.command.push_back("c_cancel"); 00264 gripperCmdOut.dutyCycle.push_back(hiDutyCycleLimit); 00265 00266 actionlib_msgs::GoalStatus gStat; 00267 gStat.goal_id.stamp = gripperCmds.header.stamp; 00268 gStat.goal_id.id = gripperCmds.name[i]; 00269 gStat.status = actionlib_msgs::GoalStatus::ACTIVE; 00270 gStat.text = "Sending cancel"; 00271 goalStatusesOut.status_list.push_back(gStat); 00272 00273 if (!(stateIt->second == FAULT or stateIt->second == FAILURE)) 00274 { 00275 transToIdle(name); 00276 } 00277 } 00278 else if (gripperCmds.command[i] == "reset") 00279 { 00280 if (stateIt->second == FAILURE) 00281 { 00282 transToIdle(name); 00283 } 00284 } 00285 else if (gripperCmds.command[i] == "lock") 00286 { 00287 if (!(stateIt->second == FAULT or stateIt->second == FAILURE or isLocked(name))) 00288 { 00289 setpoint = gripperCmds.setpoint[i]; 00290 motcomLimit = hiDutyCycleLimit; 00291 transToLock(name); 00292 } 00293 else 00294 { 00295 // send warning via status message 00296 actionlib_msgs::GoalStatus gStat; 00297 gStat.goal_id.stamp = gripperCmds.header.stamp; 00298 gStat.goal_id.id = name; 00299 gStat.status = actionlib_msgs::GoalStatus::REJECTED; 00300 gStat.text = "Lock not valid"; 00301 goalStatusesOut.status_list.push_back(gStat); 00302 } 00303 } 00304 else if (gripperCmds.command[i] == "release") 00305 { 00306 if (!(stateIt->second == FAULT or stateIt->second == FAILURE) && (isReleaseValid(name) || baseOverride == 7)) 00307 { 00308 setpoint = gripperCmds.setpoint[i]; 00309 motcomLimit = hiDutyCycleLimit; 00310 transToRelease(name); 00311 } 00312 else 00313 { 00314 // send warning via status message 00315 actionlib_msgs::GoalStatus gStat; 00316 gStat.goal_id.stamp = gripperCmds.header.stamp; 00317 gStat.goal_id.id = name; 00318 gStat.status = actionlib_msgs::GoalStatus::REJECTED; 00319 gStat.text = "Release not valid"; 00320 goalStatusesOut.status_list.push_back(gStat); 00321 } 00322 } 00323 else if (gripperCmds.command[i] == "set") 00324 { 00325 // including "backdoor" to allow gripper to close regardless of other base frames being present 00326 if (!(stateIt->second == FAULT or stateIt->second == FAILURE) && (isReleaseValid(name) || baseOverride == 7)) 00327 { 00328 setpoint = gripperCmds.setpoint[i]; 00329 motcomLimit = hiDutyCycleLimit; 00330 transToSet(name); 00331 } 00332 else 00333 { 00334 // send warning via status message 00335 actionlib_msgs::GoalStatus gStat; 00336 gStat.goal_id.stamp = gripperCmds.header.stamp; 00337 gStat.goal_id.id = name; 00338 gStat.status = actionlib_msgs::GoalStatus::REJECTED; 00339 gStat.text = "Set not valid"; 00340 goalStatusesOut.status_list.push_back(gStat); 00341 } 00342 } 00343 else 00344 { 00345 // send warning via status message 00346 actionlib_msgs::GoalStatus gStat; 00347 gStat.goal_id.stamp = gripperCmds.header.stamp; 00348 gStat.goal_id.id = name; 00349 gStat.status = actionlib_msgs::GoalStatus::REJECTED; 00350 gStat.text = "Not a valid command"; 00351 goalStatusesOut.status_list.push_back(gStat); 00352 } 00353 } 00354 } 00355 00356 runStateMachine(name); 00357 } 00358 00359 gripperCmds.name.clear(); 00360 gripperCmds.setpoint.clear(); 00361 gripperCmds.command.clear(); 00362 gripperCmds.dutyCycle.clear(); 00363 00364 for (errIt = errorStates.begin(); errIt != errorStates.end(); ++errIt) 00365 { 00366 runStateMachine(errIt->first); 00367 } 00368 00369 return; 00370 } 00371 00372 int GripperSupervisor::detectChangeInErrorState(const std::string& name) 00373 { 00374 00375 if ((errIt = errorStates.find(name)) == errorStates.end() || (intIt = gripperJointModeMap.find(name)) == gripperJointModeMap.end()) 00376 { 00377 return -1; 00378 } 00379 00380 if ((intIt->second.state == r2_msgs::JointControlMode::FAULTED and !errIt->second) 00381 || (intIt->second.state != r2_msgs::JointControlMode::FAULTED and errIt->second)) 00382 { 00383 return 1; // true, there is a change! 00384 } 00385 00386 return 0; // no change 00387 } 00388 00389 int GripperSupervisor::updateErrorState(const std::string& name) 00390 { 00391 if ((errIt = errorStates.find(name)) == errorStates.end() || (intIt = gripperJointModeMap.find(name)) == gripperJointModeMap.end()) 00392 { 00393 return -1; 00394 } 00395 00396 if (intIt->second.state == r2_msgs::JointControlMode::FAULTED) 00397 { 00398 errIt->second = true; 00399 } 00400 else 00401 { 00402 errIt->second = false; 00403 } 00404 00405 return 0; 00406 } 00407 00408 bool GripperSupervisor::isReleaseValid(const std::string& name) 00409 { 00411 std::string oppositeGripper = FindOpposite(name); 00412 std::string oppositeBase = FindOpposite(GripperToBaseFrame(name)); 00413 unsigned int numBaseFrames = baseFrameList.size(); 00414 bool matches = false; 00415 00416 if (oppositeBase.empty() || oppositeGripper.empty()) 00417 { 00418 return false; // not valid 00419 } 00420 00421 for (unsigned int i = 0; i < numBaseFrames; i++) 00422 { 00423 if (oppositeBase == baseFrameList[i]) 00424 { 00425 matches = true; 00426 break; 00427 } 00428 } 00429 00430 if (!matches) 00431 { 00432 return false; // other gripper isn't a base frame 00433 } 00434 00436 stateIt = stateMap.find(oppositeGripper); 00437 00438 if (stateIt != stateMap.end()) 00439 { 00440 if (stateIt->second != IDLE) 00441 { 00442 return false; 00443 } 00444 } 00445 else 00446 { 00447 return false; 00448 } 00449 00451 std::map<std::string, GripperControlModes>::const_iterator itm = gripperJointModeMap.find(oppositeGripper); 00452 00453 if (itm != gripperJointModeMap.end()) 00454 { 00455 if (itm->second.state != r2_msgs::JointControlMode::FAULTED && itm->second.state != r2_msgs::JointControlMode::DRIVE) 00456 { 00457 return true; // valid 00458 } 00459 } 00460 00461 return false; // not valid 00462 } 00463 00464 bool GripperSupervisor::isLocked(const std::string& name) 00465 { 00466 if ((eefIt = endEffectorMap.find(name)) != endEffectorMap.end()) 00467 { 00468 if (eefIt->second.locked == 1) 00469 { 00470 return true; 00471 } 00472 } 00473 00474 return false; 00475 } 00476 00477 bool GripperSupervisor::transToFault(const std::string& name) 00478 { 00479 if ((stateIt = stateMap.find(name)) == stateMap.end() || (intIt = gripperJointModeMap.find(name)) == gripperJointModeMap.end()) 00480 { 00481 return false; 00482 } 00483 00484 // add a command to park gripper if in drive 00485 if (intIt->second.state == r2_msgs::JointControlMode::DRIVE) 00486 { 00487 r2_msgs::JointControlData jcd; 00488 jcd.controlMode.state = r2_msgs::JointControlMode::PARK; 00489 jointModeCommands.joint.push_back(name); 00490 jointModeCommands.data.push_back(jcd); 00491 actionlib_msgs::GoalStatus gStat; 00492 gStat.goal_id.stamp = gripperCmds.header.stamp; 00493 gStat.goal_id.id = name; 00494 gStat.status = actionlib_msgs::GoalStatus::ACTIVE; 00495 gStat.text = "Trans to fault- parking joint"; 00496 goalStatusesOut.status_list.push_back(gStat); 00497 } 00498 00499 // add command to cancel this gripper 00500 gripperCmdOut.name.push_back(name); 00501 gripperCmdOut.setpoint.push_back(setpoint); 00502 gripperCmdOut.command.push_back("c_cancel"); 00503 gripperCmdOut.dutyCycle.push_back(0); 00504 00505 actionlib_msgs::GoalStatus gStat; 00506 gStat.goal_id.stamp = gripperCmds.header.stamp; 00507 gStat.goal_id.id = name; 00508 gStat.status = actionlib_msgs::GoalStatus::ABORTED; 00509 gStat.text = "Sending cancel due to gripper fault"; 00510 goalStatusesOut.status_list.push_back(gStat); 00511 00512 stateMap[name] = FAULT; 00513 00514 return true; 00515 } 00516 00517 bool GripperSupervisor::transToIdle(const std::string& name) 00518 { 00519 if ((stateIt = stateMap.find(name)) == stateMap.end() || (intIt = gripperJointModeMap.find(name)) == gripperJointModeMap.end()) 00520 { 00521 return false; 00522 } 00523 00524 // add a command to park gripper 00525 if (stateIt->second != SET_PENDING) 00526 { 00527 if (intIt->second.state == r2_msgs::JointControlMode::DRIVE) 00528 { 00529 r2_msgs::JointControlData jcd; 00530 jcd.controlMode.state = r2_msgs::JointControlMode::PARK; 00531 jointModeCommands.joint.push_back(name); 00532 jointModeCommands.data.push_back(jcd); 00533 actionlib_msgs::GoalStatus gStat; 00534 gStat.goal_id.stamp = gripperCmds.header.stamp; 00535 gStat.goal_id.id = name; 00536 gStat.status = actionlib_msgs::GoalStatus::ACTIVE; 00537 gStat.text = "Trans to idle- parking joint"; 00538 goalStatusesOut.status_list.push_back(gStat); 00539 00540 return false; 00541 } 00542 else 00543 { 00544 stateIt->second = IDLE; 00545 } 00546 } 00547 else 00548 { 00549 stateIt->second = IDLE; 00550 } 00551 00552 return true; 00553 } 00554 00555 bool GripperSupervisor::transToFailure(const std::string& name) 00556 { 00557 if ((stateIt = stateMap.find(name)) == stateMap.end() || (intIt = gripperJointModeMap.find(name)) == gripperJointModeMap.end()) 00558 { 00559 return false; 00560 } 00561 00562 // add a command to park gripper 00563 if (intIt->second.state == r2_msgs::JointControlMode::DRIVE) 00564 { 00565 r2_msgs::JointControlData jcd; 00566 jcd.controlMode.state = r2_msgs::JointControlMode::PARK; 00567 jointModeCommands.joint.push_back(name); 00568 jointModeCommands.data.push_back(jcd); 00569 actionlib_msgs::GoalStatus gStat; 00570 gStat.goal_id.stamp = gripperCmds.header.stamp; 00571 gStat.goal_id.id = name; 00572 gStat.status = actionlib_msgs::GoalStatus::ACTIVE; 00573 gStat.text = "Trans to failure- parking joint"; 00574 goalStatusesOut.status_list.push_back(gStat); 00575 } 00576 00577 stateIt->second = FAILURE; 00578 00579 return true; 00580 } 00581 00582 bool GripperSupervisor::transToLock(const std::string& name) 00583 { 00584 if ((stateIt = stateMap.find(name)) == stateMap.end() || 00585 (intIt = gripperJointModeMap.find(name)) == gripperJointModeMap.end() || 00586 (reqIt = gripperDriveApprovedMap.find(name)) == gripperDriveApprovedMap.end()) 00587 { 00588 return false; 00589 } 00590 00591 // add a command to servo gripper 00592 if (intIt->second.state == r2_msgs::JointControlMode::FAULTED) 00593 { 00594 transToFault(name); 00595 } 00596 else if (intIt->second.state != r2_msgs::JointControlMode::DRIVE) 00597 { 00598 if (reqIt->second) 00599 { 00600 r2_msgs::JointControlData jcd; 00601 jcd.controlMode.state = r2_msgs::JointControlMode::DRIVE; 00602 jointModeCommands.joint.push_back(name); 00603 jointModeCommands.data.push_back(jcd); 00604 stateIt->second = LOCK; 00605 } 00606 else 00607 { 00608 // send request to engineer 00609 driveRequest.data.push_back(name); 00610 nextState = LOCK; 00611 stateIt->second = REQUEST_PENDING; 00612 pendingTimer = 0; 00613 } 00614 } 00615 else 00616 { 00617 stateIt->second = LOCK; 00618 } 00619 00620 return true; 00621 } 00622 00623 bool GripperSupervisor::transToRelease(const std::string& name) 00624 { 00625 if ((stateIt = stateMap.find(name)) == stateMap.end() || 00626 (intIt = gripperJointModeMap.find(name)) == gripperJointModeMap.end() || 00627 (reqIt = gripperDriveApprovedMap.find(name)) == gripperDriveApprovedMap.end()) 00628 { 00629 return false; 00630 } 00631 00632 // add a command to servo gripper 00633 if (intIt->second.state == r2_msgs::JointControlMode::FAULTED) 00634 { 00635 transToFault(name); 00636 } 00637 else if (intIt->second.state != r2_msgs::JointControlMode::DRIVE) 00638 { 00639 if (reqIt->second) 00640 { 00641 r2_msgs::JointControlData jcd; 00642 jcd.controlMode.state = r2_msgs::JointControlMode::DRIVE; 00643 jointModeCommands.joint.push_back(name); 00644 jointModeCommands.data.push_back(jcd); 00645 stateIt->second = RELEASE; 00646 } 00647 else 00648 { 00649 // send request to engineer 00650 driveRequest.data.push_back(name); 00651 nextState = RELEASE; 00652 stateIt->second = REQUEST_PENDING; 00653 pendingTimer = 0; 00654 } 00655 } 00656 else 00657 { 00658 stateIt->second = RELEASE; 00659 } 00660 00661 return true; 00662 } 00663 00664 bool GripperSupervisor::transToSet(const std::string& name) 00665 { 00666 if ((stateIt = stateMap.find(name)) == stateMap.end() || 00667 (intIt = gripperJointModeMap.find(name)) == gripperJointModeMap.end() || 00668 (reqIt = gripperDriveApprovedMap.find(name)) == gripperDriveApprovedMap.end()) 00669 { 00670 return false; 00671 } 00672 00673 // add a command to servo gripper 00674 if (intIt->second.state == r2_msgs::JointControlMode::FAULTED) 00675 { 00676 transToFault(name); 00677 } 00678 else if (intIt->second.state != r2_msgs::JointControlMode::DRIVE) 00679 { 00680 if (reqIt->second) 00681 { 00682 r2_msgs::JointControlData jcd; 00683 jcd.controlMode.state = r2_msgs::JointControlMode::DRIVE; 00684 jointModeCommands.joint.push_back(name); 00685 jointModeCommands.data.push_back(jcd); 00686 stateIt->second = SET; 00687 } 00688 else 00689 { 00690 // send request to engineer 00691 driveRequest.data.push_back(name); 00692 nextState = SET; 00693 stateIt->second = REQUEST_PENDING; 00694 pendingTimer = 0; 00695 } 00696 } 00697 else 00698 { 00699 stateIt->second = SET; 00700 } 00701 00702 return true; 00703 } 00704 00705 int GripperSupervisor::runStateMachine(const std::string& name) 00706 { 00707 if ((stateIt = stateMap.find(name)) == stateMap.end() || 00708 (intIt = gripperJointModeMap.find(name)) == gripperJointModeMap.end() || 00709 (reqIt = gripperDriveApprovedMap.find(name)) == gripperDriveApprovedMap.end()) 00710 { 00711 return -1; 00712 } 00713 00714 switch (stateIt->second) 00715 { 00716 case IDLE: 00717 case FAULT: 00718 case FAILURE: 00719 break; 00720 00721 case REQUEST_PENDING: 00722 pendingTimer++; 00723 00724 if (reqIt->second) 00725 { 00726 r2_msgs::JointControlData jcd; 00727 jcd.controlMode.state = r2_msgs::JointControlMode::DRIVE; 00728 jointModeCommands.joint.push_back(name); 00729 jointModeCommands.data.push_back(jcd); 00730 stateIt->second = nextState; 00731 } 00732 else if (pendingTimer > timeLimit) 00733 { 00734 transToIdle(name); 00735 actionlib_msgs::GoalStatus gStat; 00736 gStat.goal_id.stamp = gripperCmds.header.stamp; 00737 gStat.goal_id.id = name; 00738 gStat.status = actionlib_msgs::GoalStatus::ACTIVE; 00739 gStat.text = "Request timed out- trans to idle"; 00740 goalStatusesOut.status_list.push_back(gStat); 00741 pendingTimer = 0; 00742 } 00743 else 00744 { 00745 if (std::find(driveRequest.data.begin(), driveRequest.data.end(), name) == driveRequest.data.end()) 00746 { 00747 driveRequest.data.push_back(name); 00748 } 00749 } 00750 00751 break; 00752 00753 case RELEASE_PENDING: 00754 case SET_PENDING: 00755 pendingTimer++; 00756 00757 if (pendingTimer > timeLimit) 00758 { 00759 if (!isLocked(name)) 00760 { 00761 transToIdle(name); 00762 actionlib_msgs::GoalStatus gStat; 00763 gStat.goal_id.stamp = gripperCmds.header.stamp; 00764 gStat.goal_id.id = name; 00765 gStat.status = actionlib_msgs::GoalStatus::ACTIVE; 00766 gStat.text = "Command timed out- trans to idle"; 00767 goalStatusesOut.status_list.push_back(gStat); 00768 } 00769 else 00770 { 00771 transToFailure(name); 00772 actionlib_msgs::GoalStatus gStat; 00773 gStat.goal_id.stamp = gripperCmds.header.stamp; 00774 gStat.goal_id.id = name; 00775 gStat.status = actionlib_msgs::GoalStatus::ABORTED; 00776 gStat.text = "Command timed out- trans to failure"; 00777 goalStatusesOut.status_list.push_back(gStat); 00778 } 00779 00780 pendingTimer = 0; 00781 } 00782 00783 if (intIt->second.state == r2_msgs::JointControlMode::PARK) 00784 { 00785 stateIt->second = IDLE; 00786 } 00787 00788 break; 00789 00790 case LOCK_PENDING: 00791 pendingTimer++; 00792 00793 if (pendingTimer > timeLimit) 00794 { 00795 if (isLocked(name)) 00796 { 00797 transToIdle(name); 00798 actionlib_msgs::GoalStatus gStat; 00799 gStat.goal_id.stamp = gripperCmds.header.stamp; 00800 gStat.goal_id.id = name; 00801 gStat.status = actionlib_msgs::GoalStatus::SUCCEEDED; 00802 gStat.text = "Lock timed out- trans to idle"; 00803 goalStatusesOut.status_list.push_back(gStat); 00804 } 00805 else 00806 { 00807 transToFailure(name); 00808 actionlib_msgs::GoalStatus gStat; 00809 gStat.goal_id.stamp = gripperCmds.header.stamp; 00810 gStat.goal_id.id = name; 00811 gStat.status = actionlib_msgs::GoalStatus::ABORTED; 00812 gStat.text = "Lock timed out- trans to failure"; 00813 goalStatusesOut.status_list.push_back(gStat); 00814 } 00815 00816 pendingTimer = 0; 00817 } 00818 00819 if (intIt->second.state == r2_msgs::JointControlMode::PARK) 00820 { 00821 stateIt->second = IDLE; 00822 } 00823 00824 break; 00825 00826 case LOCK: 00827 if (intIt->second.state == r2_msgs::JointControlMode::DRIVE) 00828 { 00829 // send the lock command 00830 gripperCmdOut.name.push_back(name); 00831 gripperCmdOut.setpoint.push_back(setpoint); 00832 gripperCmdOut.command.push_back("c_lock"); 00833 gripperCmdOut.dutyCycle.push_back(motcomLimit); 00834 00835 actionlib_msgs::GoalStatus gStat; 00836 gStat.goal_id.stamp = gripperCmds.header.stamp; 00837 gStat.goal_id.id = name; 00838 gStat.status = actionlib_msgs::GoalStatus::ACTIVE; 00839 gStat.text = "Sending lock command"; 00840 goalStatusesOut.status_list.push_back(gStat); 00841 00842 stateIt->second = LOCK_PENDING; 00843 pendingTimer = 0; 00844 } 00845 00846 break; 00847 00848 case RELEASE: 00849 if (intIt->second.state == r2_msgs::JointControlMode::DRIVE) 00850 { 00851 // send the release command 00852 gripperCmdOut.name.push_back(name); 00853 gripperCmdOut.setpoint.push_back(setpoint); 00854 gripperCmdOut.command.push_back("c_release"); 00855 gripperCmdOut.dutyCycle.push_back(motcomLimit); 00856 00857 actionlib_msgs::GoalStatus gStat; 00858 gStat.goal_id.stamp = gripperCmds.header.stamp; 00859 gStat.goal_id.id = name; 00860 gStat.status = actionlib_msgs::GoalStatus::ACTIVE; 00861 gStat.text = "Sending release command"; 00862 goalStatusesOut.status_list.push_back(gStat); 00863 00864 stateIt->second = RELEASE_PENDING; 00865 pendingTimer = 0; 00866 } 00867 00868 break; 00869 00870 case SET: 00871 if (intIt->second.state == r2_msgs::JointControlMode::DRIVE) 00872 { 00873 // send the set command 00874 gripperCmdOut.name.push_back(name); 00875 gripperCmdOut.setpoint.push_back(setpoint); 00876 gripperCmdOut.command.push_back("c_set"); 00877 gripperCmdOut.dutyCycle.push_back(motcomLimit); 00878 00879 actionlib_msgs::GoalStatus gStat; 00880 gStat.goal_id.stamp = gripperCmds.header.stamp; 00881 gStat.goal_id.id = name; 00882 gStat.status = actionlib_msgs::GoalStatus::ACTIVE; 00883 gStat.text = "Sending set command"; 00884 goalStatusesOut.status_list.push_back(gStat); 00885 00886 stateIt->second = SET_PENDING; 00887 pendingTimer = 0; 00888 } 00889 00890 break; 00891 00892 default: 00893 // unknown 00894 break; 00895 } 00896 00897 return 0; 00898 } 00899 00900 int GripperSupervisor::getState(const std::string& name) 00901 { 00902 if ((stateIt = stateMap.find(name)) == stateMap.end()) 00903 { 00904 return -1; 00905 } 00906 00907 return stateIt->second; 00908 } 00909 00910 void GripperSupervisor::setLimits(const int& highDuty, const int& time) 00911 { 00912 hiDutyCycleLimit = highDuty; 00913 timeLimit = time; 00914 }