pr2_interactive_gripper_pose_action.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2011, Willow Garage, Inc.
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions are met:
00007  *
00008  *     * Redistributions of source code must retain the above copyright
00009  *       notice, this list of conditions and the following disclaimer.
00010  *     * Redistributions in binary form must reproduce the above copyright
00011  *       notice, this list of conditions and the following disclaimer in the
00012  *       documentation and/or other materials provided with the distribution.
00013  *     * Neither the name of the Willow Garage, Inc. nor the names of its
00014  *       contributors may be used to endorse or promote products derived from
00015  *       this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00018  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00021  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00022  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00023  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00024  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00025  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00026  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00027  * POSSIBILITY OF SUCH DAMAGE.
00028  */
00029 
00030 // author: Adam Leeper
00031 
00032 // **** 10 ***** 20 ****** 30 ****** 40 ****** 50 ****** 60 ****** 70 ****** 80 ****** 90 ***** 100 ***** 110 ***** 120
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   // ****************** class members *********************
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     // Dummy box to avoid empty_server bug...
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     // Initialization must happen at the end!
00211     initMenus();
00212     //initMarkers();
00213     
00214     //register the goal and feeback callbacks
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   /*  try{
00228       tfl_.waitForTransform(frame_id, gripper_pose_.header.frame_id, gripper_pose_.header.stamp, ros::Duration(3.0));
00229       tfl_.transformPose(frame_id, gripper_pose_, gripper_pose_);
00230       return true;
00231     }
00232     catch(...){
00233       ROS_ERROR("TF can't transform!");
00234       return false;
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     //tf::quaternionTFToMsg(q, ps.pose.orientation);
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     //ps.header = seed->header;
00271     //ROS_INFO_STREAM("Processed seed before wrist offset was \n" << ps);
00272 
00273     gripper_pose_ = toWrist(ps);
00274     //ROS_INFO_STREAM("Processed seed was \n" << gripper_pose_);
00275     //transformGripperPose();
00276     //ROS_DEBUG_STREAM("But after transforming it is \n" << gripper_pose_);
00277     //ROS_INFO_STREAM("ansforming it is \n" << gripper_pose_);
00278     //transformGripperPose();
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     //focus the camera on the new pose
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     //check if we want to call the planner, find alternatives, or show invalid grasps now
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       // Something to draw...
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         // Try to use object model, if there is one
00349         if(!use_cloud)
00350         {
00351           ROS_INFO("Goal contains object model; looking for model mesh...");
00352           // Connect to databse, get object mesh.
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           // Store point cloud
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       //ROS_DEBUG_STREAM("Default was \n" << gripper_pose_);
00430       //transformGripperPose();
00431       //ROS_DEBUG_STREAM("Default after transform is\n" << gripper_pose_);
00432       gripper_opening_ = 0.086;
00433       updateGripperAngle();
00434     }
00435     else
00436     {
00437       gripper_pose_ = goal.gripper_pose;
00438       //transformGripperPose();
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     //out.pose = object_manipulator::msg::applyShift(ps.pose, tf::Vector3(-0.15,0,0));
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     //out.pose = object_manipulator::msg::applyShift(ps.pose, tf::Vector3(-0.15,0,0));
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 // **** 10 ***** 20 ****** 30 ****** 40 ****** 50 ****** 60 ****** 70 ****** 80 ****** 90 ***** 100 ***** 110 ***** 120
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       // create arrow marker
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       // TODO figure out how to delete stuff gracefully
00553     }
00554   }
00555 
00556   void eraseAllGraspMarkers()
00557   {
00558     for(unsigned int i = 0; i < planner_poses_.size(); i++)
00559     {
00560       // delete
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     int start_ind = planner_index_+1;
00578     for(unsigned int i = 0; i < planner_poses_.size(); i++)
00579     {
00580       if(start_ind + (int)i >= (int)planner_poses_.size() ) start_ind = -i;
00581       if(planner_states_[ start_ind + i ] == VALID || show_invalid_grasps_)
00582       {
00583         selectGraspIndex( start_ind + i );
00584         break;
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     int total = 0;
00622     for(unsigned int i = 0; i < planner_poses_.size(); i++)
00623     {
00624       if(planner_states_[i] != VALID && !show_invalid_grasps_) continue;
00625       total++;
00626       if((int)i <= planner_index_) num++;
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     //updatePoses();
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             //fill in planner_states_ with whether the grasps were VALID or INVALID
00713             for (size_t i=0; i<result->valid.size(); i++)
00714             {
00715               PoseState pose_state = INVALID;
00716 
00717               //valid grasp
00718               if (result->valid[i])
00719               {
00720                 pose_state = VALID;                 
00721 
00722                 //only show the first feasible grasp in each direction if we're testing alternatives
00723                 if (testing_alternatives_){
00724                   if(planner_grasp_types_[i] == dim_index)
00725                   {
00726                     //found the first good grasp along the first direction
00727                     if(!dim_grasp_found)
00728                     {
00729                       dim_grasp_found = true;
00730                     }
00731 
00732                     //ignoring all other grasps along this direction
00733                     else pose_state = UNTESTED;
00734                   }
00735 
00736                   //found the first good grasp along this direction
00737                   else
00738                   {
00739                     dim_index = planner_grasp_types_[i];
00740                     dim_grasp_found = true;
00741                   }
00742                 }
00743               }
00744 
00745               //invalid grasp
00746               else
00747               {
00748                 if(testing_alternatives_)
00749                 {
00750                   //don't show invalid alternatives-grasps, even if show_invalid_grasps is true
00751                   pose_state = UNTESTED;
00752 
00753                   //moving onto the next direction to search, haven't found a good grasp yet
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               //grasp is valid or we're showing invalid grasps, add it to the list
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             //erase all current grasp markers
00768             eraseAllGraspMarkers();
00769 
00770             //copy the temporary lists into the real ones            
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             //create the grasp markers
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         //create the button marker for switching grasps
00789         if(planner_poses_.size() > 1 || testing_alternatives_) initButtonMarker();
00790       }
00791 
00792       //just testing the one grasp
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         //if we want to always find alternatives, do so if the grasp is invalid
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     //pub_cloud_.publish(plan_goal.target.region.cloud);
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     //initButtonMarker();
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     //planning succeeded, send the results for feasibility testing
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     //planning failed, just check the original seed pose in gripper_pose_
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       //initButtonMarker();
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     //tf::Quaternion q = pose.getRotation();
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     //tf::Quaternion q = pose.getRotation();
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     //generate a bunch of poses to test in all directions around gripper_pose_
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     //generate shifted poses in all directions
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     //generated rotated poses around all axes
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     //switch back to wrist frame
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     //add gripper_pose_
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     //test the generated poses
01059     testing_planned_grasp_ = true;
01060     testing_alternatives_ = true;
01061     tested_grasp_index_ = 0;
01062     testing_current_grasp_ = false;
01063     //initGraspMarkers();
01064     testPoses(planner_poses_, gripper_opening_);    
01065   } 
01066 
01068   void gripperClickCB( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback )
01069   {
01070     //disabled for user studies or if the param is set
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         //ROS_DEBUG_STREAM( "Marker is being moved, stored pose is invalidated." );
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     //eraseAllGraspMarkers();
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       //int_marker.header = object_cloud_->header;
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       //ROS_INFO_STREAM( "Adding point cluster. #points=" << object_.cluster.points.size() );
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 }


pr2_interactive_gripper_pose_action
Author(s): Adam Leeper
autogenerated on Fri Jan 3 2014 12:05:16