tabletop_push_node.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 # Software License Agreement (BSD License)
00003 #
00004 #  Copyright (c) 2011, Georgia Institute of Technology
00005 #  All rights reserved.
00006 #
00007 #  Redistribution and use in source and binary forms, with or without
00008 #  modification, are permitted provided that the following conditions
00009 #  are met:
00010 #
00011 #  * Redistributions of source code must retain the above copyright
00012 #     notice, this list of conditions and the following disclaimer.
00013 #  * Redistributions in binary form must reproduce the above
00014 #     copyright notice, this list of conditions and the following
00015 #     disclaimer in the documentation and/or other materials provided
00016 #     with the distribution.
00017 #  * Neither the name of the Georgia Institute of Technology nor the names of
00018 #     its contributors may be used to endorse or promote products derived
00019 #     from this software without specific prior written permission.
00020 #
00021 #  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022 #  'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023 #  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024 #  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025 #  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026 #  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027 #  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028 #  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029 #  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030 #  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031 #  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032 #  POSSIBILITY OF SUCH DAMAGE.
00033 
00034 import roslib; roslib.load_manifest('tabletop_pushing')
00035 import rospy
00036 import hrl_pr2_lib.linear_move as lm
00037 import hrl_pr2_lib.pr2 as pr2
00038 import hrl_lib.tf_utils as tfu
00039 from hrl_pr2_arms.pr2_controller_switcher import ControllerSwitcher
00040 from geometry_msgs.msg import PoseStamped
00041 from pr2_controllers_msgs.msg import *
00042 import tf
00043 import numpy as np
00044 from tabletop_pushing.srv import *
00045 from math import sin, cos, pi, fabs
00046 import sys
00047 
00048 # Setup joints stolen from Kelsey's code.
00049 LEFT_ARM_SETUP_JOINTS = np.matrix([[1.32734204881265387,
00050                                     -0.34601608409943324,
00051                                     1.4620635485239604,
00052                                     -1.2729772622637399,
00053                                     7.5123303230158518,
00054                                     -1.5570651396529178,
00055                                     -5.5929916630672727]]).T
00056 RIGHT_ARM_SETUP_JOINTS = np.matrix([[-1.32734204881265387,
00057                                       -0.34601608409943324,
00058                                       -1.4620635485239604,
00059                                       -1.2729772622637399,
00060                                       -7.5123303230158518,
00061                                       -1.5570651396529178,
00062                                       -7.163787989862169]]).T
00063 LEFT_ARM_READY_JOINTS = np.matrix([[0.42427649, 0.0656137,
00064                                     1.43411927, -2.11931035,
00065                                     -15.78839978, -1.64163257,
00066                                     -17.2947453]]).T
00067 RIGHT_ARM_READY_JOINTS = np.matrix([[-0.42427649, 0.0656137,
00068                                      -1.43411927, -2.11931035,
00069                                      15.78839978, -1.64163257,
00070                                      8.64421842e+01]]).T
00071 LEFT_ARM_PULL_READY_JOINTS = np.matrix([[0.42427649,
00072                                          -0.34601608409943324,
00073                                          1.43411927,
00074                                          -2.11931035,
00075                                          82.9984037,
00076                                          -1.64163257,
00077                                          -36.16]]).T
00078 RIGHT_ARM_PULL_READY_JOINTS = np.matrix([[-0.42427649,
00079                                          -0.34601608409943324,
00080                                          -1.43411927,
00081                                          -2.11931035,
00082                                          -82.9984037,
00083                                          -1.64163257,
00084                                          54.8]]).T
00085 LEFT_ARM_HIGH_PUSH_READY_JOINTS = np.matrix([[0.42427649,
00086                                               -0.34601608409943324,
00087                                               1.43411927,
00088                                               -2.11931035,
00089                                               -15.78839978,
00090                                               -1.64163257,
00091                                               -17.2947453]]).T
00092 RIGHT_ARM_HIGH_PUSH_READY_JOINTS = np.matrix([[-0.42427649,
00093                                                 -0.34601608409943324,
00094                                                 -1.43411927,
00095                                                 -2.11931035,
00096                                                 15.78839978,
00097                                                 -1.64163257,
00098                                                 8.64421842e+01]]).T
00099 LEFT_ARM_HIGH_SWEEP_READY_JOINTS = LEFT_ARM_HIGH_PUSH_READY_JOINTS
00100 RIGHT_ARM_HIGH_SWEEP_READY_JOINTS = RIGHT_ARM_HIGH_PUSH_READY_JOINTS
00101 
00102 READY_POSE_MOVE_THRESH = 0.5
00103 
00104 class TabletopPushNode:
00105 
00106     def __init__(self):
00107         rospy.init_node('tabletop_push_node', log_level=rospy.DEBUG)
00108         self.torso_z_offset = rospy.get_param('~torso_z_offset', 0.30)
00109         self.look_pt_x = rospy.get_param('~look_point_x', 0.7)
00110         self.high_arm_init_z = rospy.get_param('~high_arm_start_z', 0.05)
00111         self.head_pose_cam_frame = rospy.get_param('~head_pose_cam_frame',
00112                                                    'head_mount_kinect_rgb_link')
00113         self.default_torso_height = rospy.get_param('~default_torso_height',
00114                                                     0.2)
00115         self.gripper_raise_dist = rospy.get_param('~graipper_post_push_raise_dist',
00116                                                   0.05)
00117         self.pull_raise_dist = rospy.get_param('~graipper_post_push_raise_dist',
00118                                                   0.10)
00119         use_slip = rospy.get_param('~use_slip_detection', 1)
00120 
00121         self.tf_listener = tf.TransformListener()
00122 
00123         # Set joint gains
00124         prefix = roslib.packages.get_pkg_dir('hrl_pr2_arms')+'/params/'
00125         cs = ControllerSwitcher()
00126         rospy.loginfo(cs.switch("r_arm_controller", "r_arm_controller",
00127                                 prefix + "pr2_arm_controllers_push.yaml"))
00128         rospy.loginfo(cs.switch("l_arm_controller", "l_arm_controller",
00129                                 prefix + "pr2_arm_controllers_push.yaml"))
00130 
00131         # Setup arms
00132         rospy.loginfo('Creating pr2 object')
00133         self.robot = pr2.PR2(self.tf_listener, arms=True, base=False)
00134         rospy.loginfo('Setting up left arm move')
00135         self.left_arm_move = lm.LinearReactiveMovement('l', self.robot,
00136                                                        self.tf_listener,
00137                                                        use_slip, use_slip)
00138         rospy.loginfo('Setting up right arm move')
00139         self.right_arm_move = lm.LinearReactiveMovement('r', self.robot,
00140                                                         self.tf_listener,
00141                                                         use_slip, use_slip)
00142 
00143 
00144         self.gripper_push_service = rospy.Service('gripper_push',
00145                                                   GripperPush,
00146                                                   self.gripper_push_action)
00147         self.gripper_pre_push_service = rospy.Service('gripper_pre_push',
00148                                                   GripperPush,
00149                                                   self.gripper_pre_push_action)
00150         self.gripper_post_push_service = rospy.Service('gripper_post_push',
00151                                                        GripperPush,
00152                                                        self.gripper_post_push_action)
00153         self.gripper_sweep_service = rospy.Service('gripper_sweep',
00154                                                    GripperPush,
00155                                                    self.gripper_sweep_action)
00156         self.gripper_pre_sweep_service = rospy.Service('gripper_pre_sweep',
00157                                                        GripperPush,
00158                                                        self.gripper_pre_sweep_action)
00159         self.gripper_post_sweep_service = rospy.Service('gripper_post_sweep',
00160                                                         GripperPush,
00161                                                         self.gripper_post_sweep_action)
00162         self.overhead_push_service = rospy.Service('overhead_push',
00163                                                    GripperPush,
00164                                                    self.overhead_push_action)
00165         self.overhead_pre_push_service = rospy.Service('overhead_pre_push',
00166                                                        GripperPush,
00167                                                        self.overhead_pre_push_action)
00168         self.overhead_post_push_service = rospy.Service('overhead_post_push',
00169                                                         GripperPush,
00170                                                         self.overhead_post_push_action)
00171         self.overhead_pull_service = rospy.Service('overhead_pull',
00172                                                    GripperPush,
00173                                                    self.overhead_pull_action)
00174         self.overhead_pre_pull_service = rospy.Service('overhead_pre_pull',
00175                                                        GripperPush,
00176                                                        self.overhead_pre_pull_action)
00177         self.overhead_post_pull_service = rospy.Service('overhead_post_pull',
00178                                                         GripperPush,
00179                                                         self.overhead_post_pull_action)
00180         self.raise_and_look_serice = rospy.Service('raise_and_look',
00181                                                    RaiseAndLook,
00182                                                    self.raise_and_look)
00183 
00184     #
00185     # Arm pose initialization functions
00186     #
00187     def init_arm_pose(self, force_ready=False, which_arm='l'):
00188         '''
00189         Move the arm to the initial pose to be out of the way for viewing the
00190         tabletop
00191         '''
00192         if which_arm == 'l':
00193             push_arm = self.left_arm_move
00194             robot_arm = self.robot.left
00195             robot_gripper = self.robot.left_gripper
00196             ready_joints = LEFT_ARM_READY_JOINTS
00197             setup_joints = LEFT_ARM_SETUP_JOINTS
00198         else:
00199             push_arm = self.right_arm_move
00200             robot_arm = self.robot.right
00201             robot_gripper = self.robot.right_gripper
00202             ready_joints = RIGHT_ARM_READY_JOINTS
00203             setup_joints = RIGHT_ARM_SETUP_JOINTS
00204 
00205         ready_diff = np.linalg.norm(pr2.diff_arm_pose(robot_arm.pose(),
00206                                                       ready_joints))
00207         push_arm.set_movement_mode_ik()
00208 
00209         rospy.loginfo('Moving %s_arm to setup pose' % which_arm)
00210         robot_arm.set_pose(setup_joints, nsecs=2.0, block=True)
00211         rospy.loginfo('Moved %s_arm to setup pose' % which_arm)
00212 
00213         rospy.loginfo('Closing %s_gripper' % which_arm)
00214         res = robot_gripper.close(block=True)
00215         rospy.loginfo('Closed %s_gripper' % which_arm)
00216         push_arm.pressure_listener.rezero()
00217 
00218     def reset_arm_pose(self, force_ready=False, which_arm='l',
00219                        high_arm_joints=False):
00220         '''
00221         Move the arm to the initial pose to be out of the way for viewing the
00222         tabletop
00223         '''
00224         if which_arm == 'l':
00225             push_arm = self.left_arm_move
00226             robot_arm = self.robot.left
00227             robot_gripper = self.robot.left_gripper
00228             if high_arm_joints:
00229                 ready_joints = LEFT_ARM_HIGH_PUSH_READY_JOINTS
00230             else:
00231                 ready_joints = LEFT_ARM_READY_JOINTS
00232             setup_joints = LEFT_ARM_SETUP_JOINTS
00233         else:
00234             push_arm = self.right_arm_move
00235             robot_arm = self.robot.right
00236             robot_gripper = self.robot.right_gripper
00237             if high_arm_joints:
00238                 ready_joints = RIGHT_ARM_HIGH_PUSH_READY_JOINTS
00239             else:
00240                 ready_joints = RIGHT_ARM_READY_JOINTS
00241             setup_joints = RIGHT_ARM_SETUP_JOINTS
00242         push_arm.pressure_listener.rezero()
00243 
00244         ready_diff = np.linalg.norm(pr2.diff_arm_pose(robot_arm.pose(),
00245                                                       ready_joints))
00246         push_arm.set_movement_mode_ik()
00247 
00248         # Choose to move to ready first, if it is closer, then move to init
00249         moved_ready = False
00250         if force_ready or ready_diff > READY_POSE_MOVE_THRESH or force_ready:
00251             rospy.loginfo('Moving %s_arm to ready pose' % which_arm)
00252             robot_arm.set_pose(ready_joints, nsecs=1.5, block=True)
00253             rospy.loginfo('Moved %s_arm to ready pose' % which_arm)
00254             moved_ready = True
00255         else:
00256             rospy.loginfo('Arm in ready pose')
00257 
00258 
00259         rospy.loginfo('Moving %s_arm to setup pose' % which_arm)
00260         robot_arm.set_pose(setup_joints, nsecs=1.5, block=True)
00261         rospy.loginfo('Moved %s_arm to setup pose' % which_arm)
00262 
00263     #
00264     # Behavior functions
00265     #
00266     def gripper_push_action(self, request):
00267         response = GripperPushResponse()
00268         push_frame = request.start_point.header.frame_id
00269         start_point = request.start_point.point
00270         wrist_yaw = request.wrist_yaw
00271         push_dist = request.desired_push_dist
00272 
00273         if request.left_arm:
00274             push_arm = self.left_arm_move
00275             robot_arm = self.robot.left
00276             ready_joints = LEFT_ARM_READY_JOINTS
00277             which_arm = 'l'
00278         else:
00279             push_arm = self.right_arm_move
00280             robot_arm = self.robot.right
00281             ready_joints = RIGHT_ARM_READY_JOINTS
00282             which_arm = 'r'
00283         push_arm.pressure_listener.rezero()
00284 
00285         # Push in a straight line
00286         rospy.loginfo('Pushing forward')
00287         r, pos_error = push_arm.move_relative_gripper(
00288             np.matrix([push_dist, 0.0, 0.0]).T,
00289             stop='pressure', pressure=5000)
00290         rospy.loginfo('Done pushing forward')
00291 
00292         response.dist_pushed = push_dist - pos_error
00293         return response
00294 
00295     def gripper_pre_push_action(self, request):
00296         response = GripperPushResponse()
00297         push_frame = request.start_point.header.frame_id
00298         rospy.loginfo('Have a request frame of: ' + str(push_frame));
00299         start_point = request.start_point.point
00300         wrist_yaw = request.wrist_yaw
00301         push_dist = request.desired_push_dist
00302         if request.left_arm:
00303             push_arm = self.left_arm_move
00304             robot_arm = self.robot.left
00305             ready_joints = LEFT_ARM_READY_JOINTS
00306             if request.high_arm_init:
00307                 ready_joints = LEFT_ARM_HIGH_PUSH_READY_JOINTS
00308             which_arm = 'l'
00309         else:
00310             push_arm = self.right_arm_move
00311             robot_arm = self.robot.right
00312             ready_joints = RIGHT_ARM_READY_JOINTS
00313             if request.high_arm_init:
00314                 ready_joints = RIGHT_ARM_HIGH_PUSH_READY_JOINTS
00315             which_arm = 'r'
00316 
00317         if request.arm_init:
00318             rospy.loginfo('Moving %s_arm to ready pose' % which_arm)
00319             push_arm.set_movement_mode_ik()
00320             robot_arm.set_pose(ready_joints, nsecs=1.5, block=True)
00321 
00322         orientation = tf.transformations.quaternion_from_euler(0.0, 0.0,
00323                                                                wrist_yaw)
00324         pose = np.matrix([start_point.x, start_point.y, start_point.z])
00325         rot = np.matrix([orientation])
00326         if request.high_arm_init:
00327             # Move to offset pose above the table
00328             pose = np.matrix([start_point.x, start_point.y,
00329                               self.high_arm_init_z])
00330             loc = [pose, rot]
00331             push_arm.set_movement_mode_cart()
00332             push_arm.move_absolute(loc, stop='pressure', frame=push_frame)
00333             rospy.loginfo('Done moving to overhead start point')
00334             # Lower arm to table
00335             pose = np.matrix([start_point.x, start_point.y, start_point.z])
00336             loc = [pose, rot]
00337             push_arm.set_movement_mode_cart()
00338             push_arm.move_absolute(loc, stop='pressure', frame=push_frame)
00339             rospy.loginfo('Done moving to start point')
00340         else:
00341             # Move to start pose
00342             loc = [pose, rot]
00343             push_arm.set_movement_mode_cart()
00344             push_arm.move_absolute(loc, stop='pressure', frame=push_frame)
00345             rospy.loginfo('Done moving to start point')
00346         return response
00347 
00348     def gripper_post_push_action(self, request):
00349         response = GripperPushResponse()
00350         push_frame = request.start_point.header.frame_id
00351         start_point = request.start_point.point
00352         wrist_yaw = request.wrist_yaw
00353         push_dist = request.desired_push_dist
00354 
00355         if request.left_arm:
00356             push_arm = self.left_arm_move
00357             robot_arm = self.robot.left
00358             ready_joints = LEFT_ARM_READY_JOINTS
00359             which_arm = 'l'
00360         else:
00361             push_arm = self.right_arm_move
00362             robot_arm = self.robot.right
00363             ready_joints = RIGHT_ARM_READY_JOINTS
00364             which_arm = 'r'
00365 
00366         # Retract in a straight line
00367         rospy.loginfo('Moving gripper up')
00368         push_arm.move_relative_gripper(
00369             np.matrix([0.0, 0.0, self.gripper_raise_dist]).T,
00370             stop='pressure', pressure=5000)
00371         rospy.loginfo('Done moving up')
00372 
00373         rospy.loginfo('Moving gripper backwards')
00374         push_arm.move_relative_gripper(
00375             np.matrix([-push_dist, 0.0, 0.0]).T,
00376             stop='pressure', pressure=5000)
00377         rospy.loginfo('Done moving backwards')
00378 
00379         if request.high_arm_init:
00380             rospy.loginfo('Moving up to end point')
00381             wrist_yaw = request.wrist_yaw
00382             orientation = tf.transformations.quaternion_from_euler(0.0, 0.0,
00383                                                                    wrist_yaw)
00384             pose = np.matrix([start_point.x, start_point.y,
00385                               self.high_arm_init_z])
00386             rot = np.matrix([orientation])
00387             loc = [pose, rot]
00388             push_arm.set_movement_mode_cart()
00389             push_arm.move_absolute(loc, stop='pressure', frame=push_frame)
00390             rospy.loginfo('Done moving up to end point')
00391 
00392         if request.arm_reset:
00393             self.reset_arm_pose(True, which_arm, request.high_arm_init)
00394         return response
00395 
00396     def gripper_sweep_action(self, request):
00397         response = GripperPushResponse()
00398         push_frame = request.start_point.header.frame_id
00399         start_point = request.start_point.point
00400         wrist_yaw = request.wrist_yaw
00401         push_dist = request.desired_push_dist
00402 
00403         if request.left_arm:
00404             push_arm = self.left_arm_move
00405             robot_arm = self.robot.left
00406             ready_joints = LEFT_ARM_READY_JOINTS
00407             which_arm = 'l'
00408             wrist_roll = -pi
00409         else:
00410             push_arm = self.right_arm_move
00411             robot_arm = self.robot.right
00412             ready_joints = RIGHT_ARM_READY_JOINTS
00413             which_arm = 'r'
00414             wrist_roll = 0.0
00415         push_arm.pressure_listener.rezero()
00416 
00417         # NOTE: because of the wrist roll orientation, +Z at the gripper
00418         # equates to negative Y in the torso_lift_link at 0.0 yaw
00419         # So we flip the push_dist to make things look like one would expect
00420         rospy.loginfo('Sweeping in')
00421         r, pos_error = push_arm.move_relative_gripper(
00422             np.matrix([0.0, 0.0, -push_dist]).T,
00423             stop='pressure', pressure=5000)
00424         rospy.loginfo('Done sweeping in')
00425 
00426         response.dist_pushed = push_dist - pos_error
00427         return response
00428 
00429     def gripper_pre_sweep_action(self, request):
00430         response = GripperPushResponse()
00431         push_frame = request.start_point.header.frame_id
00432         start_point = request.start_point.point
00433         wrist_yaw = request.wrist_yaw
00434         push_dist = request.desired_push_dist
00435 
00436         if request.left_arm:
00437             push_arm = self.left_arm_move
00438             robot_arm = self.robot.left
00439             ready_joints = LEFT_ARM_READY_JOINTS
00440             if request.high_arm_init:
00441                 ready_joints = LEFT_ARM_HIGH_SWEEP_READY_JOINTS
00442             which_arm = 'l'
00443             wrist_roll = -pi
00444         else:
00445             push_arm = self.right_arm_move
00446             robot_arm = self.robot.right
00447             ready_joints = RIGHT_ARM_READY_JOINTS
00448             if request.high_arm_init:
00449                 ready_joints = RIGHT_ARM_HIGH_SWEEP_READY_JOINTS
00450             which_arm = 'r'
00451             wrist_roll = 0.0
00452 
00453         if request.arm_init:
00454             rospy.loginfo('Moving %s_arm to ready pose' % which_arm)
00455             push_arm.set_movement_mode_ik()
00456             robot_arm.set_pose(ready_joints, nsecs=1.5, block=True)
00457 
00458         orientation = tf.transformations.quaternion_from_euler(0.5*pi, 0.0,
00459                                                                wrist_yaw)
00460         pose = np.matrix([start_point.x, start_point.y, start_point.z])
00461         rot = np.matrix([orientation])
00462 
00463         if request.arm_init:
00464             # Rotate wrist before moving to position
00465             rospy.loginfo('Rotating wrist for sweep')
00466             arm_pose = robot_arm.pose()
00467             arm_pose[-1] =  wrist_roll
00468             robot_arm.set_pose(arm_pose, nsecs=1.0, block=True)
00469         if request.high_arm_init:
00470             # Move to offset pose above the table
00471             pose = np.matrix([start_point.x, start_point.y,
00472                               self.high_arm_init_z])
00473             loc = [pose, rot]
00474             push_arm.set_movement_mode_cart()
00475             push_arm.move_absolute(loc, stop='pressure', frame=push_frame)
00476             rospy.loginfo('Done moving to overhead start point')
00477             # Lower arm to table
00478             pose = np.matrix([start_point.x, start_point.y, start_point.z])
00479             loc = [pose, rot]
00480             push_arm.set_movement_mode_cart()
00481             push_arm.move_absolute(loc, stop='pressure', frame=push_frame)
00482             rospy.loginfo('Done moving to start point')
00483         else:
00484             # Move to offset pose
00485             loc = [pose, rot]
00486             push_arm.set_movement_mode_cart()
00487             push_arm.move_absolute(loc, stop='pressure', frame=push_frame)
00488             rospy.loginfo('Done moving to start point')
00489 
00490         return response
00491 
00492     def gripper_post_sweep_action(self, request):
00493         response = GripperPushResponse()
00494         push_frame = request.start_point.header.frame_id
00495         start_point = request.start_point.point
00496         wrist_yaw = request.wrist_yaw
00497         push_dist = request.desired_push_dist
00498 
00499         if request.left_arm:
00500             push_arm = self.left_arm_move
00501             robot_arm = self.robot.left
00502             ready_joints = LEFT_ARM_READY_JOINTS
00503             which_arm = 'l'
00504             wrist_roll = -pi
00505         else:
00506             push_arm = self.right_arm_move
00507             robot_arm = self.robot.right
00508             ready_joints = RIGHT_ARM_READY_JOINTS
00509             which_arm = 'r'
00510             wrist_roll = 0.0
00511 
00512         rospy.loginfo('Moving gripper up')
00513         push_arm.move_relative_gripper(
00514             np.matrix([0.0, self.gripper_raise_dist, 0.0]).T,
00515             stop='pressure', pressure=5000)
00516         rospy.loginfo('Done moving up')
00517 
00518         rospy.loginfo('Sweeping outward')
00519         push_arm.move_relative_gripper(
00520             np.matrix([0.0, 0.0, (push_dist)]).T,
00521             stop='pressure', pressure=5000)
00522         rospy.loginfo('Done sweeping outward')
00523 
00524         if request.high_arm_init:
00525             rospy.loginfo('Moving up to end point')
00526             wrist_yaw = request.wrist_yaw
00527             orientation = tf.transformations.quaternion_from_euler(0.5*pi, 0.0,
00528                                                                    wrist_yaw)
00529             pose = np.matrix([start_point.x, start_point.y,
00530                               self.high_arm_init_z])
00531             rot = np.matrix([orientation])
00532             loc = [pose, rot]
00533             push_arm.set_movement_mode_cart()
00534             push_arm.move_absolute(loc, stop='pressure', frame=push_frame)
00535             rospy.loginfo('Done moving up to end point')
00536 
00537         if request.arm_reset:
00538             self.reset_arm_pose(True, which_arm, request.high_arm_init)
00539         return response
00540 
00541     def overhead_push_action(self, request):
00542         response = GripperPushResponse()
00543         push_frame = request.start_point.header.frame_id
00544         start_point = request.start_point.point
00545         wrist_yaw = request.wrist_yaw
00546         push_dist = request.desired_push_dist
00547 
00548         if request.left_arm:
00549             push_arm = self.left_arm_move
00550             robot_arm = self.robot.left
00551             ready_joints = LEFT_ARM_READY_JOINTS
00552             which_arm = 'l'
00553             wrist_pitch = 0.5*pi
00554         else:
00555             push_arm = self.right_arm_move
00556             robot_arm = self.robot.right
00557             ready_joints = RIGHT_ARM_READY_JOINTS
00558             which_arm = 'r'
00559             wrist_pitch = -0.5*pi
00560 
00561         push_arm.pressure_listener.rezero()
00562 
00563         rospy.loginfo('Pushing forward')
00564         r, pos_error = push_arm.move_relative_gripper(
00565             np.matrix([0.0, 0.0, push_dist]).T,
00566             stop='pressure', pressure=5000)
00567         rospy.loginfo('Done pushing forward')
00568 
00569         response.dist_pushed = push_dist - pos_error
00570         return response
00571 
00572     def overhead_pre_push_action(self, request):
00573         response = GripperPushResponse()
00574         push_frame = request.start_point.header.frame_id
00575         start_point = request.start_point.point
00576         wrist_yaw = request.wrist_yaw
00577         push_dist = request.desired_push_dist
00578 
00579         if request.left_arm:
00580             push_arm = self.left_arm_move
00581             robot_arm = self.robot.left
00582             ready_joints = LEFT_ARM_READY_JOINTS
00583             if request.high_arm_init:
00584                 ready_joints = LEFT_ARM_PULL_READY_JOINTS
00585             which_arm = 'l'
00586             wrist_pitch = 0.5*pi
00587         else:
00588             push_arm = self.right_arm_move
00589             robot_arm = self.robot.right
00590             ready_joints = RIGHT_ARM_READY_JOINTS
00591             if request.high_arm_init:
00592                 ready_joints = RIGHT_ARM_PULL_READY_JOINTS
00593             which_arm = 'r'
00594             wrist_pitch = -0.5*pi
00595 
00596         orientation = tf.transformations.quaternion_from_euler(
00597             0.0, fabs(wrist_pitch), wrist_yaw)
00598         pose = np.matrix([start_point.x, start_point.y, start_point.z])
00599         rot = np.matrix([orientation])
00600 
00601         if request.arm_init:
00602             rospy.loginfo('Moving %s_arm to ready pose' % which_arm)
00603             push_arm.set_movement_mode_ik()
00604             robot_arm.set_pose(ready_joints, nsecs=1.5, block=True)
00605 
00606             if not request.high_arm_init:
00607                 # Rotate wrist before moving to position
00608                 rospy.loginfo('Rotating elbow for overhead push')
00609                 arm_pose = robot_arm.pose()
00610                 arm_pose[-3] =  wrist_pitch
00611                 robot_arm.set_pose(arm_pose, nsecs=1.0, block=True)
00612 
00613             # Rotate wrist before moving to position
00614             # TODO: Figure this out using IK...
00615             rospy.loginfo('Rotating wrist for overhead push')
00616             arm_pose = robot_arm.pose()
00617             arm_pose[-1] = wrist_yaw
00618             robot_arm.set_pose(arm_pose, nsecs=1.0, block=True)
00619 
00620         if request.high_arm_init:
00621             # Move to offset pose above the table
00622             pose = np.matrix([start_point.x, start_point.y,
00623                               self.high_arm_init_z])
00624             loc = [pose, rot]
00625             push_arm.set_movement_mode_cart()
00626             push_arm.move_absolute(loc, stop='pressure', frame=push_frame)
00627             rospy.loginfo('Done moving to overhead start point')
00628             # Lower arm to table
00629             pose = np.matrix([start_point.x, start_point.y, start_point.z])
00630             loc = [pose, rot]
00631             push_arm.set_movement_mode_cart()
00632             push_arm.move_absolute(loc, stop='pressure', frame=push_frame)
00633             rospy.loginfo('Done moving to start point')
00634         else:
00635             # Move to offset pose
00636             loc = [pose, rot]
00637             push_arm.set_movement_mode_cart()
00638             push_arm.move_absolute(loc, stop='pressure', frame=push_frame)
00639             rospy.loginfo('Done moving to start point')
00640 
00641         return response
00642 
00643     def overhead_post_push_action(self, request):
00644         response = GripperPushResponse()
00645         push_frame = request.start_point.header.frame_id
00646         start_point = request.start_point.point
00647         wrist_yaw = request.wrist_yaw
00648         push_dist = request.desired_push_dist
00649 
00650         if request.left_arm:
00651             push_arm = self.left_arm_move
00652             robot_arm = self.robot.left
00653             ready_joints = LEFT_ARM_READY_JOINTS
00654             if request.high_arm_init:
00655                 ready_joints = LEFT_ARM_PULL_READY_JOINTS
00656             which_arm = 'l'
00657             wrist_pitch = 0.5*pi
00658         else:
00659             push_arm = self.right_arm_move
00660             robot_arm = self.robot.right
00661             ready_joints = RIGHT_ARM_READY_JOINTS
00662             if request.high_arm_init:
00663                 ready_joints = RIGHT_ARM_PULL_READY_JOINTS
00664             which_arm = 'r'
00665             wrist_pitch = -0.5*pi
00666 
00667         rospy.loginfo('Moving gripper up')
00668         push_arm.move_relative_gripper(
00669             np.matrix([-self.gripper_raise_dist, 0.0, 0.0]).T,
00670             stop='pressure', pressure=5000)
00671         rospy.loginfo('Done moving up')
00672         rospy.loginfo('Pushing reverse')
00673         push_arm.move_relative_gripper(
00674             np.matrix([0.0, 0.0, -push_dist]).T,
00675             stop='pressure', pressure=5000)
00676         rospy.loginfo('Done pushing reverse')
00677 
00678         if request.high_arm_init:
00679             rospy.loginfo('Moving up to end point')
00680             wrist_yaw = request.wrist_yaw
00681             orientation = tf.transformations.quaternion_from_euler(0.0, 0.5*pi,
00682                                                                    wrist_yaw)
00683             pose = np.matrix([start_point.x, start_point.y,
00684                               self.high_arm_init_z])
00685             rot = np.matrix([orientation])
00686             loc = [pose, rot]
00687             push_arm.set_movement_mode_cart()
00688             push_arm.move_absolute(loc, stop='pressure', frame=push_frame)
00689             rospy.loginfo('Done moving up to end point')
00690 
00691         if request.arm_reset:
00692             self.reset_arm_pose(True, which_arm, request.high_arm_init)
00693         return response
00694 
00695     def overhead_pull_action(self, request):
00696         response = GripperPushResponse()
00697         push_frame = request.start_point.header.frame_id
00698         start_point = request.start_point.point
00699         wrist_yaw = request.wrist_yaw
00700         push_dist = request.desired_push_dist
00701 
00702         if request.left_arm:
00703             push_arm = self.left_arm_move
00704             robot_arm = self.robot.left
00705             ready_joints = LEFT_ARM_READY_JOINTS
00706             which_arm = 'l'
00707             wrist_pitch = 0.5*pi
00708         else:
00709             push_arm = self.right_arm_move
00710             robot_arm = self.robot.right
00711             ready_joints = RIGHT_ARM_READY_JOINTS
00712             which_arm = 'r'
00713             wrist_pitch = -0.5*pi
00714 
00715         push_arm.pressure_listener.rezero()
00716 
00717         rospy.loginfo('Pull backwards')
00718         r, pos_error = push_arm.move_relative_gripper(
00719             np.matrix([0.0, 0.0, -push_dist]).T,
00720             stop='pressure', pressure=5000)
00721         rospy.loginfo('Done pushing forward')
00722 
00723         response.dist_pushed = push_dist - pos_error
00724         return response
00725 
00726     def overhead_pre_pull_action(self, request):
00727         response = GripperPushResponse()
00728         push_frame = request.start_point.header.frame_id
00729         start_point = request.start_point.point
00730         wrist_yaw = request.wrist_yaw
00731         push_dist = request.desired_push_dist
00732 
00733         if request.left_arm:
00734             push_arm = self.left_arm_move
00735             robot_arm = self.robot.left
00736             ready_joints = LEFT_ARM_PULL_READY_JOINTS
00737             which_arm = 'l'
00738             wrist_pitch = 0.5*pi
00739         else:
00740             push_arm = self.right_arm_move
00741             robot_arm = self.robot.right
00742             ready_joints = RIGHT_ARM_PULL_READY_JOINTS
00743             which_arm = 'r'
00744             wrist_pitch = -0.5*pi
00745 
00746         if request.arm_init:
00747             rospy.loginfo('Moving %s_arm to ready pose' % which_arm)
00748             push_arm.set_movement_mode_ik()
00749             robot_arm.set_pose(ready_joints, nsecs=1.5, block=True)
00750 
00751         orientation = tf.transformations.quaternion_from_euler(0.0, 0.5*pi,
00752                                                                wrist_yaw)
00753         pose = np.matrix([start_point.x, start_point.y,
00754                           self.high_arm_init_z])
00755         rot = np.matrix([orientation])
00756 
00757         # Rotate wrist before moving to position
00758         # rospy.loginfo('Rotating elbow for overhead push')
00759         # arm_pose = robot_arm.pose()
00760         # arm_pose[-3] =  wrist_pitch
00761         # robot_arm.set_pose(arm_pose, nsecs=1.0, block=True)
00762 
00763         # Move to offset pose above the table
00764         loc = [pose, rot]
00765         push_arm.set_movement_mode_cart()
00766         push_arm.move_absolute(loc, stop='pressure', frame=push_frame)
00767         rospy.loginfo('Done moving to overhead start point')
00768 
00769 
00770         # Lower arm to table
00771         pose = np.matrix([start_point.x, start_point.y, start_point.z])
00772         rot = np.matrix([orientation])
00773         loc = [pose, rot]
00774         push_arm.set_movement_mode_cart()
00775         push_arm.move_absolute(loc, stop='pressure', frame=push_frame)
00776         rospy.loginfo('Done moving to start point')
00777 
00778         return response
00779 
00780     def overhead_post_pull_action(self, request):
00781         response = GripperPushResponse()
00782         push_frame = request.start_point.header.frame_id
00783         start_point = request.start_point.point
00784         wrist_yaw = request.wrist_yaw
00785         push_dist = request.desired_push_dist
00786 
00787         if request.left_arm:
00788             push_arm = self.left_arm_move
00789             robot_arm = self.robot.left
00790             ready_joints = LEFT_ARM_PULL_READY_JOINTS
00791             which_arm = 'l'
00792             wrist_pitch = 0.5*pi
00793         else:
00794             push_arm = self.right_arm_move
00795             robot_arm = self.robot.right
00796             ready_joints = RIGHT_ARM_PULL_READY_JOINTS
00797             which_arm = 'r'
00798             wrist_pitch = -0.5*pi
00799 
00800         rospy.loginfo('Moving gripper up')
00801         push_arm.move_relative_gripper(
00802             np.matrix([-self.pull_raise_dist, 0.0, 0.0]).T,
00803             stop='pressure', pressure=5000)
00804         rospy.loginfo('Done moving up')
00805         rospy.loginfo('Pushing reverse')
00806         push_arm.move_relative_gripper(
00807             np.matrix([0.0, 0.0, push_dist]).T,
00808             stop='pressure', pressure=5000)
00809         rospy.loginfo('Done pushing reverse')
00810 
00811         rospy.loginfo('Moving up to end point')
00812         wrist_yaw = request.wrist_yaw
00813         orientation = tf.transformations.quaternion_from_euler(0.0, 0.5*pi,
00814                                                                wrist_yaw)
00815         pose = np.matrix([start_point.x, start_point.y,
00816                           self.high_arm_init_z])
00817         rot = np.matrix([orientation])
00818         loc = [pose, rot]
00819         push_arm.set_movement_mode_cart()
00820         push_arm.move_absolute(loc, stop='pressure', frame=push_frame)
00821         rospy.loginfo('Done moving up to end point')
00822 
00823         if request.arm_reset:
00824             self.reset_arm_pose(True, which_arm, request.high_arm_init)
00825         return response
00826 
00827     def raise_and_look(self, request):
00828         '''
00829         Service callback to raise the spine to a specific height relative to the
00830         table height and tilt the head so that the Kinect views the table
00831         '''
00832         if request.init_arms:
00833             self.init_arms()
00834 
00835         if request.point_head_only:
00836             response = RaiseAndLookResponse()
00837             response.head_succeeded = self.init_head_pose(request.camera_frame)
00838             return response
00839 
00840         if not request.have_table_centroid:
00841             response = RaiseAndLookResponse()
00842             response.head_succeeded = self.init_head_pose(request.camera_frame)
00843             self.init_spine_pose()
00844             return response
00845 
00846         # Get torso_lift_link position in base_link frame
00847         (trans, rot) = self.tf_listener.lookupTransform('base_link',
00848                                                         'torso_lift_link',
00849                                                         rospy.Time(0))
00850         lift_link_z = trans[2]
00851 
00852         # tabletop position in base_link frame
00853         request.table_centroid.header.stamp = rospy.Time(0)
00854         table_base = self.tf_listener.transformPose('base_link',
00855                                                     request.table_centroid)
00856         table_z = table_base.pose.position.z
00857         goal_lift_link_z = table_z + self.torso_z_offset
00858         lift_link_delta_z = goal_lift_link_z - lift_link_z
00859         # rospy.logdebug('Torso height (m): ' + str(lift_link_z))
00860         rospy.logdebug('Table height (m): ' + str(table_z))
00861         rospy.logdebug('Torso goal height (m): ' + str(goal_lift_link_z))
00862         # rospy.logdebug('Torso delta (m): ' + str(lift_link_delta_z))
00863 
00864         # Set goal height based on passed on table height
00865         # TODO: Set these better
00866         torso_max = 0.3
00867         torso_min = 0.01
00868         current_torso_position = np.asarray(self.robot.torso.pose()).ravel()[0]
00869         torso_goal_position = current_torso_position + lift_link_delta_z
00870         torso_goal_position = (max(min(torso_max, torso_goal_position),
00871                                    torso_min))
00872         # rospy.logdebug('Moving torso to ' + str(torso_goal_position))
00873         # Multiply by 2.0, because of units of spine
00874         self.robot.torso.set_pose(torso_goal_position)
00875 
00876         # rospy.logdebug('Got torso client result')
00877         new_torso_position = np.asarray(self.robot.torso.pose()).ravel()[0]
00878         rospy.loginfo('New spine height is ' + str(new_torso_position))
00879 
00880         # Get torso_lift_link position in base_link frame
00881 
00882         (new_trans, rot) = self.tf_listener.lookupTransform('base_link',
00883                                                             'torso_lift_link',
00884                                                             rospy.Time(0))
00885         new_lift_link_z = new_trans[2]
00886         # rospy.logdebug('New Torso height (m): ' + str(new_lift_link_z))
00887         # tabletop position in base_link frame
00888         new_table_base = self.tf_listener.transformPose('base_link',
00889                                                         request.table_centroid)
00890         new_table_z = new_table_base.pose.position.z
00891         rospy.loginfo('New Table height: ' + str(new_table_z))
00892 
00893         # Point the head at the table centroid
00894         # NOTE: Should we fix the tilt angle instead for consistency?
00895         look_pt = np.asmatrix([self.look_pt_x,
00896                                0.0,
00897                                -self.torso_z_offset])
00898         rospy.logdebug('Point head at ' + str(look_pt))
00899         head_res = self.robot.head.look_at(look_pt,
00900                                            request.table_centroid.header.frame_id,
00901                                            request.camera_frame)
00902         response = RaiseAndLookResponse()
00903         if head_res:
00904             rospy.loginfo('Succeeded in pointing head')
00905             response.head_succeeded = True
00906         else:
00907             rospy.logwarn('Failed to point head')
00908             response.head_succeeded = False
00909         return response
00910 
00911     #
00912     # Util Functions
00913     #
00914     def print_pose(self):
00915         pose = self.robot.left.pose()
00916         rospy.loginfo('Left arm pose: ' + str(pose))
00917         cart_pose = self.left_arm_move.arm_obj.pose_cartesian_tf()
00918         rospy.loginfo('Left Cart_position: ' + str(cart_pose[0]))
00919         rospy.loginfo('Left Cart_orientation: ' + str(cart_pose[1]))
00920         cart_pose = self.right_arm_move.arm_obj.pose_cartesian_tf()
00921         pose = self.robot.right.pose()
00922         rospy.loginfo('Right arm pose: ' + str(pose))
00923         rospy.loginfo('Right Cart_position: ' + str(cart_pose[0]))
00924         rospy.loginfo('Right Cart_orientation: ' + str(cart_pose[1]))
00925 
00926     def init_head_pose(self, camera_frame):
00927         look_pt = np.asmatrix([self.look_pt_x, 0.0, -self.torso_z_offset])
00928         rospy.loginfo('Point head at ' + str(look_pt))
00929         head_res = self.robot.head.look_at(look_pt,
00930                                            'torso_lift_link',
00931                                            camera_frame)
00932         if head_res:
00933             rospy.loginfo('Succeeded in pointing head')
00934             return True
00935         else:
00936             rospy.loginfo('Failed to point head')
00937             return False
00938 
00939     def init_spine_pose(self):
00940         rospy.loginfo('Setting spine height to '+str(self.default_torso_height))
00941         self.robot.torso.set_pose(self.default_torso_height)
00942         new_torso_position = np.asarray(self.robot.torso.pose()).ravel()[0]
00943         rospy.loginfo('New spine height is ' + str(new_torso_position))
00944 
00945     def init_arms(self):
00946         self.init_arm_pose(True, which_arm='r')
00947         self.init_arm_pose(True, which_arm='l')
00948         rospy.loginfo('Done initializing arms')
00949 
00950     #
00951     # Main Control Loop
00952     #
00953     def run(self):
00954         '''
00955         Main control loop for the node
00956         '''
00957         # self.print_pose()
00958         self.init_spine_pose()
00959         self.init_head_pose(self.head_pose_cam_frame)
00960         self.init_arms()
00961         rospy.loginfo('Done initializing tabletop_push_node')
00962         rospy.spin()
00963 
00964 if __name__ == '__main__':
00965     node = TabletopPushNode()
00966     node.run()


tabletop_pushing
Author(s): Tucker Hermans
autogenerated on Wed Nov 27 2013 11:59:44