marker_control.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 "pr2_marker_control/generate_robot_model.h"
00035 
00036 #include <ros/ros.h>
00037 #include <math.h>
00038 
00039 #include <arm_navigation_msgs/GetStateValidity.h>
00040 
00041 #include <interactive_markers/interactive_marker_server.h>
00042 #include <interactive_markers/menu_handler.h>
00043 
00044 #include <std_srvs/Empty.h>
00045 
00046 #include <actionlib/client/simple_action_client.h>
00047 #include <actionlib/server/simple_action_server.h>
00048    
00049 #include <boost/thread.hpp>
00050 
00051 #include <tf/transform_listener.h>
00052 
00053 #include <interactive_marker_helpers/interactive_marker_helpers.h>
00054 #include <pr2_object_manipulation_msgs/GetNavPoseAction.h>
00055 #include <pr2_marker_control/cloud_handler.h>
00056 #include <pr2_marker_control/marker_control.h>
00057 
00058 using namespace object_manipulator;
00059 using namespace visualization_msgs;
00060 using namespace interactive_markers;
00061 using namespace im_helpers;
00062 
00064 
00065 // First define a useful helper function...
00070 void offsetPS(tf::StampedTransform &st, const tf::Transform &offset)
00071 {
00072   tf::Transform pose = tf::Transform(st.getRotation(), st.getOrigin());
00073   pose = pose * offset;
00074   st.setData(pose);
00075 }
00076 
00078 geometry_msgs::PoseStamped PR2MarkerControl::toolToWrist(const geometry_msgs::PoseStamped &ps)
00079 {
00080   geometry_msgs::PoseStamped out;
00081   out.header = ps.header;
00082   tf::Transform T, P;
00083   tf::poseMsgToTF(ps.pose, P);
00084   tf::poseMsgToTF(tool_frame_offset_, T);
00085   tf::poseTFToMsg( P*T.inverse(), out.pose);
00086   //out.pose = object_manipulator::msg::applyShift(ps.pose, tf::Vector3(-0.15,0,0));
00087   return out;
00088 }
00089 
00091 geometry_msgs::PoseStamped PR2MarkerControl::wristToTool(const geometry_msgs::PoseStamped &ps)
00092 {
00093   geometry_msgs::PoseStamped out;
00094   out.header = ps.header;
00095   tf::Transform T, P;
00096   tf::poseMsgToTF(ps.pose, P);
00097   tf::poseMsgToTF(tool_frame_offset_, T);
00098   tf::poseTFToMsg( P*T, out.pose);
00099   //out.pose = object_manipulator::msg::applyShift(ps.pose, tf::Vector3(-0.15,0,0));
00100   return out;
00101 }
00102 
00103 // This is a convenience function (rather specific to this file) to get the arm name from one of several marker names.
00104 std::string getArmNameFromMarkerName(const std::string &name){
00105   std::string arm_name = "";
00106   if( name == "r_upper_arm_link" || name == "r_gripper_palm_link"
00107       || name == "r_gripper_l_finger_link" || name == "r_gripper_r_finger_link"
00108       || name == "r_gripper_l_finger_tip_link" || name == "r_gripper_r_finger_tip_link")
00109     arm_name = "right_arm";
00110   else if( name == "l_upper_arm_link" || name == "l_gripper_palm_link"
00111            || name == "l_gripper_l_finger_link" || name == "l_gripper_r_finger_link"
00112            || name == "l_gripper_l_finger_tip_link" || name == "l_gripper_r_finger_tip_link")
00113     arm_name = "left_arm";
00114   else
00115     ROS_WARN("Marker name [%s] not handled!", name.c_str());
00116 
00117   return arm_name;
00118 }
00119 
00121 
00122 
00123 PR2MarkerControl::PR2MarkerControl() :
00124   nh_("/"),
00125   pnh_("~"),
00126   server_(ros::names::resolve("pr2_marker_control"), "marker_control", false),
00127   tfl_(nh_),
00128   torso_client_(),
00129   base_client_(nh_, ros::Duration(2.0), &tfl_),
00130   tuck_arms_client_(nh_, ros::Duration(20.0)),
00131   plugs_client_(nh_, ros::Duration(90.0)),
00132   check_state_validity_client_("/current_state_validator/get_state_validity"),
00133   collider_node_reset_srv_("/collider_node/reset"),
00134   snapshot_client_(&nh_, &tfl_, "interactive_manipulation_snapshot", 
00135                    "interactive_point_cloud", "interactive_manipulation_snapshot_server", 
00136                    mechanism_, "odom_combined"),
00137   object_cloud_left_(&nh_, &tfl_, "in_hand_object_cloud_left", 
00138                      "in_hand_objects", "in_hand_object_server_left", 
00139                      mechanism_, "l_wrist_roll_link"),
00140   object_cloud_right_(&nh_, &tfl_, "in_hand_object_cloud_right", 
00141                       "in_hand_objects", "in_hand_object_server_right", 
00142                       mechanism_, "r_wrist_roll_link"),
00143   base_pose_client_("pr2_interactive_nav_action", true),
00144   gripper_pose_client_("pr2_interactive_gripper_pose_action", true),
00145   alignedOdomValid_(false),
00146   alignedOdomThread_( boost::bind( &PR2MarkerControl::publishAlignedOdom, this ) )
00147 {
00148   ROS_INFO( "-------------------------- Starting up PR2 MARKER CONTROL application. --------------------------------" );
00149 
00150   ros::Duration(2.0).sleep();
00151 
00152   pnh_.param<bool>("transparent", transparent_, false);
00153 
00154   pnh_.param<bool>("use_right_arm", use_right_arm_, true);
00155   pnh_.param<bool>("use_left_arm", use_left_arm_, true);
00156   pnh_.param<bool>("use_state_validator", use_state_validator_, true);
00157 
00158   pnh_.param<double>("gripper_control_linear_deadband",   gripper_control_linear_deadband_,  0.002);
00159   pnh_.param<double>("gripper_control_angular_deadband",  gripper_control_angular_deadband_, 0.01);
00160   pnh_.param<double>("update_period",  update_period_, 0.05);
00161   pnh_.param<double>("cartesian_clip_distance",  cartesian_clip_distance_, 2);
00162   pnh_.param<double>("cartesian_clip_angle",  cartesian_clip_angle_, 10);
00163   pnh_.param<std::string>("head_pointing_frame", head_pointing_frame_, "default_head_pointing_frame");
00164   pnh_.param<std::string>("move_base_node_name", move_base_node_name_, "move_base_node");
00165   pnh_.param<bool>("nav_3d", using_3d_nav_, false);
00166 
00167   pnh_.param<double>("max_direct_nav_radius",   max_direct_nav_radius_,  0.4);
00168 
00169   nh_.param<int>("interactive_grasping/interface_number", interface_number_, 0);
00170   if (interface_number_) ROS_INFO("Using interface number %d for grasping study", interface_number_);
00171   nh_.param<int>("interactive_grasping/task_number", task_number_, 0);
00172   if (task_number_) ROS_INFO("Using task number %d for grasping study", task_number_);
00173 
00174   pnh_.param<bool>("planar_only", control_state_.planar_only_, false);
00175   pnh_.param<std::string>("marker_frame", manipulator_base_frame_, "base_link");
00176 
00177   pnh_.param<std::string>("l_gripper_type", l_gripper_type_, "pr2");
00178   pnh_.param<std::string>("r_gripper_type", r_gripper_type_, "pr2");
00179 
00180   object_cloud_left_sub_ = nh_.subscribe("in_hand_object_left", 1,
00181                                          &PR2MarkerControl::inHandObjectLeftCallback, this);
00182   object_cloud_right_sub_ = nh_.subscribe("in_hand_object_right", 1,
00183                                           &PR2MarkerControl::inHandObjectRightCallback, this);
00184 
00185   ROS_INFO("***************************** %s *****************************", manipulator_base_frame_.c_str());
00186 
00187   if (interface_number_ == 1)
00188   {
00189     control_state_.r_gripper_.on_ = true;
00190     control_state_.posture_r_ = true;
00191     switchToCartesian();
00192   }
00193 
00194   in_collision_r_ = false;
00195   in_collision_l_ = false;
00196 
00197   control_state_.r_gripper_.torso_frame_ = true;
00198   control_state_.l_gripper_.torso_frame_ = true;
00199   control_state_.dual_grippers_.torso_frame_ = true;
00200    
00201   tf::Transform offset = tf::Transform(tf::Quaternion(0, 0, 0, 1), tf::Vector3(0.1, 0, 0));
00202   pose_offset_.push_back(offset);
00203   pose_offset_.push_back(offset);
00204 
00205   dual_gripper_offsets_.push_back(offset);
00206   dual_gripper_offsets_.push_back(offset);
00207 
00208   dual_pose_offset_ = tf::Transform(tf::Quaternion(0, 0, 0, 1), tf::Vector3(0, 0, 0));
00209 
00210   tool_frame_offset_ = msg::createPoseMsg(tf::Pose(tf::Quaternion::getIdentity(), tf::Vector3(0.18,0,0)));
00211 
00212   head_goal_pose_.pose.position.x = 1.0;
00213   head_goal_pose_.pose.position.z = 1.0;
00214   head_goal_pose_.header.frame_id = "base_link";
00215 
00216   base_goal_pose_.header.frame_id = "base_link";
00217   base_goal_pose_.pose.orientation.w = 1;
00218 
00219   // Must initialize the menus before creating the markers!
00220   initMenus();
00221 
00222   // Initialize (or hard "reset") of all markers.
00223   initAllMarkers();
00224 
00225   spin_timer_ =  nh_.createTimer(ros::Duration(update_period_), boost::bind( &PR2MarkerControl::fastUpdate, this ) );
00226   slow_sync_timer_ =  nh_.createTimer(ros::Duration(0.5), boost::bind( &PR2MarkerControl::slowUpdate, this ) );
00227 }
00228 
00229 
00230 void PR2MarkerControl::fastUpdate()
00231 {
00232   ros::Time now = ros::Time(0);
00233 
00234   tf::StampedTransform stamped;
00235   geometry_msgs::TransformStamped ts;
00236 
00237   if(control_state_.r_gripper_.on_)
00238   {
00239     geometry_msgs::PoseStamped ps;
00240     static geometry_msgs::PoseStamped last;
00241     tfl_.waitForTransform("r_wrist_roll_link", "base_link", now, ros::Duration(2.0));
00242     tfl_.lookupTransform("base_link", "r_wrist_roll_link", now, stamped);
00243     offsetPS(stamped, pose_offset_[0]);
00244     tf::transformStampedTFToMsg(stamped, ts);
00245     ps = object_manipulator::msg::createPoseStampedMsg(ts);
00246     ps.header.stamp = ros::Time(0);  // Time(0) makes this stay fixed in base_link
00247 
00248     double pos_dist = 0, angle = 0;
00249     mechanism_.poseDists(ps.pose, last.pose, pos_dist, angle);
00250     if(pos_dist > gripper_control_linear_deadband_ || angle > gripper_control_angular_deadband_)
00251     {
00252       server_.setPose("r_gripper_control", ps.pose, ps.header);
00253       last = ps;
00254     }
00255   }
00256   if(control_state_.l_gripper_.on_)
00257   {
00258     geometry_msgs::PoseStamped ps;
00259     static geometry_msgs::PoseStamped last;
00260     tfl_.waitForTransform("l_wrist_roll_link", manipulator_base_frame_, now, ros::Duration(2.0));
00261     tfl_.lookupTransform(manipulator_base_frame_, "l_wrist_roll_link", now, stamped);
00262     offsetPS(stamped, pose_offset_[1]);
00263     tf::transformStampedTFToMsg(stamped, ts);
00264     ps = object_manipulator::msg::createPoseStampedMsg(ts);
00265     ps.header.stamp = ros::Time(0); // Time(0) makes this stay fixed in base_link
00266 
00267     double pos_dist = 0, angle = 0;
00268     mechanism_.poseDists(ps.pose, last.pose, pos_dist, angle);
00269     if(pos_dist > gripper_control_linear_deadband_ || angle > gripper_control_angular_deadband_)
00270     {
00271       server_.setPose("l_gripper_control", ps.pose, ps.header);
00272       last = ps;
00273     }
00274   }
00275 
00276   server_.applyChanges();
00277 }
00278 
00279 void PR2MarkerControl::slowUpdate()
00280 {
00281   static bool last_r_cart, last_l_cart, last_move_base_active;
00282 
00283   bool r_cart = false, l_cart = false;
00284   bool init_mesh_markers = false, init_all_markers = false, init_control_markers = false;
00285 
00286 
00287   if(use_right_arm_)
00288   {
00289     r_cart = mechanism_.checkController("r_cart");
00290     if(! r_cart)
00291     {
00292       control_state_.r_gripper_.on_ = false;
00293       control_state_.posture_r_ = false;
00294       control_state_.dual_grippers_.on_ = false;
00295     }
00296     // It's much smoother if we don't do this!
00297     //if( r_cart && !control_state_.posture_r_ ) refreshPosture("right_arm");
00298     //if( r_cart ) refreshPosture("right_arm");
00299   }
00300   if(use_left_arm_)
00301   {
00302     l_cart = mechanism_.checkController("l_cart");
00303     if(! l_cart)
00304     {
00305       control_state_.l_gripper_.on_ = false;
00306       control_state_.posture_l_ = false;
00307       control_state_.dual_grippers_.on_ = false;
00308     }
00309     // It's much smoother if we don't do this!
00310     //if( l_cart && !control_state_.posture_l_ ) refreshPosture("left_arm");
00311     //if( l_cart ) refreshPosture("left_arm");
00312   }
00313 
00314 //  if( r_cart || l_cart )
00315 //  {
00316 //    if(joint_handle_)       menu_arms_.setCheckState(joint_handle_, MenuHandler::UNCHECKED);
00317 //    if(jtranspose_handle_)  menu_arms_.setCheckState(jtranspose_handle_, MenuHandler::CHECKED);
00318 //  }
00319 //  else
00320 //  {
00321 //    if(joint_handle_)       menu_arms_.setCheckState(joint_handle_, MenuHandler::CHECKED);
00322 //    if(jtranspose_handle_)  menu_arms_.setCheckState(jtranspose_handle_, MenuHandler::UNCHECKED);
00323 //    control_state_.r_gripper_.on_ = false;
00324 //    control_state_.l_gripper_.on_ = false;
00325 //    control_state_.posture_r_ = false;
00326 //    control_state_.posture_l_ = false;
00327 //  }
00328 
00329   bool controller_changed = (r_cart != last_r_cart) || (l_cart != last_l_cart);
00330   last_r_cart = r_cart;
00331   last_l_cart = l_cart;
00332 
00333   if(controller_changed)
00334   {
00335     //if(tuck_handle_) menu_arms_.setVisible(tuck_handle_, !(r_cart || l_cart) );
00336     //init_mesh_markers = true;
00337     init_control_markers = true;
00338     //init_all_markers = true;
00339   }
00340 
00341   ROS_DEBUG("r_cart: %d  l_cart: %d", r_cart, l_cart);
00342 
00343   // ---------------------------------------------------------------
00344   // Current state validator stuff
00345 
00346   bool meshes_changed = false;
00347 
00348   bool in_collision_r = !checkStateValidity("right_arm");
00349   if (in_collision_r_ != in_collision_r) meshes_changed = true;
00350   in_collision_r_ = in_collision_r;
00351 
00352   bool in_collision_l = !checkStateValidity("left_arm");
00353   if (in_collision_l_ != in_collision_l) meshes_changed = true;
00354   in_collision_l_ = in_collision_l;
00355 
00356   init_mesh_markers = meshes_changed;
00357   //if (meshes_changed) initMeshMarkers();
00358 
00359   // ---------------------------------------------------------------
00360   // Base client stuff
00361   bool move_base_active = base_client_.hasGoal();
00362   if( move_base_active != last_move_base_active ) init_control_markers = true;
00363   last_move_base_active = move_base_active;
00364 
00365 
00366   // ---------------------------------------------------------------
00367   // Call a re-draw to the necessary markers.
00368   if(init_all_markers) initAllMarkers();
00369   else
00370   {
00371     if(init_control_markers) initControlMarkers();
00372     if(init_mesh_markers) initMeshMarkers();
00373   }
00374 }
00375 
00377 double PR2MarkerControl::getJointPosition( std::string name, const arm_navigation_msgs::RobotState& robot_state)
00378 {
00379   for (size_t i=0; i<robot_state.joint_state.name.size(); i++)
00380   {
00381     if (robot_state.joint_state.name[i] == name)
00382     {
00383       ROS_ASSERT(robot_state.joint_state.position.size() > i);
00384       return robot_state.joint_state.position[i];
00385     }
00386   }
00387   ROS_ERROR_STREAM("Joint " << name << " not found in robot state");
00388   return 0.0;
00389 }
00390 
00392 void PR2MarkerControl::initControlMarkers()
00393 {
00394   ros::Time now = ros::Time::now();
00395   ROS_INFO("Re-initializing all control markers!");
00396   arm_navigation_msgs::RobotState robot_state;
00397   //wait for the service to initialize, for how long it takes
00398   mechanism_.get_robot_state_client_.client(ros::Duration(-1));
00399   mechanism_.getRobotState(robot_state);
00400   
00401   control_state_.print();
00402   // Right gripper control
00403   if(!control_state_.dual_grippers_.on_ && control_state_.r_gripper_.on_ && use_right_arm_ &&
00404      (interface_number_ == 0 || interface_number_ == 1) )
00405   {
00406     tfl_.waitForTransform("r_wrist_roll_link","base_link", now, ros::Duration(2.0));
00407     tf::StampedTransform stamped;
00408     geometry_msgs::TransformStamped ts;
00409     geometry_msgs::PoseStamped ps;
00410     tfl_.lookupTransform("base_link", "r_wrist_roll_link", now, stamped);
00411     offsetPS(stamped, pose_offset_[0]);
00412     tf::transformStampedTFToMsg(stamped, ts);
00413     ps = msg::createPoseStampedMsg(ts);
00414     ps.header.stamp = ros::Time(0);   // Time(0) is needed, else the markers seem to end up in random places
00415     if ( control_state_.planar_only_ ) {
00416       ROS_INFO("making planar control");
00417       server_.insert(makePlanarMarker( "r_gripper_control", ps, 0.25, true), 
00418                      boost::bind( &PR2MarkerControl::updateGripper, this, _1, 0));
00419     } else {
00420       server_.insert(make6DofMarker( "r_gripper_control", ps, 0.25, control_state_.r_gripper_.torso_frame_,
00421                                      control_state_.r_gripper_.view_facing_),
00422                      boost::bind( &PR2MarkerControl::updateGripper, this, _1, 0));
00423     }
00424     menu_grippers_.apply(server_, "r_gripper_control");
00425   }
00426   else
00427   {
00428     server_.erase("r_gripper_control");
00429   }
00430 
00431   // Left gripper control
00432   if(!control_state_.dual_grippers_.on_ && control_state_.l_gripper_.on_ && use_left_arm_ &&
00433      (interface_number_ == 0 || interface_number_ == 1))
00434   {
00435     tfl_.waitForTransform("base_link", "odom_combined", now, ros::Duration(2.0));
00436     tf::StampedTransform tfbaseLink_expressedIn_odomCombined;
00437     tfl_.lookupTransform("odom_combined", "base_link", now, tfbaseLink_expressedIn_odomCombined);
00438     tf::Transform odomCombined2_expressedIn_odomCombined = tf::Transform(tfbaseLink_expressedIn_odomCombined.getRotation());
00439     tf::StampedTransform outST(odomCombined2_expressedIn_odomCombined, now, "odom_combined", "base_aligned_odom_combined"); 
00440     {
00441       boost::mutex::scoped_lock lock(alignedOdomMutex_);
00442       alignedOdom_ = outST;
00443       alignedOdomValid_ = true;
00444       tfb_.sendTransform(alignedOdom_);
00445       tfl_.setTransform(alignedOdom_);
00446     }
00447     
00448     /*
00449     tfl_.waitForTransform("l_wrist_roll_link", manipulator_base_frame_, now, ros::Duration(2.0));
00450     tfl_.waitForTransform("base_link", manipulator_base_frame_, now, ros::Duration(2.0));
00451     tf::StampedTransform tfbaseLink_expressedIn_odomCombined, tfgripper_expressedIn_odomCombined;
00452     tfl_.lookupTransform(manipulator_base_frame_, "l_wrist_roll_link", now, tfgripper_expressedIn_odomCombined);
00453     tfl_.lookupTransform(manipulator_base_frame_, "base_link", now, tfbaseLink_expressedIn_odomCombined);
00454     tf::Transform gripper_expressedIn_odomCombined = tf::Transform(tfgripper_expressedIn_odomCombined.getRotation(), tfgripper_expressedIn_odomCombined.getOrigin());
00455     tf::Transform odomCombined2_expressedIn_odomCombined = tf::Transform(tfbaseLink_expressedIn_odomCombined.getRotation());
00456     tf::Transform gripper_expressedIn_odomCombined2 = gripper_expressedIn_odomCombined * odomCombined2_expressedIn_odomCombined.inverse();
00457     
00458     geometry_msgs::PoseStamped psGripper_expressedIn_odomCombined2;
00459     tf::poseTFToMsg(gripper_expressedIn_odomCombined2, psGripper_expressedIn_odomCombined2.pose);
00460     psGripper_expressedIn_odomCombined2.header.stamp = ros::Time(0);
00461     
00462     server_.insert(make6DofMarker( "l_gripper_control", psGripper_expressedIn_odomCombined2, 
00463                                    0.25, control_state_.l_gripper_.torso_frame_,
00464                                    control_state_.l_gripper_.view_facing_),
00465                    boost::bind( &PR2MarkerControl::updateGripper, this, _1, 1 ));
00466     menu_grippers_.apply(server_, "l_gripper_control");
00467     */
00468     
00469     
00470     tfl_.waitForTransform("l_wrist_roll_link", manipulator_base_frame_, now, ros::Duration(2.0));
00471     tf::StampedTransform stamped;
00472     geometry_msgs::TransformStamped ts;
00473     geometry_msgs::PoseStamped ps;
00474     tfl_.lookupTransform(manipulator_base_frame_, "l_wrist_roll_link", now, stamped);
00475     offsetPS(stamped, pose_offset_[1]);
00476     tf::transformStampedTFToMsg(stamped, ts);
00477     ps = msg::createPoseStampedMsg(ts);
00478     ps.header.stamp = ros::Time(0); // Time(0) is needed, else the markers seem to end up in random places
00479     server_.insert(make6DofMarker( "l_gripper_control", ps, 0.25, control_state_.l_gripper_.torso_frame_,
00480                                    control_state_.l_gripper_.view_facing_),
00481                    boost::bind( &PR2MarkerControl::updateGripper, this, _1, 1 ));
00482     menu_grippers_.apply(server_, "l_gripper_control");
00483     
00484     ROS_DEBUG_STREAM("init marker in frame " << ps.header.frame_id << "(" 
00485                     << ps.pose.position.x << ", "
00486                     << ps.pose.position.y << ", "
00487                     << ps.pose.position.z << ")" );
00488  
00489   }
00490   else
00491   {
00492     server_.erase("l_gripper_control");
00493   }
00494 
00495   // Dual-gripper control
00496   if(control_state_.dual_grippers_.on_)
00497   {
00498 //    // TODO should this update with gripper poses, or be more of a fixed thing?
00499 //    // If it auto updates it might lead to stability issues...
00500 //    tfl_.waitForTransform("r_gripper_tool_frame","base_link", now, ros::Duration(2.0));
00501 //    tfl_.waitForTransform("l_gripper_tool_frame","base_link", now, ros::Duration(2.0));
00502 //    tf::StampedTransform stamped;
00503 //    geometry_msgs::TransformStamped ts;
00504 //    geometry_msgs::PoseStamped ps;
00505 //    tfl_.lookupTransform("base_link", "r_wrist_roll_link", now, stamped);
00506 //    offsetPS(stamped, pose_offset_[1]);
00507 //    tf::transformStampedTFToMsg(stamped, ts);
00508 //    ps = msg::createPoseStampedMsg(ts);
00509 
00510     tf::Transform dual_grippers_frame_tf;
00511     tf::poseMsgToTF(dual_grippers_frame_.pose, dual_grippers_frame_tf);
00512     tf::Transform offset_frame = dual_grippers_frame_tf * dual_pose_offset_.inverse();
00513     geometry_msgs::Pose offset_pose;
00514     tf::poseTFToMsg(offset_frame, offset_pose);
00515     geometry_msgs::PoseStamped offset_ps = object_manipulator::msg::createPoseStampedMsg(offset_pose,
00516                                                                                   dual_grippers_frame_.header.frame_id,
00517                                                                                   ros::Time(0));
00518     server_.insert(make6DofMarker( "dual_gripper_control", offset_ps, 0.25, 
00519                                    control_state_.dual_grippers_.torso_frame_, false),
00520                    boost::bind( &PR2MarkerControl::updateDualGripper, this, _1 ));
00521     menu_dual_grippers_.apply(server_, "dual_gripper_control");
00522   }
00523   else
00524   {
00525     server_.erase("dual_gripper_control");
00526   }
00527 
00528 
00529   if(control_state_.posture_r_ && use_right_arm_ &&
00530      (interface_number_ <= 2))
00531   {
00532       tf::StampedTransform stamped;
00533       geometry_msgs::TransformStamped ts;
00534       geometry_msgs::PoseStamped ps;
00535       tfl_.waitForTransform("r_shoulder_pan_link","base_link", now, ros::Duration(2.0));
00536       tfl_.lookupTransform("base_link", "r_shoulder_pan_link", now, stamped);
00537       tf::transformStampedTFToMsg(stamped, ts);
00538       float angle = getJointPosition("r_upper_arm_roll_joint", robot_state);
00539       ts.transform.rotation = msg::createQuaternionMsg( tf::Quaternion( tf::Vector3(1,0,0), angle) );
00540       ps = msg::createPoseStampedMsg(ts);
00541       ps.header.stamp = ros::Time(0);
00542       server_.insert(makePostureMarker( "r_posture_control", ps, 0.55, false, false),
00543                  boost::bind( &PR2MarkerControl::updatePosture, this, _1, 0 ));
00544   }
00545   else
00546   {
00547       server_.erase("r_posture_control");
00548   }
00549 
00550   if(control_state_.posture_l_ && use_left_arm_ &&
00551      (interface_number_ <= 2))
00552   {
00553       tf::StampedTransform stamped;
00554       geometry_msgs::TransformStamped ts;
00555       geometry_msgs::PoseStamped ps;
00556       tfl_.waitForTransform("l_shoulder_pan_link",manipulator_base_frame_, now, ros::Duration(2.0));
00557       tfl_.lookupTransform(manipulator_base_frame_, "l_shoulder_pan_link", now, stamped);
00558       tf::transformStampedTFToMsg(stamped, ts);
00559       float angle = getJointPosition("l_upper_arm_roll_joint", robot_state);
00560       ts.transform.rotation = msg::createQuaternionMsg( tf::Quaternion( tf::Vector3(1,0,0), angle) );
00561       ps = msg::createPoseStampedMsg(ts);
00562       ps.header.stamp = ros::Time(0);
00563       server_.insert(makePostureMarker( "l_posture_control", ps, 0.55, false, false),
00564                  boost::bind( &PR2MarkerControl::updatePosture, this, _1, 1 ));
00565   }
00566   else
00567   {
00568     server_.erase("l_posture_control");
00569   }
00570 
00571   if(control_state_.head_on_ && control_state_.init_head_goal_)
00572   {
00573     control_state_.init_head_goal_ = false;
00574     //geometry_msgs::PoseStamped ps = msg::createPoseStampedMsg( head_goal_pose_, "base_link", now);
00575     head_goal_pose_.header.stamp = ros::Time(0);
00576     //ps.header.stamp = ros::Time(0);
00577     server_.insert(makeHeadGoalMarker( "head_point_goal", head_goal_pose_, 0.1),
00578                    boost::bind( &PR2MarkerControl::updateHeadGoal, this, _1, 0 ));
00579   }
00580   if(!control_state_.head_on_)
00581   {
00582     server_.erase("head_point_goal");
00583   }
00584 
00585   if (interface_number_ == 0)
00586   {
00587     geometry_msgs::PoseStamped ps;
00588     ps.pose.position.x = -0.35;
00589     ps.pose.position.z = 1.1;
00590     ps.pose.orientation.w = 1;
00591     ps.header.frame_id = "base_link";
00592     ps.header.stamp = ros::Time(0);
00593     server_.insert(makeElevatorMarker( "torso_control", ps, 0.25, false),
00594                    boost::bind( &PR2MarkerControl::updateTorso, this, _1 ));
00595     menu_torso_.apply(server_, "torso_control");
00596   }
00597 
00598   if(control_state_.base_on_ && interface_number_ == 0) // base control (!)
00599   {
00600     geometry_msgs::PoseStamped ps;
00601     ps.pose.orientation.w = 1;
00602     ps.header.frame_id = "base_link";
00603     ps.header.stamp = ros::Time(0);
00604     server_.insert(makeBaseMarker( "base_control", ps, 0.75, false),
00605                    boost::bind( &PR2MarkerControl::updateBase, this, _1 ));
00606   }
00607   else
00608   {
00609     server_.erase("base_control");
00610   }
00611 
00612   // The giant ball around the robot when it is driving somewhere.
00613   if( base_client_.hasGoal() )
00614   {
00615     geometry_msgs::PoseStamped ps;
00616     ps.pose.position.z = 1.0;
00617     ps.pose.orientation.w = 1;
00618     ps.header.frame_id = "base_link";
00619     ps.header.stamp = ros::Time(0);
00620 
00621     std_msgs::ColorRGBA color = object_manipulator::msg::createColorMsg(1.0, 0.8, 0.8, 0.2);
00622     server_.insert(makeButtonSphere( "move_base_e_stop", ps, 2.0, false, false, color ));
00623     server_.setCallback("move_base_e_stop", boost::bind( &PR2MarkerControl::cancelBaseMovement, this),
00624                           visualization_msgs::InteractiveMarkerFeedback::MOUSE_DOWN );
00625   
00626     // TODO this should absolutely be read from the robot_description parameter
00627     std::vector< std::string > mesh_paths, mesh_frames;
00628     mesh_paths.push_back("package://pr2_description/meshes/base_v0/base.dae");
00629     mesh_frames.push_back("base_link");
00630     mesh_paths.push_back("package://pr2_description/meshes/torso_v0/torso_lift.dae");
00631     mesh_frames.push_back("torso_lift_link");
00632     mesh_paths.push_back("package://pr2_description/meshes/shoulder_v0/shoulder_pan.dae");
00633     mesh_frames.push_back("r_shoulder_pan_link");
00634     mesh_paths.push_back("package://pr2_description/meshes/shoulder_v0/shoulder_pan.dae");
00635     mesh_frames.push_back("l_shoulder_pan_link");
00636     mesh_paths.push_back("package://pr2_description/meshes/shoulder_v0/shoulder_lift.dae");
00637     mesh_frames.push_back("r_shoulder_lift_link");
00638     mesh_paths.push_back("package://pr2_description/meshes/shoulder_v0/shoulder_lift.dae");
00639     mesh_frames.push_back("l_shoulder_lift_link");
00640     mesh_paths.push_back("package://pr2_description/meshes/upper_arm_v0/upper_arm.dae");
00641     mesh_frames.push_back("r_upper_arm_link");
00642     mesh_paths.push_back("package://pr2_description/meshes/upper_arm_v0/upper_arm.dae");
00643     mesh_frames.push_back("l_upper_arm_link");
00644     mesh_paths.push_back("package://pr2_description/meshes/forearm_v0/forearm.dae");
00645     mesh_frames.push_back("r_forearm_link");
00646     mesh_paths.push_back("package://pr2_description/meshes/forearm_v0/forearm.dae");
00647     mesh_frames.push_back("l_forearm_link");
00648 
00649     // Right Gripper
00650     mesh_paths.push_back("package://pr2_description/meshes/gripper_v0/gripper_palm.dae");
00651     mesh_frames.push_back("r_gripper_palm_link");
00652     mesh_paths.push_back("package://pr2_description/meshes/gripper_v0/upper_finger_r.stl");
00653     mesh_frames.push_back("r_gripper_r_finger_link");
00654     mesh_paths.push_back("package://pr2_description/meshes/gripper_v0/upper_finger_l.stl");
00655     mesh_frames.push_back("r_gripper_l_finger_link");
00656     mesh_paths.push_back("package://pr2_description/meshes/gripper_v0/finger_tip_r.stl");
00657     mesh_frames.push_back("r_gripper_r_finger_tip_link");
00658     mesh_paths.push_back("package://pr2_description/meshes/gripper_v0/finger_tip_l.stl");
00659     mesh_frames.push_back("r_gripper_l_finger_tip_link");
00660 
00661 
00662     // Left Gripper
00663     mesh_paths.push_back("package://pr2_description/meshes/gripper_v0/gripper_palm.dae");
00664     mesh_frames.push_back("l_gripper_palm_link");
00665     mesh_paths.push_back("package://pr2_description/meshes/gripper_v0/upper_finger_r.stl");
00666     mesh_frames.push_back("l_gripper_r_finger_link");
00667     mesh_paths.push_back("package://pr2_description/meshes/gripper_v0/upper_finger_l.stl");
00668     mesh_frames.push_back("l_gripper_l_finger_link");
00669     mesh_paths.push_back("package://pr2_description/meshes/gripper_v0/finger_tip_r.stl");
00670     mesh_frames.push_back("l_gripper_r_finger_tip_link");
00671     mesh_paths.push_back("package://pr2_description/meshes/gripper_v0/finger_tip_l.stl");
00672     mesh_frames.push_back("l_gripper_l_finger_tip_link");
00673 
00674     // Head
00675     mesh_paths.push_back("package://pr2_description/meshes/head_v0/head_pan.dae");
00676     mesh_frames.push_back("head_pan_link");
00677     mesh_paths.push_back("package://pr2_description/meshes/head_v0/head_tilt.dae");
00678     mesh_frames.push_back("head_tilt_link");
00679 
00680 
00681     if(mesh_paths.size() != mesh_frames.size()) ROS_ERROR("The number of mesh paths and mash frame_ids is not equal!");
00682 
00683     std::vector< geometry_msgs::PoseStamped > mesh_poses;
00684     for(size_t i = 0; i < mesh_paths.size(); i++)
00685     {
00686         geometry_msgs::PoseStamped ps;
00687         ps.header.stamp = ros::Time(0);
00688         ps.header.frame_id = mesh_frames[i];
00689         ps.pose.orientation.w = 1;
00690         tfl_.waitForTransform("base_link", ps.header.frame_id, ps.header.stamp,ros::Duration(3.0));
00691         tfl_.transformPose("base_link", ps, ps);
00692         mesh_poses.push_back(ps);
00693     }
00694 
00695     server_.insert(makePosedMultiMeshMarker( "move_base_goal", base_goal_pose_, mesh_poses, mesh_paths, 1.0, true));
00696 
00697   }
00698   else
00699   {
00700     server_.erase("move_base_e_stop");
00701     server_.erase("move_base_goal");
00702   }
00703 
00704 }
00705 
00707 void PR2MarkerControl::initMeshMarkers()
00708 {
00709   // create interactive markers for all links
00710   std::vector<visualization_msgs::InteractiveMarker> mesh_markers;
00711   addMeshMarkersFromRobotModel(mesh_markers);
00712 
00713   for ( unsigned i=0; i<mesh_markers.size(); i++)
00714   {
00715     // make head, grippers and upper arms into buttons
00716     if ( mesh_markers[i].controls.size() == 1 &&
00717          mesh_markers[i].controls[0].markers.size() == 1 && (
00718         mesh_markers[i].name == "head_tilt_link" ||
00719         mesh_markers[i].name == "base_link" ||
00720         mesh_markers[i].name.find("gripper") != std::string::npos ||
00721         mesh_markers[i].name.find("upper_arm_link") != std::string::npos
00722          ))
00723     {
00724       mesh_markers[i].controls[0].interaction_mode = visualization_msgs::InteractiveMarkerControl::BUTTON;
00725       if ( transparent_ )
00726       {
00727         mesh_markers[i].controls[0].markers[0].mesh_use_embedded_materials = false;
00728         mesh_markers[i].controls[0].markers[0].color.a = 0;
00729         mesh_markers[i].controls[0].markers[0].color.r = 1;
00730         mesh_markers[i].controls[0].markers[0].color.g = 1;
00731         mesh_markers[i].controls[0].markers[0].color.b = 1;
00732         mesh_markers[i].controls[0].markers[0].scale.x = 1.1;
00733         mesh_markers[i].controls[0].markers[0].scale.y = 1.1;
00734         mesh_markers[i].controls[0].markers[0].scale.z = 1.1;
00735         mesh_markers[i].controls[0].markers[0].pose.position.x = -0.01;
00736         mesh_markers[i].controls[0].markers[0].ns = mesh_markers[i].name;
00737       }
00738       server_.insert(mesh_markers[i]);
00739     }
00740     else
00741     {
00742       // in non-transparent mode, add all links
00743       if ( !transparent_ )
00744       {
00745         server_.insert(mesh_markers[i]);
00746       }
00747     }
00748   }
00749 
00750   ros::Time now = ros::Time(0);
00751 
00752   menu_head_.apply(server_, "head_tilt_link");
00753 
00754   if(use_right_arm_)
00755   {
00756     server_.setCallback("r_upper_arm_link", boost::bind( &PR2MarkerControl::upperArmButtonCB, this, _1, 0),
00757                         visualization_msgs::InteractiveMarkerFeedback::BUTTON_CLICK );
00758     menu_arms_.apply(server_, "r_upper_arm_link");
00759 
00760     server_.setCallback("r_gripper_palm_link", boost::bind( &PR2MarkerControl::gripperButtonCB, this, _1, "toggle") );
00761     server_.setCallback("r_gripper_l_finger_link", boost::bind( &PR2MarkerControl::gripperButtonCB, this, _1, "toggle") );
00762     server_.setCallback("r_gripper_l_finger_tip_link", boost::bind( &PR2MarkerControl::gripperButtonCB, this, _1, "toggle") );
00763     server_.setCallback("r_gripper_r_finger_link", boost::bind( &PR2MarkerControl::gripperButtonCB, this, _1, "toggle") );
00764     server_.setCallback("r_gripper_r_finger_tip_link", boost::bind( &PR2MarkerControl::gripperButtonCB, this, _1, "toggle") );
00765 
00766     menu_gripper_close_.apply(server_, "r_gripper_palm_link");
00767     menu_gripper_close_.apply(server_, "r_gripper_l_finger_link");
00768     menu_gripper_close_.apply(server_, "r_gripper_l_finger_tip_link");
00769     menu_gripper_close_.apply(server_, "r_gripper_r_finger_link");
00770     menu_gripper_close_.apply(server_, "r_gripper_r_finger_tip_link");
00771   }
00772 
00773   if(use_left_arm_)
00774   {
00775     server_.setCallback("l_upper_arm_link", boost::bind( &PR2MarkerControl::upperArmButtonCB, this, _1, 1),
00776                         visualization_msgs::InteractiveMarkerFeedback::BUTTON_CLICK );
00777     menu_arms_.apply(server_, "l_upper_arm_link");
00778 
00779     server_.setCallback("l_gripper_palm_link", boost::bind( &PR2MarkerControl::gripperButtonCB, this, _1, "toggle") );
00780     server_.setCallback("l_gripper_l_finger_link", boost::bind( &PR2MarkerControl::gripperButtonCB, this, _1, "toggle") );
00781     server_.setCallback("l_gripper_l_finger_tip_link", boost::bind( &PR2MarkerControl::gripperButtonCB, this, _1, "toggle") );
00782     server_.setCallback("l_gripper_r_finger_link", boost::bind( &PR2MarkerControl::gripperButtonCB, this, _1, "toggle") );
00783     server_.setCallback("l_gripper_r_finger_tip_link", boost::bind( &PR2MarkerControl::gripperButtonCB, this, _1, "toggle") );
00784 
00785     menu_gripper_close_.apply(server_, "l_gripper_palm_link");
00786     menu_gripper_close_.apply(server_, "l_gripper_l_finger_link");
00787     menu_gripper_close_.apply(server_, "l_gripper_l_finger_tip_link");
00788     menu_gripper_close_.apply(server_, "l_gripper_r_finger_link");
00789     menu_gripper_close_.apply(server_, "l_gripper_r_finger_tip_link");
00790   }
00791 
00792   if (interface_number_ == 0) // base link not allowed in studies
00793   {
00794     server_.setCallback("base_link", boost::bind( &PR2MarkerControl::baseButtonCB, this, _1),
00795                         visualization_msgs::InteractiveMarkerFeedback::BUTTON_CLICK );
00796     menu_base_.apply(server_, "base_link");
00797   }
00798 
00799   if(control_state_.projector_on_)
00800   {
00801     geometry_msgs::PoseStamped ps;
00802     server_.insert(makeProjectorMarker( "projector_control", ps, 1.0),
00803                    boost::bind( &PR2MarkerControl::projectorMenuCB, this, _1 ));
00804   }
00805   else
00806   {
00807     server_.erase("projector_control");
00808   }
00809 
00810   // The "reset" box over the PR2's head.
00811 
00812   geometry_msgs::PoseStamped ps;
00813   ps = msg::createPoseStampedMsg(msg::createPointMsg(0,0,0.85), msg::createQuaternionMsg(0,0,0,1),
00814                                  "torso_lift_link", ros::Time(0));
00815   server_.insert(makeButtonBox( "PR2 Marker Control Reset", ps, 0.05, false, true),
00816                  boost::bind( &PR2MarkerControl::initAllMarkers, this, true ),
00817                  visualization_msgs::InteractiveMarkerFeedback::BUTTON_CLICK);
00818 }
00819 
00820 
00821 void PR2MarkerControl::switchToCartesian()
00822 {
00823   ROS_DEBUG("Switching to cartesian control.");
00824 
00825   // start out with posture control disabled
00826   std::vector<double> arm_angles(7);
00827   for( size_t i = 0; i < arm_angles.size(); i++) arm_angles[i] = 9999;
00828 
00829   mechanism_.get_robot_state_client_.client(ros::Duration(100.0));
00830   if(use_left_arm_){
00831       try {
00832         mechanism_.switchToCartesian("left_arm");
00833       }
00834       catch ( std::runtime_error &e )
00835       {
00836         ROS_ERROR("Caught exception while switching to cartesian controller: %s", e.what( ));
00837       }
00838       mechanism_.sendCartesianPostureCommand("left_arm", arm_angles);
00839   }
00840 
00841   if(use_right_arm_)
00842   {
00843       try {
00844         mechanism_.switchToCartesian("right_arm");
00845       }
00846       catch ( std::runtime_error &e ) {
00847         ROS_ERROR("Caught exception while switching to cartesian controller: %s", e.what( ));
00848       }
00849       mechanism_.sendCartesianPostureCommand("right_arm", arm_angles);
00850   }
00851 
00852   if(joint_handle_)       menu_arms_.setCheckState(joint_handle_, MenuHandler::UNCHECKED);
00853   if(jtranspose_handle_)  menu_arms_.setCheckState(jtranspose_handle_, MenuHandler::CHECKED);
00854   menu_arms_.reApply(server_);
00855   initControlMarkers();
00856 }
00857 
00858 void PR2MarkerControl::switchToJoint()
00859 {
00860   ROS_DEBUG("Switching to joint control.");
00861   if(use_left_arm_)
00862   {
00863       try {
00864         mechanism_.switchToJoint("left_arm");
00865       }
00866       catch ( std::runtime_error &e ) {
00867         ROS_ERROR("Caught exception while switching to cartesian controller: %s", e.what( ));
00868       }
00869   }
00870 
00871   if(use_right_arm_)
00872   {
00873       try {
00874         mechanism_.switchToJoint("right_arm");
00875       }
00876       catch ( std::runtime_error &e ) {
00877         ROS_ERROR("Caught exception while switching to cartesian controller: %s", e.what( ));
00878       }
00879   }
00880 
00881   if(joint_handle_)       menu_arms_.setCheckState(joint_handle_, MenuHandler::CHECKED);
00882   if(jtranspose_handle_)  menu_arms_.setCheckState(jtranspose_handle_, MenuHandler::UNCHECKED);
00883   menu_arms_.reApply(server_);
00884   initControlMarkers();
00885 }
00886 
00887 bool PR2MarkerControl::checkStateValidity(std::string arm_name)
00888 {
00889   // Hack to avoid using this for now
00890   if(!use_state_validator_) return true;
00891 
00892   if (interface_number_ != 0) return true;
00893   arm_navigation_msgs::GetStateValidity::Request request;
00894   request.group_name = arm_name;
00895   arm_navigation_msgs::GetStateValidity::Response response;
00896   try
00897   {
00898     if (!check_state_validity_client_.client().call(request, response))
00899     {
00900       ROS_ERROR("Call to get state validity failed");
00901       return false;
00902     }
00903     if (response.error_code.val != response.error_code.SUCCESS) return false;
00904     return true;
00905   }
00906   catch (object_manipulator::ServiceNotFoundException &ex)
00907   {
00908     ROS_ERROR("Get state validity service not found");
00909     return false;
00910   }
00911 }
00912 
00913 void PR2MarkerControl::updateHeadGoal( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback, int arm_id )
00914 {
00915   ros::Time now = ros::Time(0);
00916 
00917   switch ( feedback->event_type )
00918   {
00919     case visualization_msgs::InteractiveMarkerFeedback::BUTTON_CLICK:
00920       ROS_INFO_STREAM( feedback->marker_name << " was clicked on." );
00921       break;
00922     case visualization_msgs::InteractiveMarkerFeedback::MENU_SELECT:
00923       ROS_INFO_STREAM(    "Marker " << feedback->marker_name
00924                        << " control " << feedback->control_name
00925                        << " menu_entry_id " << feedback->menu_entry_id);
00926 
00927     case visualization_msgs::InteractiveMarkerFeedback::POSE_UPDATE:
00928       geometry_msgs::PointStamped ps;
00929       ps.point = feedback-> pose.position;
00930       ps.header.frame_id = feedback->header.frame_id;
00931       ps.header.stamp = now;
00932       head_goal_pose_.pose = feedback->pose;
00933       head_goal_pose_.header = feedback->header;
00934       mechanism_.pointHeadAction(ps, head_pointing_frame_, false);
00935       break;
00936   }
00937 }
00938 
00939 void PR2MarkerControl::targetPointMenuCB( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback )
00940 {
00941   control_state_.head_on_ ^= true;
00942   control_state_.init_head_goal_ = true;
00943 
00944   if(control_state_.head_on_)
00945     menu_head_.setCheckState(head_target_handle_, MenuHandler::CHECKED);
00946   else
00947     menu_head_.setCheckState(head_target_handle_, MenuHandler::UNCHECKED);
00948 
00949   initControlMarkers();
00950   menu_head_.reApply(server_);
00951 }
00952 
00953 void PR2MarkerControl::projectorMenuCB( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback )
00954 {
00955   if(control_state_.projector_on_)
00956   {
00957     ROS_INFO("Trying to turn projector OFF");
00958     int ok = system("rosrun dynamic_reconfigure dynparam set camera_synchronizer_node \"{'projector_mode':1, 'narrow_stereo_trig_mode':2}\" ");
00959     ROS_INFO("Done!");
00960     if(ok < 0)
00961       ROS_WARN("Dynamic reconfigure for setting trigger mode OFF failed");
00962     else
00963     {
00964       control_state_.projector_on_ = false;
00965       menu_head_.setCheckState(projector_handle_, MenuHandler::UNCHECKED);
00966     }
00967   }
00968   else
00969   {
00970     ROS_INFO("Trying to turn projector ON");
00971     int ok = system("rosrun dynamic_reconfigure dynparam set camera_synchronizer_node \"{'projector_mode':3, 'narrow_stereo_trig_mode':5}\" ");
00972     ROS_INFO("Done!");
00973     if(ok < 0)
00974       ROS_WARN("Dynamic reconfigure for setting trigger mode ON failed");
00975     else
00976     {
00977       control_state_.projector_on_ = true;
00978       menu_head_.setCheckState(projector_handle_, MenuHandler::CHECKED);
00979     }
00980   }
00981   menu_head_.reApply(server_);
00982 }
00983 
00984 void PR2MarkerControl::gripperToggleModeCB( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback )
00985 {
00986   MenuHandler::EntryHandle handle = feedback->menu_entry_id;
00987   //MenuHandler::CheckState state;
00988   //if(!menu_arms_.getCheckState(handle, state))  return;
00989 
00990   if ( handle == gripper_view_facing_handle_ )
00991   {
00992     control_state_.r_gripper_.view_facing_ = true;
00993     control_state_.l_gripper_.view_facing_ = true;
00994     assert(menu_grippers_.setCheckState(gripper_view_facing_handle_, MenuHandler::CHECKED));
00995     assert(menu_grippers_.setCheckState(gripper_6dof_handle_, MenuHandler::UNCHECKED));
00996   }
00997   if ( handle == gripper_6dof_handle_ )
00998   {
00999     control_state_.r_gripper_.view_facing_ = false;
01000     control_state_.l_gripper_.view_facing_ = false;
01001     assert(menu_grippers_.setCheckState(gripper_view_facing_handle_, MenuHandler::UNCHECKED));
01002     assert(menu_grippers_.setCheckState(gripper_6dof_handle_, MenuHandler::CHECKED));
01003   }
01004 
01005   menu_grippers_.reApply(server_);
01006   initControlMarkers();
01007 }
01008 
01009 void PR2MarkerControl::gripperToggleFixedCB( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback )
01010 {
01011   control_state_.r_gripper_.torso_frame_ ^= true;
01012   control_state_.l_gripper_.torso_frame_ ^= true;
01013 
01014   // TODO right now I'm assuming these will always be in the same state together...
01015   if(control_state_.r_gripper_.torso_frame_)
01016     menu_grippers_.setCheckState(gripper_fixed_control_handle_, MenuHandler::CHECKED);
01017   else
01018     menu_grippers_.setCheckState(gripper_fixed_control_handle_, MenuHandler::UNCHECKED);
01019 
01020   menu_grippers_.reApply(server_);
01021   initControlMarkers();
01022 }
01023 
01024 void PR2MarkerControl::dualGripperToggleFixedCB( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback )
01025 {
01026   control_state_.dual_grippers_.torso_frame_ ^= true;
01027 
01028   if(control_state_.dual_grippers_.torso_frame_)
01029     menu_dual_grippers_.setCheckState(dual_gripper_fixed_control_handle_, MenuHandler::CHECKED);
01030   else
01031     menu_dual_grippers_.setCheckState(dual_gripper_fixed_control_handle_, MenuHandler::UNCHECKED);
01032 
01033   menu_dual_grippers_.reApply(server_);
01034   initControlMarkers();
01035 }
01036 
01037 void PR2MarkerControl::gripperToggleControlCB( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback )
01038 {
01039   control_state_.r_gripper_.edit_control_ ^= true;
01040   control_state_.l_gripper_.edit_control_ ^= true;
01041 
01042   // TODO right now I'm assuming these will always be in the same state together...
01043   if(control_state_.r_gripper_.edit_control_)
01044     menu_grippers_.setCheckState(gripper_edit_control_handle_, MenuHandler::CHECKED);
01045   else
01046     menu_grippers_.setCheckState(gripper_edit_control_handle_, MenuHandler::UNCHECKED);
01047 
01048   menu_grippers_.reApply(server_);
01049   initControlMarkers();
01050 }
01051 
01052 void PR2MarkerControl::dualGripperToggleControlCB( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback )
01053 {
01054   control_state_.dual_grippers_.edit_control_ ^= true;
01055 
01056   if(control_state_.dual_grippers_.edit_control_)
01057     menu_dual_grippers_.setCheckState(dual_gripper_edit_control_handle_, MenuHandler::CHECKED);
01058   else
01059     menu_dual_grippers_.setCheckState(dual_gripper_edit_control_handle_, MenuHandler::UNCHECKED);
01060 
01061   ROS_INFO("toggling dual gripper edit control frame, current state is %d", control_state_.dual_grippers_.edit_control_);
01062 
01063   menu_dual_grippers_.reApply(server_);
01064   initControlMarkers();
01065 }
01066 
01067 void PR2MarkerControl::gripperResetControlCB( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback )
01068 {
01069   int arm_id = -1;
01070   if(!feedback->marker_name.compare("r_gripper_control"))
01071     arm_id = 0;
01072   else if(!feedback->marker_name.compare("l_gripper_control"))
01073     arm_id = 1;
01074   else
01075   {
01076     ROS_ERROR("Marker name [%s] not recognized...", feedback->marker_name.c_str());
01077     return;
01078   }
01079   pose_offset_[arm_id].setOrigin(tf::Vector3(0.1, 0, 0));
01080   pose_offset_[arm_id].setRotation(tf::Quaternion(0, 0, 0, 1));
01081 }
01082 
01083 void PR2MarkerControl::dualGripperResetControlCB( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback )
01084 {
01085   dual_pose_offset_.setOrigin(tf::Vector3(0, 0, 0));
01086   dual_pose_offset_.setRotation(tf::Quaternion(0, 0, 0, 1));
01087   initControlMarkers();
01088 }
01089 
01090 void PR2MarkerControl::startDualGrippers( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback, bool active )
01091 {
01092   control_state_.dual_grippers_.on_ = active;
01093 
01094   // right and left gripper transforms to base, and right and left transforms to middle frame
01095   tf::Transform b_T_rw, b_T_lw, b_T_rt, b_T_lt;
01096 
01097   if(active)
01098   {
01099     //disable edit control mode in both grippers, in case they were on when we switched
01100     control_state_.r_gripper_.edit_control_ = false;
01101     control_state_.l_gripper_.edit_control_ = false;
01102     menu_grippers_.setCheckState(gripper_edit_control_handle_, MenuHandler::UNCHECKED);
01103 
01104     geometry_msgs::PoseStamped right_tool, left_tool;
01105     geometry_msgs::PoseStamped right_wrist = mechanism_.getGripperPose("right_arm", feedback->header.frame_id);
01106     geometry_msgs::PoseStamped left_wrist  = mechanism_.getGripperPose("left_arm", feedback->header.frame_id);
01107     right_tool = wristToTool(right_wrist);
01108     left_tool  = wristToTool(left_wrist);
01109     tf::poseMsgToTF(right_wrist.pose, b_T_rw);
01110     tf::poseMsgToTF(left_wrist.pose, b_T_lw);
01111     tf::poseMsgToTF(right_tool.pose, b_T_rt);
01112     tf::poseMsgToTF(left_tool.pose, b_T_lt);
01113 
01114     // compute midpoint frame using tool frames!
01115     tf::Vector3 midpoint = b_T_rt.getOrigin() + 0.5*(b_T_lt.getOrigin() - b_T_rt.getOrigin());
01116     // TODO this orientation is in the wrong frame!
01117     // Even if we set the correct torso frame initially, I suppose we need to continue
01118     // updating it if the robot drives around...
01119     tf::Transform b_T_m = tf::Transform(tf::Quaternion(0,0,0,1), midpoint);
01120 
01121     //compute gripper wrist offsets using wrist frames!
01122     dual_gripper_offsets_[0] = b_T_m.inverse()*b_T_rw;
01123     dual_gripper_offsets_[1] = b_T_m.inverse()*b_T_lw;
01124 
01125     //control frame offset from default dual gripper frame
01126     dual_pose_offset_ = tf::Transform(tf::Quaternion(0, 0, 0, 1), tf::Vector3(0, 0, 0));
01127     control_state_.dual_grippers_.edit_control_ = false;
01128     menu_dual_grippers_.setCheckState(dual_gripper_edit_control_handle_, MenuHandler::UNCHECKED);
01129     control_state_.dual_grippers_.torso_frame_ = true;
01130     menu_dual_grippers_.setCheckState(dual_gripper_fixed_control_handle_, MenuHandler::CHECKED);
01131 
01132     dual_grippers_frame_ = msg::createPoseStampedMsg(b_T_m, feedback->header.frame_id, ros::Time(0)); // Time(0) prevents disappearing markers bug.
01133   }
01134 
01135   menu_grippers_.reApply(server_);
01136   menu_dual_grippers_.reApply(server_);
01137   initControlMarkers();
01138 }
01139 
01140 void PR2MarkerControl::commandGripperPose(const geometry_msgs::PoseStamped &ps, int arm_id, bool use_offset)
01141 {
01142   std::string arm = "right_arm";
01143   if(arm_id == 1) arm = "left_arm";
01144   const char *arm_name = arm.c_str();
01145 
01146   tf::Transform control_pose, command_pose;
01147   tf::poseMsgToTF(ps.pose, control_pose);
01148   if(use_offset)
01149     command_pose = control_pose * pose_offset_[arm_id].inverse();
01150   else
01151     command_pose = control_pose;
01152   double dummy_var = 0;
01153   geometry_msgs::PoseStamped desired_pose = mechanism_.clipDesiredPose(arm_name,
01154                                                                        msg::createPoseStampedMsg(command_pose, ps.header.frame_id, ros::Time::now()),
01155                                                                        cartesian_clip_distance_*update_period_,
01156                                                                        cartesian_clip_angle_*update_period_,
01157                                                                        dummy_var);
01158 
01159   ROS_DEBUG_STREAM("sending gripper command in frame " << desired_pose.header.frame_id << "(" 
01160                   << desired_pose.pose.position.x << ", "
01161                   << desired_pose.pose.position.y << ", "
01162                   << desired_pose.pose.position.z << ")" );
01163 
01164   try {
01165     mechanism_.sendCartesianPoseCommand( arm_name, desired_pose);
01166   }
01167   catch ( std::runtime_error &e )
01168   {
01169     ROS_ERROR("Caught exception while sending pose command: %s", e.what( ));
01170   }
01171 }
01172 
01173 
01174 void PR2MarkerControl::updateGripper( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback, int arm_id )
01175 {
01176   ros::Time now = ros::Time(0);
01177   std::string arm = "right_arm";
01178   if(arm_id == 1) arm = "left_arm";
01179   const char *arm_name = arm.c_str();
01180 
01181   switch ( feedback->event_type )
01182   {
01183   case visualization_msgs::InteractiveMarkerFeedback::MOUSE_UP:
01184       try {
01185         mechanism_.sendCartesianPoseCommand( arm_name, mechanism_.getGripperPose(arm_name, feedback->header.frame_id));
01186       }
01187       catch ( std::runtime_error &e )
01188       {
01189         ROS_ERROR("Caught exception while sending pose command: %s", e.what( ));
01190       }
01191       break;
01192 
01193   case visualization_msgs::InteractiveMarkerFeedback::POSE_UPDATE:
01194     // TODO still assuming l and r will always be in sync... this is probably BAD...
01195     if(control_state_.r_gripper_.edit_control_ )
01196     {
01197       geometry_msgs::PoseStamped ps = object_manipulator::msg::createPoseStampedMsg(feedback->pose,
01198                                                                                     feedback->header.frame_id,
01199                                                                                     ros::Time(0));
01200       if(!strcmp(arm_name, "right_arm"))
01201         tfl_.transformPose("r_wrist_roll_link", ps, ps );
01202       if(!strcmp(arm_name, "left_arm"))
01203         tfl_.transformPose("l_wrist_roll_link", ps, ps );
01204 
01205       tf::poseMsgToTF(ps.pose, pose_offset_[arm_id]);
01206     }
01207     else
01208     {
01209       //geometry_msgs::PoseStamped ps = object_manipulator::msg::createPoseStampedMsg(
01210       //                                              feedback->pose, feedback->header.frame_id, ros::Time(0));
01211       //tfl_.transformPose("base_link", ps, ps );
01212 //      tf::Transform control_pose;
01213 //      tf::poseMsgToTF(feedback->pose, control_pose);
01214 //      tf::Transform command_pose = control_pose * pose_offset_[arm_id].inverse();
01215 
01216       ROS_DEBUG_STREAM("got updated gripper pose in frame " << feedback->header.frame_id);
01217 
01218       geometry_msgs::PoseStamped ps = object_manipulator::msg::createPoseStampedMsg(
01219                                                     feedback->pose, feedback->header.frame_id, feedback->header.stamp);
01220       commandGripperPose(ps, arm_id, true);
01221     }
01222     break;
01223   }
01224 }
01225 
01226 void PR2MarkerControl::updateDualGripper( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback )
01227 {
01228   ros::Time now = ros::Time(0);
01229   if(!control_state_.dual_grippers_.on_) return;
01230 
01231   //float half_width = 0.15;  // TODO this should be controllable in some way!
01232 
01233   switch ( feedback->event_type )
01234   {
01235   case visualization_msgs::InteractiveMarkerFeedback::MOUSE_UP:
01236       try {
01237         mechanism_.sendCartesianPoseCommand( "right_arm", mechanism_.getGripperPose("right_arm", feedback->header.frame_id));
01238         mechanism_.sendCartesianPoseCommand( "left_arm",  mechanism_.getGripperPose("left_arm",  feedback->header.frame_id));
01239       }
01240       catch ( std::runtime_error &e )
01241       {
01242         ROS_ERROR("Caught exception while sending pose command: %s", e.what( ));
01243       }
01244       break;
01245 
01246   case visualization_msgs::InteractiveMarkerFeedback::POSE_UPDATE:
01247     // TODO still assuming l and r will always be in sync... this is probably BAD...
01248 //    if(control_state_.r_gripper_.edit_control_ )
01249 //    {
01250 //      geometry_msgs::PoseStamped ps = object_manipulator::msg::createPoseStampedMsg(feedback->pose,
01251 //                                                                                    feedback->header.frame_id,
01252 //                                                                                    ros::Time(0));
01253 //      if(!strcmp(arm_name, "right_arm"))
01254 //        tfl_.transformPose("r_wrist_roll_link", ps, ps );
01255 //      if(!strcmp(arm_name, "left_arm"))
01256 //        tfl_.transformPose("l_wrist_roll_link", ps, ps );
01257 //
01258 //      tf::poseMsgToTF(ps.pose, pose_offset_[arm_id]);
01259 //    }
01260 //    else
01261     {
01262       if(control_state_.dual_grippers_.edit_control_ )
01263       {
01264         geometry_msgs::PoseStamped ps = object_manipulator::msg::createPoseStampedMsg(feedback->pose,
01265                                                                                       feedback->header.frame_id,
01266                                                                                       ros::Time(0));
01267         tfl_.transformPose(dual_grippers_frame_.header.frame_id, ps, ps ); 
01268         tf::Transform feedback_trans;
01269         tf::poseMsgToTF(ps.pose, feedback_trans);
01270         tf::Transform dual_pose_offset_tf;
01271         tf::Transform dual_grippers_frame_tf;
01272         tf::poseMsgToTF(dual_grippers_frame_.pose, dual_grippers_frame_tf);
01273         dual_pose_offset_ = feedback_trans.inverse() * dual_grippers_frame_tf;
01274       }
01275       else
01276       {
01277         tf::Transform command_pose;
01278 
01279         tf::poseMsgToTF(feedback->pose, command_pose);
01280         //tf::Transform command_pose = control_pose * pose_offset_[arm_id].inverse();
01281 
01282         double dummy_var = 0;
01283         tf::Transform offset_command_pose_tf = command_pose * dual_pose_offset_;
01284         geometry_msgs::Pose offset_command_pose;
01285         tf::poseTFToMsg(offset_command_pose_tf, offset_command_pose);
01286         geometry_msgs::PoseStamped offset_command_pose_stamped = msg::createPoseStampedMsg(offset_command_pose, feedback->header.frame_id, now);
01287         geometry_msgs::PoseStamped desired_pose =
01288           mechanism_.clipDesiredPose(dual_grippers_frame_,
01289                                      offset_command_pose_stamped,
01290                                      0.3*cartesian_clip_distance_*update_period_,
01291                                      0.3*cartesian_clip_angle_*update_period_,
01292                                      dummy_var);
01293 
01294         // compute left and right gripper poses
01295         tf::Transform b_T_m, b_T_r, b_T_l;
01296         tf::poseMsgToTF(desired_pose.pose, b_T_m);
01297         b_T_r = b_T_m * dual_gripper_offsets_[0];
01298         b_T_l = b_T_m * dual_gripper_offsets_[1];
01299         geometry_msgs::PoseStamped right_pose = msg::createPoseStampedMsg(b_T_r, feedback->header.frame_id, ros::Time(0));
01300         geometry_msgs::PoseStamped left_pose =  msg::createPoseStampedMsg(b_T_l, feedback->header.frame_id, ros::Time(0));
01301 
01302         //store new dual_grippers_frame_
01303         dual_grippers_frame_ = desired_pose;
01304 
01305         // send the commands
01306         try {
01307           mechanism_.sendCartesianPoseCommand( "right_arm", right_pose);
01308           mechanism_.sendCartesianPoseCommand( "left_arm",  left_pose);
01309         }
01310         catch ( std::runtime_error &e )
01311         {
01312           ROS_ERROR("Caught exception while sending pose command: %s", e.what( ));
01313         }
01314       }
01315     }
01316     break;
01317   }
01318 }
01319 
01320 
01321 
01323 void PR2MarkerControl::gripperButtonCB( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback, std::string action)
01324 {
01325   if (interface_number_ != 0 && interface_number_ != 1) return;
01326 
01327   std::string arm_name = getArmNameFromMarkerName(feedback->marker_name);
01328 
01329   if(arm_name == "right_arm")
01330   {
01331     if(action == "toggle") control_state_.r_gripper_.on_ ^= true;
01332     else if(action == "turn on") control_state_.r_gripper_.on_ = true;
01333     else control_state_.r_gripper_.on_ = false;
01334   }
01335   if(arm_name == "left_arm")
01336   {
01337     if(action == "toggle") control_state_.l_gripper_.on_ ^= true;
01338     else if(action == "turn on") control_state_.l_gripper_.on_ = true;
01339     else control_state_.l_gripper_.on_ = false;
01340   }
01341 
01342   if ( control_state_.r_gripper_.on_ || control_state_.l_gripper_.on_ ||
01343        control_state_.posture_r_ || control_state_.posture_l_ )
01344   {
01345     switchToCartesian();
01346   }
01347   else
01348   {
01349     switchToJoint();
01350   }
01351 }
01352 
01353 void PR2MarkerControl::upperArmButtonCB( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback, int id)
01354 {
01355   if (interface_number_ > 2) return;
01356 
01357   if(id == 0)
01358     control_state_.posture_r_ ^= true;
01359   if(id == 1)
01360     control_state_.posture_l_ ^= true;
01361 
01362   //always switch to Cartesian, so that joint trajectories are stopped in a hurry (e-stop)
01363   switchToCartesian();
01364 }
01365 
01366 void PR2MarkerControl::updatePosture( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback, int arm_id )
01367 {
01368   std::string arm_name = "right_arm";
01369   if(arm_id == 1) arm_name = "left_arm";
01370 
01371   std::vector<double> arm_angles(7);
01372   //mechanism_.getArmAngles(arm_name, arm_angles);
01373 
01374   switch ( feedback->event_type )
01375   {
01376     case visualization_msgs::InteractiveMarkerFeedback::MOUSE_UP:
01377     {
01378       // This value (9999) disables the posture control for the joint.
01379       for( size_t i = 0; i < arm_angles.size(); i++) arm_angles[i] = 9999;
01380       mechanism_.sendCartesianPostureCommand(arm_name, arm_angles);
01381       break;
01382     }
01383     case visualization_msgs::InteractiveMarkerFeedback::POSE_UPDATE:
01384     {
01385       tf::Quaternion q;
01386       tf::quaternionMsgToTF(feedback->pose.orientation, q);
01387       float angle = q.getAngle()*q.getAxis().dot(tf::Vector3(1,0,0));
01388 
01389       for( size_t i = 0; i < arm_angles.size(); i++) arm_angles[i] = 9999;
01390       arm_angles[2] = angle;
01391       mechanism_.sendCartesianPostureCommand(arm_name, arm_angles);
01392       break;
01393     }
01394   }
01395 }
01396 
01397 /*
01398 void PR2MarkerControl::controllerSelectMenuCB( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback )
01399 {
01400   MenuHandler::EntryHandle handle = feedback->menu_entry_id;
01401   MenuHandler::CheckState state;
01402 
01403   if(!menu_arms_.getCheckState(handle, state))  return;
01404   if ( handle == joint_handle_ )
01405   {
01406     switchToJoint();
01407     control_state_.r_gripper_.on_ = false;
01408     control_state_.l_gripper_.on_ = false;
01409   }
01410   if ( handle == jtranspose_handle_ )
01411   {
01412     switchToCartesian();
01413   }
01414 
01415   initAllMarkers();
01416   }*/
01417 
01418 void PR2MarkerControl::updateTorso( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback)
01419 {
01420   switch ( feedback->event_type )
01421   {
01422   case visualization_msgs::InteractiveMarkerFeedback::MOUSE_DOWN:
01423     if(!feedback->control_name.compare("up"))
01424       torso_client_.top();
01425     else if(!feedback->control_name.compare("down"))
01426       torso_client_.bottom();
01427     else
01428       ROS_ERROR("Marker control unrecognized, this is an error in the client implementation!");
01429     break;
01430   case visualization_msgs::InteractiveMarkerFeedback::MOUSE_UP:
01431     {
01432       arm_navigation_msgs::RobotState robot_state;
01433       mechanism_.getRobotState(robot_state);
01434       torso_client_.moveTo( getJointPosition("torso_lift_joint", robot_state) );
01435       break;
01436     }
01437   case visualization_msgs::InteractiveMarkerFeedback::BUTTON_CLICK:
01438     break;
01439   }
01440 }
01441 
01442 
01443 void PR2MarkerControl::updateBase( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback)
01444 {
01445   geometry_msgs::TwistStamped ts;
01446   ts.header.stamp = ros::Time::now();
01447   ts.header.frame_id = "base_link";
01448 
01449   tf::Vector3 linear  = tf::Vector3(0,0,0);
01450   tf::Vector3 angular = tf::Vector3(0,0,0);
01451 
01452   switch ( feedback->event_type )
01453   {
01454   case visualization_msgs::InteractiveMarkerFeedback::MOUSE_DOWN:
01455   {
01456 
01457     tf::Quaternion q;
01458     tf::quaternionMsgToTF(feedback->pose.orientation, q);
01459     tf::Matrix3x3 mat(q);
01460 
01461     if(!feedback->control_name.compare("forward"))  linear = tf::Vector3( 1, 0, 0);
01462     if(!feedback->control_name.compare("back"))     linear = tf::Vector3(-1, 0, 0);
01463     if(!feedback->control_name.compare("left"))     linear = tf::Vector3( 0, 1, 0);
01464     if(!feedback->control_name.compare("right"))    linear = tf::Vector3( 0,-1, 0);
01465     if(!feedback->control_name.compare("rotate right"))  angular = tf::Vector3(0, 0,-1);
01466     if(!feedback->control_name.compare("rotate left"))   angular = tf::Vector3(0, 0, 1);
01467 
01468     linear = 0.3*(mat*linear);
01469     angular = 0.5*angular;
01470 
01471     tf::vector3TFToMsg(linear, ts.twist.linear);
01472     tf::vector3TFToMsg(angular, ts.twist.angular);
01473 
01474     base_client_.applyTwist(ts);
01475     break;
01476   }
01477   case visualization_msgs::InteractiveMarkerFeedback::MOUSE_UP:
01478     base_client_.applyTwist(ts);
01479     break;
01480   case visualization_msgs::InteractiveMarkerFeedback::BUTTON_CLICK:
01481     break;
01482   }
01483 }
01484 
01485 void PR2MarkerControl::torsoMenuCB( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback)
01486 {
01487   if(!feedback->control_name.compare("up"))
01488     torso_client_.top();
01489   else if(!feedback->control_name.compare("down"))
01490     torso_client_.bottom();
01491   else
01492     ROS_ERROR("Marker control unrecognized, this is an error in the client implementation!");
01493 }
01494 
01495 
01496 void PR2MarkerControl::gripperClosureCB( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback, const float &command)
01497 {
01498   std::string arm_name = getArmNameFromMarkerName(feedback->marker_name);
01499   double open = gripper_client_.getGripperOpenGap(arm_name);
01500   double closed = gripper_client_.getGripperClosedGap(arm_name);
01501   double value = closed + (open - closed) * command;
01502 
01503   if( arm_name != "" )
01504   {
01505     gripper_client_.commandGripperValue(arm_name, value);
01506   }
01507   else
01508     ROS_ERROR("Marker name [%s] not handled!", feedback->marker_name.c_str());
01509 
01510   //if opening the gripper, reset attached objects for that arm
01511   if (value > closed + (open - closed)/2.)
01512     mechanism_.detachAllObjectsFromGripper(arm_name);
01513 }
01514 
01515 void PR2MarkerControl::requestGripperPose(  const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback,
01516                                             int arm_id)
01517 {
01518   std::string arm_name;
01519   if(!feedback->marker_name.compare("r_gripper_control")){
01520     arm_name = "right_arm";
01521   }
01522   else if(!feedback->marker_name.compare("l_gripper_control"))
01523   {
01524     arm_name = "left_arm";
01525   }
01526   else
01527   {
01528     ROS_ERROR("Marker name [%s] not recognized...", feedback->marker_name.c_str());
01529     return;
01530   }
01531 
01532   pr2_object_manipulation_msgs::GetGripperPoseGoal goal;
01533   goal.arm_name = arm_name;
01534   goal.gripper_opening = 0.08;
01535   if(arm_name == "right_arm") goal.gripper_pose = mechanism_.getGripperPose(arm_name, "torso_lift_link");
01536   if(arm_name == "left_arm") goal.gripper_pose = mechanism_.getGripperPose(arm_name, "torso_lift_link");
01537   gripper_pose_client_.client().sendGoal( goal,
01538                                           boost::bind(&PR2MarkerControl::processGripperPoseResult, this, _1, _2, arm_name),
01539                                           actionlib::SimpleActionClient<pr2_object_manipulation_msgs::GetGripperPoseAction>::SimpleActiveCallback(),
01540                                           //actionlib::SimpleActionClient<pr2_object_manipulation_msgs::GetGripperPoseAction>::SimpleFeedbackCallback());//,
01541                                           boost::bind(&PR2MarkerControl::processGripperPoseFeedback, this, _1, arm_name) );
01542   
01543   control_state_.r_gripper_.on_ = false;
01544   control_state_.l_gripper_.on_ = false;
01545   initControlMarkers();
01546 }
01547 
01548 void PR2MarkerControl::processGripperPoseFeedback(  const pr2_object_manipulation_msgs::GetGripperPoseFeedbackConstPtr &result,
01549                                                     const std::string &arm_name)
01550 {
01551   int arm_id = 0;
01552   if(arm_name == "left_arm") arm_id = 1;
01553 
01554   commandGripperPose(result->gripper_pose, arm_id, false);
01555 
01556 }
01557 
01558 void PR2MarkerControl::processGripperPoseResult(  const actionlib::SimpleClientGoalState& state,
01559                                                   const pr2_object_manipulation_msgs::GetGripperPoseResultConstPtr &result,
01560                                                   const std::string &arm_name)
01561 {
01562   ROS_ERROR("We should be setting the state back to 'controls active' here.");
01563   control_state_.r_gripper_.on_ = true;
01564   control_state_.l_gripper_.on_ = true;
01565   initControlMarkers();
01566 }
01567 
01568 void PR2MarkerControl::moveArm( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback, const std::string &position,
01569               bool planner)
01570 {
01571   std::string arm_name;
01572   if( feedback->marker_name == "r_upper_arm_link" || feedback->marker_name == "r_gripper_palm_link" )
01573     arm_name = "right_arm";
01574   else if( feedback->marker_name == "l_upper_arm_link" || feedback->marker_name == "l_gripper_palm_link" )
01575     arm_name = "left_arm";
01576   else
01577     ROS_WARN("Marker name [%s] not handled!", feedback->marker_name.c_str());
01578 
01579   std::string move_type = (planner)?("with planner"):("open-loop");
01580   ROS_INFO("moving %s to %s %s", arm_name.c_str(), position.c_str(), move_type.c_str());
01581   sys_thread_.reset( new boost::thread( boost::bind(
01582               &PR2MarkerControl::moveArmThread, this, arm_name, position, true, planner ) ) );
01583 }
01584 
01585 
01586 void PR2MarkerControl::moveArmThread(std::string arm_name, std::string position, bool collision, bool planner)
01587 {
01588   if (interface_number_ != 0) gripper_client_.commandGripperValue(arm_name, gripper_client_.getGripperOpenGap(arm_name));
01589   try
01590   {
01591     ROS_DEBUG("Attempting arm motion");
01592     arm_navigation_msgs::OrderedCollisionOperations ord;
01593     if (!collision)
01594     {
01595       arm_navigation_msgs::CollisionOperation coll;
01596       coll.object1 = arm_navigation_msgs::CollisionOperation::COLLISION_SET_ALL;
01597       coll.object2 = arm_navigation_msgs::CollisionOperation::COLLISION_SET_ALL;
01598       coll.operation = arm_navigation_msgs::CollisionOperation::DISABLE;
01599       ord.collision_operations.push_back(coll);
01600     }
01601     std::vector<arm_navigation_msgs::LinkPadding> pad;
01602     if (collision)
01603     {
01604       pad = object_manipulator::concat( object_manipulator::MechanismInterface::gripperPadding("left_arm", 0.0),
01605                                         object_manipulator::MechanismInterface::gripperPadding("right_arm", 0.0) );
01606     }
01607     if (planner)
01608     {
01609       //ompl will crash if move_arm for the right and left arms try to plan at the same time, so lock to make sure we don't send two goals at once
01610       if(planner_lock_.try_lock())
01611       {
01612         ROS_INFO("Locking to attemptMoveArmToGoal for %s", arm_name.c_str());
01613 
01614         //clear any current move arm goals if there are any running before trying to issue our own
01615         mechanism_.clearMoveArmGoals();
01616 
01617         //trying move_arm twice, resetting map if stuck, timeout of 30 seconds
01618         mechanism_.attemptMoveArmToGoal(arm_name,
01619                                         object_manipulator::armConfigurations().position(arm_name, position), ord, pad, 2, true, 30.);
01620         planner_lock_.unlock();
01621         ROS_INFO("moveArmThread for %s released lock", arm_name.c_str());
01622       }
01623       //if we're already asking move_arm to do something, try to cancel goals and then try again
01624       else
01625       {
01626         ROS_INFO("marker control: Failed to get lock when trying to move %s!  Clearing move arm goals twice", arm_name.c_str());
01627 
01628         //clear goals twice, since we always try twice
01629         mechanism_.clearMoveArmGoals();
01630         ros::Duration(0.25).sleep();
01631         ROS_INFO("marker control: clearing move arm goals a second time");
01632         mechanism_.clearMoveArmGoals();
01633         ROS_INFO("marker control: done clearing move arm goals before moving %s", arm_name.c_str());
01634         if(planner_lock_.try_lock())
01635         {
01636           ROS_INFO("Got lock this time, locking to attemptMoveArmToGoal for %s", arm_name.c_str());
01637           //trying twice, resetting map if stuck, timeout of 30 seconds
01638           mechanism_.attemptMoveArmToGoal(arm_name,
01639                                           object_manipulator::armConfigurations().position(arm_name, position), ord, pad, 2, true, 30.);
01640           planner_lock_.unlock();
01641           ROS_INFO("released lock after moving %s", arm_name.c_str());
01642         }
01643         else
01644         {
01645           ROS_INFO("Failed to get lock again when trying to move %s, giving up", arm_name.c_str());
01646         }
01647       }
01648     }
01649     else
01650     {
01651       mechanism_.attemptTrajectory(arm_name, object_manipulator::armConfigurations().trajectory(arm_name, position),
01652                                    false, 2.0);
01653     }
01654   }
01655   catch (object_manipulator::ServiceNotFoundException &ex)
01656   {
01657     ROS_ERROR("a needed service or action server was not found");
01658   }
01659   catch (object_manipulator::MoveArmStuckException &ex)
01660   {
01661     ROS_ERROR("arm is stuck in a colliding position");
01662     planner_lock_.unlock();
01663   }
01664   catch (object_manipulator::MissingParamException &ex)
01665   {
01666     ROS_ERROR("parameters missing; is manipulation pipeline running?");
01667   }
01668   catch (object_manipulator::MechanismException &ex)
01669   {
01670     ROS_ERROR("Error: %s", ex.what());
01671     planner_lock_.unlock();
01672   }
01673   catch (...)
01674   {
01675     ROS_ERROR("an unknown error has occured, please call helpdesk");
01676     planner_lock_.unlock();
01677   }
01678 
01679   // Interface 1 (cartesian teleop) should always pop up the control rings.
01680   if(interface_number_ == 1)
01681   {
01682     switchToCartesian();
01683     control_state_.r_gripper_.on_ = true;
01684   }
01685   // Auto-refresh / reset collision map is useful when running with novice users.
01686   if(interface_number_ != 0){
01687     snapshot_client_.refresh( nh_.resolveName("snapshot_input_topic", true) );
01688     std_srvs::Empty srv;
01689     if (!collider_node_reset_srv_.client().call(srv)) ROS_ERROR("failed to reset collision map!");
01690   }
01691 }
01692 
01693 
01694 void PR2MarkerControl::requestNavGoal(const bool &collision_aware)
01695 {
01696   //ROS_WARN("Starting requestNavGoal");
01697   // First call the 'get pose' action so that the user is distracted.
01698   pr2_object_manipulation_msgs::GetNavPoseGoal goal;
01699   goal.max_distance = collision_aware ? (-1.0): (max_direct_nav_radius_);
01700   base_pose_client_.client().sendGoal( goal, boost::bind(&PR2MarkerControl::processNavGoal, this, _1, _2, collision_aware));
01701 
01702   if( using_3d_nav_ ) 
01703   {
01704     ROS_INFO("Using 3D navigation, not changing global or local planners");
01705     return;
01706   }
01707 
01708   // While the user is using the requested action, configure the planner in the background. 
01709   std::string reconfigure = "rosrun dynamic_reconfigure dynparam set ";
01710   std::string move_base_config, costmap_config;
01711   
01712   if( collision_aware )
01713   {
01714     ROS_INFO("Activating 'global' planner.");
01715     // Don't just use "restore_defaults: true" because it restores whatever was on the param server when the node started."
01716 
01717     // We could dynamically set the footprint of the robot based on the arm pose during these calls!
01718     move_base_config = reconfigure + move_base_node_name_ + " "
01719                        + "\"{'base_global_planner': 'navfn/NavfnROS', "
01720                        + "   'base_local_planner' : 'dwa_local_planner/DWAPlannerROS'}\" ";
01721     costmap_config = reconfigure + move_base_node_name_ + "/local_costmap \"{ "
01722                      + "'max_obstacle_height' : 2.0, 'inflation_radius' : 0.55 }\" ";
01723   }
01724   else
01725   {
01726     ROS_INFO("Activating 'local' planner.");
01727     move_base_config = reconfigure + move_base_node_name_ +" "
01728 //                       + "\"{'base_global_planner': 'navfn/NavfnROS', "
01729                        + "\"{'base_global_planner': 'pr2_navigation_controllers/GoalPasser', "
01730                        + "   'base_local_planner' : 'pr2_navigation_controllers/PoseFollower'}\" ";
01731     
01732     costmap_config = reconfigure + move_base_node_name_ + "/local_costmap \"{ "
01733                      + "'max_obstacle_height' : 0.36 , 'inflation_radius': 0.01 }\" ";
01734   }
01735 
01736   //ROS_WARN("Setting planners...");
01737   int ok = system(move_base_config.c_str());
01738   if(ok < 0)
01739     ROS_ERROR("Dynamic reconfigure for move_base_node FAILED!");
01740   //ROS_WARN("Setting costmap configuration...");
01741   ok = system(costmap_config.c_str());
01742   if(ok < 0)
01743     ROS_ERROR("Dynamic reconfigure for move_base_node/local_costmap FAILED!");  
01744   ROS_INFO("Done!");
01745   //ROS_WARN("Exiting requestNavGoal");
01746 }
01747 
01748 void PR2MarkerControl::processNavGoal(  const actionlib::SimpleClientGoalState& state,
01749                                         const pr2_object_manipulation_msgs::GetNavPoseResultConstPtr &result,
01750                                         const bool &collision_aware )
01751 {
01752   if(state.state_ == state.SUCCEEDED)
01753   {
01754     ROS_DEBUG("Got a valid base pose.");
01755     base_goal_pose_ = result->pose;
01756     sendLastNavGoal();
01757   }
01758   else
01759   {
01760     ROS_WARN("Get Base Pose Action did not succeed; state = %d", (int)state.state_);
01761   }
01762 }
01763 
01764 void PR2MarkerControl::requestBasePoseEstimate()
01765 {
01766   pr2_object_manipulation_msgs::GetNavPoseGoal goal;
01767   goal.max_distance = -1.0;
01768   base_pose_client_.client().sendGoal( goal, boost::bind(&PR2MarkerControl::processBasePoseEstimate, this, _1, _2));
01769 }
01770 
01771 
01772 void PR2MarkerControl::processBasePoseEstimate( const actionlib::SimpleClientGoalState& state,
01773                                                 const pr2_object_manipulation_msgs::GetNavPoseResultConstPtr &result )
01774 {
01775   if(state.state_ == state.SUCCEEDED)
01776   {
01777     ROS_DEBUG("Got a valid estimate for base pose.");
01778     geometry_msgs::PoseWithCovarianceStamped ps;
01779     ps.pose.pose = result->pose.pose;
01780     ps.pose.pose.position.z = 0;  //enforce 0 ground-plane position
01781     ps.header = result->pose.header;
01782 
01783     //Covariance values taken from what Rviz publishes... no idea if these are optimal though.
01784     ps.pose.covariance.at(6*0 + 0) = 0.25;
01785     ps.pose.covariance.at(6*1 + 1) = 0.25;
01786     ps.pose.covariance.at(6*5 + 5) = 0.06853891945200942;
01787 
01788     base_client_.sendPoseEstimate(ps);
01789   }
01790   else
01791   {
01792     ROS_WARN("Get Base Pose Action did not succeed; state = %d", (int)state.state_);
01793   }
01794 }
01795 
01796 void PR2MarkerControl::sendLastNavGoal()
01797 {
01798     if( (ros::Time::now() - base_goal_pose_.header.stamp).toSec() < 60.0 )
01799     {
01800         ROS_INFO("Sending last base goal pose");
01801         base_client_.sendNavGoal( base_goal_pose_ );
01802     }
01803     else
01804     {
01805         base_goal_pose_ = geometry_msgs::PoseStamped();
01806         base_goal_pose_.header.frame_id = "base_link";
01807         base_goal_pose_.pose.orientation.w = 1; 
01808         ROS_INFO("Last goal was from too long ago; sending identity base goal pose");
01809         base_client_.sendNavGoal( base_goal_pose_ );
01810     }
01811 }
01812 
01813 void PR2MarkerControl::clearLocalCostmap()
01814 {
01815     ROS_INFO("Clearing the navigation costmap...");
01816     base_client_.clearLocalCostmap( );
01817 }
01818 
01819 void PR2MarkerControl::inHandObjectRightCallback(const sensor_msgs::PointCloud2ConstPtr &cloud)
01820 {
01821   ROS_INFO("Got an in-hand object cloud for the right hand!");
01822   object_cloud_right_.updateCloud(*cloud, "in_hand_object_right");
01823 }
01824 
01825 void PR2MarkerControl::inHandObjectLeftCallback(const sensor_msgs::PointCloud2ConstPtr &cloud)
01826 {
01827   ROS_INFO("Got an in-hand object cloud for the left hand!");
01828   object_cloud_left_.updateCloud(*cloud, "in_hand_object_left");
01829 }
01830 
01831 void PR2MarkerControl::initMenus()
01832 {
01833   MenuHandler::EntryHandle handle;
01834 
01835   // - - - - - - - - - - Head Menu - - - - - - - - - - //
01836 
01837   menu_head_.insert("Take Snapshot", boost::bind( &PR2MarkerControl::snapshotCB, this ) );
01838 
01839   if (interface_number_ == 0)
01840   {
01841     head_target_handle_ = menu_head_.insert( "Target Point", boost::bind( &PR2MarkerControl::targetPointMenuCB,
01842                                                                           this, _1 ) );
01843     menu_head_.setCheckState(head_target_handle_, MenuHandler::UNCHECKED);
01844 
01845     projector_handle_ = menu_head_.insert("Projector", boost::bind( &PR2MarkerControl::projectorMenuCB,
01846                                                                     this, _1 ) );
01847     menu_head_.setCheckState(projector_handle_, MenuHandler::UNCHECKED);
01848 
01849     menu_head_.insert( "Move Head To Center", boost::bind( &PR2MarkerControl::centerHeadCB,
01850                                                            this ) );
01851     menu_head_.reApply(server_);
01852   }
01853 
01854 
01855   // - - - - - - - - - - Arm Menu - - - - - - - - - - //
01856   if (interface_number_ == 0)
01857   {
01858     tuck_handle_ = menu_arms_.insert( "Tuck..." );
01859     menu_arms_.insert(tuck_handle_, "Untuck Both Arms",         boost::bind( &PR2MarkerControl::tuckArmsCB, this, false, false));
01860     menu_arms_.insert(tuck_handle_, "Untuck left, tuck right",  boost::bind( &PR2MarkerControl::tuckArmsCB, this, false, true ));
01861     menu_arms_.insert(tuck_handle_, "Tuck left, untuck right",  boost::bind( &PR2MarkerControl::tuckArmsCB, this, true, false ));
01862     menu_arms_.insert(tuck_handle_, "Tuck Both Arms",           boost::bind( &PR2MarkerControl::tuckArmsCB, this, true, true  ));
01863   }
01864 
01865   if (interface_number_ == 0)
01866   {
01867     handle = menu_arms_.insert( "Safe move to ... " );
01868     menu_arms_.insert( handle, "above", boost::bind( &PR2MarkerControl::moveArm, this, _1, "above", true  ) );
01869     menu_arms_.insert( handle, "side",  boost::bind( &PR2MarkerControl::moveArm, this, _1, "side", true  ) );
01870     menu_arms_.insert( handle, "front", boost::bind( &PR2MarkerControl::moveArm, this, _1, "front", true ) );
01871 
01872     handle = menu_arms_.insert( "Forced move to ... " );
01873     menu_arms_.insert( handle, "above", boost::bind( &PR2MarkerControl::moveArm, this, _1, "above", false  ) );
01874     menu_arms_.insert( handle, "side",  boost::bind( &PR2MarkerControl::moveArm, this, _1, "side", false  ) );
01875     menu_arms_.insert( handle, "front", boost::bind( &PR2MarkerControl::moveArm, this, _1, "front", false ) );
01876 
01877     handle = menu_arms_.insert( "Gripper commands" );
01878     menu_arms_.insert( handle, "Activate Cartesian control",
01879                        boost::bind( &PR2MarkerControl::gripperButtonCB, this, _1, "turn on") );
01880     menu_arms_.insert( handle, "Turn off Cartesian control",
01881                        boost::bind( &PR2MarkerControl::gripperButtonCB, this, _1, "turn off") );
01882     menu_arms_.insert( handle, "Open Gripper",
01883                        boost::bind( &PR2MarkerControl::gripperClosureCB, this, _1, 1 ) );
01884     menu_arms_.insert( handle, "Close Gripper",
01885                        boost::bind( &PR2MarkerControl::gripperClosureCB, this, _1, 0 ) );
01886 
01887     handle = menu_arms_.insert( "Plug..." );
01888     menu_arms_.insert( handle, "Plug in", boost::bind( &PR2MarkerControl::plugsCB, this, PLUGS_PLUGIN) );
01889     menu_arms_.insert( handle, "Unplug", boost::bind( &PR2MarkerControl::plugsCB, this, PLUGS_UNPLUG) );
01890     menu_arms_.insert( handle, "Cancel", boost::bind( &PR2MarkerControl::plugsCB, this, PLUGS_CANCEL) );
01891   }
01892   else
01893   {
01894     menu_arms_.insert( "Drop object and reset position",
01895                        boost::bind( &PR2MarkerControl::moveArm, this, _1, "side", true  ) );
01896   }
01897 
01898   // - - - - - - - - - - Gripper Control Menu - - - - - - - - - - //
01899 
01900   gripper_fixed_control_handle_ = menu_grippers_.insert( "Torso-Fixed Control",
01901                                                   boost::bind( &PR2MarkerControl::gripperToggleFixedCB, this, _1 ) );
01902   menu_grippers_.setCheckState(gripper_fixed_control_handle_, MenuHandler::CHECKED);
01903 
01904   if (interface_number_ == 0)
01905   {
01906     handle = menu_grippers_.insert( "Marker Mode" );
01907 
01908     gripper_6dof_handle_ = menu_grippers_.insert( handle, "6 DOF",
01909                                                   boost::bind( &PR2MarkerControl::gripperToggleModeCB, this, _1 ) );
01910     menu_grippers_.setCheckState(gripper_6dof_handle_, MenuHandler::CHECKED);
01911 
01912     gripper_view_facing_handle_ = menu_grippers_.insert( handle, "View Facing",
01913                                                   boost::bind( &PR2MarkerControl::gripperToggleModeCB, this, _1 ) );
01914     menu_grippers_.setCheckState(gripper_view_facing_handle_, MenuHandler::UNCHECKED);
01915 
01916     gripper_edit_control_handle_ = menu_grippers_.insert( "Edit Control Frame",
01917                                                boost::bind( &PR2MarkerControl::gripperToggleControlCB, this, _1 ) );
01918     menu_grippers_.setCheckState(gripper_edit_control_handle_, MenuHandler::UNCHECKED);
01919 
01920     gripper_reset_control_handle_ = menu_grippers_.insert( "Reset Control Frame",
01921                                                 boost::bind( &PR2MarkerControl::gripperResetControlCB, this, _1 ) );
01922     menu_grippers_.insert( "Dual Grippers", boost::bind( &PR2MarkerControl::startDualGrippers, this, _1, true ) );
01923     menu_grippers_.insert( "Collision-Constraint", boost::bind( &PR2MarkerControl::requestGripperPose, this, _1, 0 ) );
01924   }
01925 
01926   // - - - - - - - - - - Dual-Gripper Control Menu - - - - - - - - - - //
01927 
01928   if (interface_number_ == 0)
01929   {
01930     menu_dual_grippers_.insert( "Exit", boost::bind( &PR2MarkerControl::startDualGrippers, this, _1, false ) );
01931     dual_gripper_fixed_control_handle_ = menu_dual_grippers_.insert( "Torso-Fixed Control", 
01932                                               boost::bind( &PR2MarkerControl::dualGripperToggleFixedCB, this, _1 ) );
01933     menu_dual_grippers_.setCheckState(dual_gripper_edit_control_handle_, MenuHandler::CHECKED);
01934     dual_gripper_edit_control_handle_ = menu_dual_grippers_.insert( "Edit Control Frame", 
01935                                               boost::bind( &PR2MarkerControl::dualGripperToggleControlCB, this, _1 ) );
01936     menu_dual_grippers_.setCheckState(dual_gripper_edit_control_handle_, MenuHandler::UNCHECKED);
01937     dual_gripper_reset_control_handle_ = menu_dual_grippers_.insert( "Reset Control Frame", 
01938                                               boost::bind( &PR2MarkerControl::dualGripperResetControlCB, this, _1 ) );
01939   }
01940 
01941   // - - - - - - - - - - Gripper Closure Menu - - - - - - - - - - //
01942 
01943   if (interface_number_ < 3)
01944   {
01945     menu_gripper_close_.insert( "Open Gripper",  boost::bind( &PR2MarkerControl::gripperClosureCB, this, _1, 1 ) );
01946     menu_gripper_close_.insert( "Close Gripper", boost::bind( &PR2MarkerControl::gripperClosureCB, this, _1, 0 ) );
01947   }
01948   else
01949   {
01950     menu_gripper_close_.insert( "Drop object and reset position",
01951         boost::bind( &PR2MarkerControl::moveArm, this, _1, "side", true  ) );
01952   }
01953 
01954   // - - - - - - - - - - Torso Menu - - - - - - - - - - //
01955   menu_torso_.insert( "All the way", boost::bind( &PR2MarkerControl::torsoMenuCB, this, _1 ) );
01956 
01957   // - - - - - - - - - - Base Menu - - - - - - - - - - //
01958   menu_base_.insert( "Navigate to...",      boost::bind( &PR2MarkerControl::requestNavGoal, this, true ) );
01959   menu_base_.insert( "Directly Move to...", boost::bind( &PR2MarkerControl::requestNavGoal, this, false ) );
01960   menu_base_.insert( "Resume last Goal", boost::bind( &PR2MarkerControl::sendLastNavGoal, this ) );
01961   menu_base_.insert( "Clear costmaps", boost::bind( &PR2MarkerControl::clearLocalCostmap, this ) );
01962   menu_base_.insert( "Set Pose on Map", boost::bind( &PR2MarkerControl::requestBasePoseEstimate, this ) );
01963 }
01964 
01965 
01966 // Graveyard


pr2_marker_control
Author(s): Adam Leeper
autogenerated on Mon Oct 6 2014 12:48:08