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 #include <math.h>
00036
00037 #include <interactive_markers/interactive_marker_server.h>
00038 #include <interactive_markers/menu_handler.h>
00039
00040 #include <object_manipulator/tools/mechanism_interface.h>
00041 #include <object_manipulator/tools/msg_helpers.h>
00042
00043 #include <boost/thread.hpp>
00044 #include <tf/transform_listener.h>
00045 #include <boost/thread/recursive_mutex.hpp>
00046
00047 #include <actionlib/client/simple_action_client.h>
00048 #include <actionlib/server/simple_action_server.h>
00049 #include <point_cloud_server/StoreCloudAction.h>
00050 #include <object_manipulation_msgs/GraspPlanningAction.h>
00051
00052 #include <pr2_object_manipulation_msgs/TestGripperPoseAction.h>
00053 #include <pr2_object_manipulation_msgs/GetGripperPoseAction.h>
00054 #include <pr2_object_manipulation_msgs/CameraFocus.h>
00055
00056 #include <sensor_msgs/point_cloud_conversion.h>
00057
00058 #include "eigen_conversions/eigen_msg.h"
00059
00060 #include "eigen3/Eigen/Geometry"
00061 #include "pcl/io/pcd_io.h"
00062 #include "pcl/point_types.h"
00063 #include "pcl_ros/transforms.h"
00064
00065 #include <household_objects_database_msgs/GetModelDescription.h>
00066 #include <household_objects_database_msgs/GetModelMesh.h>
00067
00068 #include <interactive_marker_helpers/interactive_marker_helpers.h>
00069
00070 using namespace object_manipulator;
00071 using namespace visualization_msgs;
00072 using namespace interactive_markers;
00073 using namespace pr2_object_manipulation_msgs;
00074 using namespace im_helpers;
00075
00076 typedef pcl::PointXYZRGB PointT;
00077
00079
00080
00083 class GripperPoseAction
00084 {
00085 protected:
00086
00087
00088
00089 std::vector<geometry_msgs::PoseStamped> planner_poses_;
00090 std::vector<PoseState> planner_states_;
00091 std::vector<int> planner_grasp_types_;
00092 int planner_index_;
00093 geometry_msgs::PoseStamped button_marker_pose_;
00094
00095 geometry_msgs::PoseStamped gripper_pose_;
00096 geometry_msgs::PoseStamped control_offset_;
00097 float gripper_opening_;
00098 float gripper_angle_;
00099 pcl::PointCloud<PointT>::Ptr object_cloud_;
00100 bool active_;
00101 bool object_model_;
00102 bool always_call_planner_;
00103 bool show_invalid_grasps_;
00104 bool always_find_alternatives_;
00105 bool gripper_opening_cycling_;
00106
00107 int interface_number_;
00108 int task_number_;
00109 bool testing_planned_grasp_;
00110 int tested_grasp_index_;
00111 bool testing_current_grasp_;
00112 bool testing_alternatives_;
00113
00114 double alternatives_search_dist_;
00115 double alternatives_search_dist_resolution_;
00116 double alternatives_search_angle_;
00117 double alternatives_search_angle_resolution_;
00118 double grasp_plan_region_len_x_;
00119 double grasp_plan_region_len_y_;
00120 double grasp_plan_region_len_z_;
00121
00122 PoseState pose_state_;
00123 ros::NodeHandle nh_;
00124 ros::NodeHandle pnh_;
00125 ros::Subscriber sub_seed_;
00126 ros::ServiceClient get_model_mesh_client_;
00127 ros::Timer spin_timer_;
00128 ros::Timer slow_sync_timer_;
00129 InteractiveMarkerServer server_;
00130
00131 ros::Publisher pub_cloud_;
00132 ros::Publisher pub_focus_;
00133
00134 MenuHandler menu_gripper_;
00135 MenuHandler::EntryHandle accept_handle_;
00136 MenuHandler::EntryHandle cancel_handle_;
00137 MenuHandler::EntryHandle focus_handle_;
00138 MenuHandler::EntryHandle alternatives_handle_;
00139
00140 tf::TransformListener tfl_;
00141
00142 object_manipulator::MechanismInterface mechanism_;
00143
00144 object_manipulator::ActionWrapper<pr2_object_manipulation_msgs::TestGripperPoseAction> test_pose_client_;
00145 object_manipulator::ActionWrapper<object_manipulation_msgs::GraspPlanningAction> grasp_plan_client_;
00146 object_manipulator::ActionWrapper<point_cloud_server::StoreCloudAction> cloud_server_client_;
00147
00148 std::string get_pose_name_;
00149 actionlib::SimpleActionServer<pr2_object_manipulation_msgs::GetGripperPoseAction> get_pose_server_;
00150
00151 public:
00152
00153 GripperPoseAction() :
00154 planner_index_(0),
00155 gripper_angle_(0.541),
00156 object_cloud_(new pcl::PointCloud<PointT>()),
00157 active_(false),
00158 object_model_(false),
00159 pose_state_(UNTESTED),
00160 nh_("/"),
00161 pnh_("~"),
00162 server_("pr2_marker_control", "server 2", false),
00163 tfl_(nh_),
00164 test_pose_client_("test_gripper_pose", true),
00165 grasp_plan_client_("grasp_plan_action", true),
00166 cloud_server_client_("point_cloud_server_action", true),
00167 get_pose_name_(ros::this_node::getName()),
00168 get_pose_server_(nh_, get_pose_name_, false)
00169 {
00170 ROS_INFO( "pr2_interactive_gripper_pose_action is starting up." );
00171
00172 ros::Duration(1.0).sleep();
00173
00174 pnh_.param<bool>("always_call_planner", always_call_planner_, false);
00175 pnh_.param<bool>("always_find_alternatives", always_find_alternatives_, true);
00176 pnh_.param<bool>("show_invalid_grasps", show_invalid_grasps_, false);
00177 pnh_.param<bool>("gripper_opening_cycling", gripper_opening_cycling_, false);
00178
00179 nh_.param<int>("interactive_grasping/interface_number", interface_number_, 0);
00180 if (!interface_number_) ROS_WARN("No interface number specified for grasping study; using default configuration");
00181 else ROS_INFO("Using interface number %d for grasping study", interface_number_);
00182 nh_.param<int>("interactive_grasping/task_number", task_number_, 0);
00183 if (!task_number_) ROS_WARN("No task number specified for grasping study; using default configuration");
00184 else ROS_INFO("Using task number %d for grasping study", task_number_);
00185 pnh_.param<double>("alternatives_search_dist", alternatives_search_dist_, .15);
00186 pnh_.param<double>("alternatives_search_dist_resolution", alternatives_search_dist_resolution_, .005);
00187 pnh_.param<double>("alternatives_search_angle", alternatives_search_angle_, M_PI/2);
00188 pnh_.param<double>("alternatives_search_angle_resolution", alternatives_search_angle_resolution_, M_PI/10);
00189 pnh_.param<double>("grasp_plan_region_len_x", grasp_plan_region_len_x_, 0.3);
00190 pnh_.param<double>("grasp_plan_region_len_y", grasp_plan_region_len_y_, 0.3);
00191 pnh_.param<double>("grasp_plan_region_len_z", grasp_plan_region_len_z_, 0.3);
00192
00193 if(interface_number_ == 4) always_call_planner_ = true;
00194 else if(interface_number_ >= 1) always_call_planner_ = false;
00195
00196
00197 geometry_msgs::PoseStamped ps;
00198 ps.header.frame_id = "/base_link";
00199 server_.insert(makeButtonBox( "test_box", ps, 0.01, false, false));
00200
00201 pub_cloud_ = nh_.advertise<sensor_msgs::PointCloud2>("cloud_debug", 1);
00202 pub_focus_ = nh_.advertise<pr2_object_manipulation_msgs::CameraFocus>("camera_focus", 1);
00203
00204 get_model_mesh_client_ = nh_.serviceClient<household_objects_database_msgs::GetModelMesh>("objects_database_node/get_model_mesh", false);
00205
00206 spin_timer_ = nh_.createTimer(ros::Duration(0.05), boost::bind( &GripperPoseAction::spinOnce, this ) );
00207
00208 sub_seed_ = nh_.subscribe<geometry_msgs::PoseStamped>("cloud_click_point", 1, boost::bind(&GripperPoseAction::setSeed, this, _1));
00209
00210
00211 initMenus();
00212
00213
00214
00215 get_pose_server_.registerGoalCallback( boost::bind(&GripperPoseAction::goalCB, this));
00216 get_pose_server_.registerPreemptCallback( boost::bind(&GripperPoseAction::preemptCB, this));
00217
00218 get_pose_server_.start();
00219 }
00220
00221 ~GripperPoseAction()
00222 {
00223 }
00224
00225 bool transformGripperPose(const std::string frame_id = "/base_link")
00226 {
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237 return true;
00238 }
00239
00240 void updateGripperOpening()
00241 {
00242 gripper_opening_ = gripper_angle_ * 0.1714;
00243 }
00244
00245 void updateGripperAngle()
00246 {
00247 gripper_angle_ = gripper_opening_ * 5.834;
00248 }
00249
00250 void setSeed(const geometry_msgs::PoseStampedConstPtr &seed)
00251 {
00252 if(!active_) return;
00253 ROS_DEBUG("Setting seed.");
00254 geometry_msgs::PoseStamped ps = *seed;
00255 ROS_DEBUG_STREAM("Input seed was \n" << ps);
00256 tf::Pose pose;
00257 tf::poseMsgToTF(ps.pose, pose);
00258 tf::Quaternion q = pose.getRotation();
00259 tf::Matrix3x3 rot(q);
00260 tf::Matrix3x3 perm( 0, 0, 1,
00261 0, 1, 0,
00262 -1, 0, 0);
00263 (rot*perm).getRotation(q);
00264
00265 pose.setRotation(q);
00266
00267 if(object_model_) pose = pose*tf::Transform(tf::Quaternion(tf::Vector3(0,1,0), M_PI/2.0), tf::Vector3(0,0,0)).inverse();
00268
00269 tf::poseTFToMsg(pose, ps.pose);
00270
00271
00272
00273 gripper_pose_ = toWrist(ps);
00274
00275
00276
00277
00278
00279
00280 pose_state_ = UNTESTED;
00281 eraseAllGraspMarkers();
00282
00283 testing_planned_grasp_ = false;
00284 testing_alternatives_ = false;
00285 testing_current_grasp_ = true;
00286 if(always_call_planner_)
00287 {
00288 ROS_INFO("Always call planner is on");
00289 graspPlanCB();
00290 }
00291 else
00292 {
00293 initMarkers();
00294 testPose(gripper_pose_, gripper_opening_);
00295 }
00296
00297 focusCB();
00298 }
00299
00301 void setIdle(){
00302 active_ = false;
00303 server_.erase("ghosted_gripper");
00304 server_.erase("gripper_controls");
00305 server_.erase("object_cloud");
00306 eraseAllGraspMarkers();
00307 planner_states_.clear();
00308 planner_poses_.clear();
00309 }
00310
00311
00313 void goalCB()
00314 {
00315 active_ = true;
00316 object_model_ = false;
00317 planner_index_ = 0;
00318 ROS_INFO("Ghosted gripper called");
00319 pr2_object_manipulation_msgs::GetGripperPoseGoal goal = *get_pose_server_.acceptNewGoal();
00320 object_cloud_.reset( new pcl::PointCloud<PointT>());
00321 pcl::PointCloud<PointT>::Ptr cloud(new pcl::PointCloud<PointT>());
00322 control_offset_.pose = object_manipulator::msg::createPoseMsg(tf::Pose(tf::Quaternion::getIdentity(), tf::Vector3(0.15,0,0)));
00323
00324
00325 if(interface_number_ == 0)
00326 {
00327 pnh_.param<bool>("always_call_planner", always_call_planner_, false);
00328 pnh_.param<bool>("always_find_alternatives", always_find_alternatives_, true);
00329 pnh_.param<bool>("show_invalid_grasps", show_invalid_grasps_, true);
00330 pnh_.param<bool>("gripper_opening_cycling", gripper_opening_cycling_, false);
00331 ROS_INFO("always_call_planner: %d, always_find_alt: %d, show_invalid: %d, gripper_opening_cycle: %d",
00332 (int)always_call_planner_, (int)always_find_alternatives_, (int)show_invalid_grasps_, (int)gripper_opening_cycling_);
00333 }
00334
00335 if( !goal.object.cluster.points.empty() ||
00336 !goal.object.potential_models.empty() )
00337 {
00338 ROS_INFO("Goal object contains %d cluster and %d models.",
00339 !goal.object.cluster.points.empty(), (int)goal.object.potential_models.size() );
00340
00341 try
00342 {
00343 ROS_INFO("Converting to reference_frame...");
00344 mechanism_.convertGraspableObjectComponentsToFrame(goal.object, goal.object.reference_frame_id);
00345
00346 bool use_cloud = goal.object.potential_models.empty();
00347
00348
00349 if(!use_cloud)
00350 {
00351 ROS_INFO("Goal contains object model; looking for model mesh...");
00352
00353 arm_navigation_msgs::Shape mesh;
00354 if(!getModelMesh(goal.object.potential_models[0].model_id, mesh))
00355 {
00356 ROS_INFO("Unable to get database model, continuing with cluster.");
00357 use_cloud = true;
00358 }
00359
00360 if(!use_cloud)
00361 {
00362 object_model_ = true;
00363 for(unsigned int i = 0; i < mesh.vertices.size(); i++)
00364 {
00365 PointT pt;
00366 pt.x = mesh.vertices[i].x;
00367 pt.y = mesh.vertices[i].y;
00368 pt.z = mesh.vertices[i].z;
00369 pt.rgb = 0x11FF11;
00370 cloud->points.push_back(pt);
00371 }
00372 cloud->width = cloud->points.size();
00373 cloud->height = 1;
00374 cloud->is_dense = false;
00375 cloud->header.frame_id = goal.object.reference_frame_id;
00376
00377 geometry_msgs::Pose &m = goal.object.potential_models[0].pose.pose;
00378 Eigen::Affine3f affine = Eigen::Translation3f(m.position.x,
00379 m.position.y,
00380 m.position.z) *
00381 Eigen::Quaternionf(m.orientation.w,
00382 m.orientation.x,
00383 m.orientation.y,
00384 m.orientation.z);
00385 pcl::transformPointCloud(*cloud, *cloud, affine);
00386
00387 tf::Transform T_o, T_g;
00388 tf::poseMsgToTF(goal.object.potential_models[0].pose.pose, T_o);
00389 tf::poseMsgToTF(goal.grasp.grasp_pose, T_g);
00390 tf::Transform T = T_g.inverse()*T_o;
00391 tf::poseTFToMsg(T, control_offset_.pose);
00392
00393 }
00394 }
00395
00396 if(use_cloud)
00397 {
00398
00399
00400 sensor_msgs::PointCloud2 converted_cloud;
00401 sensor_msgs::convertPointCloudToPointCloud2 (goal.object.cluster, converted_cloud);
00402
00403 pcl::fromROSMsg(converted_cloud, *cloud);
00404 }
00405
00406 geometry_msgs::Pose &m = goal.grasp.grasp_pose;
00407 Eigen::Affine3f affine = Eigen::Translation3f(m.position.x,
00408 m.position.y,
00409 m.position.z) *
00410 Eigen::Quaternionf(m.orientation.w,
00411 m.orientation.x,
00412 m.orientation.y,
00413 m.orientation.z);
00414 affine = affine.inverse();
00415 pcl::transformPointCloud(*cloud, *object_cloud_, affine);
00416 }
00417 catch(...){
00418 ROS_ERROR("%s: Error converting graspable object to reference frame id [%s]!",
00419 get_pose_name_.c_str(), goal.object.reference_frame_id.c_str());
00420 }
00421 }
00422 if (goal.gripper_pose.pose.orientation.x == 0 &&
00423 goal.gripper_pose.pose.orientation.y == 0 &&
00424 goal.gripper_pose.pose.orientation.z == 0 &&
00425 goal.gripper_pose.pose.orientation.w == 0 )
00426 {
00427 ROS_INFO("Empty pose passed in; using default");
00428 gripper_pose_ = getDefaultPose(goal.arm_name);
00429
00430
00431
00432 gripper_opening_ = 0.086;
00433 updateGripperAngle();
00434 }
00435 else
00436 {
00437 gripper_pose_ = goal.gripper_pose;
00438
00439 gripper_opening_ = goal.gripper_opening;
00440 updateGripperAngle();
00441 }
00442 if (get_pose_server_.isPreemptRequested())
00443 {
00444 if(test_pose_client_.client().getState() == actionlib::SimpleClientGoalState::ACTIVE ||
00445 test_pose_client_.client().getState() == actionlib::SimpleClientGoalState::PENDING )
00446 {
00447 test_pose_client_.client().cancelAllGoals();
00448 }
00449 get_pose_server_.setPreempted();
00450 setIdle();
00451 return;
00452 }
00453
00454 pose_state_ = UNTESTED;
00455 initMarkers();
00456 pr2_object_manipulation_msgs::TestGripperPoseGoal test_goal;
00457 test_goal.gripper_poses.push_back(gripper_pose_);
00458 test_goal.gripper_openings.push_back(gripper_opening_);
00459 test_pose_client_.client().sendGoal( test_goal, boost::bind(&GripperPoseAction::testGripperResultCallback, this, _1, _2));
00460 }
00461
00462
00464 void preemptCB()
00465 {
00466 ROS_INFO("%s: Preempted", get_pose_name_.c_str());
00467 test_pose_client_.client().cancelAllGoals();
00468 grasp_plan_client_.client().cancelGoal();
00469 get_pose_server_.setPreempted();
00470 setIdle();
00471 }
00472
00474 geometry_msgs::PoseStamped toWrist(const geometry_msgs::PoseStamped &ps)
00475 {
00476 geometry_msgs::PoseStamped out;
00477 out.header = ps.header;
00478 tf::Transform T, P;
00479 tf::poseMsgToTF(ps.pose, P);
00480 tf::poseMsgToTF(control_offset_.pose, T);
00481 tf::poseTFToMsg( P*T.inverse(), out.pose);
00482
00483 return out;
00484 }
00485
00487 geometry_msgs::PoseStamped fromWrist(const geometry_msgs::PoseStamped &ps)
00488 {
00489 geometry_msgs::PoseStamped out;
00490 out.header = ps.header;
00491 tf::Transform T, P;
00492 tf::poseMsgToTF(ps.pose, P);
00493 tf::poseMsgToTF(control_offset_.pose, T);
00494 tf::poseTFToMsg( P*T, out.pose);
00495
00496 return out;
00497 }
00498
00499
00502 void updatePoses()
00503 {
00504 server_.setPose("ghosted_gripper", gripper_pose_.pose, gripper_pose_.header);
00505 server_.setPose("object_cloud", gripper_pose_.pose, gripper_pose_.header);
00506 }
00507
00508 geometry_msgs::PoseStamped getDefaultPose(std::string arm_name)
00509 {
00510 ros::Time now = ros::Time(0);
00511 tfl_.waitForTransform("r_gripper_tool_frame","/base_link", now, ros::Duration(2.0));
00512 tf::StampedTransform stamped;
00513 geometry_msgs::TransformStamped ts;
00514 geometry_msgs::PoseStamped ps;
00515 std::string arm_frame;
00516 if (arm_name == "right_arm") arm_frame="r_wrist_roll_link";
00517 else if (arm_name == "left_arm") arm_frame="l_wrist_roll_link";
00518 else
00519 {
00520 arm_frame="r_wrist_roll_link";
00521 ROS_ERROR("Unknown arm name passed to ghosted gripper");
00522 }
00523 tfl_.lookupTransform("/base_link", arm_frame, now, stamped);
00524 tf::transformStampedTFToMsg(stamped, ts);
00525 ps = msg::createPoseStampedMsg(ts);
00526 return ps;
00527 }
00528
00529
00530
00531
00534 void initMarkers()
00535 {
00536 initGripperMarker();
00537 initObjectMarker();
00538 initGripperControl();
00539 }
00540
00541 void initGraspMarkers()
00542 {
00543 for(unsigned int i = 0; i < planner_poses_.size(); i++)
00544 {
00545
00546 std::stringstream ss;
00547 ss << "grasp_" << i;
00548 server_.insert(makeGraspMarker(ss.str().c_str(), planner_poses_[i], 1.5, planner_states_[i]));
00549 server_.setCallback(ss.str(), boost::bind( &GripperPoseAction::selectGrasp, this, _1),
00550 visualization_msgs::InteractiveMarkerFeedback::MOUSE_DOWN );
00551
00552
00553 }
00554 }
00555
00556 void eraseAllGraspMarkers()
00557 {
00558 for(unsigned int i = 0; i < planner_poses_.size(); i++)
00559 {
00560
00561 std::stringstream ss;
00562 ss << "grasp_" << i;
00563 server_.erase(ss.str().c_str());
00564 }
00565 server_.erase("grasp_toggle");
00566 planner_index_ = 0;
00567 planner_poses_.resize(0);
00568 planner_states_.resize(0);
00569 planner_grasp_types_.resize(0);
00570
00571 }
00572
00573 void selectNextGrasp()
00574 {
00575 selectGraspIndex( planner_index_+1 );
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587 }
00588
00589 void selectGraspIndex(int index)
00590 {
00591 planner_index_ = index;
00592 if( planner_index_ >= (int)planner_poses_.size() ) planner_index_ = 0;
00593 gripper_pose_ = planner_poses_[ planner_index_ ];
00594 pose_state_ = planner_states_[ planner_index_ ];
00595 ROS_INFO("Selecting grasp %d", planner_index_);
00596 initMarkers();
00597
00598 if(pose_state_ == UNTESTED)
00599 {
00600 testing_planned_grasp_ = false;
00601 testing_alternatives_ = false;
00602 tested_grasp_index_ = planner_index_;
00603 testing_current_grasp_ = true;
00604 testPose(gripper_pose_, gripper_opening_);
00605 }
00606 }
00607
00608 void selectGrasp( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback )
00609 {
00610 int index = atoi(feedback->marker_name.substr(6).c_str());
00611 if( index >= (int)planner_poses_.size() ) return;
00612 selectGraspIndex(index);
00613 }
00614
00615 void initButtonMarker()
00616 {
00617 button_marker_pose_.header.stamp = ros::Time(0);
00618 int num = 0;
00619 if(planner_poses_.size()) num = planner_index_ + 1;
00620
00621
00622
00623
00624
00625
00626
00627
00628 server_.insert(makeListControl("grasp_toggle", button_marker_pose_, num, planner_poses_.size(), 0.3));
00629 server_.setCallback("grasp_toggle", boost::bind( &GripperPoseAction::cycleGrasps, this, _1),
00630 visualization_msgs::InteractiveMarkerFeedback::MOUSE_DOWN );
00631 }
00632
00633 void initObjectMarker()
00634 {
00635 if(object_cloud_->points.size())
00636 {
00637 server_.insert(makeCloudMarker( "object_cloud", gripper_pose_, 0.004,
00638 object_manipulator::msg::createColorMsg(0.2, 0.8, 0.2,1.0) ));
00639 }
00640 }
00641
00642 void initGripperMarker()
00643 {
00644 float r,g,b;
00645 switch(pose_state_)
00646 {
00647 case INVALID:
00648 r = 1.0; g = 0.2; b = 0.2;
00649 break;
00650 case VALID:
00651 r = 0.2; g = 1.0; b = 0.2;
00652 break;
00653 default:
00654 r = 0.5; g = 0.5; b = 0.5;
00655 }
00656 std_msgs::ColorRGBA color = object_manipulator::msg::createColorMsg(r,g,b,1.0);
00657
00658 server_.insert(makeGripperMarker( "ghosted_gripper", gripper_pose_, 1.01, gripper_angle_, false, color),
00659 boost::bind( &GripperPoseAction::gripperClickCB, this, _1));
00660 menu_gripper_.apply(server_, "ghosted_gripper");
00661 }
00662
00663 void initGripperControl()
00664 {
00665 geometry_msgs::PoseStamped ps = fromWrist(gripper_pose_);
00666 ps.header.stamp = ros::Time(0);
00667 server_.insert(make6DofMarker( "gripper_controls", ps, 0.2, false, false),
00668 boost::bind( &GripperPoseAction::updateGripper, this, _1));
00669 menu_gripper_.apply(server_, "gripper_controls");
00670 }
00671
00672
00673 protected:
00674
00675
00677 void spinOnce()
00678 {
00679
00680 server_.applyChanges();
00681 }
00682
00683 void slowSync()
00684 {
00685 }
00686
00688 void testGripperResultCallback(const actionlib::SimpleClientGoalState& state,
00689 const pr2_object_manipulation_msgs::TestGripperPoseResultConstPtr &result)
00690 {
00691 if (result->valid.empty())
00692 {
00693 ROS_ERROR("Test gripper pose returned with empty result list");
00694 return;
00695 }
00696 if(state.state_ == state.SUCCEEDED)
00697 {
00698 ROS_INFO("Test pose action returned with result %d", (int)result->valid[0]);
00699
00700 if (testing_planned_grasp_)
00701 {
00702 if (!planner_states_.empty())
00703 {
00704 if(planner_states_.size() == result->valid.size())
00705 {
00706 int dim_index = 0;
00707 bool dim_grasp_found = false;
00708 if(testing_alternatives_) dim_index = planner_grasp_types_[0];
00709 std::vector<geometry_msgs::PoseStamped> planner_poses_temp;
00710 std::vector<PoseState> planner_states_temp;
00711
00712
00713 for (size_t i=0; i<result->valid.size(); i++)
00714 {
00715 PoseState pose_state = INVALID;
00716
00717
00718 if (result->valid[i])
00719 {
00720 pose_state = VALID;
00721
00722
00723 if (testing_alternatives_){
00724 if(planner_grasp_types_[i] == dim_index)
00725 {
00726
00727 if(!dim_grasp_found)
00728 {
00729 dim_grasp_found = true;
00730 }
00731
00732
00733 else pose_state = UNTESTED;
00734 }
00735
00736
00737 else
00738 {
00739 dim_index = planner_grasp_types_[i];
00740 dim_grasp_found = true;
00741 }
00742 }
00743 }
00744
00745
00746 else
00747 {
00748 if(testing_alternatives_)
00749 {
00750
00751 pose_state = UNTESTED;
00752
00753
00754 if(planner_grasp_types_[i] != dim_index){
00755 dim_index = planner_grasp_types_[i];
00756 dim_grasp_found = false;
00757 }
00758 }
00759 }
00760
00761
00762 if(pose_state == UNTESTED || (pose_state == INVALID && !show_invalid_grasps_)) continue;
00763 planner_states_temp.push_back(pose_state);
00764 planner_poses_temp.push_back(planner_poses_[i]);
00765 }
00766
00767
00768 eraseAllGraspMarkers();
00769
00770
00771 planner_states_ = planner_states_temp;
00772 planner_poses_ = planner_poses_temp;
00773 ROS_INFO("planner_states has %zd entries", planner_states_.size());
00774
00775
00776 initGraspMarkers();
00777 }
00778 else
00779 {
00780 ROS_ERROR("planner_states_ size did not match result->valid size!");
00781 }
00782 }
00783 else
00784 {
00785 ROS_ERROR("planner_states_ was empty!");
00786 }
00787
00788
00789 if(planner_poses_.size() > 1 || testing_alternatives_) initButtonMarker();
00790 }
00791
00792
00793 if (testing_current_grasp_)
00794 {
00795 PoseState pose_state = INVALID;
00796 if (result->valid[0]) pose_state = VALID;
00797 pose_state_ = pose_state;
00798 initGripperMarker();
00799
00800
00801 if(always_find_alternatives_ && pose_state == INVALID)
00802 {
00803 alternativesCB();
00804 }
00805 }
00806 }
00807 else
00808 {
00809 ROS_WARN("Test pose action did not succeed; state = %d", (int)state.state_);
00810 }
00811 }
00812
00814 void graspPlanCB()
00815 {
00816 eraseAllGraspMarkers();
00817
00818 point_cloud_server::StoreCloudGoal cloud_goal;
00819 cloud_goal.action = cloud_goal.GET;
00820 cloud_goal.name = "interactive_manipulation_snapshot";
00821 cloud_server_client_.client().sendGoal(cloud_goal);
00822 if(!cloud_server_client_.client().waitForResult(ros::Duration(3.0)))
00823 {
00824 ROS_WARN("Timed-out while waiting for cloud from server!");
00825 return;
00826 }
00827
00828 object_manipulation_msgs::GraspPlanningGoal plan_goal;
00829 plan_goal.target.region.cloud = cloud_server_client_.client().getResult()->cloud;
00830 plan_goal.target.region.roi_box_pose = fromWrist(gripper_pose_);
00831 plan_goal.target.region.roi_box_dims = object_manipulator::msg::createVector3Msg(grasp_plan_region_len_x_,
00832 grasp_plan_region_len_y_,
00833 grasp_plan_region_len_z_);
00834 int cloud_size = plan_goal.target.region.cloud.width * plan_goal.target.region.cloud.height;
00835 plan_goal.target.reference_frame_id = gripper_pose_.header.frame_id;
00836 object_manipulation_msgs::Grasp seed;
00837 seed.grasp_pose = gripper_pose_.pose;
00838 plan_goal.grasps_to_evaluate.push_back(seed);
00839
00840 ROS_DEBUG_STREAM("Requesting adjustment on cloud with " << cloud_size << " points, pose \n" << seed);
00841
00842 grasp_plan_client_.client().sendGoal( plan_goal, boost::bind(&GripperPoseAction::graspPlanResultCB, this, _1, _2));
00843
00844 button_marker_pose_ = gripper_pose_;
00845 button_marker_pose_.header.stamp = ros::Time(0);
00846 button_marker_pose_.pose.orientation = geometry_msgs::Quaternion();
00847 button_marker_pose_.pose.orientation.w = 1;
00848 button_marker_pose_.pose.position.z -= 0.2;
00849
00850 server_.erase("gripper_controls");
00851 server_.erase("ghosted_gripper");
00852 }
00853
00855 void graspPlanResultCB(const actionlib::SimpleClientGoalState& state,
00856 const object_manipulation_msgs::GraspPlanningResultConstPtr &result)
00857 {
00858 planner_index_ = 0;
00859
00860
00861 if(state.state_ == state.SUCCEEDED)
00862 {
00863 ROS_INFO("Grasp plan action succeeded.");
00864
00865 int num = result->grasps.size();
00866
00867 planner_poses_.resize(num + 1);
00868 planner_states_.resize(num + 1);
00869
00870 for(int i = 0; i < num; i++)
00871 {
00872 planner_poses_[i].pose = result->grasps[i].grasp_pose;
00873 planner_poses_[i].header = gripper_pose_.header;
00874 planner_poses_[i].header.stamp = ros::Time(0);
00875 planner_states_[i] = UNTESTED;
00876 }
00877 planner_poses_[num] = gripper_pose_;
00878 planner_poses_[num].header.stamp = ros::Time(0);
00879 planner_states_[num] = UNTESTED;
00880 initGraspMarkers();
00881 testing_planned_grasp_ = true;
00882 testing_alternatives_ = false;
00883 tested_grasp_index_ = 0;
00884 testing_current_grasp_ = false;
00885 testPoses(planner_poses_, gripper_opening_);
00886 }
00887
00888
00889 else
00890 {
00891 ROS_WARN("Grasp plan action did not succeed; state = %d", (int)state.state_);
00892 planner_poses_.resize(1);
00893 planner_states_.resize(1);
00894 planner_poses_[0] = gripper_pose_;
00895 planner_poses_[0].header.stamp = ros::Time(0);
00896 planner_states_[0] = UNTESTED;
00897 gripper_pose_ = planner_poses_[0];
00898 initMarkers();
00899
00900 pose_state_ = UNTESTED;
00901 testing_current_grasp_ = true;
00902 testing_planned_grasp_ = false;
00903 testing_alternatives_ = false;
00904 tested_grasp_index_ = 0;
00905 testPose(gripper_pose_, gripper_opening_);
00906 }
00907 }
00908
00910 void cycleGrasps(const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback)
00911 {
00912 selectNextGrasp();
00913 initButtonMarker();
00914 }
00915
00917 void acceptCB()
00918 {
00919 if( pose_state_ == VALID )
00920 {
00921 if(test_pose_client_.client().getState() == actionlib::SimpleClientGoalState::ACTIVE ||
00922 test_pose_client_.client().getState() == actionlib::SimpleClientGoalState::PENDING )
00923 {
00924 test_pose_client_.client().cancelGoal();
00925 }
00926 setIdle();
00927 pr2_object_manipulation_msgs::GetGripperPoseResult result;
00928 result.gripper_pose = gripper_pose_;
00929 result.gripper_opening = gripper_opening_;
00930 get_pose_server_.setSucceeded(result);
00931 }
00932 }
00933
00935 void cancelCB()
00936 {
00937 if(test_pose_client_.client().getState() == actionlib::SimpleClientGoalState::ACTIVE ||
00938 test_pose_client_.client().getState() == actionlib::SimpleClientGoalState::PENDING )
00939 {
00940 test_pose_client_.client().cancelGoal();
00941 }
00942 get_pose_server_.setAborted();
00943 setIdle();
00944 }
00945
00947 void focusCB()
00948 {
00949 pr2_object_manipulation_msgs::CameraFocus msg;
00950 msg.focal_point.point = gripper_pose_.pose.position;
00951 msg.focal_point.header = gripper_pose_.header;
00952 pub_focus_.publish(msg);
00953 }
00954
00956 std::vector<geometry_msgs::PoseStamped> generatePosesAlongDir(tf::Pose pose, tf::Vector3 axis,
00957 double min_shift, double max_shift, double resolution, std::string frame_id)
00958 {
00959 std::vector<geometry_msgs::PoseStamped> shifted_poses;
00960
00961 for(double dist=min_shift; dist<=max_shift; dist += resolution)
00962 {
00963 if(dist < 1e-6 && dist > -1e-6) continue;
00964 tf::Pose shifted_pose = pose*tf::Transform(tf::createIdentityQuaternion(), axis*dist);
00965 geometry_msgs::PoseStamped shifted_pose_stamped;
00966 tf::poseTFToMsg(shifted_pose, shifted_pose_stamped.pose);
00967 shifted_pose_stamped.header.frame_id = frame_id;
00968 if(fabs(min_shift) > fabs(max_shift)){
00969 shifted_poses.insert(shifted_poses.begin(), shifted_pose_stamped);
00970 }
00971 else shifted_poses.push_back(shifted_pose_stamped);
00972 }
00973 return shifted_poses;
00974 }
00975
00977 std::vector<geometry_msgs::PoseStamped> generateRotatedPoses(tf::Pose pose, tf::Vector3 axis,
00978 double min_rot, double max_rot, double resolution, std::string frame_id)
00979 {
00980 std::vector<geometry_msgs::PoseStamped> rotated_poses;
00981
00982 for(double angle=min_rot; angle<=max_rot; angle += resolution)
00983 {
00984 if(angle < 1e-6 && angle > -1e-6) continue;
00985 tf::Quaternion rot = tf::Quaternion(axis, angle);
00986 tf::Pose rotated_pose = pose*tf::Transform(rot, tf::Vector3(0,0,0));
00987 geometry_msgs::PoseStamped rotated_pose_stamped;
00988 tf::poseTFToMsg(rotated_pose, rotated_pose_stamped.pose);
00989 rotated_pose_stamped.header.frame_id = frame_id;
00990 if(fabs(min_rot) > fabs(max_rot)){
00991 rotated_poses.insert(rotated_poses.begin(), rotated_pose_stamped);
00992 }
00993 else rotated_poses.push_back(rotated_pose_stamped);
00994 }
00995 return rotated_poses;
00996 }
00997
00999 void alternativesCB()
01000 {
01001 if(test_pose_client_.client().getState() == actionlib::SimpleClientGoalState::ACTIVE ||
01002 test_pose_client_.client().getState() == actionlib::SimpleClientGoalState::PENDING )
01003 {
01004 test_pose_client_.client().cancelGoal();
01005 }
01006 eraseAllGraspMarkers();
01007
01008
01009 geometry_msgs::PoseStamped fingertips_pose = fromWrist(gripper_pose_);
01010 tf::Pose pose;
01011 tf::poseMsgToTF(fingertips_pose.pose, pose);
01012 std::vector<geometry_msgs::PoseStamped> poses;
01013 std::string frame_id = gripper_pose_.header.frame_id;
01014 tf::Vector3 axes[3] = {tf::Vector3(1,0,0), tf::Vector3(0,1,0), tf::Vector3(0,0,1)};
01015 std::vector<geometry_msgs::PoseStamped> some_poses;
01016 std::vector<int> some_types;
01017
01018
01019 for(int ind=0; ind<3; ind++)
01020 {
01021 some_poses = generatePosesAlongDir(pose, axes[ind], 0, alternatives_search_dist_, alternatives_search_dist_resolution_, frame_id);
01022 poses.insert(poses.end(), some_poses.begin(), some_poses.end());
01023 planner_grasp_types_.insert(planner_grasp_types_.end(), some_poses.size(), ind*2);
01024 some_poses = generatePosesAlongDir(pose, axes[ind], -alternatives_search_dist_, 0, alternatives_search_dist_resolution_, frame_id);
01025 poses.insert(poses.end(), some_poses.begin(), some_poses.end());
01026 planner_grasp_types_.insert(planner_grasp_types_.end(), some_poses.size(), ind*2+1);
01027 }
01028
01029
01030 for(int ind=0; ind<3; ind++)
01031 {
01032 some_poses = generateRotatedPoses(pose, axes[ind], 0, alternatives_search_angle_, alternatives_search_angle_resolution_, frame_id);
01033 poses.insert(poses.end(), some_poses.begin(), some_poses.end());
01034 planner_grasp_types_.insert(planner_grasp_types_.end(), some_poses.size(), ind*2+6);
01035 some_poses = generateRotatedPoses(pose, axes[ind], -alternatives_search_angle_, 0, alternatives_search_angle_resolution_, frame_id);
01036 poses.insert(poses.end(), some_poses.begin(), some_poses.end());
01037 planner_grasp_types_.insert(planner_grasp_types_.end(), some_poses.size(), ind*2+7);
01038 }
01039
01040
01041 for(size_t i=0; i<poses.size(); i++)
01042 {
01043 planner_poses_.push_back(toWrist(poses[i]));
01044 planner_states_.push_back(UNTESTED);
01045 }
01046
01047
01048 planner_poses_.push_back(gripper_pose_);
01049 planner_states_.push_back(UNTESTED);
01050 planner_grasp_types_.push_back(-1);
01051
01052 button_marker_pose_ = gripper_pose_;
01053 button_marker_pose_.header.stamp = ros::Time(0);
01054 button_marker_pose_.pose.orientation = geometry_msgs::Quaternion();
01055 button_marker_pose_.pose.orientation.w = 1;
01056 button_marker_pose_.pose.position.z -= 0.2;
01057
01058
01059 testing_planned_grasp_ = true;
01060 testing_alternatives_ = true;
01061 tested_grasp_index_ = 0;
01062 testing_current_grasp_ = false;
01063
01064 testPoses(planner_poses_, gripper_opening_);
01065 }
01066
01068 void gripperClickCB( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback )
01069 {
01070
01071 if(interface_number_ != 0 || !gripper_opening_cycling_) return;
01072
01073 ros::Time now = ros::Time(0);
01074
01075 switch ( feedback->event_type )
01076 {
01077 case visualization_msgs::InteractiveMarkerFeedback::BUTTON_CLICK:
01078
01079 float max_gripper_angle = 0.541;
01080 gripper_angle_ -= 0.12;
01081 if(gripper_angle_ < 0.04)
01082 gripper_angle_ = max_gripper_angle;
01083 updateGripperOpening();
01084 initGripperMarker();
01085 ROS_DEBUG( "Gripper opening = %.2f, angle = %.2f", gripper_opening_, gripper_angle_);
01086 break;
01087 }
01088 }
01089
01091 void testPose(geometry_msgs::PoseStamped pose, float opening)
01092 {
01093 eraseAllGraspMarkers();
01094 pr2_object_manipulation_msgs::TestGripperPoseGoal goal;
01095 goal.gripper_poses.push_back(pose);
01096 goal.gripper_openings.push_back(opening);
01097 test_pose_client_.client().sendGoal( goal, boost::bind(&GripperPoseAction::testGripperResultCallback, this, _1, _2));
01098 }
01099
01101 void testPoses(std::vector<geometry_msgs::PoseStamped> poses, float opening)
01102 {
01103
01104 pr2_object_manipulation_msgs::TestGripperPoseGoal goal;
01105 for(size_t i=0; i<poses.size(); i++){
01106 goal.gripper_poses.push_back(poses[i]);
01107 goal.gripper_openings.push_back(opening);
01108 }
01109 test_pose_client_.client().sendGoal( goal, boost::bind(&GripperPoseAction::testGripperResultCallback, this, _1, _2));
01110 }
01111
01113 void updateGripper( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback )
01114 {
01115 ros::Time now = ros::Time(0);
01116
01117 switch ( feedback->event_type )
01118 {
01119 case visualization_msgs::InteractiveMarkerFeedback::MOUSE_DOWN:
01120 ROS_DEBUG_STREAM( "Marker is being moved, stored pose is invalidated." );
01121 test_pose_client_.client().cancelAllGoals();
01122 pose_state_ = UNTESTED;
01123 eraseAllGraspMarkers();
01124 break;
01125 case visualization_msgs::InteractiveMarkerFeedback::MOUSE_UP:
01126 ROS_DEBUG_STREAM( "Marker was released, storing pose and checking." );
01127 gripper_pose_.pose = feedback->pose;
01128 gripper_pose_.header = feedback->header;
01129 gripper_pose_ = toWrist(gripper_pose_);
01130 initMarkers();
01131 testing_planned_grasp_ = false;
01132 testing_alternatives_ = false;
01133 testing_current_grasp_ = true;
01134 testPose(gripper_pose_, gripper_opening_);
01135 break;
01136 case visualization_msgs::InteractiveMarkerFeedback::POSE_UPDATE:
01137 ROS_DEBUG_STREAM("POSE_UPDATE in frame " << feedback->header.frame_id << std::endl << feedback->pose);
01138 gripper_pose_.pose = feedback->pose;
01139 gripper_pose_.header = feedback->header;
01140 gripper_pose_ = toWrist(gripper_pose_);
01141 updatePoses();
01142 break;
01143 }
01144 }
01145
01147 void initMenus()
01148 {
01149 accept_handle_ = menu_gripper_.insert("Accept", boost::bind( &GripperPoseAction::acceptCB, this ) );
01150 cancel_handle_ = menu_gripper_.insert("Cancel", boost::bind( &GripperPoseAction::cancelCB, this ) );
01151 focus_handle_ = menu_gripper_.insert("Focus camera", boost::bind( &GripperPoseAction::focusCB, this ) );
01152 alternatives_handle_ = menu_gripper_.insert("Find alternatives", boost::bind( &GripperPoseAction::alternativesCB, this ) );
01153 if(interface_number_ == 0 || interface_number_ == 4)
01154 {
01155 menu_gripper_.insert("Run Grasp Planner", boost::bind( &GripperPoseAction::graspPlanCB, this ) );
01156 }
01157 }
01158
01160 bool getModelMesh( int model_id, arm_navigation_msgs::Shape& mesh )
01161 {
01162 household_objects_database_msgs::GetModelMesh mesh_srv;
01163
01164 mesh_srv.request.model_id = model_id;
01165 if ( !get_model_mesh_client_.call(mesh_srv) )
01166 {
01167 ROS_ERROR("Failed to call get model mesh service");
01168 return false;
01169 }
01170
01171 if (mesh_srv.response.return_code.code != household_objects_database_msgs::DatabaseReturnCode::SUCCESS)
01172 {
01173 ROS_ERROR("Model mesh service reports an error (code %d)", mesh_srv.response.return_code.code);
01174 return false;
01175 }
01176
01177 mesh = mesh_srv.response.mesh;
01178 return true;
01179 }
01180
01181
01182
01184 visualization_msgs::InteractiveMarker makeCloudMarker( const char *name, const geometry_msgs::PoseStamped &stamped,
01185 float point_size, std_msgs::ColorRGBA color)
01186 {
01187 InteractiveMarker int_marker;
01188 int_marker.name = name;
01189 int_marker.pose = stamped.pose;
01190 int_marker.header = stamped.header;
01191
01192 Marker marker;
01193 marker.color = color;
01194 marker.frame_locked = false;
01195
01196 if(object_cloud_->points.size())
01197 {
01198
01199 marker.scale.x = point_size;
01200 marker.scale.y = point_size;
01201 marker.scale.z = point_size;
01202 marker.type = visualization_msgs::Marker::SPHERE_LIST;
01203
01204 int num_points = object_cloud_->points.size();
01205 marker.points.resize( num_points );
01206 marker.colors.resize( num_points );
01207
01208
01209
01210 for ( int i=0; i<num_points; i++)
01211 {
01212 marker.points[i].x = object_cloud_->points[i].x;
01213 marker.points[i].y = object_cloud_->points[i].y;
01214 marker.points[i].z = object_cloud_->points[i].z;
01215 marker.colors[i].r = object_cloud_->points[i].r/255.;
01216 marker.colors[i].g = object_cloud_->points[i].g/255.;
01217 marker.colors[i].b = object_cloud_->points[i].b/255.;
01218 marker.colors[i].a = 1.0;
01219 }
01220 }
01221 else
01222 {
01223
01224 }
01225
01226 InteractiveMarkerControl control;
01227 control.always_visible = true;
01228 control.interaction_mode = visualization_msgs::InteractiveMarkerControl::BUTTON;
01229 control.orientation_mode = visualization_msgs::InteractiveMarkerControl::INHERIT;
01230
01231 control.markers.push_back( marker );
01232
01233 int_marker.controls.push_back( control );
01234
01235 return int_marker;
01236 }
01237
01238 };
01239
01240
01241 int main(int argc, char** argv)
01242 {
01243 ros::init(argc, argv, "pr2_interactive_pose_select_action");
01244 GripperPoseAction gripper_pose_action;
01245
01246 ros::Duration(1.0).sleep();
01247
01248 ros::spin();
01249 }