Go to the documentation of this file.00001
00046 #include <kinova/KinovaTypes.h>
00047 #include "jaco_driver/jaco_fingers_action.h"
00048 #include "jaco_driver/jaco_types.h"
00049
00050
00051 namespace jaco
00052 {
00053
00054 JacoFingersActionServer::JacoFingersActionServer(JacoComm &arm_comm, const ros::NodeHandle &nh)
00055 : arm_comm_(arm_comm),
00056 node_handle_(nh, "fingers"),
00057 action_server_(node_handle_, "finger_positions",
00058 boost::bind(&JacoFingersActionServer::actionCallback, this, _1), false)
00059 {
00060 double tolerance;
00061 node_handle_.param<double>("stall_interval_seconds", stall_interval_seconds_, 0.5);
00062 node_handle_.param<double>("stall_threshold", stall_threshold_, 1.0);
00063 node_handle_.param<double>("rate_hz", rate_hz_, 10.0);
00064 node_handle_.param<double>("tolerance", tolerance, 2.0);
00065 tolerance_ = static_cast<float>(tolerance);
00066
00067 action_server_.start();
00068 }
00069
00070
00071 JacoFingersActionServer::~JacoFingersActionServer()
00072 {
00073 }
00074
00075
00076 void JacoFingersActionServer::actionCallback(const jaco_msgs::SetFingersPositionGoalConstPtr &goal)
00077 {
00078 if ((arm_comm_.numFingers() < 3) && (goal->fingers.finger3 != 0.0))
00079 {
00080 ROS_WARN("Detected that the third finger command was non-zero even though there "
00081 "are only two fingers on the gripper. The goal for the third finger "
00082 "should be set to zero or you make experience delays in action results.");
00083 }
00084
00085 jaco_msgs::SetFingersPositionFeedback feedback;
00086 jaco_msgs::SetFingersPositionResult result;
00087 FingerAngles current_finger_positions;
00088 ros::Time current_time = ros::Time::now();
00089
00090 try
00091 {
00092 arm_comm_.getFingerPositions(current_finger_positions);
00093
00094 if (arm_comm_.isStopped())
00095 {
00096 ROS_INFO("Could not complete finger action because the arm is stopped");
00097 result.fingers = current_finger_positions.constructFingersMsg();
00098 action_server_.setAborted(result);
00099 return;
00100 }
00101
00102 last_nonstall_time_ = current_time;
00103 last_nonstall_finger_positions_ = current_finger_positions;
00104
00105 FingerAngles target(goal->fingers);
00106 arm_comm_.setFingerPositions(target);
00107
00108
00109
00110
00111 while (true)
00112 {
00113 ros::spinOnce();
00114
00115 if (action_server_.isPreemptRequested() || !ros::ok())
00116 {
00117 result.fingers = current_finger_positions.constructFingersMsg();
00118 arm_comm_.stopAPI();
00119 arm_comm_.startAPI();
00120 action_server_.setPreempted(result);
00121 return;
00122 }
00123 else if (arm_comm_.isStopped())
00124 {
00125 result.fingers = current_finger_positions.constructFingersMsg();
00126 action_server_.setAborted(result);
00127 return;
00128 }
00129
00130 arm_comm_.getFingerPositions(current_finger_positions);
00131 current_time = ros::Time::now();
00132 feedback.fingers = current_finger_positions.constructFingersMsg();
00133 action_server_.publishFeedback(feedback);
00134
00135 if (target.isCloseToOther(current_finger_positions, tolerance_))
00136 {
00137
00138 result.fingers = current_finger_positions.constructFingersMsg();
00139 action_server_.setSucceeded(result);
00140 return;
00141 }
00142 else if (!last_nonstall_finger_positions_.isCloseToOther(current_finger_positions, stall_threshold_))
00143 {
00144
00145 last_nonstall_time_ = current_time;
00146 last_nonstall_finger_positions_ = current_finger_positions;
00147 }
00148 else if ((current_time - last_nonstall_time_).toSec() > stall_interval_seconds_)
00149 {
00150
00151 result.fingers = current_finger_positions.constructFingersMsg();
00152 arm_comm_.stopAPI();
00153 arm_comm_.startAPI();
00154 action_server_.setPreempted(result);
00155 return;
00156 }
00157
00158 ros::Rate(rate_hz_).sleep();
00159 }
00160 }
00161 catch(const std::exception& e)
00162 {
00163 result.fingers = current_finger_positions.constructFingersMsg();
00164 ROS_ERROR_STREAM(e.what());
00165 action_server_.setAborted(result);
00166 }
00167 }
00168
00169 }