Go to the documentation of this file.00001 #include <ros/ros.h>
00002
00003 #include <actionlib/client/simple_action_client.h>
00004 #include <tabletop_object_detector/TabletopDetection.h>
00005 #include <tabletop_collision_map_processing/TabletopCollisionMapProcessing.h>
00006 #include <object_manipulation_msgs/PickupAction.h>
00007 #include <object_manipulation_msgs/PlaceAction.h>
00008
00009 int main(int argc, char **argv)
00010 {
00011
00012 ros::init(argc, argv, "pick_and_place_app");
00013 ros::NodeHandle nh;
00014
00015
00016 const std::string OBJECT_DETECTION_SERVICE_NAME = "/object_detection";
00017 const std::string COLLISION_PROCESSING_SERVICE_NAME =
00018 "/tabletop_collision_map_processing/tabletop_collision_map_processing";
00019 const std::string PICKUP_ACTION_NAME =
00020 "/object_manipulator/object_manipulator_pickup";
00021 const std::string PLACE_ACTION_NAME =
00022 "/object_manipulator/object_manipulator_place";
00023
00024
00025 ros::ServiceClient object_detection_srv;
00026 ros::ServiceClient collision_processing_srv;
00027 actionlib::SimpleActionClient<object_manipulation_msgs::PickupAction>
00028 pickup_client(PICKUP_ACTION_NAME, true);
00029 actionlib::SimpleActionClient<object_manipulation_msgs::PlaceAction>
00030 place_client(PLACE_ACTION_NAME, true);
00031
00032
00033 while ( !ros::service::waitForService(OBJECT_DETECTION_SERVICE_NAME,
00034 ros::Duration(2.0)) && nh.ok() )
00035 {
00036 ROS_INFO("Waiting for object detection service to come up");
00037 }
00038 if (!nh.ok()) exit(0);
00039 object_detection_srv =
00040 nh.serviceClient<tabletop_object_detector::TabletopDetection>
00041 (OBJECT_DETECTION_SERVICE_NAME, true);
00042
00043
00044 while ( !ros::service::waitForService(COLLISION_PROCESSING_SERVICE_NAME,
00045 ros::Duration(2.0)) && nh.ok() )
00046 {
00047 ROS_INFO("Waiting for collision processing service to come up");
00048 }
00049 if (!nh.ok()) exit(0);
00050 collision_processing_srv =
00051 nh.serviceClient
00052 <tabletop_collision_map_processing::TabletopCollisionMapProcessing>
00053 (COLLISION_PROCESSING_SERVICE_NAME, true);
00054
00055
00056 while(!pickup_client.waitForServer(ros::Duration(2.0)) && nh.ok())
00057 {
00058 ROS_INFO_STREAM("Waiting for action client " << PICKUP_ACTION_NAME);
00059 }
00060 if (!nh.ok()) exit(0);
00061
00062
00063 while(!place_client.waitForServer(ros::Duration(2.0)) && nh.ok())
00064 {
00065 ROS_INFO_STREAM("Waiting for action client " << PLACE_ACTION_NAME);
00066 }
00067 if (!nh.ok()) exit(0);
00068
00069
00070
00071
00072 ROS_INFO("Calling tabletop detector");
00073 tabletop_object_detector::TabletopDetection detection_call;
00074
00075
00076 detection_call.request.return_clusters = true;
00077
00078 detection_call.request.return_models = true;
00079 if (!object_detection_srv.call(detection_call))
00080 {
00081 ROS_ERROR("Tabletop detection service failed");
00082 return -1;
00083 }
00084 if (detection_call.response.detection.result !=
00085 detection_call.response.detection.SUCCESS)
00086 {
00087 ROS_ERROR("Tabletop detection returned error code %d",
00088 detection_call.response.detection.result);
00089 return -1;
00090 }
00091 if (detection_call.response.detection.clusters.empty() &&
00092 detection_call.response.detection.models.empty() )
00093 {
00094 ROS_ERROR("The tabletop detector detected the table, but found no objects");
00095 return -1;
00096 }
00097
00098
00099
00100
00101 ROS_INFO("Calling collision map processing");
00102 tabletop_collision_map_processing::TabletopCollisionMapProcessing
00103 processing_call;
00104
00105 processing_call.request.detection_result = detection_call.response.detection;
00106
00107 processing_call.request.reset_static_map = true;
00108 processing_call.request.reset_collision_models = true;
00109 processing_call.request.reset_attached_models = true;
00110
00111
00112 processing_call.request.take_static_collision_map = true;
00113
00114 processing_call.request.desired_frame = "base_link";
00115 if (!collision_processing_srv.call(processing_call))
00116 {
00117 ROS_ERROR("Collision map processing service failed");
00118 return -1;
00119 }
00120
00121 if (processing_call.response.graspable_objects.empty())
00122 {
00123 ROS_ERROR("Collision map processing returned no graspable objects");
00124 return -1;
00125 }
00126
00127
00128
00129 ROS_INFO("Calling the pickup action");
00130 object_manipulation_msgs::PickupGoal pickup_goal;
00131
00132 pickup_goal.target = processing_call.response.graspable_objects.at(0);
00133
00134
00135 pickup_goal.collision_object_name =
00136 processing_call.response.collision_object_names.at(0);
00137
00138
00139 pickup_goal.collision_support_surface_name =
00140 processing_call.response.collision_support_surface_name;
00141
00142 pickup_goal.arm_name = "right_arm";
00143
00144 pickup_goal.desired_approach_distance = 0.1;
00145 pickup_goal.min_approach_distance = 0.05;
00146
00147
00148 geometry_msgs::Vector3Stamped direction;
00149 direction.header.stamp = ros::Time::now();
00150 direction.header.frame_id = "base_link";
00151 direction.vector.x = 0;
00152 direction.vector.y = 0;
00153 direction.vector.z = 1;
00154 pickup_goal.lift.direction = direction;
00155
00156 pickup_goal.lift.desired_distance = 0.1;
00157 pickup_goal.lift.min_distance = 0.05;
00158
00159 pickup_goal.use_reactive_lift = false;
00160 pickup_goal.use_reactive_execution = false;
00161
00162 pickup_client.sendGoal(pickup_goal);
00163 while (!pickup_client.waitForResult(ros::Duration(10.0)))
00164 {
00165 ROS_INFO("Waiting for the pickup action...");
00166 }
00167 object_manipulation_msgs::PickupResult pickup_result =
00168 *(pickup_client.getResult());
00169 if (pickup_client.getState() != actionlib::SimpleClientGoalState::SUCCEEDED)
00170 {
00171 ROS_ERROR("The pickup action has failed with result code %d",
00172 pickup_result.manipulation_result.value);
00173 return -1;
00174 }
00175
00176
00177
00178
00179 geometry_msgs::PoseStamped pickup_location;
00180 if (processing_call.response.graspable_objects.at(0).type ==
00181 object_manipulation_msgs::GraspableObject::DATABASE_MODEL)
00182 {
00183
00184
00185 pickup_location =
00186 processing_call.response.graspable_objects.at(0).model_pose.pose;
00187 }
00188 else
00189 {
00190
00191
00192 pickup_location.header =
00193 processing_call.response.graspable_objects.at(0).cluster.header;
00194
00195 pickup_location.pose.orientation.w = 1;
00196 }
00197
00198 geometry_msgs::PoseStamped place_location = pickup_location;
00199 place_location.header.stamp = ros::Time::now();
00200 place_location.pose.position.x += 0.2;
00201
00202
00203
00204 ROS_INFO("Calling the place action");
00205 object_manipulation_msgs::PlaceGoal place_goal;
00206
00207 place_goal.place_pose = place_location;
00208
00209
00210 place_goal.collision_object_name =
00211 processing_call.response.collision_object_names.at(0);
00212 place_goal.collision_support_surface_name =
00213 processing_call.response.collision_support_surface_name;
00214
00215
00216 place_goal.grasp = pickup_result.grasp;
00217
00218 place_goal.arm_name = "right_arm";
00219
00220
00221 place_goal.place_padding = 0.02;
00222
00223 place_goal.desired_retreat_distance = 0.40;
00224 place_goal.min_retreat_distance = 0.20;
00225
00226
00227 direction.header.stamp = ros::Time::now();
00228 direction.header.frame_id = "base_link";
00229 direction.vector.x = 0;
00230 direction.vector.y = 0;
00231 direction.vector.z = -1;
00232 place_goal.approach.direction = direction;
00233
00234 place_goal.approach.desired_distance = 0.10;
00235 place_goal.approach.min_distance = 0.05;
00236
00237 place_goal.use_reactive_place = true;
00238
00239 place_client.sendGoal(place_goal);
00240 while (!place_client.waitForResult(ros::Duration(10.0)))
00241 {
00242 ROS_INFO("Waiting for the place action...");
00243 }
00244 object_manipulation_msgs::PlaceResult place_result =
00245 *(place_client.getResult());
00246 if (place_client.getState() != actionlib::SimpleClientGoalState::SUCCEEDED)
00247 {
00248 ROS_ERROR("Place failed with error code %d",
00249 place_result.manipulation_result.value);
00250 return -1;
00251 }
00252
00253
00254 ROS_INFO("Success! Object moved.");
00255 return 0;
00256 }
00257
00258
00259
00260