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 }