jaco_pose_action.cpp
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         // Put the goal pose into the frame used by the arm
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                 // Check if we are outside of a potential stall condition
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                 // Check if the full stall condition has been meet
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 }  // namespace jaco


jaco_driver
Author(s): Ilia Baranov (Clearpath) , Jeff Schmidt (Clearpath) , Alex Bencz (Clearpath) , Matt DeDonato (WPI), Braden Stenning
autogenerated on Mon Mar 2 2015 16:21:03