00001
00013
00014 #include "rail_grasp_collection/GraspCollector.h"
00015
00016
00017 #include <tf2_sensor_msgs/tf2_sensor_msgs.h>
00018
00019 using namespace std;
00020 using namespace rail::pick_and_place;
00021
00022 GraspCollector::GraspCollector()
00023 : private_node_("~"), ac_wait_time_(AC_WAIT_TIME), tf_listener_(tf_buffer_),
00024 robot_fixed_frame_id_("base_footprint"), eef_frame_id_("eef_link"),
00025 as_(private_node_, "grasp_and_store", boost::bind(&GraspCollector::graspAndStore, this, _1), false)
00026 {
00027
00028 debug_ = DEFAULT_DEBUG;
00029 int port = graspdb::Client::DEFAULT_PORT;
00030 string segmented_objects_topic("/segmentation/segmented_objects");
00031 string gripper_action_server("/manipulation/gripper");
00032 string lift_action_server("/manipulation/lift");
00033 string verify_grasp_action_server("/manipulation/verify_grasp");
00034 string host("127.0.0.1");
00035 string user("ros");
00036 string password("");
00037 string db("graspdb");
00038
00039
00040 private_node_.getParam("debug", debug_);
00041 private_node_.getParam("robot_fixed_frame_id", robot_fixed_frame_id_);
00042 private_node_.getParam("eef_frame_id", eef_frame_id_);
00043 private_node_.getParam("segmented_objects_topic", segmented_objects_topic);
00044 private_node_.getParam("gripper_action_server", gripper_action_server);
00045 private_node_.getParam("lift_action_server", lift_action_server);
00046 private_node_.getParam("verify_grasp_action_server", verify_grasp_action_server);
00047 node_.getParam("/graspdb/host", host);
00048 node_.getParam("/graspdb/port", port);
00049 node_.getParam("/graspdb/user", user);
00050 node_.getParam("/graspdb/password", password);
00051 node_.getParam("/graspdb/db", db);
00052
00053
00054 graspdb_ = new graspdb::Client(host, port, user, password, db);
00055 okay_ = graspdb_->connect();
00056
00057
00058 if (debug_)
00059 {
00060 debug_pub_ = private_node_.advertise<sensor_msgs::PointCloud2>("debug", 1, true);
00061 }
00062
00063
00064 segmented_objects_sub_ = node_.subscribe(segmented_objects_topic, 1, &GraspCollector::segmentedObjectsCallback,
00065 this);
00066
00067
00068 gripper_ac_ = new actionlib::SimpleActionClient<rail_manipulation_msgs::GripperAction>(gripper_action_server, true);
00069 lift_ac_ = new actionlib::SimpleActionClient<rail_manipulation_msgs::LiftAction>(lift_action_server, true);
00070 verify_grasp_ac_ = new actionlib::SimpleActionClient<rail_manipulation_msgs::VerifyGraspAction>(
00071 verify_grasp_action_server, true
00072 );
00073
00074
00075 as_.start();
00076
00077 if (okay_)
00078 {
00079 ROS_INFO("Grasp Collector Successfully Initialized");
00080 }
00081 }
00082
00083 GraspCollector::~GraspCollector()
00084 {
00085
00086 as_.shutdown();
00087 graspdb_->disconnect();
00088 delete gripper_ac_;
00089 delete lift_ac_;
00090 delete verify_grasp_ac_;
00091 delete graspdb_;
00092 }
00093
00094 bool GraspCollector::okay() const
00095 {
00096 return okay_;
00097 }
00098
00099 void GraspCollector::graspAndStore(const rail_pick_and_place_msgs::GraspAndStoreGoalConstPtr &goal)
00100 {
00101 ROS_INFO("Store grasp requset received.");
00102
00103 rail_pick_and_place_msgs::GraspAndStoreFeedback feedback;
00104 rail_pick_and_place_msgs::GraspAndStoreResult result;
00105
00106 result.success = false;
00107 result.id = 0;
00108
00109
00110 bool completed, succeeded, success;
00111
00112
00113 feedback.message = "Requesting a close gripper action...";
00114 as_.publishFeedback(feedback);
00115 rail_manipulation_msgs::GripperGoal gripper_goal;
00116 gripper_goal.close = true;
00117 gripper_ac_->sendGoal(gripper_goal);
00118 completed = gripper_ac_->waitForResult(ac_wait_time_);
00119 succeeded = (gripper_ac_->getState() == actionlib::SimpleClientGoalState::SUCCEEDED);
00120 success = gripper_ac_->getResult()->success;
00121 if (!completed || !succeeded || !success)
00122 {
00123 as_.setSucceeded(result, "Could not close the gripper.");
00124 return;
00125 }
00126
00127
00128 feedback.message = "Determinging grasp position...";
00129 as_.publishFeedback(feedback);
00130
00131 geometry_msgs::TransformStamped grasp;
00132 try
00133 {
00134 grasp = tf_buffer_.lookupTransform(robot_fixed_frame_id_, eef_frame_id_, ros::Time(0));
00135 } catch (tf2::TransformException &ex)
00136 {
00137 ROS_WARN("%s", ex.what());
00138 as_.setSucceeded(result, "Could not transform from the grasp frame to the robot fixed frame.");
00139 return;
00140 }
00141
00142
00143 if (goal->lift)
00144 {
00145
00146 feedback.message = "Requesting lift...";
00147 as_.publishFeedback(feedback);
00148 rail_manipulation_msgs::LiftGoal lift_goal;
00149 lift_ac_->sendGoal(lift_goal);
00150 completed = lift_ac_->waitForResult(ac_wait_time_);
00151 succeeded = (lift_ac_->getState() == actionlib::SimpleClientGoalState::SUCCEEDED);
00152 success = lift_ac_->getResult()->success;
00153 if (!completed || !succeeded || !success)
00154 {
00155 as_.setSucceeded(result, "Could not execute lift.");
00156 return;
00157 }
00158 }
00159
00160
00161 if (goal->verify)
00162 {
00163
00164 feedback.message = "Requesting grasp verification...";
00165 as_.publishFeedback(feedback);
00166 rail_manipulation_msgs::VerifyGraspGoal verify_grasp_goal;
00167 verify_grasp_ac_->sendGoal(verify_grasp_goal);
00168 completed = verify_grasp_ac_->waitForResult(ac_wait_time_);
00169 succeeded = (verify_grasp_ac_->getState() == actionlib::SimpleClientGoalState::SUCCEEDED);
00170 rail_manipulation_msgs::VerifyGraspResultConstPtr verify_result = verify_grasp_ac_->getResult();
00171 success = verify_result->success;
00172 if (!completed || !succeeded || !success)
00173 {
00174 as_.setSucceeded(result, "Could not verify grasp.");
00175 return;
00176 } else if (!verify_result->grasping)
00177 {
00178 as_.setSucceeded(result, "Grasp is not verified.");
00179 return;
00180 }
00181 }
00182
00183
00184 feedback.message = "Searching for the closest segmented object...";
00185 as_.publishFeedback(feedback);
00186
00187 {
00188 boost::mutex::scoped_lock lock(mutex_);
00189
00190 int closest = 0;
00191 if (object_list_->objects.size() == 0)
00192 {
00193 as_.setSucceeded(result, "No segmented objects found.");
00194 return;
00195 } else if (object_list_->objects.size() > 1)
00196 {
00197
00198 float min = numeric_limits<float>::infinity();
00199
00200
00201 for (size_t i = 0; i < object_list_->objects.size(); i++)
00202 {
00203 geometry_msgs::TransformStamped eef_transform = tf_buffer_.lookupTransform(
00204 object_list_->objects[i].point_cloud.header.frame_id, eef_frame_id_, ros::Time(0)
00205 );
00206 geometry_msgs::Vector3 &v = eef_transform.transform.translation;
00207
00208 sensor_msgs::PointCloud cloud;
00209 sensor_msgs::convertPointCloud2ToPointCloud(object_list_->objects[i].point_cloud, cloud);
00210
00211 for (size_t j = 0; j < cloud.points.size(); j++)
00212 {
00213
00214 float dist = sqrt(
00215 pow(cloud.points[j].x - v.x, 2) + pow(cloud.points[j].y - v.y, 2) + pow(cloud.points[j].z - v.z, 2)
00216 );
00217 if (dist < min)
00218 {
00219 min = dist;
00220 closest = i;
00221 }
00222 }
00223 }
00224 }
00225
00226 rail_manipulation_msgs::SegmentedObject &object = object_list_->objects[closest];
00227 if (object.point_cloud.header.frame_id != robot_fixed_frame_id_)
00228 {
00229 try
00230 {
00231 sensor_msgs::PointCloud2 transformed_cloud = tf_buffer_.transform(object.point_cloud, robot_fixed_frame_id_,
00232 ros::Time(0),
00233 object.point_cloud.header.frame_id);
00234 object.point_cloud = transformed_cloud;
00235 object.point_cloud.header.frame_id = robot_fixed_frame_id_;
00236 } catch (tf2::TransformException &ex)
00237 {
00238 ROS_WARN("%s", ex.what());
00239 as_.setSucceeded(result, "Could not transform the segemented object to the robot fixed frame.");
00240 return;
00241 }
00242 }
00243
00244 if (debug_)
00245 {
00246 debug_pub_.publish(object.point_cloud);
00247 }
00248
00249
00250 feedback.message = "Storing grasp data...";
00251 as_.publishFeedback(feedback);
00252 graspdb::GraspDemonstration gd(goal->object_name, graspdb::Pose(grasp), eef_frame_id_, object.point_cloud,
00253 object.image);
00254 if (graspdb_->addGraspDemonstration(gd))
00255 {
00256
00257 result.id = gd.getID();
00258 } else
00259 {
00260 as_.setSucceeded(result, "Could not insert into database.");
00261 return;
00262 }
00263 }
00264
00265
00266 result.success = true;
00267 as_.setSucceeded(result, "Success!");
00268 }
00269
00270 void GraspCollector::segmentedObjectsCallback(const rail_manipulation_msgs::SegmentedObjectList::Ptr &object_list)
00271 {
00272 ROS_INFO("Updated segmented object list received.");
00273
00274 boost::mutex::scoped_lock lock(mutex_);
00275 object_list_ = object_list;
00276 }