Go to the documentation of this file.00001 
00006 #include "robotiq_action_server/robotiq_c_model_action_server.h"
00007 
00008 
00009 
00010 
00011 namespace
00012 {
00013   using namespace robotiq_action_server;
00014 
00015   
00016 
00017 
00018 
00019   struct BadArgumentsError {};
00020 
00021 
00022   GripperOutput goalToRegisterState(const GripperCommandGoal& goal, const CModelGripperParams& params)
00023   {
00024     GripperOutput result;
00025     result.rACT = 0x1; 
00026     result.rGTO = 0x1; 
00027     result.rATR = 0x0; 
00028     result.rSP = 128; 
00029     
00030     if (goal.command.position > params.max_gap_ || goal.command.position < params.min_gap_)
00031     {
00032       ROS_WARN("Goal gripper gap size is out of range(%f to %f): %f m",
00033                params.min_gap_, params.max_gap_, goal.command.position);
00034       throw BadArgumentsError();
00035     }
00036     
00037     if (goal.command.max_effort < params.min_effort_ || goal.command.max_effort > params.max_effort_)
00038     {
00039       ROS_WARN("Goal gripper effort out of range (%f to %f N): %f N",
00040                params.min_effort_, params.max_effort_, goal.command.max_effort);
00041       throw BadArgumentsError();
00042     }
00043 
00044     double dist_per_tick = (params.max_gap_ - params.min_gap_) / 255;
00045     double eff_per_tick = (params.max_effort_ - params.min_effort_) / 255;
00046 
00047     result.rPR = static_cast<uint8_t>((params.max_gap_ - goal.command.position) / dist_per_tick);
00048     result.rFR = static_cast<uint8_t>((goal.command.max_effort - params.min_effort_) / eff_per_tick);
00049 
00050     ROS_INFO("Setting goal position register to %hhu", result.rPR);
00051 
00052     return result;
00053   }
00054 
00055   
00056 
00057 
00058 
00059   template<typename T>
00060   T registerStateToResultT(const GripperInput& input, const CModelGripperParams& params, uint8_t goal_pos)
00061   {
00062     T result;
00063     double dist_per_tick = (params.max_gap_ - params.min_gap_) / 255;
00064     double eff_per_tick = (params.max_effort_ - params.min_effort_) / 255;
00065 
00066     result.position = input.gPO * dist_per_tick + params.min_gap_;
00067     result.effort = input.gCU * eff_per_tick + params.min_effort_;
00068     result.stalled = input.gOBJ == 0x1 || input.gOBJ == 0x2;
00069     result.reached_goal = input.gPO == goal_pos;
00070 
00071     return result;
00072   }
00073 
00074   
00075   inline
00076   GripperCommandResult registerStateToResult(const GripperInput& input, const CModelGripperParams& params, uint8_t goal_pos)
00077   {
00078     return registerStateToResultT<GripperCommandResult>(input, params, goal_pos);
00079   }
00080 
00081   inline
00082   GripperCommandFeedback registerStateToFeedback(const GripperInput& input, const CModelGripperParams& params, uint8_t goal_pos)
00083   {
00084     return registerStateToResultT<GripperCommandFeedback>(input, params, goal_pos);
00085   }
00086 
00087 } 
00088 
00089 namespace robotiq_action_server
00090 {
00091 
00092 CModelGripperActionServer::CModelGripperActionServer(const std::string& name, const CModelGripperParams& params)
00093   : nh_()
00094   , as_(nh_, name, false)
00095   , action_name_(name)
00096   , gripper_params_(params)
00097 {
00098   as_.registerGoalCallback(boost::bind(&CModelGripperActionServer::goalCB, this));
00099   as_.registerPreemptCallback(boost::bind(&CModelGripperActionServer::preemptCB, this));
00100 
00101   state_sub_ = nh_.subscribe("input", 1, &CModelGripperActionServer::analysisCB, this);
00102   goal_pub_ = nh_.advertise<GripperOutput>("output", 1);
00103 
00104   as_.start();
00105 }
00106 
00107 void CModelGripperActionServer::goalCB()
00108 {
00109   
00110   if (current_reg_state_.gSTA != 0x3)
00111   {
00112     ROS_WARN("%s could not accept goal because the gripper is not yet active", action_name_.c_str());
00113     return;
00114   }
00115 
00116   GripperCommandGoal current_goal (*(as_.acceptNewGoal()));
00117 
00118   if (as_.isPreemptRequested())
00119   {
00120     as_.setPreempted();
00121   }
00122 
00123   try
00124   {
00125     goal_reg_state_ = goalToRegisterState(current_goal, gripper_params_);
00126     goal_pub_.publish(goal_reg_state_);
00127   }
00128   catch (BadArgumentsError& e)
00129   {
00130     ROS_INFO("%s No goal issued to gripper", action_name_.c_str());
00131   }
00132 }
00133 
00134 void CModelGripperActionServer::preemptCB()
00135 {
00136   ROS_INFO("%s: Preempted", action_name_.c_str());
00137   as_.setPreempted();
00138 }
00139 
00140 void CModelGripperActionServer::analysisCB(const GripperInput::ConstPtr& msg)
00141 {
00142   current_reg_state_ = *msg;
00143 
00144   if (!as_.isActive()) return;
00145 
00146   
00147   if (current_reg_state_.gSTA != 0x3)
00148   {
00149     
00150     if (current_reg_state_.gSTA == 0x0 && goal_reg_state_.rACT != 0x1)
00151     {
00152       
00153       issueActivation();
00154     }
00155 
00156     
00157     
00158     return;
00159   }
00160 
00161   
00162   if (current_reg_state_.gFLT)
00163   {
00164     ROS_WARN("%s faulted with code: %x", action_name_.c_str(), current_reg_state_.gFLT);
00165     as_.setAborted(registerStateToResult(current_reg_state_,
00166                                          gripper_params_,
00167                                          goal_reg_state_.rPR));
00168   }
00169   else if (current_reg_state_.gGTO && current_reg_state_.gOBJ && current_reg_state_.gPR == goal_reg_state_.rPR)
00170   {
00171     
00172     
00173     ROS_INFO("%s succeeded", action_name_.c_str());
00174     as_.setSucceeded(registerStateToResult(current_reg_state_,
00175                                            gripper_params_,
00176                                            goal_reg_state_.rPR));
00177   }
00178   else
00179   {
00180     
00181     as_.publishFeedback(registerStateToFeedback(current_reg_state_,
00182                                                 gripper_params_,
00183                                                 goal_reg_state_.rPR));
00184   }
00185 }
00186 
00187 void CModelGripperActionServer::issueActivation()
00188 {
00189   ROS_INFO("Activating gripper for gripper action server: %s", action_name_.c_str());
00190   GripperOutput out;
00191   out.rACT = 0x1;
00192   
00193   goal_reg_state_ = out;
00194   goal_pub_.publish(out);
00195 }
00196 }