calc_grasppoints_action_client.cpp
Go to the documentation of this file.
1 /*
2  * David Fischinger - Vienna University of Technology
3  * March 2015
4  *
5  * ** Grasp Action Client - for Testing **
6  *
7  * This node is serving as a client for the calculation of grasp points
8  * based on the action server for grasp calculation.
9  * This nodes subscribes to the topic /haf_grasping/depth_registered/single_cloud/points_in_lcs (lcs: local coordinate system)
10  * and receives (single) point clouds (in a local coordinate system where z is perpendicular to the floor).
11  * The node sends the point cloud as an action server goal and receives the grasp result.
12  *
13  */
14 
15 
16 //ROS includes
17 #include <ros/ros.h>
18 #include <ros/package.h>
19 #include "sensor_msgs/PointCloud2.h"
20 #include <geometry_msgs/Point.h>
21 #include <geometry_msgs/Vector3.h>
22 //actionlib
25 //grasp action message
26 #include <haf_grasping/CalcGraspPointsServerAction.h>
27 // service messages
28 #include <haf_grasping/GraspSearchCenter.h>
29 #include <haf_grasping/GraspSearchRectangleSize.h>
30 #include <haf_grasping/GraspCalculationTimeMax.h>
31 #include <haf_grasping/GraspApproachVector.h>
32 #include <haf_grasping/ShowOnlyBestGrasp.h>
33 #include <haf_grasping/GraspPreGripperOpeningWidth.h>
34 // for reading pcd file
35 #include <iostream>
36 #include <pcl/io/pcd_io.h>
37 #include <pcl/point_types.h>
38 #include "pcl_ros/transforms.h"
39 #include <pcl_ros/point_cloud.h>
40 //#include "pcl/io/io.h"
41 //#include <boost/thread/thread.hpp>
42 
43 
44 
46 {
47 public:
48  ros::Subscriber pc_sub; //subscriber for pointcloud
49  ros::Subscriber pcd_sub; //subscriber for path for pcd-file (to read)
50  ros::ServiceServer srv_set_grasp_center; // service to set new grasp center (center of rectangles where grasps are searched for)
51  ros::ServiceServer srv_set_grasp_search_area_size; // service to set size of rectangle where grasps are searched
52  ros::ServiceServer srv_set_grasp_calculation_time_max; // service to set maximal grasp calculation time (sec) before result is returned
53  ros::ServiceServer srv_set_approach_vector; // service to set approach vector for grasping (only direction hand is approaching, not roll angle)
54  ros::ServiceServer srv_set_show_only_best_grasp; // service to set show_only_best_grasp bool variable
55  ros::ServiceServer srv_set_gripper_width; // service to set factor f that is used for scaling point cloud to imitate pre-gripper opening width of 1/f
56  geometry_msgs::Point graspsearchcenter; // center for searching for grasps
57  geometry_msgs::Vector3 approach_vector; // defines the direction from where a grasp should be executed
58  int grasp_search_size_x; // the size (x direction) where grasps are really calculated (in each direction 7cm more are needed for feature calculation!
59  int grasp_search_size_y; // the size (y direction) where grasps are really calculated (in each direction 7cm more are needed for feature calculation!
60  int max_grasp_search_size_x; // x-limit for grasp search area size
61  int max_grasp_search_size_y; // y-limit for grasp search area size
62  ros::Duration grasp_calculation_time_max; //max time used for grasp calculation (sec) before result is returned
64  std::string base_frame_default;
65  int gripper_opening_width; //defines pre-grasp gripper opening width
66 
67  void get_grasp_cb(const sensor_msgs::PointCloud2ConstPtr& pc_in);
68  void open_pcd_and_trig_get_grasp_cb(std_msgs::String pcd_path);
69  bool set_grasp_center(haf_grasping::GraspSearchCenter::Request &req, haf_grasping::GraspSearchCenter::Response &res);
70  bool set_grasp_search_area_size(haf_grasping::GraspSearchRectangleSize::Request &req, haf_grasping::GraspSearchRectangleSize::Response &res);
71  bool set_grasp_calculation_time_max(haf_grasping::GraspCalculationTimeMax::Request &req, haf_grasping::GraspCalculationTimeMax::Response &res);
72  bool set_approach_vector(haf_grasping::GraspApproachVector::Request &req, haf_grasping::GraspApproachVector::Response &res);
73  bool set_show_only_best_grasp(haf_grasping::ShowOnlyBestGrasp::Request &req, haf_grasping::ShowOnlyBestGrasp::Response &res);
74  bool set_gripper_width(haf_grasping::GraspPreGripperOpeningWidth::Request &req, haf_grasping::GraspPreGripperOpeningWidth::Response &res);
75 
77  {
78  //define center of grasp search rectangle (respectively take from launch file)
79  this->graspsearchcenter.x = this->graspsearchcenter.y = this->graspsearchcenter.z = 0.0; //default values
80  std::vector<float> grasp_search_center_tmp;
81  if ( nh_.getParam("grasp_search_center", grasp_search_center_tmp) ) {
82  this->graspsearchcenter.x = grasp_search_center_tmp[0];
83  this->graspsearchcenter.y = grasp_search_center_tmp[1];
84  this->graspsearchcenter.z = grasp_search_center_tmp[2];
85  }
86  //define grasp approach direction (respectively take from launch file)
87  this->approach_vector.x = this->approach_vector.y = 0.0;
88  this->approach_vector.z = 1.0;
89  std::vector<float> gripper_approach_vector_tmp;
90  if ( nh_.getParam("gripper_approach_vector", gripper_approach_vector_tmp) ) {
91  this->approach_vector.x = gripper_approach_vector_tmp[0];
92  this->approach_vector.y = gripper_approach_vector_tmp[1];
93  this->approach_vector.z = gripper_approach_vector_tmp[2];
94  }
95 
96  //define size of grasp search rectangle (respectively take from launch file)
97  nh_.param("grasp_search_size_x", this->grasp_search_size_x, 18); //default value = max. limit 32
98  nh_.param("grasp_search_size_y", this->grasp_search_size_y, 30); //default value = max. limit 44
99  this->max_grasp_search_size_x = 18; //max. limit 32-14=18
100  this->max_grasp_search_size_y = 30; //max. limit 44-14=30
101  if (this->grasp_search_size_x < 1 or this->grasp_search_size_x > this->max_grasp_search_size_x)
102  this->grasp_search_size_x = this->max_grasp_search_size_x;
103  if (this->grasp_search_size_y < 1 or this->grasp_search_size_y > this->max_grasp_search_size_y)
104  this->grasp_search_size_y = this->max_grasp_search_size_y;
105 
106  // define maximal time before grasp result is returned
107  int max_calculation_time;
108  nh_.param("max_calculation_time", max_calculation_time, 50); // in sec, with default value 50
109  this->grasp_calculation_time_max = ros::Duration(max_calculation_time);
110 
111  // define if only the best grasp should be visualized (respectively take bool value from launch file)
112  nh_.param("show_only_best_grasp", this->show_only_best_grasp, true);
113 
114  // set default cloud frame (if cloud is generated from pcd)
115 
116  nh_.param("base_frame", this->base_frame_default, std::string("base_link"));
117  // set gripper opening with factor => 1/gripper opening width is tested
118  nh_.param("gripper_width", this->gripper_opening_width, 1);
119 
120 
121  //subscriber for the point cloud
122  std::string input_pc_topic = "/haf_grasping/depth_registered/single_cloud/points_in_lcs";
123  nh_.param("input_pc_topic", input_pc_topic, input_pc_topic);
124  this->pc_sub = nh_.subscribe(input_pc_topic,1, &CCalcGrasppointsClient::get_grasp_cb, this);
125  this->pcd_sub = nh_.subscribe("/haf_grasping/input_pcd_rcs_path",1, &CCalcGrasppointsClient::open_pcd_and_trig_get_grasp_cb, this);
126  //services for setting parameters
127  this->srv_set_grasp_center = nh_.advertiseService("/haf_grasping/set_grasp_center", &CCalcGrasppointsClient::set_grasp_center,this);
128  this->srv_set_grasp_search_area_size = nh_.advertiseService("/haf_grasping/set_grasp_search_area_size", &CCalcGrasppointsClient::set_grasp_search_area_size,this);
129  this->srv_set_grasp_calculation_time_max = nh_.advertiseService("/haf_grasping/set_grasp_calculation_time_max", &CCalcGrasppointsClient::set_grasp_calculation_time_max,this);
130  this->srv_set_approach_vector = nh_.advertiseService("/haf_grasping/set_approach_vector", &CCalcGrasppointsClient::set_approach_vector, this);
131  this->srv_set_show_only_best_grasp = nh_.advertiseService("/haf_grasping/set_show_only_best_grasp", &CCalcGrasppointsClient::set_show_only_best_grasp, this);
132  this->srv_set_gripper_width = nh_.advertiseService("/haf_grasping/set_gripper_opening_width", &CCalcGrasppointsClient::set_gripper_width, this);
133  }
134 };
135 
136 // open pcd file for given path and start get_grasp_cb (that triggers grasp calculation)
138 {
139  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
140 
141  if (pcl::io::loadPCDFile<pcl::PointXYZ> (pcd_path.data.c_str(), *cloud) == -1) //* load the file
142  {
143  PCL_ERROR ("Couldn't read input file (pcd) \n");
144  return;
145  }
146  std::cout << "Loaded "
147  << cloud->width * cloud->height
148  << " data points from " << pcd_path.data.c_str();
149 
150  //transform pcl to ros-msg
151  sensor_msgs::PointCloud2 pcd_as_ros_msg;// = new sensor_msgs::PointCloud2ConstPtr();
152  pcl::toROSMsg(*cloud, pcd_as_ros_msg);
153  pcd_as_ros_msg.header.frame_id = this->base_frame_default /*"base_link"*/;
154  pcd_as_ros_msg.header.stamp = ros::Time(0);
155  const sensor_msgs::PointCloud2ConstPtr pcd_as_ros_msg_const_ptr = boost::make_shared<sensor_msgs::PointCloud2>(pcd_as_ros_msg);
156  CCalcGrasppointsClient::get_grasp_cb(pcd_as_ros_msg_const_ptr);
157 }
158 
159 // define goal (input) for grasp calculation, send it to grasp action server and receive result
160 void CCalcGrasppointsClient::get_grasp_cb(const sensor_msgs::PointCloud2ConstPtr& pc_in)
161 {
162  ROS_INFO("\nFrom calc_grasppoints_action_client: point cloud received");
163 
164  // create the action client
165  // true causes the client to spin its own thread
166  actionlib::SimpleActionClient<haf_grasping::CalcGraspPointsServerAction> ac("calc_grasppoints_svm_action_server", true);
167 
168  ROS_INFO("Waiting for action server to start.");
169  // wait for the action server to start
170  ac.waitForServer(); //will wait for infinite time
171 
172  ROS_INFO("Action server started, sending goal.");
173  // send a goal to the action
174  haf_grasping::CalcGraspPointsServerGoal goal;
175  goal.graspinput.input_pc = *pc_in;
176 
177  goal.graspinput.grasp_area_center = this->graspsearchcenter;
178 
179  //set grasp approach vector
180  goal.graspinput.approach_vector = this->approach_vector;
181 
182  // set size of grasp search area
183  goal.graspinput.grasp_area_length_x = this->grasp_search_size_x+14;
184  goal.graspinput.grasp_area_length_y = this->grasp_search_size_y+14;
185 
186  // set max grasp calculation time
187  goal.graspinput.max_calculation_time = this->grasp_calculation_time_max;
188 
189  // set if only best grasp should be visualized
190  goal.graspinput.show_only_best_grasp = this->show_only_best_grasp;
191 
192  // set pre-grasp gripper opening width (factor for scaling pc)
193  goal.graspinput.gripper_opening_width = this->gripper_opening_width;
194 
195  //send goal
196  ac.sendGoal(goal);
197 
198  //wait for the action to return
199  bool finished_before_timeout = ac.waitForResult(ros::Duration(50.0));
200 
201  if (finished_before_timeout)
202  {
205  ROS_INFO_STREAM("Result: %s" << (*(result)).graspOutput);
206  ROS_INFO("Action finished: %s",state.toString().c_str());
207  }
208  else
209  ROS_INFO("Action did not finish before the time out.");
210 }
211 
212 
213 //set grasp search center
214 bool CCalcGrasppointsClient::set_grasp_center(haf_grasping::GraspSearchCenter::Request &req,
215  haf_grasping::GraspSearchCenter::Response &res)
216 {
217  //set grasp search center
218  this->graspsearchcenter.x = req.graspsearchcenter.x;
219  this->graspsearchcenter.y = req.graspsearchcenter.y;
220  this->graspsearchcenter.z = req.graspsearchcenter.z;
221  ROS_INFO("Set grasp search center to: x=%f, y=%f, z=%f", req.graspsearchcenter.x, req.graspsearchcenter.y, req.graspsearchcenter.z);
222  res.result = true;
223  ROS_INFO("sending back response: [%ld]", (long int)res.result);
224  return res.result;
225 }
226 
227 //set size of rectangle where grasps are searched
228 bool CCalcGrasppointsClient::set_grasp_search_area_size(haf_grasping::GraspSearchRectangleSize::Request &req,
229  haf_grasping::GraspSearchRectangleSize::Response &res)
230 {
231  //set grasp search rectangle size
232  if (req.grasp_search_size_x >= 0 and req.grasp_search_size_x <= this->max_grasp_search_size_x){
233  this->grasp_search_size_x = req.grasp_search_size_x;
234  ROS_INFO("Set grasp rectangle size to: x=%ld", (long int)req.grasp_search_size_x);
235  } else {
236  ROS_INFO("Could not set grasp rectangle size for x. Allowed values: [0, %ld ]. Received value was: x=%ld", (long int)this->max_grasp_search_size_x,(long int)req.grasp_search_size_x);
237  res.result = false;
238  return res.result;
239  }
240  if (req.grasp_search_size_y >= 0 and req.grasp_search_size_y <= this->max_grasp_search_size_y){
241  this->grasp_search_size_y = req.grasp_search_size_y;
242  ROS_INFO("Set grasp rectangle size to: y=%ld", (long int)req.grasp_search_size_y);
243  } else {
244  ROS_INFO("Could not set grasp rectangle size for y. Allowed values: [0, %ld ]. Received value was: y=%ld", (long int)this->max_grasp_search_size_y,(long int)req.grasp_search_size_y);
245  res.result = false;
246  return res.result;
247  }
248 
249  res.result = true;
250  ROS_INFO("sending back response: [%ld]", (long int)res.result);
251  return res.result;
252 }
253 
254 
255 //set maximal grasp calculation time before result has to be returned
256 bool CCalcGrasppointsClient::set_grasp_calculation_time_max(haf_grasping::GraspCalculationTimeMax::Request &req,
257  haf_grasping::GraspCalculationTimeMax::Response &res)
258 {
259  //set max grasp calculation time
260  this->grasp_calculation_time_max = req.max_calculation_time;
261  ROS_INFO("Set max calculation time (sec) to: x=%d", (int)req.max_calculation_time.toSec());
262  res.result = true;
263  ROS_INFO("sending back response: [%d]", (int)res.result);
264  return res.result;
265 }
266 
267 //set approach vector for approaching the object with gripper
268 bool CCalcGrasppointsClient::set_approach_vector(haf_grasping::GraspApproachVector::Request &req, haf_grasping::GraspApproachVector::Response &res)
269 {
270  //set grasp approach vector
271  this->approach_vector = req.approach_vector;
272  ROS_INFO("Set approach vector to: [%f,%f,%f]", this->approach_vector.x,this->approach_vector.y,this->approach_vector.z);
273  res.result = true;
274  ROS_INFO("sending back response: [%d]", (int)res.result);
275  return res.result;
276 }
277 
278 //set show_only_best_grasp (for visualization)
279 bool CCalcGrasppointsClient::set_show_only_best_grasp(haf_grasping::ShowOnlyBestGrasp::Request &req,
280  haf_grasping::ShowOnlyBestGrasp::Response &res)
281 {
282  //set show_only_best_grasp
283  this->show_only_best_grasp = req.show_only_best_grasp;
284  ROS_INFO("Set show_only_best_grasp to: [%d] ", (int)this->show_only_best_grasp);
285  res.result = true;
286  ROS_INFO("sending back response: [%d]", (int)res.result);
287  return res.result;
288 }
289 
290 //set maximal grasp calculation time before result has to be returned
291 bool CCalcGrasppointsClient::set_gripper_width(haf_grasping::GraspPreGripperOpeningWidth::Request &req,
292  haf_grasping::GraspPreGripperOpeningWidth::Response &res)
293 {
294  //set pre-grasp gripper opening width
295  this->gripper_opening_width = req.gripper_opening_width;
296  ROS_INFO("Set gripper_opening_width (factor for scaling pc) to: x=%d", (int)req.gripper_opening_width);
297  res.result = true;
298  ROS_INFO("sending back response: [%d]", (int)res.result);
299  return res.result;
300 }
301 
302 
303 int main (int argc, char **argv)
304 {
305  ROS_INFO("ROS NODE calc_grasppoints_client started");
306  ros::init(argc, argv, "calc_grasppoint_client");
307  ros::NodeHandle nh_;
308  CCalcGrasppointsClient grasp_client(nh_);
309 
310  ros::spin();
311  return 0;
312 }
313 
314 
int main(int argc, char **argv)
bool waitForServer(const ros::Duration &timeout=ros::Duration(0, 0)) const
bool set_grasp_calculation_time_max(haf_grasping::GraspCalculationTimeMax::Request &req, haf_grasping::GraspCalculationTimeMax::Response &res)
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
bool waitForResult(const ros::Duration &timeout=ros::Duration(0, 0))
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
ServiceServer advertiseService(const std::string &service, bool(T::*srv_func)(MReq &, MRes &), T *obj)
ROSCPP_DECL void spin(Spinner &spinner)
std::string toString() const
bool set_grasp_search_area_size(haf_grasping::GraspSearchRectangleSize::Request &req, haf_grasping::GraspSearchRectangleSize::Response &res)
bool set_grasp_center(haf_grasping::GraspSearchCenter::Request &req, haf_grasping::GraspSearchCenter::Response &res)
#define ROS_INFO(...)
bool param(const std::string &param_name, T &param_val, const T &default_val) const
void open_pcd_and_trig_get_grasp_cb(std_msgs::String pcd_path)
bool set_approach_vector(haf_grasping::GraspApproachVector::Request &req, haf_grasping::GraspApproachVector::Response &res)
void sendGoal(const Goal &goal, SimpleDoneCallback done_cb=SimpleDoneCallback(), SimpleActiveCallback active_cb=SimpleActiveCallback(), SimpleFeedbackCallback feedback_cb=SimpleFeedbackCallback())
#define ROS_INFO_STREAM(args)
bool set_show_only_best_grasp(haf_grasping::ShowOnlyBestGrasp::Request &req, haf_grasping::ShowOnlyBestGrasp::Response &res)
bool getParam(const std::string &key, std::string &s) const
void toROSMsg(const sensor_msgs::PointCloud2 &cloud, sensor_msgs::Image &image)
void get_grasp_cb(const sensor_msgs::PointCloud2ConstPtr &pc_in)
SimpleClientGoalState getState() const
ResultConstPtr getResult() const
bool set_gripper_width(haf_grasping::GraspPreGripperOpeningWidth::Request &req, haf_grasping::GraspPreGripperOpeningWidth::Response &res)
ros::ServiceServer srv_set_grasp_calculation_time_max
ros::ServiceServer srv_set_grasp_search_area_size


haf_grasping
Author(s): David Fischinger
autogenerated on Mon Jun 10 2019 13:28:43