Go to the documentation of this file.00001
00046 #include "jaco_driver/jaco_pose_action.h"
00047 #include <kinova/KinovaTypes.h>
00048 #include "jaco_driver/jaco_types.h"
00049 #include <string>
00050
00051
00052 namespace jaco
00053 {
00054
00055 JacoPoseActionServer::JacoPoseActionServer(JacoComm &arm_comm, const ros::NodeHandle &nh)
00056 : arm_comm_(arm_comm),
00057 node_handle_(nh, "arm_pose"),
00058 action_server_(node_handle_, "arm_pose",
00059 boost::bind(&JacoPoseActionServer::actionCallback, this, _1), false)
00060 {
00061 double tolerance;
00062 node_handle_.param<double>("stall_interval_seconds", stall_interval_seconds_, 1.0);
00063 node_handle_.param<double>("stall_threshold", stall_threshold_, 0.005);
00064 node_handle_.param<double>("rate_hz", rate_hz_, 10.0);
00065 node_handle_.param<double>("tolerance", tolerance, 0.01);
00066 node_handle_.param<std::string>("tf_prefix", tf_prefix_, "jaco_");
00067
00068 tolerance_ = static_cast<float>(tolerance);
00069 std::stringstream ss;
00070 ss << tf_prefix_ << "api_origin";
00071 api_origin_frame_ = ss.str();
00072
00073 action_server_.start();
00074 }
00075
00076
00077 JacoPoseActionServer::~JacoPoseActionServer()
00078 {
00079 }
00080
00081
00082 void JacoPoseActionServer::actionCallback(const jaco_msgs::ArmPoseGoalConstPtr &goal)
00083 {
00084 jaco_msgs::ArmPoseFeedback feedback;
00085 jaco_msgs::ArmPoseResult result;
00086 feedback.pose.header.frame_id = goal->pose.header.frame_id;
00087 result.pose.header.frame_id = goal->pose.header.frame_id;
00088
00089 ros::Time current_time = ros::Time::now();
00090 JacoPose current_pose;
00091 geometry_msgs::PoseStamped local_pose;
00092 local_pose.header.frame_id = api_origin_frame_;
00093
00094 try
00095 {
00096
00097 if (ros::ok()
00098 && !listener.canTransform(api_origin_frame_, goal->pose.header.frame_id,
00099 goal->pose.header.stamp))
00100 {
00101 ROS_ERROR("Could not get transfrom from %s to %s, aborting cartesian movement",
00102 api_origin_frame_.c_str(), goal->pose.header.frame_id.c_str());
00103 action_server_.setAborted(result);
00104 return;
00105 }
00106
00107 listener.transformPose(local_pose.header.frame_id, goal->pose, local_pose);
00108 arm_comm_.getCartesianPosition(current_pose);
00109
00110 if (arm_comm_.isStopped())
00111 {
00112 ROS_INFO("Could not complete cartesian action because the arm is 'stopped'.");
00113 local_pose.pose = current_pose.constructPoseMsg();
00114 listener.transformPose(result.pose.header.frame_id, local_pose, result.pose);
00115 action_server_.setAborted(result);
00116 return;
00117 }
00118
00119 last_nonstall_time_ = current_time;
00120 last_nonstall_pose_ = current_pose;
00121
00122 JacoPose target(local_pose.pose);
00123 arm_comm_.setCartesianPosition(target);
00124
00125 while (true)
00126 {
00127 ros::spinOnce();
00128
00129 if (action_server_.isPreemptRequested() || !ros::ok())
00130 {
00131 result.pose = feedback.pose;
00132 arm_comm_.stopAPI();
00133 arm_comm_.startAPI();
00134 action_server_.setPreempted(result);
00135 return;
00136 }
00137 else if (arm_comm_.isStopped())
00138 {
00139 result.pose = feedback.pose;
00140 action_server_.setAborted(result);
00141 return;
00142 }
00143
00144 arm_comm_.getCartesianPosition(current_pose);
00145 current_time = ros::Time::now();
00146 local_pose.pose = current_pose.constructPoseMsg();
00147 listener.transformPose(feedback.pose.header.frame_id, local_pose, feedback.pose);
00148 action_server_.publishFeedback(feedback);
00149
00150 if (target.isCloseToOther(current_pose, tolerance_))
00151 {
00152 result.pose = feedback.pose;
00153 action_server_.setSucceeded(result);
00154 return;
00155 }
00156 else if (!last_nonstall_pose_.isCloseToOther(current_pose, stall_threshold_))
00157 {
00158
00159 last_nonstall_time_ = current_time;
00160 last_nonstall_pose_ = current_pose;
00161 }
00162 else if ((current_time - last_nonstall_time_).toSec() > stall_interval_seconds_)
00163 {
00164
00165 result.pose = feedback.pose;
00166 arm_comm_.stopAPI();
00167 arm_comm_.startAPI();
00168 action_server_.setPreempted(result);
00169 return;
00170 }
00171
00172 ros::Rate(rate_hz_).sleep();
00173 }
00174 }
00175 catch(const std::exception& e)
00176 {
00177 result.pose = feedback.pose;
00178 ROS_ERROR_STREAM(e.what());
00179 action_server_.setAborted(result);
00180 }
00181 }
00182
00183 }