Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include <ros/ros.h>
00035
00036 #include <actionlib/server/simple_action_server.h>
00037 #include <actionlib/client/simple_action_client.h>
00038
00039 #include <pr2_controllers_msgs/Pr2GripperCommandAction.h>
00040
00041 #include <sensor_msgs/JointState.h>
00042
00043 #include <object_manipulation_msgs/GraspHandPostureExecutionAction.h>
00044 #include <object_manipulation_msgs/GraspStatus.h>
00045
00046 static const std::string JOINT_STATES_TOPIC = "joint_states";
00047
00049
00054 class PR2GripperGraspController
00055 {
00056 private:
00057
00059 ros::NodeHandle root_nh_;
00060
00062 ros::NodeHandle priv_nh_;
00063
00065 actionlib::SimpleActionClient<pr2_controllers_msgs::Pr2GripperCommandAction> *gripper_action_client_;
00066
00068 actionlib::SimpleActionServer<object_manipulation_msgs::GraspHandPostureExecutionAction> *action_server_;
00069
00071 ros::ServiceServer query_srv_;
00072
00074 std::string gripper_virtual_joint_name_;
00075
00077 bool sim_;
00078
00080 double sim_wait_;
00081
00082
00083
00085 double gripper_open_gap_value_;
00087 static const double DEFAULT_GRIPPER_OPEN;
00088
00090 double gripper_closed_gap_value_;
00092 static const double DEFAULT_GRIPPER_CLOSED;
00093
00095 double gripper_object_presence_threshold_;
00097 static const double DEFAULT_GRIPPER_OBJECT_PRESENCE_THRESHOLD;
00098
00100 double gripper_max_effort_;
00102 static const double DEFAULT_GRIPPER_MAX_EFFORT;
00103
00105 std::string gripper_type_;
00106
00107
00108
00110 bool getGripperValue(double &value)
00111 {
00112
00113 sensor_msgs::JointState::ConstPtr joint_states =
00114 ros::topic::waitForMessage<sensor_msgs::JointState>(JOINT_STATES_TOPIC, root_nh_);
00115 if (!joint_states)
00116 {
00117 ROS_ERROR("pr2 gripper grasp status: joint states not received");
00118 return false;
00119 }
00120
00121
00122 size_t i;
00123 for (i=0; i<joint_states->name.size(); i++)
00124 {
00125 if (joint_states->name[i] == gripper_virtual_joint_name_) break;
00126 }
00127 if (i==joint_states->name.size())
00128 {
00129 ROS_ERROR("pr2_gripper grasp status: gripper joint %s not found in joint state",
00130 gripper_virtual_joint_name_.c_str());
00131 return false;
00132 }
00133 if (joint_states->position.size() <= i)
00134 {
00135 ROS_ERROR("pr2_gripper grasp status: malformed joint state message received");
00136 return false;
00137 }
00138 value = joint_states->position[i];
00139 return true;
00140 }
00141
00143
00144 double jointToGap(double jointValue)
00145 {
00146 if (gripper_type_ == "pr2") return jointValue / 0.5 * 0.0857;
00147 else if (gripper_type_ == "lcg") return 2.0 * ( cos(jointValue)*60.0 + 17.5 - 6.0 ) * 1.0e-3;
00148 else {ROS_ERROR_STREAM("pr2_gripper_grasp_controller: unknown gripper type: " << gripper_type_); return 0.0;}
00149 }
00150
00151 void executeCB(const object_manipulation_msgs::GraspHandPostureExecutionGoalConstPtr &goal)
00152 {
00153
00154 pr2_controllers_msgs::Pr2GripperCommandGoal gripper_command;
00155 switch (goal->goal)
00156 {
00157 case object_manipulation_msgs::GraspHandPostureExecutionGoal::GRASP:
00158 if (goal->grasp.grasp_posture.position.empty())
00159 {
00160 ROS_ERROR("pr2 gripper grasp execution: position vector empty in requested grasp");
00161 action_server_->setAborted();
00162 return;
00163 }
00164 gripper_command.command.position = gripper_closed_gap_value_;
00165
00166 if (goal->grasp.grasp_posture.effort.empty())
00167 {
00168 if(goal->max_contact_force > 0)
00169 {
00170 ROS_INFO("limiting max contact force to %f", goal->max_contact_force);
00171 gripper_command.command.max_effort = goal->max_contact_force;
00172 }
00173 else gripper_command.command.max_effort = gripper_max_effort_;
00174 ROS_WARN("pr2 gripper grasp execution: effort vector empty in requested grasp, using max force");
00175
00176
00177 }
00178
00179 else
00180 {
00181 if(goal->grasp.grasp_posture.effort.at(0) < goal->max_contact_force || goal->max_contact_force == 0)
00182 gripper_command.command.max_effort = goal->grasp.grasp_posture.effort.at(0);
00183 else gripper_command.command.max_effort = goal->max_contact_force;
00184 }
00185 break;
00186 case object_manipulation_msgs::GraspHandPostureExecutionGoal::PRE_GRASP:
00187 if (goal->grasp.pre_grasp_posture.position.empty())
00188 {
00189 ROS_ERROR("pr2 gripper grasp execution: position vector empty in requested pre_grasp");
00190 action_server_->setAborted();
00191 return;
00192 }
00193
00194 gripper_command.command.position = jointToGap( goal->grasp.pre_grasp_posture.position.at(0) );
00195 ROS_DEBUG("pre grasp posture opening is %.3f", gripper_command.command.position);
00196 if (goal->grasp.pre_grasp_posture.effort.empty())
00197 {
00198 gripper_command.command.max_effort = gripper_max_effort_;
00199 ROS_WARN("pr2 gripper grasp execution: effort vector empty in requested pre_grasp, using max");
00200 }
00201 else
00202 {
00203 gripper_command.command.max_effort = goal->grasp.pre_grasp_posture.effort.at(0);
00204 }
00205 break;
00206 case object_manipulation_msgs::GraspHandPostureExecutionGoal::RELEASE:
00207 gripper_command.command.position = gripper_open_gap_value_;
00208 gripper_command.command.max_effort = gripper_max_effort_;
00209 break;
00210 default:
00211 ROS_ERROR("pr2 gripper grasp execution: unknown goal code (%d)", goal->goal);
00212 action_server_->setAborted();
00213 return;
00214 }
00215
00216
00217 if (gripper_command.command.max_effort > gripper_max_effort_)
00218 {
00219 ROS_WARN("pr2 gripper grasp execution: effort exceeds max value for gripper, reducing to max");
00220 gripper_command.command.max_effort = gripper_max_effort_;
00221 }
00222
00223
00224 gripper_action_client_->sendGoal(gripper_command);
00225 if (!sim_)
00226 {
00227 gripper_action_client_->waitForResult();
00228 }
00229 else
00230 {
00231
00232
00233 bool withinWait = gripper_action_client_->waitForResult(ros::Duration(sim_wait_));
00234 if (!withinWait)
00235 {
00236 ROS_WARN("pr2 gripper grasp execution: controller has not returned within limit, "
00237 "but since we are in simulation we are continuing anyway.");
00238 }
00239 }
00240
00241
00242 if(gripper_action_client_->getState() == actionlib::SimpleClientGoalState::SUCCEEDED)
00243 {
00244 ROS_INFO("Gripper goal achieved");
00245 action_server_->setSucceeded();
00246 }
00247 else
00248 {
00249 if (goal->goal == object_manipulation_msgs::GraspHandPostureExecutionGoal::GRASP)
00250 {
00251
00252
00253 action_server_->setSucceeded();
00254 }
00255 else
00256 {
00257 ROS_WARN("Gripper goal not achieved for pre-grasp or release");
00258
00259 action_server_->setSucceeded();
00260 }
00261 }
00262 }
00263
00264 bool serviceCallback(object_manipulation_msgs::GraspStatus::Request &request,
00265 object_manipulation_msgs::GraspStatus::Response &response)
00266 {
00267 double gripper_value;
00268 if (!getGripperValue(gripper_value)) return false;
00269
00270 double min_gripper_opening = gripper_object_presence_threshold_;
00271 if (gripper_value < min_gripper_opening)
00272 {
00273 ROS_INFO("Gripper grasp query false: gripper value %f below threshold %f",
00274 gripper_value, min_gripper_opening);
00275 response.is_hand_occupied = false;
00276 }
00277 else
00278 {
00279 ROS_DEBUG("Gripper grasp query true: gripper value %f above threshold %f",
00280 gripper_value, min_gripper_opening);
00281 response.is_hand_occupied = true;
00282 }
00283 return true;
00284 }
00285
00286
00287 public:
00288 PR2GripperGraspController() :
00289 root_nh_(""),
00290 priv_nh_("~")
00291 {
00292 std::string gripper_action_name = root_nh_.resolveName("gripper_action_name");
00293 gripper_action_client_ = new actionlib::SimpleActionClient<pr2_controllers_msgs::Pr2GripperCommandAction>
00294 (gripper_action_name, true);
00295 while(!gripper_action_client_->waitForServer(ros::Duration(2.0)) && root_nh_.ok())
00296 {
00297 ROS_INFO_STREAM("Waiting for gripper action client on topic " << gripper_action_name);
00298 }
00299 if (!root_nh_.ok()) exit(0);
00300 ROS_INFO_STREAM("Using gripper action client on topic " << gripper_action_name);
00301
00302 priv_nh_.param<std::string>("gripper_virtual_joint_name", gripper_virtual_joint_name_, "undefined");
00303 if ( gripper_virtual_joint_name_ == "undefined" )
00304 {
00305 ROS_ERROR("Gripper virtual joint name not defined; set the parameter "
00306 "gripper_virtual_joint_name in the launch file");
00307 exit(0);
00308 }
00309
00310 priv_nh_.param<double>("gripper_object_presence_threshold", gripper_object_presence_threshold_,
00311 DEFAULT_GRIPPER_OBJECT_PRESENCE_THRESHOLD);
00312 priv_nh_.param<double>("gripper_open_gap_value", gripper_open_gap_value_, DEFAULT_GRIPPER_OPEN);
00313 priv_nh_.param<double>("gripper_closed_gap_value", gripper_closed_gap_value_, DEFAULT_GRIPPER_CLOSED);
00314 priv_nh_.param<double>("gripper_max_effort", gripper_max_effort_, DEFAULT_GRIPPER_MAX_EFFORT);
00315 priv_nh_.param<std::string>("gripper_type", gripper_type_, "pr2");
00316 priv_nh_.param<bool>("sim", sim_, false);
00317 priv_nh_.param<double>("sim_wait", sim_wait_, 8.0);
00318
00319 std::string query_service_name = root_nh_.resolveName("grasp_query_name");
00320 query_srv_ = root_nh_.advertiseService(query_service_name, &PR2GripperGraspController::serviceCallback, this);
00321 ROS_INFO_STREAM("pr2_gripper grasp query service started on topic " << query_service_name);
00322
00323 std::string posture_action_name = root_nh_.resolveName("posture_action_name");
00324 action_server_ = new actionlib::SimpleActionServer<object_manipulation_msgs::GraspHandPostureExecutionAction>
00325 (root_nh_, posture_action_name, boost::bind(&PR2GripperGraspController::executeCB, this, _1), false);
00326 action_server_->start();
00327 ROS_INFO_STREAM("pr2_gripper grasp hand posture action server started on topic " << posture_action_name);
00328 }
00329
00330 ~PR2GripperGraspController()
00331 {
00332 delete action_server_;
00333 delete gripper_action_client_;
00334 }
00335
00336 };
00337
00338
00339 const double PR2GripperGraspController::DEFAULT_GRIPPER_OPEN = 0.086;
00340 const double PR2GripperGraspController::DEFAULT_GRIPPER_CLOSED = 0.0;
00341 const double PR2GripperGraspController::DEFAULT_GRIPPER_OBJECT_PRESENCE_THRESHOLD = 0.0021;
00342 const double PR2GripperGraspController::DEFAULT_GRIPPER_MAX_EFFORT = 100;
00343
00344 int main(int argc, char **argv)
00345 {
00346 ros::init(argc, argv, "pr2_gripper_grasp_controller");
00347 PR2GripperGraspController node;
00348 ros::spin();
00349 return 0;
00350 }