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 #include "pr2_interactive_manipulation/interactive_manipulation_backend.h"
00031
00032 #include <object_manipulation_msgs/Grasp.h>
00033 #include <object_manipulation_msgs/GraspPlanning.h>
00034 #include <object_manipulation_msgs/PlacePlanning.h>
00035 #include <object_manipulation_msgs/ClusterBoundingBox.h>
00036
00037 #include <object_manipulator/tools/vector_tools.h>
00038
00039 #include <tf/transform_datatypes.h>
00040
00041 #include <household_objects_database_msgs/GetModelDescription.h>
00042
00043 #include <sensor_msgs/point_cloud_conversion.h>
00044
00045 #include "pr2_interactive_manipulation/arm_locations.h"
00046
00047 using object_manipulation_msgs::ManipulationResult;
00048
00049 namespace pr2_interactive_manipulation {
00050
00051 geometry_msgs::Pose translatePose(geometry_msgs::Pose pose_in, btVector3 translation)
00052 {
00053 tf::Transform trans_in;
00054 tf::poseMsgToTF(pose_in, trans_in);
00055 tf::StampedTransform translate_trans;
00056 translate_trans.setIdentity();
00057 translate_trans.setOrigin(translation);
00058 tf::Transform trans_out = trans_in * translate_trans;
00059 geometry_msgs::Pose pose_out;
00060 tf::poseTFToMsg(trans_out, pose_out);
00061 return pose_out;
00062 }
00063
00064 geometry_msgs::Pose preTranslatePose(geometry_msgs::Pose pose_in, btVector3 translation)
00065 {
00066 tf::Transform trans_in;
00067 tf::poseMsgToTF(pose_in, trans_in);
00068 tf::StampedTransform translate_trans;
00069 translate_trans.setIdentity();
00070 translate_trans.setOrigin(translation);
00071 tf::Transform trans_out = translate_trans * trans_in;
00072 geometry_msgs::Pose pose_out;
00073 tf::poseTFToMsg(trans_out, pose_out);
00074 return pose_out;
00075 }
00076
00077 std::string getGraspResultInfo(object_manipulation_msgs::GraspResult result)
00078 {
00079 switch (result.result_code)
00080 {
00081 case object_manipulation_msgs::GraspResult::SUCCESS: return ("grasp success");
00082 case object_manipulation_msgs::GraspResult::GRASP_OUT_OF_REACH: return ("grasp out of reach");
00083 case object_manipulation_msgs::GraspResult::GRASP_IN_COLLISION: return ("grasp in collision");
00084 case object_manipulation_msgs::GraspResult::GRASP_UNFEASIBLE: return ("grasp unfeasible");
00085 case object_manipulation_msgs::GraspResult::PREGRASP_OUT_OF_REACH: return ("pregrasp out of reach");
00086 case object_manipulation_msgs::GraspResult::PREGRASP_IN_COLLISION: return ("pregrasp in collision");
00087 case object_manipulation_msgs::GraspResult::PREGRASP_UNFEASIBLE: return ("pregrasp unfeasible");
00088 case object_manipulation_msgs::GraspResult::LIFT_OUT_OF_REACH: return ("lift position out of reach");
00089 case object_manipulation_msgs::GraspResult::LIFT_IN_COLLISION: return ("lift position in collision");
00090 case object_manipulation_msgs::GraspResult::LIFT_UNFEASIBLE: return ("lift position unfeasible");
00091 case object_manipulation_msgs::GraspResult::MOVE_ARM_FAILED: return ("arm movement failed");
00092 case object_manipulation_msgs::GraspResult::GRASP_FAILED: return ("grasp failed");
00093 case object_manipulation_msgs::GraspResult::LIFT_FAILED: return ("lift failed");
00094 case object_manipulation_msgs::GraspResult::RETREAT_FAILED: return ("retreat failed");
00095 default: return("unknown result code returned");
00096 }
00097 }
00098
00099 std::string getPlaceLocationResultInfo(object_manipulation_msgs::PlaceLocationResult result)
00100 {
00101 switch (result.result_code)
00102 {
00103 case object_manipulation_msgs::PlaceLocationResult::SUCCESS: return ("place success");
00104 case object_manipulation_msgs::PlaceLocationResult::PLACE_OUT_OF_REACH: return ("place location out of reach");
00105 case object_manipulation_msgs::PlaceLocationResult::PLACE_IN_COLLISION: return ("place location in collision");
00106 case object_manipulation_msgs::PlaceLocationResult::PLACE_UNFEASIBLE: return ("place in location unfeasible");
00107 case object_manipulation_msgs::PlaceLocationResult::PREPLACE_OUT_OF_REACH: return ("preplace location out of reach");
00108 case object_manipulation_msgs::PlaceLocationResult::PREPLACE_IN_COLLISION: return ("preplace location in collision");
00109 case object_manipulation_msgs::PlaceLocationResult::PREPLACE_UNFEASIBLE: return ("preplace location unfeasible");
00110 case object_manipulation_msgs::PlaceLocationResult::RETREAT_OUT_OF_REACH: return ("retreat location out of reach");
00111 case object_manipulation_msgs::PlaceLocationResult::RETREAT_IN_COLLISION: return ("retreat location in collision");
00112 case object_manipulation_msgs::PlaceLocationResult::RETREAT_UNFEASIBLE: return ("retreat location unfeasible");
00113 case object_manipulation_msgs::PlaceLocationResult::MOVE_ARM_FAILED: return ("arm movement failed");
00114 case object_manipulation_msgs::PlaceLocationResult::PLACE_FAILED: return ("place failed");
00115 case object_manipulation_msgs::PlaceLocationResult::RETREAT_FAILED: return ("retreat failed");
00116 default: return("unknown result code returned");
00117 }
00118 }
00119
00120 InteractiveManipulationBackend::InteractiveManipulationBackend() :
00121 root_nh_(""),
00122 priv_nh_("~")
00123 {
00124 grasp_planning_service_name_ = "/grasp_planning_gripper_click";
00125 grasp_planning_srv_ = root_nh_.serviceClient<object_manipulation_msgs::GraspPlanning>(grasp_planning_service_name_,
00126 false);
00127 place_planning_service_name_ = "/place_planning_gripper_click";
00128 place_planning_srv_ = root_nh_.serviceClient<object_manipulation_msgs::PlacePlanning>(place_planning_service_name_,
00129 false);
00130 pickup_action_name_ = "/object_manipulator/object_manipulator_pickup";
00131 pickup_client_ = new actionlib::SimpleActionClient<object_manipulation_msgs::PickupAction>(pickup_action_name_, true);
00132
00133 place_action_name_ = "/object_manipulator/object_manipulator_place";
00134 place_client_ = new actionlib::SimpleActionClient<object_manipulation_msgs::PlaceAction>(place_action_name_, true);
00135
00136 std::string graspable_objects_topic_name = "interactive_object_recognition_result";
00137 graspable_objects_sub_ = root_nh_.subscribe(graspable_objects_topic_name, 10,
00138 &InteractiveManipulationBackend::graspableObjectsCallback, this);
00139
00140 std::string get_model_description_name = "/objects_database_node/get_model_description";
00141 get_model_description_srv_ = root_nh_.serviceClient<household_objects_database_msgs::GetModelDescription>
00142 (get_model_description_name, true);
00143
00144 create_model_action_name_ = "/create_object_model_server/model_object_in_hand_action";
00145 create_model_client_ =
00146 new actionlib::SimpleActionClient<pr2_create_object_model::ModelObjectInHandAction>(create_model_action_name_, true);
00147
00148 action_name_ = "imgui_action";
00149 action_server_ = new actionlib::SimpleActionServer<IMGUIAction>(root_nh_, action_name_,
00150 boost::bind(&InteractiveManipulationBackend::actionCallback, this, _1),
00151 false);
00152 action_server_->start();
00153
00154 ROS_INFO("IM Backend ready");
00155 }
00156
00157 InteractiveManipulationBackend::~InteractiveManipulationBackend()
00158 {
00159 delete action_server_;
00160 }
00161
00162 void InteractiveManipulationBackend::actionCallback(const IMGUIGoalConstPtr &goal)
00163 {
00164 ROS_DEBUG("IM Backend received goal with command %d", goal->command.command);
00165 IMGUIResult im_result;
00166 switch (goal->command.command)
00167 {
00168 case IMGUICommand::PICKUP:
00169 if (goal->options.grasp_selection == 0)
00170 {
00171 im_result.result.value = pickupObject(goal->options);
00172 }
00173 else
00174 {
00175 im_result.result.value = pickupObject(goal->options, goal->options.selected_object);
00176 }
00177 break;
00178 case IMGUICommand::PLACE:
00179 im_result.result.value = placeObject(goal->options);
00180 break;
00181 case IMGUICommand::TAKE_MAP:
00182 takeMap();
00183 im_result.result.value = object_manipulation_msgs::ManipulationResult::SUCCESS;
00184 break;
00185 case IMGUICommand::RESET:
00186 collisionReset(goal->options.reset_choice);
00187 im_result.result.value = object_manipulation_msgs::ManipulationResult::SUCCESS;
00188 break;
00189 case IMGUICommand::MOVE_ARM:
00190 armMotion(goal->options.arm_selection, goal->options.arm_action_choice,
00191 goal->options.arm_planner_choice, goal->options.collision_checked, im_result.result);
00192 break;
00193 case IMGUICommand::LOOK_AT_TABLE:
00194 lookAtTable();
00195 im_result.result.value = object_manipulation_msgs::ManipulationResult::SUCCESS;
00196 break;
00197 case IMGUICommand::MOVE_GRIPPER:
00198 moveGripper(goal->options);
00199 im_result.result.value = object_manipulation_msgs::ManipulationResult::SUCCESS;
00200 break;
00201 case IMGUICommand::MODEL_OBJECT:
00202 im_result.result.value = modelObject(goal->options);
00203 break;
00204 default:
00205 ROS_ERROR("IM Backend could not understand command: %d", goal->command.command);
00206 setStatusLabel("Command not yet implemented");
00207 im_result.result.value = object_manipulation_msgs::ManipulationResult::ERROR;
00208 }
00209 action_server_->setSucceeded(im_result);
00210 ROS_DEBUG("IM Backend: goal finished");
00211 }
00212
00213 void InteractiveManipulationBackend::graspableObjectsCallback(
00214 const pr2_interactive_object_detection::GraspableObjectListConstPtr &objects)
00215 {
00216 boost::mutex::scoped_lock lock(received_objects_mutex_);
00217 received_objects_ = objects;
00218 }
00219
00220 void InteractiveManipulationBackend::setStatusLabel(std::string text)
00221 {
00222 if (!action_server_->isActive()) ROS_WARN("IM Backend trying to give feedback, but no goal is active. Text: %s",
00223 text.c_str());
00224 IMGUIFeedback feedback;
00225 feedback.status = text;
00226 action_server_->publishFeedback(feedback);
00227 ROS_DEBUG_STREAM("IM backend feedback: " << text);
00228 ROS_INFO_STREAM( text );
00229 }
00230
00231 bool InteractiveManipulationBackend::interruptRequested()
00232 {
00233 return ( !priv_nh_.ok() || action_server_->isPreemptRequested() );
00234 }
00235
00236 void populateGraspOptions(object_manipulation_msgs::PickupGoal &pickup_goal,
00237 std::string arm_name, const IMGUIOptions &options)
00238 {
00239 pickup_goal.arm_name = arm_name;
00240 pickup_goal.desired_approach_distance = 0.1;
00241 pickup_goal.min_approach_distance = 0.05;
00242 if ( options.adv_options.lift_vertically )
00243 {
00244 if (arm_name == "right_arm") pickup_goal.lift.direction.header.frame_id = "r_wrist_roll_link";
00245 else pickup_goal.lift.direction.header.frame_id = "l_wrist_roll_link";
00246 pickup_goal.lift.direction.vector.x = -1;
00247 pickup_goal.lift.direction.vector.y = 0;
00248 pickup_goal.lift.direction.vector.z = 0;
00249 }
00250 else
00251 {
00252 pickup_goal.lift.direction.header.frame_id = "base_link";
00253 pickup_goal.lift.direction.vector.x = 0;
00254 pickup_goal.lift.direction.vector.y = 0;
00255 pickup_goal.lift.direction.vector.z = 1;
00256 }
00257 pickup_goal.lift.desired_distance = options.adv_options.lift_steps * 0.01;
00258 pickup_goal.lift.min_distance = pickup_goal.lift.desired_distance / 2.0;
00259 pickup_goal.use_reactive_lift = options.adv_options.reactive_force;
00260 pickup_goal.use_reactive_execution = options.adv_options.reactive_grasping;
00261 }
00262
00263 bool InteractiveManipulationBackend::processCollisionMapForPickup(const IMGUIOptions &options,
00264 object_manipulation_msgs::PickupGoal &goal)
00265 {
00266 if (options.collision_checked)
00267 {
00268
00269 setStatusLabel("waiting for collision map services...");
00270 ros::Time start_time = ros::Time::now();
00271 while (!collision_map_interface_.connectionsEstablished(ros::Duration(1.0)))
00272 {
00273 if (interruptRequested() || ros::Time::now() - start_time >= ros::Duration(5.0))
00274 {
00275 setStatusLabel("collision map services not found");
00276 return false;
00277 }
00278 }
00279 if ( !goal.target.cluster.points.empty() )
00280 {
00281
00282 setStatusLabel("creating collision object from point cloud...");
00283 object_manipulation_msgs::ClusterBoundingBox bbox;
00284 collision_map_interface_.getClusterBoundingBox(goal.target.cluster, bbox.pose_stamped, bbox.dimensions);
00285 collision_map_interface_.processCollisionGeometryForBoundingBox(bbox, goal.collision_object_name);
00286 }
00287 else if (!goal.target.potential_models.empty())
00288 {
00289
00290 setStatusLabel("creating collision object from mesh...");
00291 try
00292 {
00293 collision_map_interface_.processCollisionGeometryForObject(goal.target.potential_models[0],
00294 goal.collision_object_name);
00295 }
00296 catch (tabletop_collision_map_processing::CollisionMapException &ex)
00297 {
00298 setStatusLabel("failed to add mesh to collision map");
00299 return false;
00300 }
00301 }
00302 else
00303 {
00304
00305 goal.collision_support_surface_name = motion_planning_msgs::CollisionOperation::COLLISION_SET_ALL;
00306 goal.allow_gripper_support_collision = true;
00307 }
00308
00309 goal.additional_link_padding = object_manipulator::concat(
00310 object_manipulator::MechanismInterface::gripperPadding("left_arm", 0.0),
00311 object_manipulator::MechanismInterface::gripperPadding("right_arm", 0.0) );
00312 }
00313 else
00314 {
00315
00316 motion_planning_msgs::CollisionOperation coll;
00317 coll.object1 = motion_planning_msgs::CollisionOperation::COLLISION_SET_ALL;
00318 coll.object2 = motion_planning_msgs::CollisionOperation::COLLISION_SET_ALL;
00319 coll.operation = motion_planning_msgs::CollisionOperation::DISABLE;
00320 goal.additional_collision_operations.collision_operations.push_back(coll);
00321 }
00322 return true;
00323 }
00324
00325 int InteractiveManipulationBackend::pickupObject(const IMGUIOptions &options,
00326 object_manipulation_msgs::GraspableObject object)
00327 {
00328 std::string arm_name;
00329 if (options.arm_selection == 0) arm_name = "right_arm";
00330 else arm_name = "left_arm";
00331
00332 ROS_INFO("Graspable object has %d points and %d database models",
00333 (int)object.cluster.points.size(), (int)object.potential_models.size());
00334
00335
00336
00337 try
00338 {
00339 mech_interface_.convertGraspableObjectComponentsToFrame(object, "base_link");
00340 }
00341 catch(object_manipulator::MechanismException &ex)
00342 {
00343 ROS_ERROR_STREAM("Conversion error: " << ex.what());
00344 setStatusLabel("failed to convert object to desired frame");
00345 return object_manipulation_msgs::ManipulationResult::ERROR;
00346 }
00347
00348
00349 object_manipulation_msgs::PickupGoal pickup_goal;
00350
00351
00352 if ( object.cluster.points.empty() && object.potential_models.empty() )
00353 {
00354 int success = callGripperClickPickup( arm_name, pickup_goal.desired_grasps );
00355 if ( success != object_manipulation_msgs::ManipulationResult::SUCCESS ) return success;
00356 pickup_goal.target.reference_frame_id = "base_link";
00357 }
00358 else
00359 {
00360 pickup_goal.target = object;
00361 }
00362
00363
00364 if (!processCollisionMapForPickup(options, pickup_goal)) return object_manipulation_msgs::ManipulationResult::ERROR;
00365
00366
00367 populateGraspOptions(pickup_goal, arm_name, options);
00368
00369
00370 setStatusLabel("waiting for pickup action server...");
00371 while ( !pickup_client_->waitForServer(ros::Duration(1.0)) && !interruptRequested() ) {}
00372 if (interruptRequested())
00373 {
00374 setStatusLabel("Pickup canceled");
00375 pickup_client_->cancelGoal();
00376 return object_manipulation_msgs::ManipulationResult::CANCELLED;
00377 }
00378
00379
00380 pickup_client_->sendGoal(pickup_goal);
00381 while (!pickup_client_->waitForResult(ros::Duration(1.0)) &&
00382 pickup_client_->isServerConnected() && !interruptRequested())
00383 {
00384 ROS_DEBUG("Waiting for pickup result..");
00385 }
00386
00387
00388 if (interruptRequested())
00389 {
00390 setStatusLabel("Pickup canceled.");
00391 pickup_client_->cancelGoal();
00392 return object_manipulation_msgs::ManipulationResult::CANCELLED;
00393 }
00394
00395
00396 object_manipulation_msgs::PickupResult pickup_result = *(pickup_client_->getResult());
00397 if (pickup_client_->getState() != actionlib::SimpleClientGoalState::SUCCEEDED)
00398 {
00399 if (pickup_result.attempted_grasp_results.empty())
00400 {
00401 setStatusLabel("Pickup failed.");
00402 return object_manipulation_msgs::ManipulationResult::ERROR;
00403 }
00404 else
00405 {
00406 setStatusLabel(getGraspResultInfo(pickup_result.attempted_grasp_results[0]));
00407 }
00408 return object_manipulation_msgs::ManipulationResult::UNFEASIBLE;
00409 }
00410
00411
00412
00413 geometry_msgs::Pose grasp_pose;
00414
00415 grasp_pose.orientation = pickup_result.grasp.grasp_pose.orientation;
00416
00417 grasp_pose = translatePose(grasp_pose, btVector3(-0.20, 0.0, 0.0));
00418
00419
00420 getGraspInfo(arm_name)->object_ = object;
00421 getGraspInfo(arm_name)->object_collision_name_ = pickup_goal.collision_object_name;
00422 getGraspInfo(arm_name)->grasp_.grasp_pose = grasp_pose;
00423 getGraspInfo(arm_name)->object_orientation_ = GraspInfo::identityQuaternion();
00424
00425 setStatusLabel("grasp completed");
00426 return object_manipulation_msgs::ManipulationResult::SUCCESS;
00427 }
00428
00429 void populatePlaceOptions(object_manipulation_msgs::PlaceGoal &place_goal,
00430 std::string arm_name, const IMGUIOptions &options)
00431 {
00432 place_goal.arm_name = arm_name;
00433 place_goal.place_padding = 0.0;
00434 place_goal.desired_retreat_distance = 0.1;
00435 place_goal.min_retreat_distance = 0.05;
00436 if (options.adv_options.lift_vertically == 0)
00437 {
00438 place_goal.approach.direction.header.frame_id = "base_link";
00439 place_goal.approach.direction.vector.x = 0;
00440 place_goal.approach.direction.vector.y = 0;
00441 place_goal.approach.direction.vector.z = -1;
00442 }
00443 else
00444 {
00445 if (arm_name == "right_arm") place_goal.approach.direction.header.frame_id = "r_wrist_roll_link";
00446 else place_goal.approach.direction.header.frame_id = "l_wrist_roll_link";
00447 place_goal.approach.direction.vector.x = 1;
00448 place_goal.approach.direction.vector.y = 0;
00449 place_goal.approach.direction.vector.z = 0;
00450 }
00451 place_goal.approach.desired_distance = options.adv_options.lift_steps * 0.01;
00452 place_goal.approach.min_distance = place_goal.approach.desired_distance * 0.5;
00453 place_goal.use_reactive_place = options.adv_options.reactive_place;
00454 }
00455
00456 int InteractiveManipulationBackend::placeObject(const IMGUIOptions &options)
00457 {
00458 std::string arm_name;
00459 if (options.arm_selection == 0) arm_name = "right_arm";
00460 else arm_name = "left_arm";
00461
00462
00463 while ( !ros::service::waitForService(place_planning_service_name_, ros::Duration(2.0)) &&
00464 !interruptRequested())
00465 {
00466 setStatusLabel("waiting for place planning service...");
00467 }
00468 if (interruptRequested())
00469 {
00470 setStatusLabel("place planning service was not found");
00471 return object_manipulation_msgs::ManipulationResult::ERROR;
00472 }
00473 setStatusLabel("calling place planning service...");
00474 object_manipulation_msgs::PlacePlanning place_planning;
00475
00476 place_planning.request.grasp_pose = getGraspInfo(arm_name)->grasp_.grasp_pose;
00477 place_planning.request.target = getGraspInfo(arm_name)->object_;
00478 place_planning.request.default_orientation = getGraspInfo(arm_name)->object_orientation_;
00479 if (!place_planning_srv_.call(place_planning))
00480 {
00481 setStatusLabel("call to place planning service failed");
00482 return object_manipulation_msgs::ManipulationResult::ERROR;
00483 }
00484 if (place_planning.response.error_code.value != place_planning.response.error_code.SUCCESS)
00485 {
00486 setStatusLabel("place planning returned an error code");
00487 return object_manipulation_msgs::ManipulationResult::CANCELLED;
00488 }
00489 if (place_planning.response.place_locations.empty())
00490 {
00491 setStatusLabel("place planning returned no locations");
00492 return object_manipulation_msgs::ManipulationResult::ERROR;
00493 }
00494
00495 if (interruptRequested()) return object_manipulation_msgs::ManipulationResult::CANCELLED;
00496
00497
00498 object_manipulation_msgs::PlaceGoal place_goal;
00499
00500
00501 if (!options.collision_checked)
00502 {
00503
00504 motion_planning_msgs::CollisionOperation coll;
00505 coll.object1 = motion_planning_msgs::CollisionOperation::COLLISION_SET_ALL;
00506 coll.object2 = motion_planning_msgs::CollisionOperation::COLLISION_SET_ALL;
00507 coll.operation = motion_planning_msgs::CollisionOperation::DISABLE;
00508 place_goal.additional_collision_operations.collision_operations.push_back(coll);
00509 }
00510 else
00511 {
00512
00513 place_goal.additional_link_padding =
00514 object_manipulator::concat( object_manipulator::MechanismInterface::gripperPadding("left_arm", 0.0),
00515 object_manipulator::MechanismInterface::gripperPadding("right_arm", 0.0) );
00516
00517 place_goal.collision_support_surface_name = motion_planning_msgs::CollisionOperation::COLLISION_SET_ALL;
00518 place_goal.allow_gripper_support_collision = true;
00519
00520 place_goal.collision_object_name = getGraspInfo(arm_name)->object_collision_name_;
00521 }
00522
00523
00524 populatePlaceOptions(place_goal, arm_name, options);
00525 place_goal.grasp.grasp_pose.orientation.w = 1;
00526 place_goal.place_locations.push_back(place_planning.response.place_locations[0]);
00527
00528
00529 geometry_msgs::Pose grasp_pose = place_goal.grasp.grasp_pose;
00530 ROS_INFO("Placing object %s on support %s using grasp: %f %f %f; %f %f %f %f",
00531 place_goal.collision_object_name.c_str(), place_goal.collision_support_surface_name.c_str(),
00532 grasp_pose.position.x, grasp_pose.position.y, grasp_pose.position.z,
00533 grasp_pose.orientation.x, grasp_pose.orientation.y, grasp_pose.orientation.z, grasp_pose.orientation.w);
00534
00535
00536 setStatusLabel("waiting for place action server...");
00537 while ( !place_client_->waitForServer(ros::Duration(1.0)) && !interruptRequested())
00538 {
00539 setStatusLabel("waiting for place action server...");
00540 }
00541 if (interruptRequested())
00542 {
00543 setStatusLabel("place canceled");
00544 place_client_->cancelGoal();
00545 return object_manipulation_msgs::ManipulationResult::CANCELLED;
00546 }
00547
00548
00549 place_client_->sendGoal(place_goal);
00550 while (!place_client_->waitForResult(ros::Duration(1.0)) && !interruptRequested())
00551 {
00552 setStatusLabel("calling place action...");
00553 }
00554 if (interruptRequested())
00555 {
00556 setStatusLabel("place canceled");
00557 place_client_->cancelGoal();
00558 return object_manipulation_msgs::ManipulationResult::CANCELLED;
00559 }
00560
00561
00562 object_manipulation_msgs::PlaceResult result = *(place_client_->getResult());
00563 if (place_client_->getState() != actionlib::SimpleClientGoalState::SUCCEEDED)
00564 {
00565 if (result.attempted_location_results.empty())
00566 {
00567 setStatusLabel("a serious error has occured, please call the WG helpdesk");
00568 return object_manipulation_msgs::ManipulationResult::ERROR;
00569 }
00570 else
00571 {
00572 setStatusLabel(getPlaceLocationResultInfo(result.attempted_location_results[0]));
00573 }
00574 return object_manipulation_msgs::ManipulationResult::UNFEASIBLE;
00575 }
00576
00577 setStatusLabel("place completed");
00578 return object_manipulation_msgs::ManipulationResult::SUCCESS;
00579 }
00580
00581 void InteractiveManipulationBackend::takeMap()
00582 {
00583 setStatusLabel("waiting for collision map services...");
00584 ros::Time start_time = ros::Time::now();
00585 while (!collision_map_interface_.connectionsEstablished(ros::Duration(1.0)))
00586 {
00587 if (interruptRequested() || ros::Time::now() - start_time >= ros::Duration(5.0))
00588 {
00589 setStatusLabel("collision map services not found");
00590 return;
00591 }
00592 }
00593 setStatusLabel("acquiring new collision map");
00594 try
00595 {
00596 collision_map_interface_.takeStaticMap();
00597 setStatusLabel("new collision map acquired");
00598 }
00599 catch (tabletop_collision_map_processing::CollisionMapException ex)
00600 {
00601 setStatusLabel("collision map acquisition failed");
00602 }
00603
00604
00605 try
00606 {
00607 collision_map_interface_.resetCollisionModels();
00608 }
00609 catch (tabletop_collision_map_processing::CollisionMapException &ex)
00610 {
00611 setStatusLabel("failed to reset collision models after taking new map");
00612 }
00613
00614 }
00615
00616 void InteractiveManipulationBackend::collisionReset(int reset_choice)
00617 {
00618 try
00619 {
00620 switch (reset_choice)
00621 {
00622 case 0:
00623
00624 collision_map_interface_.resetCollisionModels();
00625 setStatusLabel("collision models reset");
00626 break;
00627 case 1:
00628
00629 collision_map_interface_.resetAttachedModels();
00630 setStatusLabel("attached models reset");
00631 break;
00632 case 2:
00633
00634 collision_map_interface_.resetStaticMap();
00635 setStatusLabel("collision map reset");
00636 break;
00637 }
00638 }
00639 catch (tabletop_collision_map_processing::CollisionMapException &ex)
00640 {
00641 setStatusLabel("failed to perform requested collision operation");
00642 }
00643 }
00644
00645 void InteractiveManipulationBackend::armMotion(int arm_selection_choice, int arm_action_choice,
00646 int arm_planner_choice, bool collision,
00647 ManipulationResult &result)
00648 {
00649 std::string arm_name;
00650 if ( arm_selection_choice == 0) arm_name = "right_arm";
00651 else arm_name = "left_arm";
00652
00653 try
00654 {
00655 ROS_DEBUG("Attempting arm motion");
00656 motion_planning_msgs::OrderedCollisionOperations ord;
00657 if (!collision)
00658 {
00659 motion_planning_msgs::CollisionOperation coll;
00660 coll.object1 = motion_planning_msgs::CollisionOperation::COLLISION_SET_ALL;
00661 coll.object2 = motion_planning_msgs::CollisionOperation::COLLISION_SET_ALL;
00662 coll.operation = motion_planning_msgs::CollisionOperation::DISABLE;
00663 ord.collision_operations.push_back(coll);
00664 }
00665 std::vector<motion_planning_msgs::LinkPadding> pad;
00666 if (collision)
00667 {
00668 pad = object_manipulator::concat( object_manipulator::MechanismInterface::gripperPadding("left_arm", 0.0),
00669 object_manipulator::MechanismInterface::gripperPadding("right_arm", 0.0) );
00670 }
00671
00672 switch(arm_action_choice)
00673 {
00674 case 0:
00675 {
00676 if (arm_planner_choice == 0)
00677 {
00678 setStatusLabel("moving arm to side using motion planner");
00679 if ( !mech_interface_.attemptMoveArmToGoal(arm_name, getSidePosition(arm_name), ord, pad) )
00680 {
00681 result.value = result.FAILED;
00682 setStatusLabel("failed to move arm to side (possible collisions)");
00683 }
00684 else
00685 {
00686 setStatusLabel("arm moved to side");
00687 result.value = result.SUCCESS;
00688 }
00689 }
00690 else
00691 {
00692 setStatusLabel("moving arm to side open-loop");
00693 mech_interface_.attemptTrajectory(arm_name, getSideTrajectory(arm_name), false, 3.0);
00694 setStatusLabel("arm moved to side");
00695 result.value = result.SUCCESS;
00696 }
00697 }
00698 break;
00699 case 1:
00700 {
00701 if (arm_planner_choice == 0)
00702 {
00703 setStatusLabel("moving arm to front using motion planner");
00704 if ( !mech_interface_.attemptMoveArmToGoal(arm_name, getFrontPosition(arm_name), ord, pad) )
00705 {
00706 setStatusLabel("failed to move arm to front (possible collisions)");
00707 result.value = result.FAILED;
00708 }
00709 else
00710 {
00711 setStatusLabel("arm moved to front");
00712 result.value = result.SUCCESS;
00713 }
00714 }
00715 else
00716 {
00717 setStatusLabel("moving arm to front open-loop");
00718 mech_interface_.attemptTrajectory(arm_name, getFrontTrajectory(arm_name), false, 3.0);
00719 setStatusLabel("arm moved to front");
00720 result.value = result.SUCCESS;
00721 }
00722 }
00723 break;
00724 case 2:
00725 {
00726 if (arm_planner_choice == 0)
00727 {
00728 setStatusLabel("moving arm to handoff using motion planner");
00729 if ( !mech_interface_.attemptMoveArmToGoal(arm_name, getSideHandoffPosition(arm_name), ord, pad) )
00730 {
00731 setStatusLabel("failed to move arm to handoff (possible collisions)");
00732 result.value = result.FAILED;
00733 }
00734 else
00735 {
00736 setStatusLabel("arm moved to handoff");
00737 result.value = result.SUCCESS;
00738 }
00739 }
00740 else
00741 {
00742 setStatusLabel("moving arm to handoff open-loop");
00743 mech_interface_.attemptTrajectory(arm_name, getSideHandoffTrajectory(arm_name), false, 3.0);
00744 setStatusLabel("arm moved to handoff");
00745 result.value = result.SUCCESS;
00746 }
00747 }
00748 default:
00749 setStatusLabel("unknown operation requested");
00750 }
00751 }
00752 catch (object_manipulator::ServiceNotFoundException &ex)
00753 {
00754 setStatusLabel("a needed service or action server was not found");
00755 result.value = result.ERROR;
00756 }
00757 catch (object_manipulator::MoveArmStuckException &ex)
00758 {
00759 setStatusLabel("arm is stuck in a colliding position");
00760 result.value = result.ERROR;
00761 }
00762 catch (object_manipulator::MissingParamException &ex)
00763 {
00764 setStatusLabel("parameters missing; is manipulation pipeline running?");
00765 result.value = result.ERROR;
00766 }
00767 catch (object_manipulator::MechanismException &ex)
00768 {
00769 setStatusLabel("an error has occured, please call helpdesk");
00770 result.value = result.ERROR;
00771 }
00772 catch (...)
00773 {
00774 setStatusLabel("an unknown error has occured, please call helpdesk");
00775 result.value = result.ERROR;
00776 }
00777 }
00778
00779 void InteractiveManipulationBackend::lookAtTable()
00780 {
00781 geometry_msgs::PointStamped target;
00782 target.point.x = 1;
00783 target.point.y = 0;
00784 target.point.z = 0;
00785 target.header.frame_id = "base_link";
00786 setStatusLabel( "moving head" );
00787 try
00788 {
00789 if ( !mech_interface_.pointHeadAction( target, "/narrow_stereo_optical_frame" ) )
00790 {
00791 setStatusLabel( "head movement failed");
00792 }
00793 else
00794 {
00795 setStatusLabel( "head movement completed");
00796 }
00797 }
00798 catch (object_manipulator::ServiceNotFoundException &ex)
00799 {
00800 setStatusLabel("a needed service or action server was not found");
00801 }
00802 }
00803
00804 void InteractiveManipulationBackend::moveGripper(IMGUIOptions options)
00805 {
00806 std::string arm_name;
00807 if (options.arm_selection == 0) arm_name = "right_arm";
00808 else arm_name = "left_arm";
00809 double value = GripperController::GRIPPER_CLOSED +
00810 (GripperController::GRIPPER_OPEN - GripperController::GRIPPER_CLOSED) *
00811 (double)(options.gripper_slider_position)/100.0;
00812 bool result = gripper_controller_.commandGripperValue(arm_name, value);
00813 if (!result) setStatusLabel("failed to command gripper position");
00814 else setStatusLabel("sent gripper position command");
00815 }
00816
00817 int InteractiveManipulationBackend::modelObject(IMGUIOptions options)
00818 {
00819 std::string arm_name;
00820 if (options.arm_selection == 0) arm_name = "right_arm";
00821 else arm_name = "left_arm";
00822
00823
00824 setStatusLabel("waiting for collision map services...");
00825 ros::Time start_time = ros::Time::now();
00826 while (!collision_map_interface_.connectionsEstablished(ros::Duration(1.0)))
00827 {
00828 if (interruptRequested() || ros::Time::now() - start_time >= ros::Duration(5.0))
00829 {
00830 setStatusLabel("collision map services not found");
00831 return object_manipulation_msgs::ManipulationResult::ERROR;
00832 }
00833 }
00834
00835
00836 while ( !create_model_client_->waitForServer(ros::Duration(1.0)) && !interruptRequested())
00837 {
00838 setStatusLabel("waiting for model object in hand action server...");
00839 }
00840 if (interruptRequested()) return object_manipulation_msgs::ManipulationResult::CANCELLED;
00841 ROS_INFO("Modeling object in %s", arm_name.c_str());
00842
00843
00844 pr2_create_object_model::ModelObjectInHandGoal goal;
00845 goal.arm_name = arm_name;
00846 goal.keep_level = 0;
00847 goal.move_arm = 1;
00848 goal.add_to_collision_map = 1;
00849 create_model_client_->sendGoal(goal);
00850
00851 while (!create_model_client_->waitForResult(ros::Duration(1.0)) && !interruptRequested())
00852 {
00853 setStatusLabel("calling model object in hand action...");
00854 }
00855 if (interruptRequested())
00856 {
00857 setStatusLabel("object modeling canceled");
00858 create_model_client_->cancelGoal();
00859 return object_manipulation_msgs::ManipulationResult::CANCELLED;
00860 }
00861
00862 if (create_model_client_->getState() == actionlib::SimpleClientGoalState::SUCCEEDED &&
00863 !create_model_client_->getResult()->cluster.data.empty())
00864 {
00865 setStatusLabel("modeling object in hand completed");
00866 ROS_INFO("modeled object with collision name %s",
00867 create_model_client_->getResult()->collision_name.c_str());
00868 object_manipulation_msgs::GraspableObject object;
00869 sensor_msgs::convertPointCloud2ToPointCloud( create_model_client_->getResult()->cluster, object.cluster );
00870 object.reference_frame_id = create_model_client_->getResult()->cluster.header.frame_id;
00871 if (object.reference_frame_id != "r_wrist_roll_link" &&
00872 object.reference_frame_id != "l_wrist_roll_link" )
00873 {
00874 ROS_ERROR_STREAM("Object model expected in gripper frame and received in frame " << object.reference_frame_id);
00875 setStatusLabel("unexpected frame for modeled object");
00876 return object_manipulation_msgs::ManipulationResult::ERROR;
00877 }
00878
00879 std::string arm_name;
00880 if ( options.arm_selection == 0) arm_name = "right_arm";
00881 else arm_name = "left_arm";
00882 getGraspInfo(arm_name)->object_ = object;
00883
00884 getGraspInfo(arm_name)->grasp_.grasp_pose = GraspInfo::identityPose();
00885 getGraspInfo(arm_name)->object_collision_name_ = create_model_client_->getResult()->collision_name;
00886
00887 return object_manipulation_msgs::ManipulationResult::SUCCESS;
00888 }
00889 else
00890 {
00891 setStatusLabel("modeling object in hand failed");
00892 return object_manipulation_msgs::ManipulationResult::ERROR;
00893 }
00894 }
00895
00896
00897 int InteractiveManipulationBackend::callGripperClickPickup( std::string arm_name,
00898 std::vector<object_manipulation_msgs::Grasp> &grasps )
00899 {
00900
00901 setStatusLabel("waiting for grasp planning service...");
00902 while ( !ros::service::waitForService(grasp_planning_service_name_, ros::Duration(2.0)) && !interruptRequested()) {}
00903 if (interruptRequested())
00904 {
00905 setStatusLabel("grasp planning service not found");
00906 return object_manipulation_msgs::ManipulationResult::ERROR;
00907 }
00908
00909 setStatusLabel("calling grasp planning service...");
00910 object_manipulation_msgs::GraspPlanning grasp_planning;
00911 grasp_planning.request.target.reference_frame_id = "base_link";
00912 grasp_planning.request.arm_name = arm_name;
00913 if (!grasp_planning_srv_.call(grasp_planning))
00914 {
00915 setStatusLabel("failed to call grasp planning service");
00916 return object_manipulation_msgs::ManipulationResult::ERROR;
00917 }
00918 if (grasp_planning.response.error_code.value != grasp_planning.response.error_code.SUCCESS)
00919 {
00920 setStatusLabel("grasp planning returned an error code");
00921 return object_manipulation_msgs::ManipulationResult::CANCELLED;
00922 }
00923 if (grasp_planning.response.grasps.size() != 1 )
00924 {
00925 setStatusLabel("grasp planning returned 0 or more than 1 grasps");
00926 return object_manipulation_msgs::ManipulationResult::ERROR;
00927 }
00928 if (interruptRequested()) return object_manipulation_msgs::ManipulationResult::CANCELLED;
00929
00930 grasps = grasp_planning.response.grasps;
00931 return object_manipulation_msgs::ManipulationResult::SUCCESS;
00932 }
00933
00934
00935
00936 }
00937