$search
00001 /* 00002 * Copyright (c) 2011, Willow Garage, Inc. 00003 * All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions are met: 00007 * 00008 * * Redistributions of source code must retain the above copyright 00009 * notice, this list of conditions and the following disclaimer. 00010 * * Redistributions in binary form must reproduce the above copyright 00011 * notice, this list of conditions and the following disclaimer in the 00012 * documentation and/or other materials provided with the distribution. 00013 * * Neither the name of the Willow Garage, Inc. nor the names of its 00014 * contributors may be used to endorse or promote products derived from 00015 * this software without specific prior written permission. 00016 * 00017 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00018 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00019 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00020 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 00021 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00022 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00023 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00024 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00025 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00026 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00027 * POSSIBILITY OF SUCH DAMAGE. 00028 */ 00029 00030 // author: Adam Leeper 00031 00032 // **** 10 ***** 20 ****** 30 ****** 40 ****** 50 ****** 60 ****** 70 ****** 80 ****** 90 ***** 100 ***** 110 ***** 120 00033 00034 #include <ros/ros.h> 00035 #include <math.h> 00036 00037 #include <arm_navigation_msgs/GetStateValidity.h> 00038 00039 #include <interactive_markers/interactive_marker_server.h> 00040 #include <interactive_markers/menu_handler.h> 00041 00042 #include <std_srvs/Empty.h> 00043 00044 #include <actionlib/client/simple_action_client.h> 00045 #include <actionlib/server/simple_action_server.h> 00046 00047 #include <boost/thread.hpp> 00048 00049 #include <tf/transform_listener.h> 00050 00051 #include <interactive_marker_helpers/interactive_marker_helpers.h> 00052 #include <pr2_object_manipulation_msgs/GetNavPoseAction.h> 00053 #include "cloud_handler.h" 00054 #include "marker_control.h" 00055 00056 using namespace object_manipulator; 00057 using namespace visualization_msgs; 00058 using namespace interactive_markers; 00059 using namespace im_helpers; 00060 00062 00063 // First define a useful helper function... 00068 void offsetPS(tf::StampedTransform &st, const btTransform &offset) 00069 { 00070 btTransform pose = btTransform(st.getRotation(), st.getOrigin()); 00071 pose = pose * offset; 00072 st.setData(pose); 00073 } 00074 00076 geometry_msgs::PoseStamped PR2MarkerControl::toolToWrist(const geometry_msgs::PoseStamped &ps) 00077 { 00078 geometry_msgs::PoseStamped out; 00079 out.header = ps.header; 00080 tf::Transform T, P; 00081 tf::poseMsgToTF(ps.pose, P); 00082 tf::poseMsgToTF(tool_frame_offset_, T); 00083 tf::poseTFToMsg( P*T.inverse(), out.pose); 00084 //out.pose = object_manipulator::msg::applyShift(ps.pose, tf::Vector3(-0.15,0,0)); 00085 return out; 00086 } 00087 00089 geometry_msgs::PoseStamped PR2MarkerControl::wristToTool(const geometry_msgs::PoseStamped &ps) 00090 { 00091 geometry_msgs::PoseStamped out; 00092 out.header = ps.header; 00093 tf::Transform T, P; 00094 tf::poseMsgToTF(ps.pose, P); 00095 tf::poseMsgToTF(tool_frame_offset_, T); 00096 tf::poseTFToMsg( P*T, out.pose); 00097 //out.pose = object_manipulator::msg::applyShift(ps.pose, tf::Vector3(-0.15,0,0)); 00098 return out; 00099 } 00100 00102 00103 00104 PR2MarkerControl::PR2MarkerControl() : 00105 nh_("/"), 00106 pnh_("~"), 00107 server_("pr2_marker_control", "marker_control", false), 00108 tfl_(nh_), 00109 torso_client_(), 00110 base_client_(nh_, ros::Duration(2.0), &tfl_), 00111 tuck_arms_client_(nh_, ros::Duration(20.0)), 00112 check_state_validity_client_("/current_state_validator/get_state_validity"), 00113 collider_node_reset_srv_("/collider_node/reset"), 00114 snapshot_client_(&nh_, &tfl_, "interactive_manipulation_snapshot", server_, mechanism_), 00115 base_pose_client_("pr2_interactive_nav_action", true), 00116 gripper_pose_client_("pr2_interactive_gripper_pose_action", true) 00117 { 00118 ROS_INFO( "Starting up PR2 MARKER CONTROL application." ); 00119 00120 ros::Duration(2.0).sleep(); 00121 00122 pnh_.param<bool>("use_right_arm", use_right_arm_, true); 00123 pnh_.param<bool>("use_left_arm", use_left_arm_, true); 00124 pnh_.param<bool>("use_state_validator", use_state_validator_, true); 00125 00126 pnh_.param<double>("gripper_control_linear_deadband", gripper_control_linear_deadband_, 0.002); 00127 pnh_.param<double>("gripper_control_angular_deadband", gripper_control_angular_deadband_, 0.01); 00128 pnh_.param<double>("update_period", update_period_, 0.05); 00129 pnh_.param<double>("cartesian_clip_distance", cartesian_clip_distance_, 2); 00130 pnh_.param<double>("cartesian_clip_angle", cartesian_clip_angle_, 10); 00131 pnh_.param<std::string>("head_pointing_frame", head_pointing_frame_, "/default_head_pointing_frame"); 00132 pnh_.param<bool>("double_menu", double_menu_, false); 00133 pnh_.param<std::string>("move_base_node_name", move_base_node_name_, "move_base_node"); 00134 pnh_.param<bool>("nav_3d", using_3d_nav_, false); 00135 00136 pnh_.param<double>("max_direct_nav_radius", max_direct_nav_radius_, 0.4); 00137 00138 nh_.param<int>("interactive_grasping/interface_number", interface_number_, 0); 00139 if (interface_number_) ROS_INFO("Using interface number %d for grasping study", interface_number_); 00140 nh_.param<int>("interactive_grasping/task_number", task_number_, 0); 00141 if (task_number_) ROS_INFO("Using task number %d for grasping study", task_number_); 00142 00143 if (interface_number_ == 1) 00144 { 00145 control_state_.r_gripper_.on_ = true; 00146 control_state_.posture_r_ = true; 00147 switchToCartesian(); 00148 } 00149 00150 in_collision_r_ = false; 00151 in_collision_l_ = false; 00152 00153 btTransform offset = btTransform(btQuaternion(0, 0, 0, 1), btVector3(0.1, 0, 0)); 00154 pose_offset_.push_back(offset); 00155 pose_offset_.push_back(offset); 00156 00157 dual_gripper_offsets_.push_back(offset); 00158 dual_gripper_offsets_.push_back(offset); 00159 00160 tool_frame_offset_ = msg::createPoseMsg(tf::Pose(tf::Quaternion::getIdentity(), tf::Vector3(0.18,0,0))); 00161 00162 head_goal_pose_.pose.position.x = 1.0; 00163 head_goal_pose_.pose.position.z = 1.0; 00164 head_goal_pose_.header.frame_id = "base_link"; 00165 00166 base_goal_pose_.header.frame_id = "base_link"; 00167 base_goal_pose_.pose.orientation.w = 1; 00168 00169 // Must initialize the menus before creating the markers! 00170 initMenus(); 00171 00172 // Initialize (or hard "reset") of all markers. 00173 initAllMarkers(); 00174 00175 spin_timer_ = nh_.createTimer(ros::Duration(update_period_), boost::bind( &PR2MarkerControl::fastUpdate, this ) ); 00176 slow_sync_timer_ = nh_.createTimer(ros::Duration(0.5), boost::bind( &PR2MarkerControl::slowUpdate, this ) ); 00177 } 00178 00179 00180 void PR2MarkerControl::fastUpdate() 00181 { 00182 ros::Time now = ros::Time(0); 00183 00184 tf::StampedTransform stamped; 00185 geometry_msgs::TransformStamped ts; 00186 00187 if(control_state_.r_gripper_.on_) 00188 { 00189 geometry_msgs::PoseStamped ps; 00190 static geometry_msgs::PoseStamped last; 00191 tfl_.waitForTransform("r_wrist_roll_link","base_link", now, ros::Duration(2.0)); 00192 tfl_.lookupTransform("base_link", "r_wrist_roll_link", now, stamped); 00193 offsetPS(stamped, pose_offset_[0]); 00194 tf::transformStampedTFToMsg(stamped, ts); 00195 ps = object_manipulator::msg::createPoseStampedMsg(ts); 00196 ps.header.stamp = ros::Time(0); // Time(0) makes this stay fixed in base_link 00197 00198 double pos_dist = 0, angle = 0; 00199 mechanism_.poseDists(ps.pose, last.pose, pos_dist, angle); 00200 if(pos_dist > gripper_control_linear_deadband_ || angle > gripper_control_angular_deadband_) 00201 { 00202 server_.setPose("r_gripper_control", ps.pose, ps.header); 00203 last = ps; 00204 } 00205 } 00206 if(control_state_.l_gripper_.on_) 00207 { 00208 geometry_msgs::PoseStamped ps; 00209 static geometry_msgs::PoseStamped last; 00210 tfl_.waitForTransform("l_wrist_roll_link","base_link", now, ros::Duration(2.0)); 00211 tfl_.lookupTransform("base_link", "l_wrist_roll_link", now, stamped); 00212 offsetPS(stamped, pose_offset_[1]); 00213 tf::transformStampedTFToMsg(stamped, ts); 00214 ps = object_manipulator::msg::createPoseStampedMsg(ts); 00215 ps.header.stamp = ros::Time(0); // Time(0) makes this stay fixed in base_link 00216 00217 double pos_dist = 0, angle = 0; 00218 mechanism_.poseDists(ps.pose, last.pose, pos_dist, angle); 00219 if(pos_dist > gripper_control_linear_deadband_ || angle > gripper_control_angular_deadband_) 00220 { 00221 server_.setPose("l_gripper_control", ps.pose, ps.header); 00222 last = ps; 00223 } 00224 } 00225 00226 server_.applyChanges(); 00227 } 00228 00229 void PR2MarkerControl::slowUpdate() 00230 { 00231 static bool last_r_cart, last_l_cart, last_move_base_active; 00232 00233 bool r_cart = false, l_cart = false; 00234 bool init_mesh_markers = false, init_all_markers = false, init_control_markers = false; 00235 00236 00237 if(use_right_arm_) 00238 { 00239 r_cart = mechanism_.checkController("r_cart"); 00240 if(! r_cart) 00241 { 00242 control_state_.r_gripper_.on_ = false; 00243 control_state_.posture_r_ = false; 00244 control_state_.dual_grippers_ = false; 00245 } 00246 // It's much smoother if we don't do this! 00247 //if( r_cart && !control_state_.posture_r_ ) refreshPosture("right_arm"); 00248 //if( r_cart ) refreshPosture("right_arm"); 00249 } 00250 if(use_left_arm_) 00251 { 00252 l_cart = mechanism_.checkController("l_cart"); 00253 if(! l_cart) 00254 { 00255 control_state_.l_gripper_.on_ = false; 00256 control_state_.posture_l_ = false; 00257 control_state_.dual_grippers_ = false; 00258 } 00259 // It's much smoother if we don't do this! 00260 //if( l_cart && !control_state_.posture_l_ ) refreshPosture("left_arm"); 00261 //if( l_cart ) refreshPosture("left_arm"); 00262 } 00263 00264 // if( r_cart || l_cart ) 00265 // { 00266 // if(joint_handle_) menu_arms_.setCheckState(joint_handle_, MenuHandler::UNCHECKED); 00267 // if(jtranspose_handle_) menu_arms_.setCheckState(jtranspose_handle_, MenuHandler::CHECKED); 00268 // } 00269 // else 00270 // { 00271 // if(joint_handle_) menu_arms_.setCheckState(joint_handle_, MenuHandler::CHECKED); 00272 // if(jtranspose_handle_) menu_arms_.setCheckState(jtranspose_handle_, MenuHandler::UNCHECKED); 00273 // control_state_.r_gripper_.on_ = false; 00274 // control_state_.l_gripper_.on_ = false; 00275 // control_state_.posture_r_ = false; 00276 // control_state_.posture_l_ = false; 00277 // } 00278 00279 bool controller_changed = (r_cart != last_r_cart) || (l_cart != last_l_cart); 00280 last_r_cart = r_cart; 00281 last_l_cart = l_cart; 00282 00283 if(controller_changed) 00284 { 00285 //if(tuck_handle_) menu_arms_.setVisible(tuck_handle_, !(r_cart || l_cart) ); 00286 //init_mesh_markers = true; 00287 //init_control_markers = true; 00288 init_all_markers = true; 00289 //initAllMarkers(); 00290 } 00291 00292 ROS_DEBUG("r_cart: %d l_cart: %d", r_cart, l_cart); 00293 00294 // --------------------------------------------------------------- 00295 // Current state validator stuff 00296 00297 bool meshes_changed = false; 00298 00299 bool in_collision_r = !checkStateValidity("right_arm"); 00300 if (in_collision_r_ != in_collision_r) meshes_changed = true; 00301 in_collision_r_ = in_collision_r; 00302 00303 bool in_collision_l = !checkStateValidity("left_arm"); 00304 if (in_collision_l_ != in_collision_l) meshes_changed = true; 00305 in_collision_l_ = in_collision_l; 00306 00307 init_mesh_markers = meshes_changed; 00308 //if (meshes_changed) initMeshMarkers(); 00309 00310 // --------------------------------------------------------------- 00311 // Base client stuff 00312 bool move_base_active = base_client_.hasGoal(); 00313 if( move_base_active != last_move_base_active ) init_control_markers = true; 00314 last_move_base_active = move_base_active; 00315 00316 00317 // --------------------------------------------------------------- 00318 // Call a re-draw to the necessary markers. 00319 if(init_all_markers) initAllMarkers(); 00320 else 00321 { 00322 if(init_control_markers) initControlMarkers(); 00323 if(init_mesh_markers) initMeshMarkers(); 00324 } 00325 } 00326 00328 double PR2MarkerControl::getJointPosition( std::string name, const arm_navigation_msgs::RobotState& robot_state) 00329 { 00330 for (size_t i=0; i<robot_state.joint_state.name.size(); i++) 00331 { 00332 if (robot_state.joint_state.name[i] == name) 00333 { 00334 ROS_ASSERT(robot_state.joint_state.position.size() > i); 00335 return robot_state.joint_state.position[i]; 00336 } 00337 } 00338 ROS_ERROR_STREAM("Joint " << name << " not found in robot state"); 00339 return 0.0; 00340 } 00341 00343 void PR2MarkerControl::initControlMarkers() 00344 { 00345 ros::Time now = ros::Time::now(); 00346 ROS_INFO("Re-initializing all control markers!"); 00347 arm_navigation_msgs::RobotState robot_state; 00348 //wait for the service to initialize, for how long it takes 00349 mechanism_.get_robot_state_client_.client(ros::Duration(-1)); 00350 mechanism_.getRobotState(robot_state); 00351 00352 00353 control_state_.print(); 00354 // Right gripper control 00355 if(!control_state_.dual_grippers_ && control_state_.r_gripper_.on_ && use_right_arm_ && 00356 (interface_number_ == 0 || interface_number_ == 1) ) 00357 { 00358 tfl_.waitForTransform("r_wrist_roll_link","base_link", now, ros::Duration(2.0)); 00359 tf::StampedTransform stamped; 00360 geometry_msgs::TransformStamped ts; 00361 geometry_msgs::PoseStamped ps; 00362 tfl_.lookupTransform("base_link", "r_wrist_roll_link", now, stamped); 00363 offsetPS(stamped, pose_offset_[0]); 00364 tf::transformStampedTFToMsg(stamped, ts); 00365 ps = msg::createPoseStampedMsg(ts); 00366 ps.header.stamp = ros::Time(0); // Time(0) is needed, else the markers seem to end up in random places 00367 server_.insert(make6DofMarker( "r_gripper_control", ps, 0.25, control_state_.r_gripper_.torso_frame_, 00368 control_state_.r_gripper_.view_facing_), 00369 boost::bind( &PR2MarkerControl::updateGripper, this, _1, 0)); 00370 menu_grippers_.apply(server_, "r_gripper_control"); 00371 } 00372 else 00373 { 00374 server_.erase("r_gripper_control"); 00375 } 00376 00377 // Left gripper control 00378 if(!control_state_.dual_grippers_ && control_state_.l_gripper_.on_ && use_left_arm_ && 00379 (interface_number_ == 0 || interface_number_ == 1)) 00380 { 00381 tfl_.waitForTransform("l_wrist_roll_link","base_link", now, ros::Duration(2.0)); 00382 tf::StampedTransform stamped; 00383 geometry_msgs::TransformStamped ts; 00384 geometry_msgs::PoseStamped ps; 00385 tfl_.lookupTransform("base_link", "l_wrist_roll_link", now, stamped); 00386 offsetPS(stamped, pose_offset_[1]); 00387 tf::transformStampedTFToMsg(stamped, ts); 00388 ps = msg::createPoseStampedMsg(ts); 00389 ps.header.stamp = ros::Time(0); // Time(0) is needed, else the markers seem to end up in random places 00390 server_.insert(make6DofMarker( "l_gripper_control", ps, 0.25, control_state_.l_gripper_.torso_frame_, 00391 control_state_.l_gripper_.view_facing_), 00392 boost::bind( &PR2MarkerControl::updateGripper, this, _1, 1 )); 00393 menu_grippers_.apply(server_, "l_gripper_control"); 00394 } 00395 else 00396 { 00397 server_.erase("l_gripper_control"); 00398 } 00399 00400 // Dual-gripper control 00401 if(control_state_.dual_grippers_) 00402 { 00403 // // TODO should this update with gripper poses, or be more of a fixed thing? 00404 // // If it auto updates it might lead to stability issues... 00405 // tfl_.waitForTransform("r_gripper_tool_frame","base_link", now, ros::Duration(2.0)); 00406 // tfl_.waitForTransform("l_gripper_tool_frame","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_[1]); 00412 // tf::transformStampedTFToMsg(stamped, ts); 00413 // ps = msg::createPoseStampedMsg(ts); 00414 server_.insert(make6DofMarker( "dual_gripper_control", dual_grippers_frame_, 0.25, true, false), 00415 boost::bind( &PR2MarkerControl::updateDualGripper, this, _1 )); 00416 menu_dual_grippers_.apply(server_, "dual_gripper_control"); 00417 } 00418 else 00419 { 00420 server_.erase("dual_gripper_control"); 00421 } 00422 00423 00424 if(control_state_.posture_r_ && use_right_arm_ && 00425 (interface_number_ <= 2)) 00426 { 00427 tf::StampedTransform stamped; 00428 geometry_msgs::TransformStamped ts; 00429 geometry_msgs::PoseStamped ps; 00430 tfl_.waitForTransform("r_shoulder_pan_link","base_link", now, ros::Duration(2.0)); 00431 tfl_.lookupTransform("base_link", "r_shoulder_pan_link", now, stamped); 00432 tf::transformStampedTFToMsg(stamped, ts); 00433 float angle = getJointPosition("r_upper_arm_roll_joint", robot_state); 00434 ts.transform.rotation = msg::createQuaternionMsg( btQuaternion( btVector3(1,0,0), angle) ); 00435 ps = msg::createPoseStampedMsg(ts); 00436 ps.header.stamp = ros::Time(0); 00437 server_.insert(makePostureMarker( "r_posture_control", ps, 0.55, false, false), 00438 boost::bind( &PR2MarkerControl::updatePosture, this, _1, 0 )); 00439 } 00440 else 00441 { 00442 server_.erase("r_posture_control"); 00443 } 00444 00445 if(control_state_.posture_l_ && use_left_arm_ && 00446 (interface_number_ <= 2)) 00447 { 00448 tf::StampedTransform stamped; 00449 geometry_msgs::TransformStamped ts; 00450 geometry_msgs::PoseStamped ps; 00451 tfl_.waitForTransform("l_shoulder_pan_link","base_link", now, ros::Duration(2.0)); 00452 tfl_.lookupTransform("base_link", "l_shoulder_pan_link", now, stamped); 00453 tf::transformStampedTFToMsg(stamped, ts); 00454 float angle = getJointPosition("l_upper_arm_roll_joint", robot_state); 00455 ts.transform.rotation = msg::createQuaternionMsg( btQuaternion( btVector3(1,0,0), angle) ); 00456 ps = msg::createPoseStampedMsg(ts); 00457 ps.header.stamp = ros::Time(0); 00458 server_.insert(makePostureMarker( "l_posture_control", ps, 0.55, false, false), 00459 boost::bind( &PR2MarkerControl::updatePosture, this, _1, 1 )); 00460 } 00461 else 00462 { 00463 server_.erase("l_posture_control"); 00464 } 00465 00466 if(control_state_.head_on_ && control_state_.init_head_goal_) 00467 { 00468 control_state_.init_head_goal_ = false; 00469 //geometry_msgs::PoseStamped ps = msg::createPoseStampedMsg( head_goal_pose_, "base_link", now); 00470 head_goal_pose_.header.stamp = ros::Time(0); 00471 //ps.header.stamp = ros::Time(0); 00472 server_.insert(makeHeadGoalMarker( "head_point_goal", head_goal_pose_, 0.1), 00473 boost::bind( &PR2MarkerControl::updateHeadGoal, this, _1, 0 )); 00474 } 00475 if(!control_state_.head_on_) 00476 { 00477 server_.erase("head_point_goal"); 00478 } 00479 00480 if (interface_number_ == 0) 00481 { 00482 geometry_msgs::PoseStamped ps; 00483 ps.pose.position.x = -0.35; 00484 ps.pose.position.z = 1.1; 00485 ps.pose.orientation.w = 1; 00486 ps.header.frame_id = "base_link"; 00487 ps.header.stamp = ros::Time(0); 00488 server_.insert(makeElevatorMarker( "torso_control", ps, 0.25, false), 00489 boost::bind( &PR2MarkerControl::updateTorso, this, _1 )); 00490 menu_torso_.apply(server_, "torso_control"); 00491 } 00492 00493 if(control_state_.base_on_ && interface_number_ == 0) // base control (!) 00494 { 00495 geometry_msgs::PoseStamped ps; 00496 ps.pose.orientation.w = 1; 00497 ps.header.frame_id = "base_link"; 00498 ps.header.stamp = ros::Time(0); 00499 server_.insert(makeBaseMarker( "base_control", ps, 0.75, false), 00500 boost::bind( &PR2MarkerControl::updateBase, this, _1 )); 00501 } 00502 else 00503 { 00504 server_.erase("base_control"); 00505 } 00506 00507 // The giant ball around the robot when it is driving somewhere. 00508 if( base_client_.hasGoal() ) 00509 { 00510 geometry_msgs::PoseStamped ps; 00511 ps.pose.position.z = 0.75; 00512 ps.pose.orientation.w = 1; 00513 ps.header.frame_id = "base_link"; 00514 ps.header.stamp = ros::Time(0); 00515 00516 std_msgs::ColorRGBA color = object_manipulator::msg::createColorMsg(1.0, 0.8, 0.8, 0.2); 00517 server_.insert(makeButtonSphere( "move_base_e_stop", ps, 2.0, false, false, color )); 00518 server_.setCallback("move_base_e_stop", boost::bind( &PR2MarkerControl::cancelBaseMovement, this), 00519 visualization_msgs::InteractiveMarkerFeedback::MOUSE_DOWN ); 00520 00521 // TODO this should absolutely be read from the robot_description parameter 00522 std::vector< std::string > mesh_paths, mesh_frames; 00523 mesh_paths.push_back("package://pr2_description/meshes/base_v0/base.dae"); 00524 mesh_frames.push_back("base_link"); 00525 mesh_paths.push_back("package://pr2_description/meshes/torso_v0/torso_lift.dae"); 00526 mesh_frames.push_back("torso_lift_link"); 00527 mesh_paths.push_back("package://pr2_description/meshes/shoulder_v0/shoulder_pan.dae"); 00528 mesh_frames.push_back("r_shoulder_pan_link"); 00529 mesh_paths.push_back("package://pr2_description/meshes/shoulder_v0/shoulder_pan.dae"); 00530 mesh_frames.push_back("l_shoulder_pan_link"); 00531 mesh_paths.push_back("package://pr2_description/meshes/shoulder_v0/shoulder_lift.dae"); 00532 mesh_frames.push_back("r_shoulder_lift_link"); 00533 mesh_paths.push_back("package://pr2_description/meshes/shoulder_v0/shoulder_lift.dae"); 00534 mesh_frames.push_back("l_shoulder_lift_link"); 00535 mesh_paths.push_back("package://pr2_description/meshes/upper_arm_v0/upper_arm.dae"); 00536 mesh_frames.push_back("r_upper_arm_link"); 00537 mesh_paths.push_back("package://pr2_description/meshes/upper_arm_v0/upper_arm.dae"); 00538 mesh_frames.push_back("l_upper_arm_link"); 00539 mesh_paths.push_back("package://pr2_description/meshes/forearm_v0/forearm.dae"); 00540 mesh_frames.push_back("r_forearm_link"); 00541 mesh_paths.push_back("package://pr2_description/meshes/forearm_v0/forearm.dae"); 00542 mesh_frames.push_back("l_forearm_link"); 00543 00544 // Right Gripper 00545 mesh_paths.push_back("package://pr2_description/meshes/gripper_v0/gripper_palm.dae"); 00546 mesh_frames.push_back("r_gripper_palm_link"); 00547 mesh_paths.push_back("package://pr2_description/meshes/gripper_v0/upper_finger_r.stl"); 00548 mesh_frames.push_back("r_gripper_r_finger_link"); 00549 mesh_paths.push_back("package://pr2_description/meshes/gripper_v0/upper_finger_l.stl"); 00550 mesh_frames.push_back("r_gripper_l_finger_link"); 00551 mesh_paths.push_back("package://pr2_description/meshes/gripper_v0/finger_tip_r.stl"); 00552 mesh_frames.push_back("r_gripper_r_finger_tip_link"); 00553 mesh_paths.push_back("package://pr2_description/meshes/gripper_v0/finger_tip_l.stl"); 00554 mesh_frames.push_back("r_gripper_l_finger_tip_link"); 00555 00556 00557 // Left Gripper 00558 mesh_paths.push_back("package://pr2_description/meshes/gripper_v0/gripper_palm.dae"); 00559 mesh_frames.push_back("l_gripper_palm_link"); 00560 mesh_paths.push_back("package://pr2_description/meshes/gripper_v0/upper_finger_r.stl"); 00561 mesh_frames.push_back("l_gripper_r_finger_link"); 00562 mesh_paths.push_back("package://pr2_description/meshes/gripper_v0/upper_finger_l.stl"); 00563 mesh_frames.push_back("l_gripper_l_finger_link"); 00564 mesh_paths.push_back("package://pr2_description/meshes/gripper_v0/finger_tip_r.stl"); 00565 mesh_frames.push_back("l_gripper_r_finger_tip_link"); 00566 mesh_paths.push_back("package://pr2_description/meshes/gripper_v0/finger_tip_l.stl"); 00567 mesh_frames.push_back("l_gripper_l_finger_tip_link"); 00568 00569 // Head 00570 mesh_paths.push_back("package://pr2_description/meshes/head_v0/head_pan.dae"); 00571 mesh_frames.push_back("head_pan_link"); 00572 mesh_paths.push_back("package://pr2_description/meshes/head_v0/head_tilt.dae"); 00573 mesh_frames.push_back("head_tilt_link"); 00574 00575 00576 if(mesh_paths.size() != mesh_frames.size()) ROS_ERROR("The number of mesh paths and mash frame_ids is not equal!"); 00577 00578 std::vector< geometry_msgs::PoseStamped > mesh_poses; 00579 for(size_t i = 0; i < mesh_paths.size(); i++) 00580 { 00581 geometry_msgs::PoseStamped ps; 00582 ps.header.stamp = ros::Time(0); 00583 ps.header.frame_id = mesh_frames[i]; 00584 ps.pose.orientation.w = 1; 00585 tfl_.waitForTransform("base_link", ps.header.frame_id, ps.header.stamp,ros::Duration(3.0)); 00586 tfl_.transformPose("base_link", ps, ps); 00587 mesh_poses.push_back(ps); 00588 } 00589 00590 server_.insert(makeRobotModelMarker( "move_base_goal", base_goal_pose_, mesh_poses, mesh_paths, 1.0, true)); 00591 00592 } 00593 else 00594 { 00595 server_.erase("move_base_e_stop"); 00596 server_.erase("move_base_goal"); 00597 } 00598 00599 } 00600 00602 void PR2MarkerControl::initMeshMarkers() 00603 { 00604 ros::Time now = ros::Time(0); 00605 00606 // For making the interactive marker meshes slightly bigger than the default robot_model meshes 00607 double scale_factor = 1.02; 00608 00609 // All interactive markers will be set to time(0), so they update automatically in rviz. 00610 geometry_msgs::PoseStamped ps; 00611 ps.header.stamp = ros::Time(0); 00612 00613 if (true) // Head is always on 00614 { 00615 ps.header.frame_id = "/head_tilt_link"; 00616 server_.insert(makeMeshMarker( "head_tilt_link", "package://pr2_description/meshes/head_v0/head_tilt.dae", 00617 ps, scale_factor)); 00618 menu_head_.apply(server_, "head_tilt_link"); 00619 } 00620 00621 if(use_right_arm_) 00622 { 00623 ps.pose = geometry_msgs::Pose(); 00624 ps.header.frame_id = "/r_upper_arm_link"; 00625 ps.pose.position.x = -0.002; 00626 server_.insert(makeMeshMarker( "r_upper_arm_link", "package://pr2_description/meshes/upper_arm_v0/upper_arm.dae", 00627 ps, scale_factor, object_manipulator::msg::createColorMsg(1, 0 , 0, 1), 00628 in_collision_r_)); 00629 server_.setCallback("r_upper_arm_link", boost::bind( &PR2MarkerControl::upperArmButtonCB, this, _1, 0), 00630 visualization_msgs::InteractiveMarkerFeedback::BUTTON_CLICK ); 00631 menu_arms_.apply(server_, "r_upper_arm_link"); 00632 00633 ps.header.frame_id = "/r_gripper_palm_link"; 00634 server_.insert(makeMeshMarker( "r_gripper_palm_link", 00635 "package://pr2_description/meshes/gripper_v0/gripper_palm.dae", 00636 ps, scale_factor)); 00637 server_.setCallback("r_gripper_palm_link", boost::bind( &PR2MarkerControl::gripperButtonCB, this, _1, 0), 00638 visualization_msgs::InteractiveMarkerFeedback::BUTTON_CLICK ); 00639 menu_gripper_close_.apply(server_, "r_gripper_palm_link"); 00640 } 00641 00642 if(use_left_arm_) 00643 { 00644 ps.pose = geometry_msgs::Pose(); 00645 ps.header.frame_id = "/l_upper_arm_link"; 00646 ps.pose.position.x = -0.002; 00647 server_.insert(makeMeshMarker( "l_upper_arm_link", "package://pr2_description/meshes/upper_arm_v0/upper_arm.dae", 00648 ps, scale_factor, object_manipulator::msg::createColorMsg(1, 0 , 0, 1), 00649 in_collision_l_)); 00650 server_.setCallback("l_upper_arm_link", boost::bind( &PR2MarkerControl::upperArmButtonCB, this, _1, 1), 00651 visualization_msgs::InteractiveMarkerFeedback::BUTTON_CLICK ); 00652 menu_arms_.apply(server_, "l_upper_arm_link"); 00653 00654 ps.header.frame_id = "/l_gripper_palm_link"; 00655 server_.insert(makeMeshMarker( "l_gripper_palm_link", 00656 "package://pr2_description/meshes/gripper_v0/gripper_palm.dae", 00657 ps, scale_factor)); 00658 server_.setCallback("l_gripper_palm_link", boost::bind( &PR2MarkerControl::gripperButtonCB, this, _1, 1), 00659 visualization_msgs::InteractiveMarkerFeedback::BUTTON_CLICK ); 00660 menu_gripper_close_.apply(server_, "l_gripper_palm_link"); 00661 } 00662 00663 if (interface_number_ == 0) // base link not allowed in studies 00664 { 00665 ps.pose = geometry_msgs::Pose(); 00666 ps.header.frame_id = "base_link"; 00667 ps.pose.position.x = 0.0; 00668 ps.pose.position.z = -0.01; 00669 server_.insert(makeMeshMarker( "base_link", "package://pr2_description/meshes/base_v0/base.dae", 00670 ps, scale_factor)); 00671 server_.setCallback("base_link", boost::bind( &PR2MarkerControl::baseButtonCB, this, _1), 00672 visualization_msgs::InteractiveMarkerFeedback::BUTTON_CLICK ); 00673 menu_base_.apply(server_, "base_link"); 00674 } 00675 00676 if(control_state_.projector_on_) 00677 { 00678 ps.pose = geometry_msgs::Pose(); 00679 ps.header.frame_id = "/projector_wg6802418_frame"; 00680 ps.pose.position.x = 0.07; 00681 ps.pose.position.z = 0.02; 00682 ps.pose.orientation = msg::createQuaternionMsg( btQuaternion(btVector3(0,1,0), M_PI/2)); 00683 ps.header.stamp = ros::Time(0); 00684 server_.insert(makeProjectorMarker( "projector_control", ps, 1.0), 00685 boost::bind( &PR2MarkerControl::projectorMenuCB, this, _1 )); 00686 } 00687 else 00688 { 00689 server_.erase("projector_control"); 00690 } 00691 00692 // The "reset" box over the PR2's head. 00693 ps = msg::createPoseStampedMsg(msg::createPointMsg(0,0,0.85), msg::createQuaternionMsg(0,0,0,1), 00694 "/torso_lift_link", ros::Time(0)); 00695 server_.insert(makeButtonBox( "PR2 Marker Control Reset", ps, 0.05, false, true), 00696 boost::bind( &PR2MarkerControl::initAllMarkers, this, true ), 00697 visualization_msgs::InteractiveMarkerFeedback::BUTTON_CLICK); 00698 } 00699 00700 00701 void PR2MarkerControl::switchToCartesian() 00702 { 00703 ROS_DEBUG("Switching to cartesian control."); 00704 00705 // start out with posture control disabled 00706 std::vector<double> arm_angles(7); 00707 for( size_t i = 0; i < arm_angles.size(); i++) arm_angles[i] = 9999; 00708 00709 mechanism_.get_robot_state_client_.client(ros::Duration(100.0)); 00710 if(use_left_arm_){ 00711 try { 00712 mechanism_.switchToCartesian("left_arm"); 00713 } 00714 catch ( std::runtime_error &e ) 00715 { 00716 ROS_ERROR("Caught exception while switching to cartesian controller: %s", e.what( )); 00717 } 00718 mechanism_.sendCartesianPostureCommand("left_arm", arm_angles); 00719 } 00720 00721 if(use_right_arm_) 00722 { 00723 try { 00724 mechanism_.switchToCartesian("right_arm"); 00725 } 00726 catch ( std::runtime_error &e ) { 00727 ROS_ERROR("Caught exception while switching to cartesian controller: %s", e.what( )); 00728 } 00729 mechanism_.sendCartesianPostureCommand("right_arm", arm_angles); 00730 } 00731 00732 if(joint_handle_) menu_arms_.setCheckState(joint_handle_, MenuHandler::UNCHECKED); 00733 if(jtranspose_handle_) menu_arms_.setCheckState(jtranspose_handle_, MenuHandler::CHECKED); 00734 } 00735 00736 void PR2MarkerControl::switchToJoint() 00737 { 00738 ROS_DEBUG("Switching to joint control."); 00739 if(use_left_arm_) 00740 { 00741 try { 00742 mechanism_.switchToJoint("left_arm"); 00743 } 00744 catch ( std::runtime_error &e ) { 00745 ROS_ERROR("Caught exception while switching to cartesian controller: %s", e.what( )); 00746 } 00747 } 00748 00749 if(use_right_arm_) 00750 { 00751 try { 00752 mechanism_.switchToJoint("right_arm"); 00753 } 00754 catch ( std::runtime_error &e ) { 00755 ROS_ERROR("Caught exception while switching to cartesian controller: %s", e.what( )); 00756 } 00757 } 00758 00759 if(joint_handle_) menu_arms_.setCheckState(joint_handle_, MenuHandler::CHECKED); 00760 if(jtranspose_handle_) menu_arms_.setCheckState(jtranspose_handle_, MenuHandler::UNCHECKED); 00761 } 00762 00763 bool PR2MarkerControl::checkStateValidity(std::string arm_name) 00764 { 00765 // Hack to avoid using this for now 00766 if(!use_state_validator_) return true; 00767 00768 if (interface_number_ != 0) return true; 00769 arm_navigation_msgs::GetStateValidity::Request request; 00770 request.group_name = arm_name; 00771 arm_navigation_msgs::GetStateValidity::Response response; 00772 try 00773 { 00774 if (!check_state_validity_client_.client().call(request, response)) 00775 { 00776 ROS_ERROR("Call to get state validity failed"); 00777 return false; 00778 } 00779 if (response.error_code.val != response.error_code.SUCCESS) return false; 00780 return true; 00781 } 00782 catch (object_manipulator::ServiceNotFoundException &ex) 00783 { 00784 ROS_ERROR("Get state validity service not found"); 00785 return false; 00786 } 00787 } 00788 00789 void PR2MarkerControl::updateHeadGoal( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback, int arm_id ) 00790 { 00791 ros::Time now = ros::Time(0); 00792 00793 switch ( feedback->event_type ) 00794 { 00795 case visualization_msgs::InteractiveMarkerFeedback::BUTTON_CLICK: 00796 ROS_INFO_STREAM( feedback->marker_name << " was clicked on." ); 00797 break; 00798 case visualization_msgs::InteractiveMarkerFeedback::MENU_SELECT: 00799 ROS_INFO_STREAM( "Marker " << feedback->marker_name 00800 << " control " << feedback->control_name 00801 << " menu_entry_id " << feedback->menu_entry_id); 00802 00803 case visualization_msgs::InteractiveMarkerFeedback::POSE_UPDATE: 00804 geometry_msgs::PointStamped ps; 00805 ps.point = feedback-> pose.position; 00806 ps.header.frame_id = feedback->header.frame_id; 00807 ps.header.stamp = now; 00808 head_goal_pose_.pose = feedback->pose; 00809 head_goal_pose_.header = feedback->header; 00810 mechanism_.pointHeadAction(ps, head_pointing_frame_, false); 00811 break; 00812 } 00813 } 00814 00815 void PR2MarkerControl::targetPointMenuCB( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback ) 00816 { 00817 control_state_.head_on_ ^= true; 00818 control_state_.init_head_goal_ = true; 00819 00820 if(control_state_.head_on_) 00821 menu_head_.setCheckState(head_target_handle_, MenuHandler::CHECKED); 00822 else 00823 menu_head_.setCheckState(head_target_handle_, MenuHandler::UNCHECKED); 00824 00825 initControlMarkers(); 00826 } 00827 00828 void PR2MarkerControl::projectorMenuCB( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback ) 00829 { 00830 if(control_state_.projector_on_) 00831 { 00832 ROS_INFO("Trying to turn projector OFF"); 00833 int ok = system("rosrun dynamic_reconfigure dynparam set camera_synchronizer_node \"{'projector_mode':1, 'narrow_stereo_trig_mode':2}\" "); 00834 ROS_INFO("Done!"); 00835 if(ok < 0) 00836 ROS_WARN("Dynamic reconfigure for setting trigger mode OFF failed"); 00837 else 00838 { 00839 control_state_.projector_on_ = false; 00840 menu_head_.setCheckState(projector_handle_, MenuHandler::UNCHECKED); 00841 } 00842 } 00843 else 00844 { 00845 ROS_INFO("Trying to turn projector ON"); 00846 int ok = system("rosrun dynamic_reconfigure dynparam set camera_synchronizer_node \"{'projector_mode':3, 'narrow_stereo_trig_mode':5}\" "); 00847 ROS_INFO("Done!"); 00848 if(ok < 0) 00849 ROS_WARN("Dynamic reconfigure for setting trigger mode ON failed"); 00850 else 00851 { 00852 control_state_.projector_on_ = true; 00853 menu_head_.setCheckState(projector_handle_, MenuHandler::CHECKED); 00854 } 00855 } 00856 //menu_head_.reApply(server_); 00857 initMeshMarkers(); 00858 } 00859 00860 void PR2MarkerControl::gripperToggleModeCB( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback ) 00861 { 00862 MenuHandler::EntryHandle handle = feedback->menu_entry_id; 00863 //MenuHandler::CheckState state; 00864 //if(!menu_arms_.getCheckState(handle, state)) return; 00865 00866 if ( handle == gripper_view_facing_handle_ ) 00867 { 00868 control_state_.r_gripper_.view_facing_ = true; 00869 control_state_.l_gripper_.view_facing_ = true; 00870 assert(menu_grippers_.setCheckState(gripper_view_facing_handle_, MenuHandler::CHECKED)); 00871 assert(menu_grippers_.setCheckState(gripper_6dof_handle_, MenuHandler::UNCHECKED)); 00872 } 00873 if ( handle == gripper_6dof_handle_ ) 00874 { 00875 control_state_.r_gripper_.view_facing_ = false; 00876 control_state_.l_gripper_.view_facing_ = false; 00877 assert(menu_grippers_.setCheckState(gripper_view_facing_handle_, MenuHandler::UNCHECKED)); 00878 assert(menu_grippers_.setCheckState(gripper_6dof_handle_, MenuHandler::CHECKED)); 00879 } 00880 00881 initControlMarkers(); 00882 } 00883 00884 void PR2MarkerControl::gripperToggleFixedCB( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback ) 00885 { 00886 control_state_.r_gripper_.torso_frame_ ^= true; 00887 control_state_.l_gripper_.torso_frame_ ^= true; 00888 00889 // TODO right now I'm assuming these will always be in the same state together... 00890 if(control_state_.r_gripper_.torso_frame_) 00891 menu_grippers_.setCheckState(gripper_fixed_control_handle_, MenuHandler::CHECKED); 00892 else 00893 menu_grippers_.setCheckState(gripper_fixed_control_handle_, MenuHandler::UNCHECKED); 00894 00895 initControlMarkers(); 00896 } 00897 00898 void PR2MarkerControl::gripperToggleControlCB( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback ) 00899 { 00900 control_state_.r_gripper_.edit_control_ ^= true; 00901 control_state_.l_gripper_.edit_control_ ^= true; 00902 00903 // TODO right now I'm assuming these will always be in the same state together... 00904 if(control_state_.r_gripper_.edit_control_) 00905 menu_grippers_.setCheckState(gripper_edit_control_handle_, MenuHandler::CHECKED); 00906 else 00907 menu_grippers_.setCheckState(gripper_edit_control_handle_, MenuHandler::UNCHECKED); 00908 00909 initControlMarkers(); 00910 } 00911 00912 void PR2MarkerControl::gripperResetControlCB( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback ) 00913 { 00914 int arm_id = -1; 00915 if(!feedback->marker_name.compare("r_gripper_control")) 00916 arm_id = 0; 00917 else if(!feedback->marker_name.compare("l_gripper_control")) 00918 arm_id = 1; 00919 else 00920 { 00921 ROS_ERROR("Marker name [%s] not recognized...", feedback->marker_name.c_str()); 00922 return; 00923 } 00924 pose_offset_[arm_id].setOrigin(btVector3(0.1, 0, 0)); 00925 pose_offset_[arm_id].setRotation(btQuaternion(0, 0, 0, 1)); 00926 } 00927 00928 void PR2MarkerControl::startDualGrippers( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback, bool active ) 00929 { 00930 control_state_.dual_grippers_ = active; 00931 00932 // right and left gripper transforms to base, and right and left transforms to middle frame 00933 tf::Transform b_T_rw, b_T_lw, b_T_rt, b_T_lt; 00934 00935 if(active) 00936 { 00937 geometry_msgs::PoseStamped right_tool, left_tool; 00938 geometry_msgs::PoseStamped right_wrist = mechanism_.getGripperPose("right_arm", feedback->header.frame_id); 00939 geometry_msgs::PoseStamped left_wrist = mechanism_.getGripperPose("left_arm", feedback->header.frame_id); 00940 right_tool = wristToTool(right_wrist); 00941 left_tool = wristToTool(left_wrist); 00942 tf::poseMsgToTF(right_wrist.pose, b_T_rw); 00943 tf::poseMsgToTF(left_wrist.pose, b_T_lw); 00944 tf::poseMsgToTF(right_tool.pose, b_T_rt); 00945 tf::poseMsgToTF(left_tool.pose, b_T_lt); 00946 00947 // compute midpoint frame using tool frames! 00948 tf::Vector3 midpoint = b_T_rt.getOrigin() + 0.5*(b_T_lt.getOrigin() - b_T_rt.getOrigin()); 00949 // TODO this orientation is in the wrong frame! 00950 // Even if we set the correct torso frame initially, I suppose we need to continue 00951 // updating it if the robot drives around... 00952 tf::Transform b_T_m = tf::Transform(tf::Quaternion(0,0,0,1), midpoint); 00953 00954 //compute gripper wrist offsets using wrist frames! 00955 dual_gripper_offsets_[0] = b_T_m.inverse()*b_T_rw; 00956 dual_gripper_offsets_[1] = b_T_m.inverse()*b_T_lw; 00957 00958 dual_grippers_frame_ = msg::createPoseStampedMsg(b_T_m, feedback->header.frame_id, ros::Time(0)); // Time(0) prevents disappearing markers bug. 00959 } 00960 00961 initControlMarkers(); 00962 } 00963 00964 void PR2MarkerControl::commandGripperPose(const geometry_msgs::PoseStamped &ps, int arm_id, bool use_offset) 00965 { 00966 std::string arm = "right_arm"; 00967 if(arm_id == 1) arm = "left_arm"; 00968 const char *arm_name = arm.c_str(); 00969 00970 btTransform control_pose, command_pose; 00971 tf::poseMsgToTF(ps.pose, control_pose); 00972 if(use_offset) 00973 command_pose = control_pose * pose_offset_[arm_id].inverse(); 00974 else 00975 command_pose = control_pose; 00976 double dummy_var = 0; 00977 geometry_msgs::PoseStamped desired_pose = mechanism_.clipDesiredPose(arm_name, 00978 msg::createPoseStampedMsg(command_pose, ps.header.frame_id, ros::Time::now()), 00979 cartesian_clip_distance_*update_period_, 00980 cartesian_clip_angle_*update_period_, 00981 dummy_var); 00982 try { 00983 mechanism_.sendCartesianPoseCommand( arm_name, desired_pose); 00984 } 00985 catch ( std::runtime_error &e ) 00986 { 00987 ROS_ERROR("Caught exception while sending pose command: %s", e.what( )); 00988 } 00989 } 00990 00991 00992 void PR2MarkerControl::updateGripper( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback, int arm_id ) 00993 { 00994 ros::Time now = ros::Time(0); 00995 std::string arm = "right_arm"; 00996 if(arm_id == 1) arm = "left_arm"; 00997 const char *arm_name = arm.c_str(); 00998 00999 switch ( feedback->event_type ) 01000 { 01001 case visualization_msgs::InteractiveMarkerFeedback::MOUSE_UP: 01002 try { 01003 mechanism_.sendCartesianPoseCommand( arm_name, mechanism_.getGripperPose(arm_name, feedback->header.frame_id)); 01004 } 01005 catch ( std::runtime_error &e ) 01006 { 01007 ROS_ERROR("Caught exception while sending pose command: %s", e.what( )); 01008 } 01009 break; 01010 01011 case visualization_msgs::InteractiveMarkerFeedback::POSE_UPDATE: 01012 // TODO still assuming l and r will always be in sync... this is probably BAD... 01013 if(control_state_.r_gripper_.edit_control_ ) 01014 { 01015 geometry_msgs::PoseStamped ps = object_manipulator::msg::createPoseStampedMsg(feedback->pose, 01016 feedback->header.frame_id, 01017 ros::Time(0)); 01018 if(!strcmp(arm_name, "right_arm")) 01019 tfl_.transformPose("r_wrist_roll_link", ps, ps ); 01020 if(!strcmp(arm_name, "left_arm")) 01021 tfl_.transformPose("l_wrist_roll_link", ps, ps ); 01022 01023 tf::poseMsgToTF(ps.pose, pose_offset_[arm_id]); 01024 } 01025 else 01026 { 01027 geometry_msgs::PoseStamped ps = object_manipulator::msg::createPoseStampedMsg( 01028 feedback->pose, feedback->header.frame_id, feedback->header.stamp); 01029 commandGripperPose(ps, arm_id, true); 01030 } 01031 break; 01032 } 01033 } 01034 01035 void PR2MarkerControl::updateDualGripper( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback ) 01036 { 01037 ros::Time now = ros::Time(0); 01038 if(!control_state_.dual_grippers_) return; 01039 01040 //float half_width = 0.15; // TODO this should be controllable in some way! 01041 01042 switch ( feedback->event_type ) 01043 { 01044 case visualization_msgs::InteractiveMarkerFeedback::MOUSE_UP: 01045 try { 01046 mechanism_.sendCartesianPoseCommand( "right_arm", mechanism_.getGripperPose("right_arm", feedback->header.frame_id)); 01047 mechanism_.sendCartesianPoseCommand( "left_arm", mechanism_.getGripperPose("left_arm", feedback->header.frame_id)); 01048 } 01049 catch ( std::runtime_error &e ) 01050 { 01051 ROS_ERROR("Caught exception while sending pose command: %s", e.what( )); 01052 } 01053 break; 01054 01055 case visualization_msgs::InteractiveMarkerFeedback::POSE_UPDATE: 01056 // TODO still assuming l and r will always be in sync... this is probably BAD... 01057 // if(control_state_.r_gripper_.edit_control_ ) 01058 // { 01059 // geometry_msgs::PoseStamped ps = object_manipulator::msg::createPoseStampedMsg(feedback->pose, 01060 // feedback->header.frame_id, 01061 // ros::Time(0)); 01062 // if(!strcmp(arm_name, "right_arm")) 01063 // tfl_.transformPose("r_wrist_roll_link", ps, ps ); 01064 // if(!strcmp(arm_name, "left_arm")) 01065 // tfl_.transformPose("l_wrist_roll_link", ps, ps ); 01066 // 01067 // tf::poseMsgToTF(ps.pose, pose_offset_[arm_id]); 01068 // } 01069 // else 01070 { 01071 tf::Transform command_pose; 01072 01073 tf::poseMsgToTF(feedback->pose, command_pose); 01074 //btTransform command_pose = control_pose * pose_offset_[arm_id].inverse(); 01075 double dummy_var = 0; 01076 geometry_msgs::PoseStamped desired_pose = 01077 mechanism_.clipDesiredPose(dual_grippers_frame_, 01078 msg::createPoseStampedMsg(command_pose, feedback->header.frame_id, now), 01079 0.3*cartesian_clip_distance_*update_period_, 01080 0.3*cartesian_clip_angle_*update_period_, 01081 dummy_var); 01082 01083 // compute left and right gripper poses 01084 tf::Transform b_T_m, b_T_r, b_T_l; 01085 tf::poseMsgToTF(desired_pose.pose, b_T_m); 01086 b_T_r = b_T_m * dual_gripper_offsets_[0]; 01087 b_T_l = b_T_m * dual_gripper_offsets_[1]; 01088 geometry_msgs::PoseStamped right_pose = msg::createPoseStampedMsg(b_T_r, feedback->header.frame_id, ros::Time(0)); 01089 geometry_msgs::PoseStamped left_pose = msg::createPoseStampedMsg(b_T_l, feedback->header.frame_id, ros::Time(0)); 01090 01091 //store new dual_grippers_frame_ 01092 dual_grippers_frame_ = desired_pose; 01093 01094 // send the commands 01095 try { 01096 mechanism_.sendCartesianPoseCommand( "right_arm", right_pose); 01097 mechanism_.sendCartesianPoseCommand( "left_arm", left_pose); 01098 } 01099 catch ( std::runtime_error &e ) 01100 { 01101 ROS_ERROR("Caught exception while sending pose command: %s", e.what( )); 01102 } 01103 } 01104 break; 01105 } 01106 } 01107 01109 void PR2MarkerControl::gripperButtonCB( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback, int id) 01110 { 01111 if (interface_number_ != 0 && interface_number_ != 1) return; 01112 01113 if(id == 0) 01114 control_state_.r_gripper_.on_ ^= true; 01115 if(id == 1) 01116 control_state_.l_gripper_.on_ ^= true; 01117 01118 if ( control_state_.r_gripper_.on_ || control_state_.l_gripper_.on_ || 01119 control_state_.posture_r_ || control_state_.posture_l_ ) 01120 { 01121 switchToCartesian(); 01122 } 01123 else 01124 { 01125 switchToJoint(); 01126 } 01127 initAllMarkers(); 01128 } 01129 01130 void PR2MarkerControl::upperArmButtonCB( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback, int id) 01131 { 01132 if (interface_number_ > 2) return; 01133 01134 if(id == 0) 01135 control_state_.posture_r_ ^= true; 01136 if(id == 1) 01137 control_state_.posture_l_ ^= true; 01138 01139 if ( control_state_.r_gripper_.on_ || control_state_.l_gripper_.on_ || 01140 control_state_.posture_r_ || control_state_.posture_l_ ) 01141 { 01142 switchToCartesian(); 01143 } 01144 else 01145 { 01146 switchToJoint(); 01147 } 01148 initAllMarkers(); 01149 } 01150 01151 void PR2MarkerControl::updatePosture( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback, int arm_id ) 01152 { 01153 std::string arm_name = "right_arm"; 01154 if(arm_id == 1) arm_name = "left_arm"; 01155 01156 std::vector<double> arm_angles(7); 01157 //mechanism_.getArmAngles(arm_name, arm_angles); 01158 01159 switch ( feedback->event_type ) 01160 { 01161 case visualization_msgs::InteractiveMarkerFeedback::MOUSE_UP: 01162 { 01163 // This value (9999) disables the posture control for the joint. 01164 for( size_t i = 0; i < arm_angles.size(); i++) arm_angles[i] = 9999; 01165 mechanism_.sendCartesianPostureCommand(arm_name, arm_angles); 01166 break; 01167 } 01168 case visualization_msgs::InteractiveMarkerFeedback::POSE_UPDATE: 01169 { 01170 tf::Quaternion q; 01171 tf::quaternionMsgToTF(feedback->pose.orientation, q); 01172 float angle = q.getAngle()*q.getAxis().dot(btVector3(1,0,0)); 01173 01174 for( size_t i = 0; i < arm_angles.size(); i++) arm_angles[i] = 9999; 01175 arm_angles[2] = angle; 01176 mechanism_.sendCartesianPostureCommand(arm_name, arm_angles); 01177 break; 01178 } 01179 } 01180 } 01181 01182 void PR2MarkerControl::gripperClosureCB( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback, const float &command) 01183 { 01184 double open = pr2_wrappers::GripperController::GRIPPER_OPEN; 01185 double closed = pr2_wrappers::GripperController::GRIPPER_CLOSED; 01186 double value = closed + (open - closed) * command; 01187 std::string arm_name; 01188 if(!feedback->marker_name.compare("r_gripper_palm_link")){ 01189 gripper_client_.commandGripperValue("right_arm", value); 01190 arm_name = "right_arm"; 01191 } 01192 else if(!feedback->marker_name.compare("l_gripper_palm_link")) 01193 { 01194 gripper_client_.commandGripperValue("left_arm", value); 01195 arm_name = "left_arm"; 01196 } 01197 else 01198 ROS_ERROR("Marker control unrecognized, this is an error in the client implementation!"); 01199 01200 //if opening the gripper, reset attached objects for that arm 01201 if (value > closed + (open - closed)/2.) 01202 mechanism_.detachAllObjectsFromGripper(arm_name); 01203 } 01204 01205 void PR2MarkerControl::requestGripperPose( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback, 01206 int arm_id) 01207 { 01208 std::string arm_name; 01209 if(!feedback->marker_name.compare("r_gripper_control")){ 01210 arm_name = "right_arm"; 01211 } 01212 else if(!feedback->marker_name.compare("l_gripper_control")) 01213 { 01214 arm_name = "left_arm"; 01215 } 01216 else 01217 { 01218 ROS_ERROR("Marker name [%s] not recognized...", feedback->marker_name.c_str()); 01219 return; 01220 } 01221 01222 pr2_object_manipulation_msgs::GetGripperPoseGoal goal; 01223 goal.arm_name = arm_name; 01224 goal.gripper_opening = 0.08; 01225 if(arm_name == "right_arm") goal.gripper_pose = mechanism_.getGripperPose(arm_name, "torso_lift_link"); 01226 if(arm_name == "left_arm") goal.gripper_pose = mechanism_.getGripperPose(arm_name, "torso_lift_link"); 01227 gripper_pose_client_.client().sendGoal( goal, 01228 boost::bind(&PR2MarkerControl::processGripperPoseResult, this, _1, _2, arm_name), 01229 actionlib::SimpleActionClient<pr2_object_manipulation_msgs::GetGripperPoseAction>::SimpleActiveCallback(), 01230 //actionlib::SimpleActionClient<pr2_object_manipulation_msgs::GetGripperPoseAction>::SimpleFeedbackCallback());//, 01231 boost::bind(&PR2MarkerControl::processGripperPoseFeedback, this, _1, arm_name) ); 01232 01233 control_state_.r_gripper_.on_ = false; 01234 control_state_.l_gripper_.on_ = false; 01235 initControlMarkers(); 01236 } 01237 01238 void PR2MarkerControl::processGripperPoseFeedback( const pr2_object_manipulation_msgs::GetGripperPoseFeedbackConstPtr &result, 01239 const std::string &arm_name) 01240 { 01241 int arm_id = 0; 01242 if(arm_name == "left_arm") arm_id = 1; 01243 01244 commandGripperPose(result->gripper_pose, arm_id, false); 01245 01246 } 01247 01248 void PR2MarkerControl::processGripperPoseResult( const actionlib::SimpleClientGoalState& state, 01249 const pr2_object_manipulation_msgs::GetGripperPoseResultConstPtr &result, 01250 const std::string &arm_name) 01251 { 01252 ROS_ERROR("We should be setting the state back to 'controls active' here."); 01253 control_state_.r_gripper_.on_ = true; 01254 control_state_.l_gripper_.on_ = true; 01255 initControlMarkers(); 01256 } 01257 01258 void PR2MarkerControl::moveArm( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback, const std::string &position, 01259 bool planner) 01260 { 01261 std::string arm_name; 01262 if( feedback->marker_name == "r_upper_arm_link" || feedback->marker_name == "r_gripper_palm_link" ) 01263 arm_name = "right_arm"; 01264 else if( feedback->marker_name == "l_upper_arm_link" || feedback->marker_name == "l_gripper_palm_link" ) 01265 arm_name = "left_arm"; 01266 else 01267 ROS_WARN("Marker name [%s] not handled!", feedback->marker_name.c_str()); 01268 01269 std::string move_type = (planner)?("with planner"):("open-loop"); 01270 ROS_INFO("moving %s to %s %s", arm_name.c_str(), position.c_str(), move_type.c_str()); 01271 sys_thread_.reset( new boost::thread( boost::bind( 01272 &PR2MarkerControl::moveArmThread, this, arm_name, position, true, planner ) ) ); 01273 } 01274 01275 void PR2MarkerControl::moveArmThread(std::string arm_name, std::string position, bool collision, bool planner) 01276 { 01277 if (interface_number_ != 0) gripper_client_.commandGripperValue(arm_name, pr2_wrappers::GripperController::GRIPPER_OPEN); 01278 try 01279 { 01280 ROS_DEBUG("Attempting arm motion"); 01281 arm_navigation_msgs::OrderedCollisionOperations ord; 01282 if (!collision) 01283 { 01284 arm_navigation_msgs::CollisionOperation coll; 01285 coll.object1 = arm_navigation_msgs::CollisionOperation::COLLISION_SET_ALL; 01286 coll.object2 = arm_navigation_msgs::CollisionOperation::COLLISION_SET_ALL; 01287 coll.operation = arm_navigation_msgs::CollisionOperation::DISABLE; 01288 ord.collision_operations.push_back(coll); 01289 } 01290 std::vector<arm_navigation_msgs::LinkPadding> pad; 01291 if (collision) 01292 { 01293 pad = object_manipulator::concat( object_manipulator::MechanismInterface::gripperPadding("left_arm", 0.0), 01294 object_manipulator::MechanismInterface::gripperPadding("right_arm", 0.0) ); 01295 } 01296 if (planner) 01297 { 01298 mechanism_.attemptMoveArmToGoal(arm_name, 01299 object_manipulator::armConfigurations().position(arm_name, position), ord, pad); 01300 } 01301 else 01302 { 01303 mechanism_.attemptTrajectory(arm_name, object_manipulator::armConfigurations().trajectory(arm_name, position), 01304 false, 2.0); 01305 } 01306 } 01307 catch (object_manipulator::ServiceNotFoundException &ex) 01308 { 01309 ROS_ERROR("a needed service or action server was not found"); 01310 } 01311 catch (object_manipulator::MoveArmStuckException &ex) 01312 { 01313 ROS_ERROR("arm is stuck in a colliding position"); 01314 } 01315 catch (object_manipulator::MissingParamException &ex) 01316 { 01317 ROS_ERROR("parameters missing; is manipulation pipeline running?"); 01318 } 01319 catch (object_manipulator::MechanismException &ex) 01320 { 01321 ROS_ERROR("Error: %s", ex.what()); 01322 } 01323 catch (...) 01324 { 01325 ROS_ERROR("an unknown error has occured, please call helpdesk"); 01326 } 01327 01328 // Interface 1 (cartesian teleop) should always pop up the control rings. 01329 if(interface_number_ == 1) 01330 { 01331 switchToCartesian(); 01332 control_state_.r_gripper_.on_ = true; 01333 //control_state_.posture_r_ = true; 01334 initAllMarkers(); 01335 } 01336 // Auto-refresh / reset collision map is useful when running with novice users. 01337 if(interface_number_ != 0){ 01338 snapshot_client_.refresh( nh_.resolveName("snapshot_input_topic", true) ); 01339 std_srvs::Empty srv; 01340 if (!collider_node_reset_srv_.client().call(srv)) ROS_ERROR("failed to reset collision map!"); 01341 } 01342 } 01343 01344 void PR2MarkerControl::updateTorso( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback) 01345 { 01346 switch ( feedback->event_type ) 01347 { 01348 case visualization_msgs::InteractiveMarkerFeedback::MOUSE_DOWN: 01349 if(!feedback->control_name.compare("up")) 01350 torso_client_.top(); 01351 else if(!feedback->control_name.compare("down")) 01352 torso_client_.bottom(); 01353 else 01354 ROS_ERROR("Marker control unrecognized, this is an error in the client implementation!"); 01355 break; 01356 case visualization_msgs::InteractiveMarkerFeedback::MOUSE_UP: 01357 { 01358 arm_navigation_msgs::RobotState robot_state; 01359 mechanism_.getRobotState(robot_state); 01360 torso_client_.moveTo( getJointPosition("torso_lift_joint", robot_state) ); 01361 break; 01362 } 01363 case visualization_msgs::InteractiveMarkerFeedback::BUTTON_CLICK: 01364 break; 01365 } 01366 } 01367 01368 void PR2MarkerControl::torsoMenuCB( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback) 01369 { 01370 if(!feedback->control_name.compare("up")) 01371 torso_client_.top(); 01372 else if(!feedback->control_name.compare("down")) 01373 torso_client_.bottom(); 01374 else 01375 ROS_ERROR("Marker control unrecognized, this is an error in the client implementation!"); 01376 } 01377 01378 void PR2MarkerControl::updateBase( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback) 01379 { 01380 geometry_msgs::TwistStamped ts; 01381 ts.header.stamp = ros::Time::now(); 01382 ts.header.frame_id = "base_link"; 01383 01384 tf::Vector3 linear = tf::Vector3(0,0,0); 01385 tf::Vector3 angular = tf::Vector3(0,0,0); 01386 01387 switch ( feedback->event_type ) 01388 { 01389 case visualization_msgs::InteractiveMarkerFeedback::MOUSE_DOWN: 01390 { 01391 01392 tf::Quaternion q; 01393 tf::quaternionMsgToTF(feedback->pose.orientation, q); 01394 btMatrix3x3 mat(q); 01395 01396 if(!feedback->control_name.compare("forward")) linear = tf::Vector3( 1, 0, 0); 01397 if(!feedback->control_name.compare("back")) linear = tf::Vector3(-1, 0, 0); 01398 if(!feedback->control_name.compare("left")) linear = tf::Vector3( 0, 1, 0); 01399 if(!feedback->control_name.compare("right")) linear = tf::Vector3( 0,-1, 0); 01400 if(!feedback->control_name.compare("rotate right")) angular = tf::Vector3(0, 0,-1); 01401 if(!feedback->control_name.compare("rotate left")) angular = tf::Vector3(0, 0, 1); 01402 01403 linear = 0.3*(mat*linear); 01404 angular = 0.5*angular; 01405 01406 tf::vector3TFToMsg(linear, ts.twist.linear); 01407 tf::vector3TFToMsg(angular, ts.twist.angular); 01408 01409 base_client_.applyTwist(ts); 01410 break; 01411 } 01412 case visualization_msgs::InteractiveMarkerFeedback::MOUSE_UP: 01413 base_client_.applyTwist(ts); 01414 break; 01415 case visualization_msgs::InteractiveMarkerFeedback::BUTTON_CLICK: 01416 break; 01417 } 01418 } 01419 01420 void PR2MarkerControl::requestNavGoal( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback, 01421 const bool &collision_aware) 01422 { 01423 //ROS_WARN("Starting requestNavGoal"); 01424 // First call the 'get pose' action so that the user is distracted. 01425 pr2_object_manipulation_msgs::GetNavPoseGoal goal; 01426 goal.max_distance = collision_aware ? (-1.0): (max_direct_nav_radius_); 01427 base_pose_client_.client().sendGoal( goal, boost::bind(&PR2MarkerControl::processNavGoal, this, _1, _2, collision_aware)); 01428 01429 if( using_3d_nav_ ) 01430 { 01431 ROS_INFO("Using 3D navigation, not changing global or local planners"); 01432 return; 01433 } 01434 01435 // While the user is using the requested action, configure the planner in the background. 01436 std::string reconfigure = "rosrun dynamic_reconfigure dynparam set "; 01437 std::string move_base_config, costmap_config; 01438 01439 if( collision_aware ) 01440 { 01441 ROS_INFO("Activating 'global' planner."); 01442 // Don't just use "restore_defaults: true" because it restores whatever was on the param server when the node started." 01443 01444 // We could dynamically set the footprint of the robot based on the arm pose during these calls! 01445 move_base_config = reconfigure + move_base_node_name_ + " " 01446 + "\"{'base_global_planner': 'navfn/NavfnROS', " 01447 + " 'base_local_planner' : 'dwa_local_planner/DWAPlannerROS'}\" "; 01448 costmap_config = reconfigure + move_base_node_name_ + "/local_costmap \"{ " 01449 + "'max_obstacle_height' : 2.0, 'inflation_radius' : 0.55 }\" "; 01450 } 01451 else 01452 { 01453 ROS_INFO("Activating 'local' planner."); 01454 move_base_config = reconfigure + move_base_node_name_ +" " 01455 // + "\"{'base_global_planner': 'navfn/NavfnROS', " 01456 + "\"{'base_global_planner': 'pr2_navigation_controllers/GoalPasser', " 01457 + " 'base_local_planner' : 'pr2_navigation_controllers/PoseFollower'}\" "; 01458 01459 costmap_config = reconfigure + move_base_node_name_ + "/local_costmap \"{ " 01460 + "'max_obstacle_height' : 0.36 , 'inflation_radius': 0.01 }\" "; 01461 } 01462 01463 //ROS_WARN("Setting planners..."); 01464 int ok = system(move_base_config.c_str()); 01465 if(ok < 0) 01466 ROS_ERROR("Dynamic reconfigure for move_base_node FAILED!"); 01467 //ROS_WARN("Setting costmap configuration..."); 01468 ok = system(costmap_config.c_str()); 01469 if(ok < 0) 01470 ROS_ERROR("Dynamic reconfigure for move_base_node/local_costmap FAILED!"); 01471 ROS_INFO("Done!"); 01472 //ROS_WARN("Exiting requestNavGoal"); 01473 } 01474 01475 void PR2MarkerControl::processNavGoal( const actionlib::SimpleClientGoalState& state, 01476 const pr2_object_manipulation_msgs::GetNavPoseResultConstPtr &result, 01477 const bool &collision_aware ) 01478 { 01479 if(state.state_ == state.SUCCEEDED) 01480 { 01481 ROS_DEBUG("Got a valid base pose."); 01482 base_goal_pose_ = result->pose; 01483 sendLastNavGoal(); 01484 } 01485 else 01486 { 01487 ROS_WARN("Get Base Pose Action did not succeed; state = %d", (int)state.state_); 01488 } 01489 } 01490 01491 void PR2MarkerControl::sendLastNavGoal() 01492 { 01493 if( (ros::Time::now() - base_goal_pose_.header.stamp).toSec() < 10.0 ) 01494 { 01495 base_client_.sendNavGoal( base_goal_pose_ ); 01496 } 01497 else 01498 { 01499 base_goal_pose_ = geometry_msgs::PoseStamped(); 01500 base_goal_pose_.header.frame_id = "base_link"; 01501 base_goal_pose_.pose.orientation.w = 1; 01502 base_client_.sendNavGoal( base_goal_pose_ ); 01503 } 01504 } 01505 01506 //void PR2MarkerControl::clearLocalCostmap( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback) 01507 //{ 01508 // ROS_INFO("Clearing the navigation costmap..."); 01509 // base_client_.clearLocalCostmap( ); 01510 //} 01511 01512 void PR2MarkerControl::initMenus() 01513 { 01514 MenuHandler::EntryHandle handle; 01515 01516 // - - - - - - - - - - Head Menu - - - - - - - - - - // 01517 01518 menu_head_.insert("Take Snapshot", boost::bind( &PR2MarkerControl::snapshotCB, this ) ); 01519 if(double_menu_) menu_head_.insert("-------------", boost::bind( &PR2MarkerControl::snapshotCB, this ) ); 01520 01521 if (interface_number_ == 0) 01522 { 01523 head_target_handle_ = menu_head_.insert( "Target Point", boost::bind( &PR2MarkerControl::targetPointMenuCB, 01524 this, _1 ) ); 01525 menu_head_.setCheckState(head_target_handle_, MenuHandler::UNCHECKED); 01526 01527 projector_handle_ = menu_head_.insert("Projector", boost::bind( &PR2MarkerControl::projectorMenuCB, 01528 this, _1 ) ); 01529 menu_head_.setCheckState(projector_handle_, MenuHandler::UNCHECKED); 01530 } 01531 01532 01533 // - - - - - - - - - - Arm Menu - - - - - - - - - - // 01534 if (interface_number_ == 0) 01535 { 01536 tuck_handle_ = menu_arms_.insert( "Tuck..." ); 01537 menu_arms_.insert(tuck_handle_, "Untuck Both Arms", boost::bind( &PR2MarkerControl::tuckArmsCB, this, false, false)); 01538 if(double_menu_) menu_arms_.insert(tuck_handle_, "---------------", boost::bind( &PR2MarkerControl::tuckArmsCB, this, false, false)); 01539 menu_arms_.insert(tuck_handle_, "Untuck left, tuck right", boost::bind( &PR2MarkerControl::tuckArmsCB, this, false, true )); 01540 if(double_menu_) menu_arms_.insert(tuck_handle_, "----------------------", boost::bind( &PR2MarkerControl::tuckArmsCB, this, false, true )); 01541 menu_arms_.insert(tuck_handle_, "Tuck left, untuck right", boost::bind( &PR2MarkerControl::tuckArmsCB, this, true, false )); 01542 if(double_menu_) menu_arms_.insert(tuck_handle_, "-----------------------", boost::bind( &PR2MarkerControl::tuckArmsCB, this, true, false )); 01543 menu_arms_.insert(tuck_handle_, "Tuck Both Arms", boost::bind( &PR2MarkerControl::tuckArmsCB, this, true, true )); 01544 if(double_menu_) menu_arms_.insert(tuck_handle_, "--------------", boost::bind( &PR2MarkerControl::tuckArmsCB, this, true, true )); 01545 } 01546 01547 if (interface_number_ == 0) 01548 { 01549 handle = menu_arms_.insert( "Safe move to ... " ); 01550 menu_arms_.insert( handle, "above", boost::bind( &PR2MarkerControl::moveArm, this, _1, "above", true ) ); 01551 if(double_menu_) menu_arms_.insert( handle, "-----", boost::bind( &PR2MarkerControl::moveArm, this, _1, "above", true ) ); 01552 menu_arms_.insert( handle, "side", boost::bind( &PR2MarkerControl::moveArm, this, _1, "side", true ) ); 01553 if(double_menu_) menu_arms_.insert( handle, "----", boost::bind( &PR2MarkerControl::moveArm, this, _1, "side", true ) ); 01554 menu_arms_.insert( handle, "front", boost::bind( &PR2MarkerControl::moveArm, this, _1, "front", true ) ); 01555 if(double_menu_) menu_arms_.insert( handle, "-----", boost::bind( &PR2MarkerControl::moveArm, this, _1, "front", true ) ); 01556 01557 handle = menu_arms_.insert( "Forced move to ... " ); 01558 menu_arms_.insert( handle, "above", boost::bind( &PR2MarkerControl::moveArm, this, _1, "above", false ) ); 01559 if(double_menu_) menu_arms_.insert( handle, "-----", boost::bind( &PR2MarkerControl::moveArm, this, _1, "above", false ) ); 01560 menu_arms_.insert( handle, "side", boost::bind( &PR2MarkerControl::moveArm, this, _1, "side", false ) ); 01561 if(double_menu_) menu_arms_.insert( handle, "----", boost::bind( &PR2MarkerControl::moveArm, this, _1, "side", false ) ); 01562 menu_arms_.insert( handle, "front", boost::bind( &PR2MarkerControl::moveArm, this, _1, "front", false ) ); 01563 if(double_menu_) menu_arms_.insert( handle, "-----", boost::bind( &PR2MarkerControl::moveArm, this, _1, "front", false ) ); 01564 } 01565 else 01566 { 01567 menu_arms_.insert( "Drop object and reset position", 01568 boost::bind( &PR2MarkerControl::moveArm, this, _1, "side", true ) ); 01569 if(double_menu_) 01570 menu_arms_.insert( "------------------------------", 01571 boost::bind( &PR2MarkerControl::moveArm, this, _1, "side", true ) ); 01572 } 01573 01574 // - - - - - - - - - - Gripper Control Menu - - - - - - - - - - // 01575 01576 gripper_fixed_control_handle_ = menu_grippers_.insert( "Torso-Fixed Control", 01577 boost::bind( &PR2MarkerControl::gripperToggleFixedCB, this, _1 ) ); 01578 menu_grippers_.setCheckState(gripper_fixed_control_handle_, MenuHandler::UNCHECKED); 01579 01580 if (interface_number_ == 0) 01581 { 01582 handle = menu_grippers_.insert( "Marker Mode" ); 01583 01584 gripper_6dof_handle_ = menu_grippers_.insert( handle, "6 DOF", 01585 boost::bind( &PR2MarkerControl::gripperToggleModeCB, this, _1 ) ); 01586 menu_grippers_.setCheckState(gripper_6dof_handle_, MenuHandler::CHECKED); 01587 01588 gripper_view_facing_handle_ = menu_grippers_.insert( handle, "View Facing", 01589 boost::bind( &PR2MarkerControl::gripperToggleModeCB, this, _1 ) ); 01590 menu_grippers_.setCheckState(gripper_view_facing_handle_, MenuHandler::UNCHECKED); 01591 01592 gripper_edit_control_handle_ = menu_grippers_.insert( "Edit Control Frame", 01593 boost::bind( &PR2MarkerControl::gripperToggleControlCB, this, _1 ) ); 01594 menu_grippers_.setCheckState(gripper_edit_control_handle_, MenuHandler::UNCHECKED); 01595 01596 gripper_reset_control_handle_ = menu_grippers_.insert( "Reset Control Frame", 01597 boost::bind( &PR2MarkerControl::gripperResetControlCB, this, _1 ) ); 01598 menu_grippers_.insert( "Dual Grippers", boost::bind( &PR2MarkerControl::startDualGrippers, this, _1, true ) ); 01599 menu_grippers_.insert( "Collision-Constraint", boost::bind( &PR2MarkerControl::requestGripperPose, this, _1, 0 ) ); 01600 } 01601 01602 // - - - - - - - - - - Dual-Gripper Control Menu - - - - - - - - - - // 01603 01604 if (interface_number_ == 0) 01605 { 01606 menu_dual_grippers_.insert( "Exit", boost::bind( &PR2MarkerControl::startDualGrippers, this, _1, false ) ); 01607 } 01608 01609 // - - - - - - - - - - Gripper Closure Menu - - - - - - - - - - // 01610 01611 if (interface_number_ < 3) 01612 { 01613 menu_gripper_close_.insert( "Open Gripper", boost::bind( &PR2MarkerControl::gripperClosureCB, this, _1, 1 ) ); 01614 if(double_menu_) menu_gripper_close_.insert( "------------", boost::bind( &PR2MarkerControl::gripperClosureCB, this, _1, 1 ) ); 01615 menu_gripper_close_.insert( "Close Gripper", boost::bind( &PR2MarkerControl::gripperClosureCB, this, _1, 0 ) ); 01616 if(double_menu_) menu_gripper_close_.insert( "-------------", boost::bind( &PR2MarkerControl::gripperClosureCB, this, _1, 0 ) ); 01617 } 01618 else 01619 { 01620 menu_gripper_close_.insert( "Drop object and reset position", 01621 boost::bind( &PR2MarkerControl::moveArm, this, _1, "side", true ) ); 01622 if(double_menu_) 01623 menu_gripper_close_.insert( "------------------------------", 01624 boost::bind( &PR2MarkerControl::moveArm, this, _1, "side", true ) ); 01625 01626 } 01627 01628 // - - - - - - - - - - Torso Menu - - - - - - - - - - // 01629 menu_torso_.insert( "All the way", boost::bind( &PR2MarkerControl::torsoMenuCB, this, _1 ) ); 01630 if(double_menu_) menu_torso_.insert( "----------", boost::bind( &PR2MarkerControl::torsoMenuCB, this, _1 ) ); 01631 01632 // - - - - - - - - - - Base Menu - - - - - - - - - - // 01633 menu_base_.insert( "Navigate to...", boost::bind( &PR2MarkerControl::requestNavGoal, this, _1, true ) ); 01634 menu_base_.insert( "Directly Move to...", boost::bind( &PR2MarkerControl::requestNavGoal, this, _1, false ) ); 01635 menu_base_.insert( "Resume last Goal", boost::bind( &PR2MarkerControl::sendLastNavGoal, this ) ); 01636 } 01637 01638 01639 // Graveyard