pr2_interactive_nav_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 
00050 #include <pr2_object_manipulation_msgs/GetNavPoseAction.h>
00051 #include <pr2_object_manipulation_msgs/CameraFocus.h>
00052 
00053 #include <sensor_msgs/point_cloud_conversion.h>
00054 
00055 #include "eigen_conversions/eigen_msg.h"
00056 
00057 #include "eigen3/Eigen/Geometry"
00058 #include "pcl/io/pcd_io.h"
00059 #include "pcl/point_types.h"
00060 #include "pcl_ros/transforms.h"
00061 
00062 #include <interactive_marker_helpers/interactive_marker_helpers.h>
00063 
00064 #include <geometry_msgs/PointStamped.h>
00065 #include <geometry_msgs/PoseStamped.h>
00066 
00067 
00068 using namespace object_manipulator;
00069 using namespace visualization_msgs;
00070 using namespace interactive_markers;
00071 using namespace pr2_object_manipulation_msgs;
00072 using namespace im_helpers;
00073 
00075 
00076 
00079 class BasePoseAction
00080 {
00081 protected:
00082 
00083   // ****************** class members *********************
00084 
00085   geometry_msgs::PoseStamped base_pose_;
00086   geometry_msgs::PoseStamped control_offset_;
00087 
00088   bool active_;
00089 
00090   int interface_number_;
00091   int task_number_;
00092 
00093   bool testing_planned_grasp_;
00094   int tested_grasp_index_;
00095   bool testing_current_grasp_;
00096   double max_direct_move_radius_;
00097 
00098   ros::NodeHandle nh_;
00099   ros::NodeHandle pnh_;
00100   ros::Subscriber sub_seed_pose_;
00101   ros::Subscriber sub_seed_point_;
00102 
00103   ros::Timer fast_update_timer_;
00104   ros::Timer slow_update_timer_;
00105   InteractiveMarkerServer server_;
00106 
00107   ros::Publisher pub_focus_;
00108 
00109   MenuHandler menu_controls_;
00110   MenuHandler::EntryHandle accept_handle_;
00111   MenuHandler::EntryHandle cancel_handle_;
00112   MenuHandler::EntryHandle focus_handle_;
00113 
00114   tf::TransformListener tfl_;
00115 
00116   object_manipulator::MechanismInterface mechanism_;
00117 
00118   std::string get_pose_name_;
00119   actionlib::SimpleActionServer<pr2_object_manipulation_msgs::GetNavPoseAction> get_pose_server_;
00120 
00121 public:
00122 
00123   BasePoseAction() :
00124       active_(false),
00125       max_direct_move_radius_(10.0),
00126       nh_("/"),
00127       pnh_("~"),
00128       server_(ros::names::resolve("pr2_nav_marker_control"), "nav_action", false),
00129       tfl_(nh_),
00130       get_pose_name_(ros::this_node::getName()),
00131       get_pose_server_(nh_, get_pose_name_, false)
00132   {
00133     ROS_INFO( "pr2_interactive_base_pose_action is starting up." );
00134 
00135     ros::Duration(1.0).sleep();
00136 
00137     nh_.param<int>("interactive_grasping/interface_number", interface_number_, 0);
00138     if (!interface_number_) ROS_WARN("No interface number specified for grasping study; using default configuration");
00139     else ROS_INFO("Using interface number %d for grasping study", interface_number_);
00140     nh_.param<int>("interactive_grasping/task_number", task_number_, 0);
00141     if (!task_number_) ROS_WARN("No task number specified for grasping study; using default configuration");
00142     else ROS_INFO("Using task number %d for grasping study", task_number_);
00143 
00144     //nh_.param<double>("max_direct_move_radius", max_direct_move_radius_, 0.4);
00145 
00146     // Dummy box to avoid empty_server bug...
00147     geometry_msgs::PoseStamped ps;
00148     ps.header.frame_id = "base_link";
00149     server_.insert(makeButtonBox( "test_box", ps, 0.01, false, false));
00150 
00151     pub_focus_ = nh_.advertise<pr2_object_manipulation_msgs::CameraFocus>("camera_focus", 1);
00152 
00153     fast_update_timer_ =  nh_.createTimer(ros::Duration(0.05), boost::bind( &BasePoseAction::fast_update, this ) );
00154 
00155     sub_seed_pose_ = nh_.subscribe<geometry_msgs::PoseStamped>("/cloud_click_point", 1, boost::bind(&BasePoseAction::setSeedPoseCallback, this, _1));
00156     sub_seed_point_ = nh_.subscribe<geometry_msgs::PointStamped>("/rviz/navigate_to", 1, boost::bind(&BasePoseAction::setSeedPointCallback, this, _1));
00157 
00158     // Initialization must happen at the end!
00159     initMenus();
00160 
00161     //register the goal and feeback callbacks
00162     get_pose_server_.registerGoalCallback(    boost::bind(&BasePoseAction::goalCB, this));
00163     get_pose_server_.registerPreemptCallback( boost::bind(&BasePoseAction::preemptCB, this));
00164 
00165     get_pose_server_.start();
00166   }
00167 
00168   ~BasePoseAction()
00169   {
00170   }
00171 
00172   void setSeedPoseCallback(const geometry_msgs::PoseStampedConstPtr &seedPose)
00173   {
00174     if(!active_) return;
00175     ROS_DEBUG("Setting seed.");
00176     base_pose_ = *seedPose;
00177     base_pose_.pose.orientation = geometry_msgs::Quaternion();
00178 
00179     updateSeed();
00180   }
00181   
00182   void setSeedPointCallback(const geometry_msgs::PointStampedConstPtr &seedPoint)
00183   {
00184     if(!active_) return;
00185     ROS_DEBUG("Setting seed point.");
00186     base_pose_.pose.position= seedPoint->point;
00187     base_pose_.pose.orientation = geometry_msgs::Quaternion();
00188 
00189     updateSeed();
00190   }
00191 
00192   void updateSeed()
00193   {
00194     initMarkers();
00195   }
00196 
00197   
00198 
00200   void setIdle(){
00201     active_ = false;
00202     server_.clear();
00203   }
00204 
00205 
00207   void goalCB()
00208   {
00209     active_ = true;
00210     ROS_INFO("pr2_interactive_nav_action_called!");
00211     pr2_object_manipulation_msgs::GetNavPoseGoal goal = *get_pose_server_.acceptNewGoal();
00212 
00213     if (goal.starting_pose.pose.orientation.x == 0 &&
00214         goal.starting_pose.pose.orientation.y == 0 &&
00215         goal.starting_pose.pose.orientation.z == 0 &&
00216         goal.starting_pose.pose.orientation.w == 0 )
00217     {
00218       ROS_DEBUG("Empty pose passed in; using default");
00219       base_pose_ = getDefaultPose();
00220     }
00221     else
00222     {
00223       base_pose_ = goal.starting_pose;
00224     }
00225 
00226     if (get_pose_server_.isPreemptRequested())
00227     {
00228       preemptCB();
00229       return;
00230     }
00231     if(goal.max_distance > 0)
00232         max_direct_move_radius_ = goal.max_distance;
00233     else
00234         max_direct_move_radius_ = 1E6;
00235 
00236     initMarkers();
00237   }
00238 
00239 
00241   void preemptCB()
00242   {
00243     ROS_INFO("%s: Preempted", get_pose_name_.c_str());
00244     //test_pose_client_.client().cancelAllGoals();
00245     get_pose_server_.setPreempted();
00246     setIdle();
00247   }
00248 
00251   void updatePoses()
00252   {
00253     server_.setPose("meshes", base_pose_.pose, base_pose_.header);
00254   }
00255 
00256   geometry_msgs::PoseStamped getDefaultPose()
00257   {
00258     geometry_msgs::PoseStamped ps;
00259     ps.header.stamp = ros::Time(0);
00260     ps.header.frame_id = "base_link";
00261     ps.pose.orientation.w = 1;
00262     return ps;
00263   }
00264 
00265 
00266 // **** 10 ***** 20 ****** 30 ****** 40 ****** 50 ****** 60 ****** 70 ****** 80 ****** 90 ***** 100 ***** 110 ***** 120
00267 
00270   void initMarkers()
00271   {
00272     initMeshMarkers();
00273     initControlMarkers();
00274   }
00275 
00276   void initMeshMarkers()
00277   {
00278   }
00279 
00280   void initControlMarkers()
00281   {
00282     geometry_msgs::PoseStamped ps = base_pose_;
00283     ps.header.stamp = ros::Time(0);
00284 
00285     //ROS_ERROR("Populating meshes...");
00286 
00287     // TODO this should absolutely be read from some parameter
00288     std::vector< std::string > mesh_paths, mesh_frames;
00289     mesh_paths.push_back("package://pr2_description/meshes/base_v0/base.dae");
00290     mesh_frames.push_back("base_link");
00291     mesh_paths.push_back("package://pr2_description/meshes/torso_v0/torso_lift.dae");
00292     mesh_frames.push_back("torso_lift_link");
00293     mesh_paths.push_back("package://pr2_description/meshes/shoulder_v0/shoulder_pan.dae");
00294     mesh_frames.push_back("r_shoulder_pan_link");
00295     mesh_paths.push_back("package://pr2_description/meshes/shoulder_v0/shoulder_pan.dae");
00296     mesh_frames.push_back("l_shoulder_pan_link");
00297     mesh_paths.push_back("package://pr2_description/meshes/shoulder_v0/shoulder_lift.dae");
00298     mesh_frames.push_back("r_shoulder_lift_link");
00299     mesh_paths.push_back("package://pr2_description/meshes/shoulder_v0/shoulder_lift.dae");
00300     mesh_frames.push_back("l_shoulder_lift_link");
00301     mesh_paths.push_back("package://pr2_description/meshes/upper_arm_v0/upper_arm.dae");
00302     mesh_frames.push_back("r_upper_arm_link");
00303     mesh_paths.push_back("package://pr2_description/meshes/upper_arm_v0/upper_arm.dae");
00304     mesh_frames.push_back("l_upper_arm_link");
00305     mesh_paths.push_back("package://pr2_description/meshes/forearm_v0/forearm.dae");
00306     mesh_frames.push_back("r_forearm_link");
00307     mesh_paths.push_back("package://pr2_description/meshes/forearm_v0/forearm.dae");
00308     mesh_frames.push_back("l_forearm_link");
00309 
00310     // Right Gripper
00311     mesh_paths.push_back("package://pr2_description/meshes/gripper_v0/gripper_palm.dae");
00312     mesh_frames.push_back("r_gripper_palm_link");
00313     mesh_paths.push_back("package://pr2_description/meshes/gripper_v0/upper_finger_r.stl");
00314     mesh_frames.push_back("r_gripper_r_finger_link");
00315     mesh_paths.push_back("package://pr2_description/meshes/gripper_v0/upper_finger_l.stl");
00316     mesh_frames.push_back("r_gripper_l_finger_link");
00317     mesh_paths.push_back("package://pr2_description/meshes/gripper_v0/finger_tip_r.stl");
00318     mesh_frames.push_back("r_gripper_r_finger_tip_link");
00319     mesh_paths.push_back("package://pr2_description/meshes/gripper_v0/finger_tip_l.stl");
00320     mesh_frames.push_back("r_gripper_l_finger_tip_link");
00321 
00322 
00323     // Left Gripper
00324     mesh_paths.push_back("package://pr2_description/meshes/gripper_v0/gripper_palm.dae");
00325     mesh_frames.push_back("l_gripper_palm_link");
00326     mesh_paths.push_back("package://pr2_description/meshes/gripper_v0/upper_finger_r.stl");
00327     mesh_frames.push_back("l_gripper_r_finger_link");
00328     mesh_paths.push_back("package://pr2_description/meshes/gripper_v0/upper_finger_l.stl");
00329     mesh_frames.push_back("l_gripper_l_finger_link");
00330     mesh_paths.push_back("package://pr2_description/meshes/gripper_v0/finger_tip_r.stl");
00331     mesh_frames.push_back("l_gripper_r_finger_tip_link");
00332     mesh_paths.push_back("package://pr2_description/meshes/gripper_v0/finger_tip_l.stl");
00333     mesh_frames.push_back("l_gripper_l_finger_tip_link");
00334 
00335     // Head
00336     mesh_paths.push_back("package://pr2_description/meshes/head_v0/head_pan.dae");
00337     mesh_frames.push_back("head_pan_link");
00338     mesh_paths.push_back("package://pr2_description/meshes/head_v0/head_tilt.dae");
00339     mesh_frames.push_back("head_tilt_link");
00340 
00341 
00342     if(mesh_paths.size() != mesh_frames.size()) ROS_ERROR("The number of mesh paths and mesh frame_ids is not equal!");
00343 
00344     std::vector< geometry_msgs::PoseStamped > mesh_poses;
00345     for(size_t i = 0; i < mesh_paths.size(); i++)
00346     {
00347         geometry_msgs::PoseStamped ps;
00348         ps.header.stamp = ros::Time(0);
00349         ps.header.frame_id = mesh_frames[i];
00350         ps.pose.orientation.w = 1;
00351         tfl_.waitForTransform("base_link", ps.header.frame_id, ps.header.stamp,ros::Duration(3.0));
00352         try
00353         {
00354           tfl_.transformPose("base_link", ps, ps);
00355         }
00356         catch (tf::TransformException ex)
00357         {
00358           ROS_ERROR("pr2_interactive_nav_action: failed to transform from %s to base_link!  Skipping mesh part", ps.header.frame_id.c_str());
00359           continue;
00360         }
00361         mesh_poses.push_back(ps);
00362     }
00363 
00364     server_.insert(makePosedMultiMeshMarker( "pose_controls", ps, mesh_poses, mesh_paths, 1.03, false),
00365                    boost::bind( &BasePoseAction::poseControlCB, this, _1));
00366     menu_controls_.apply(server_, "pose_controls");
00367   }
00368 
00369 
00370 protected:
00371 
00372 
00374   void fast_update()
00375   {
00376     //updatePoses();
00377     server_.applyChanges();
00378   }
00379 
00380   void slow_update()
00381   {
00382   }
00383 
00384 
00386   void acceptCB()
00387   {
00388     setIdle();
00389     pr2_object_manipulation_msgs::GetNavPoseResult result;
00390     base_pose_.header.stamp = ros::Time::now();
00391     result.pose = base_pose_;
00392     get_pose_server_.setSucceeded(result);
00393   }
00394 
00396   void cancelCB()
00397   {
00398     get_pose_server_.setAborted();
00399     setIdle();
00400   }
00401 
00403   void focusCB()
00404   {
00405     pr2_object_manipulation_msgs::CameraFocus msg;
00406     msg.focal_point.point = base_pose_.pose.position;
00407     msg.focal_point.header = base_pose_.header;
00408     pub_focus_.publish(msg);
00409   }
00410 
00412   void poseMeshCB( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback )
00413   {
00414   }
00415 
00416   geometry_msgs::PoseStamped clipToRadius(const geometry_msgs::PoseStamped &input, const float &radius)
00417   {
00418       geometry_msgs::PoseStamped ps;
00419       try
00420       {
00421         tfl_.waitForTransform(input.header.frame_id, "base_link", input.header.stamp, ros::Duration(5.0));
00422         tfl_.transformPose("base_link", input, ps);
00423         tf::Vector3 pose_center;
00424         tf::pointMsgToTF(ps.pose.position, pose_center);
00425         float stored_z = pose_center.z();
00426         pose_center.setZ(0);
00427         float length = pose_center.length();
00428         if(length > radius)
00429         {
00430           pose_center = radius / length * pose_center;
00431           pose_center.setZ(stored_z);
00432           tf::pointTFToMsg(pose_center, ps.pose.position);
00433         }
00434         ps.header.stamp = ros::Time(0);
00435         if( tfl_.canTransform("map", ps.header.frame_id, ros::Time(0)))
00436         {
00437           tfl_.transformPose("map", ps, ps);
00438         }
00439         else if( tfl_.canTransform("odom_combined", ps.header.frame_id, ros::Time(0)))
00440         {
00441           tfl_.transformPose("odom_combined", ps, ps);
00442         }
00443         else if( tfl_.canTransform(input.header.frame_id, ps.header.frame_id, ros::Time(0)))
00444         {
00445           tfl_.transformPose(input.header.frame_id, ps, ps);
00446         }
00447         else
00448         {
00449           ROS_ERROR("TF could not transform from map, odom_combined, or %s to %s!!  clipToRadius failed\n", input.header.frame_id.c_str(), ps.header.frame_id.c_str());
00450         }
00451       }
00452       catch (tf::TransformException ex)
00453       {
00454         ROS_ERROR("pr2_interactive_nav_action: failed to transform from %s to base_link!", input.header.frame_id.c_str());
00455       }
00456       return ps;
00457   }
00458 
00460   void poseControlCB( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback )
00461   {
00462     ros::Time now = ros::Time(0);
00463 
00464     switch ( feedback->event_type )
00465     {
00466     case visualization_msgs::InteractiveMarkerFeedback::MOUSE_DOWN:
00467         break;
00468     case visualization_msgs::InteractiveMarkerFeedback::MOUSE_UP:
00469         base_pose_.pose = feedback->pose;
00470         base_pose_.header = feedback->header;
00471         ROS_DEBUG_STREAM("MOUSE_UP base_pose before clipping is\n" << base_pose_);
00472         base_pose_ = clipToRadius(base_pose_, max_direct_move_radius_);
00473         ROS_DEBUG_STREAM("MOUSE_UP base_pose after clipping is\n" << base_pose_);
00474         initMarkers();
00475         break;
00476     case visualization_msgs::InteractiveMarkerFeedback::POSE_UPDATE:
00477         ROS_DEBUG_STREAM("POSE_UPDATE in frame " << feedback->header.frame_id << std::endl << feedback->pose);
00478         base_pose_.pose = feedback->pose;
00479         base_pose_.header = feedback->header;
00480         updatePoses();
00481         break;
00482     }
00483   }
00484 
00486   void initMenus()
00487   {
00488     accept_handle_ = menu_controls_.insert("Accept", boost::bind( &BasePoseAction::acceptCB, this ) );
00489     cancel_handle_ = menu_controls_.insert("Cancel", boost::bind( &BasePoseAction::cancelCB, this ) );
00490     focus_handle_ = menu_controls_.insert("Focus camera", boost::bind( &BasePoseAction::focusCB, this ) );
00491   }
00492 };
00493 
00494 int main(int argc, char** argv)
00495 {
00496   ros::init(argc, argv, "pr2_interactive_pose_select_action");
00497   BasePoseAction base_pose_action;
00498 
00499   ros::Duration(1.0).sleep();
00500 
00501   ros::spin();
00502 }


pr2_interactive_gripper_pose_action
Author(s): Adam Leeper
autogenerated on Mon Oct 6 2014 12:40:33