00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 import roslib; roslib.load_manifest('tabletop_pushing')
00035 import rospy
00036 import actionlib
00037 import hrl_pr2_lib.pr2 as pr2
00038 import hrl_pr2_lib.pressure_listener as pl
00039 import hrl_lib.tf_utils as tfu
00040 from hrl_pr2_arms.pr2_controller_switcher import ControllerSwitcher
00041 from geometry_msgs.msg import PoseStamped, TwistStamped
00042 from kinematics_msgs.srv import *
00043 from std_msgs.msg import Float64MultiArray
00044 from pr2_controllers_msgs.msg import *
00045 from pr2_manipulation_controllers.msg import *
00046 import tf
00047 import numpy as np
00048 from tabletop_pushing.srv import *
00049 from tabletop_pushing.msg import *
00050 from math import sin, cos, pi, fabs, sqrt, atan2
00051 from push_learning import ControlAnalysisIO
00052 import rbf_control
00053 import sys
00054 
00055 
00056 from push_primitives import *
00057 
00058 _USE_CONTROLLER_IO = False
00059 _USE_LEARN_IO = True
00060 
00061 
00062 LEFT_ARM_SETUP_JOINTS = np.matrix([[1.32734204881265387,
00063                                     -0.34601608409943324,
00064                                     1.4620635485239604,
00065                                     -1.2729772622637399,
00066                                     7.5123303230158518,
00067                                     -1.5570651396529178,
00068                                     -5.5929916630672727]]).T
00069 RIGHT_ARM_SETUP_JOINTS = np.matrix([[-1.32734204881265387,
00070                                       -0.34601608409943324,
00071                                       -1.4620635485239604,
00072                                       -1.2729772622637399,
00073                                       -7.5123303230158518,
00074                                       -1.5570651396529178,
00075                                       -7.163787989862169]]).T
00076 LEFT_ARM_READY_JOINTS = np.matrix([[0.42427649, 0.0656137,
00077                                     1.43411927, -2.11931035,
00078                                     -15.78839978, -1.64163257,
00079                                     -17.2947453]]).T
00080 RIGHT_ARM_READY_JOINTS = np.matrix([[-0.42427649, 0.0656137,
00081                                      -1.43411927, -2.11931035,
00082                                      15.78839978, -1.64163257,
00083                                      8.64421842e+01]]).T
00084 LEFT_ARM_PULL_READY_JOINTS = np.matrix([[0.42427649,
00085                                          -0.34601608409943324,
00086                                          1.43411927,
00087                                          -2.11931035,
00088                                          82.9984037,
00089                                          -1.64163257,
00090                                          -36.16]]).T
00091 RIGHT_ARM_PULL_READY_JOINTS = np.matrix([[-0.42427649,
00092                                          -0.34601608409943324,
00093                                          -1.43411927,
00094                                          -2.11931035,
00095                                          -82.9984037,
00096                                          -1.64163257,
00097                                          54.8]]).T
00098 LEFT_ARM_HIGH_PUSH_READY_JOINTS = np.matrix([[0.42427649,
00099                                               -0.34601608409943324,
00100                                               1.43411927,
00101                                               -2.11931035,
00102                                               -15.78839978,
00103                                               -1.64163257,
00104                                               -17.2947453]]).T
00105 RIGHT_ARM_HIGH_PUSH_READY_JOINTS = np.matrix([[-0.42427649,
00106                                                 -0.34601608409943324,
00107                                                 -1.43411927,
00108                                                 -2.11931035,
00109                                                 15.78839978,
00110                                                 -1.64163257,
00111                                                 8.64421842e+01]]).T
00112 LEFT_ARM_HIGH_SWEEP_READY_JOINTS = LEFT_ARM_HIGH_PUSH_READY_JOINTS
00113 RIGHT_ARM_HIGH_SWEEP_READY_JOINTS = RIGHT_ARM_HIGH_PUSH_READY_JOINTS
00114 
00115 _POSTURES = {
00116     'off': [],
00117     'mantis': [0, 1, 0,  -1, 3.14, -1, 3.14],
00118     'elbowupr': [-0.79,0,-1.6,  9999, 9999, 9999, 9999],
00119     'elbowupl': [0.79,0,1.6 , 9999, 9999, 9999, 9999],
00120     'old_elbowupr': [-0.79,0,-1.6, -0.79,3.14, -0.79,5.49],
00121     'old_elbowupl': [0.79,0,1.6, -0.79,3.14, -0.79,5.49],
00122     'elbowdownr': [-0.028262077316910873, 1.2946342642324222, -0.25785640577652386, -1.5498884526859626, -31.278913849571776, -1.0527644894829107, -1.8127318367654268],
00123     'elbowdownl': [-0.0088195719039858515, 1.2834828245284853, 0.20338442004843196, -1.5565279256852611, -0.096340012666916802, -1.0235018652439782, 1.7990893054129216],
00124     'gripper_place_r': [-0.58376927, 0.20531188, -1.98435142, -1.35661954, -10.97764169, -0.08100618, -6.48535644],
00125     'gripper_place_l': [0.9424233, 0.24058796, 2.04239987, -1.4576695 , -1.58940656, -0.5444458 , -6.23912942]
00126 }
00127 
00128 _ARM_ERROR_CODES = {}
00129 _ARM_ERROR_CODES[-1] = 'PLANNING_FAILED'
00130 _ARM_ERROR_CODES[1]='SUCCESS'
00131 _ARM_ERROR_CODES[-2]='TIMED_OUT'
00132 _ARM_ERROR_CODES[-3]='START_STATE_IN_COLLISION'
00133 _ARM_ERROR_CODES[-4]='START_STATE_VIOLATES_PATH_CONSTRAINTS'
00134 _ARM_ERROR_CODES[-5]='GOAL_IN_COLLISION'
00135 _ARM_ERROR_CODES[-6]='GOAL_VIOLATES_PATH_CONSTRAINTS'
00136 _ARM_ERROR_CODES[-7]='INVALID_ROBOT_STATE'
00137 _ARM_ERROR_CODES[-8]='INCOMPLETE_ROBOT_STATE'
00138 _ARM_ERROR_CODES[-9]='INVALID_PLANNER_ID'
00139 _ARM_ERROR_CODES[-10]='INVALID_NUM_PLANNING_ATTEMPTS'
00140 _ARM_ERROR_CODES[-11]='INVALID_ALLOWED_PLANNING_TIME'
00141 _ARM_ERROR_CODES[-12]='INVALID_GROUP_NAME'
00142 _ARM_ERROR_CODES[-13]='INVALID_GOAL_JOINT_CONSTRAINTS'
00143 _ARM_ERROR_CODES[-14]='INVALID_GOAL_POSITION_CONSTRAINTS'
00144 _ARM_ERROR_CODES[-15]='INVALID_GOAL_ORIENTATION_CONSTRAINTS'
00145 _ARM_ERROR_CODES[-16]='INVALID_PATH_JOINT_CONSTRAINTS'
00146 _ARM_ERROR_CODES[-17]='INVALID_PATH_POSITION_CONSTRAINTS'
00147 _ARM_ERROR_CODES[-18]='INVALID_PATH_ORIENTATION_CONSTRAINTS'
00148 _ARM_ERROR_CODES[-19]='INVALID_TRAJECTORY'
00149 _ARM_ERROR_CODES[-20]='INVALID_INDEX'
00150 _ARM_ERROR_CODES[-21]='JOINT_LIMITS_VIOLATED'
00151 _ARM_ERROR_CODES[-22]='PATH_CONSTRAINTS_VIOLATED'
00152 _ARM_ERROR_CODES[-23]='COLLISION_CONSTRAINTS_VIOLATED'
00153 _ARM_ERROR_CODES[-24]='GOAL_CONSTRAINTS_VIOLATED'
00154 _ARM_ERROR_CODES[-25]='JOINTS_NOT_MOVING'
00155 _ARM_ERROR_CODES[-26]='TRAJECTORY_CONTROLLER_FAILED'
00156 _ARM_ERROR_CODES[-27]='FRAME_TRANSFORM_FAILURE'
00157 _ARM_ERROR_CODES[-28]='COLLISION_CHECKING_UNAVAILABLE'
00158 _ARM_ERROR_CODES[-29]='ROBOT_STATE_STALE'
00159 _ARM_ERROR_CODES[-30]='SENSOR_INFO_STALE'
00160 _ARM_ERROR_CODES[-31]='NO_IK_SOLUTION'
00161 _ARM_ERROR_CODES[-32]='INVALID_LINK_NAME'
00162 _ARM_ERROR_CODES[-33]='IK_LINK_IN_COLLISION'
00163 _ARM_ERROR_CODES[-34]='NO_FK_SOLUTION'
00164 _ARM_ERROR_CODES[-35]='KINEMATICS_STATE_IN_COLLISION'
00165 _ARM_ERROR_CODES[-36]='INVALID_TIMEOUT'
00166 
00167 def subPIAngle(theta):
00168     while theta < -pi:
00169         theta += 2.0*pi
00170     while theta > pi:
00171         theta -= 2.0*pi
00172     return theta
00173 
00174 def sign(x):
00175     if x < 0:
00176         return -1
00177     return 1
00178 
00179 def trigAugState(X, ndx, remove_old=False):
00180     X_aug = []
00181     if remove_old:
00182         for i, x in enumerate(X):
00183             if i in ndx:
00184                 continue
00185             else:
00186                 X_aug.append(x)
00187     else:
00188         X_aug = X[:]
00189     for i in ndx:
00190         X_aug = np.append(X_aug, [sin(X[i]), cos(X[i])])
00191     return np.asarray(X_aug)
00192 
00193 class PositionFeedbackPushNode:
00194 
00195     def __init__(self):
00196         rospy.init_node('position_feedback_push_node', log_level=rospy.INFO)
00197         self.controller_io = ControlAnalysisIO()
00198         self.use_learn_io = False
00199         self.use_gripper_place_joint_posture = False
00200         out_file_name = '/u/thermans/data/new/control_out_'+str(rospy.get_time())+'.txt'
00201         rospy.loginfo('Opening controller output file: '+out_file_name)
00202         if _USE_CONTROLLER_IO:
00203             self.controller_io.open_out_file(out_file_name)
00204         if _USE_LEARN_IO:
00205             self.learn_io = None
00206         
00207         self.learned_controller_base_path = rospy.get_param('~learned_controller_base_path',
00208                                                             '/u/thermans/cfg/controllers/')
00209         self.torso_z_offset = rospy.get_param('~torso_z_offset', 0.30)
00210         self.look_pt_x = rospy.get_param('~look_point_x', 0.7)
00211         self.head_pose_cam_frame = rospy.get_param('~head_pose_cam_frame',
00212                                                    'head_mount_kinect_rgb_link')
00213         self.default_torso_height = rospy.get_param('~default_torso_height',
00214                                                     0.30)
00215         self.gripper_raise_dist = rospy.get_param('~gripper_raise_dist',
00216                                                   0.05)
00217         self.gripper_pull_reverse_dist = rospy.get_param('~gripper_pull_reverse_dist',
00218                                                          0.1)
00219         self.gripper_pull_forward_dist = rospy.get_param('~gripper_pull_forward_dist',
00220                                                          0.15)
00221         self.gripper_push_reverse_dist = rospy.get_param('~gripper_push_reverse_dist',
00222                                                          0.03)
00223         self.high_arm_init_z = rospy.get_param('~high_arm_start_z', 0.15)
00224         self.lower_arm_init_z = rospy.get_param('~lower_arm_start_z', -0.10)
00225         self.post_controller_switch_sleep = rospy.get_param(
00226             '~arm_switch_sleep_time', 0.5)
00227         self.move_cart_check_hz = rospy.get_param('~move_cart_check_hz', 100)
00228         self.arm_done_moving_count_thresh = rospy.get_param(
00229             '~not_moving_count_thresh', 30)
00230         self.arm_done_moving_epc_count_thresh = rospy.get_param(
00231             '~not_moving_epc_count_thresh', 60)
00232         self.post_move_count_thresh = rospy.get_param('~post_move_count_thresh',
00233                                                       10)
00234         self.post_pull_count_thresh = rospy.get_param('~post_move_count_thresh',
00235                                                       20)
00236         self.pre_push_count_thresh = rospy.get_param('~pre_push_count_thresh',
00237                                                       50)
00238         self.still_moving_velocity = rospy.get_param('~moving_vel_thresh', 0.01)
00239         self.still_moving_angular_velocity = rospy.get_param('~angular_vel_thresh',
00240                                                              0.005)
00241         self.pressure_safety_limit = rospy.get_param('~pressure_limit',
00242                                                      2000)
00243         self.max_close_effort = rospy.get_param('~max_close_effort', 50)
00244 
00245         self.k_g = rospy.get_param('~push_control_goal_gain', 0.1)
00246         self.k_g_direct = rospy.get_param('~push_control_direct_goal_gain', 0.1);
00247         self.k_s_d = rospy.get_param('~push_control_spin_gain', 0.05)
00248         self.k_s_p = rospy.get_param('~push_control_position_spin_gain', 0.05)
00249 
00250         self.k_contact_g = rospy.get_param('~push_control_contact_goal_gain', 0.05)
00251         self.k_contact_d = rospy.get_param('~push_control_contact_gain', 0.05)
00252 
00253         self.k_h_f = rospy.get_param('~push_control_forward_heading_gain', 0.1)
00254         self.k_rotate_spin_x = rospy.get_param('~rotate_to_heading_hand_spin_gain', 0.0)
00255         self.max_heading_u_x = rospy.get_param('~max_heading_push_u_x', 0.2)
00256         self.max_heading_u_y = rospy.get_param('~max_heading_push_u_y', 0.01)
00257         self.max_goal_vel = rospy.get_param('~max_goal_vel', 0.015)
00258 
00259         self.straight_v = rospy.get_param('~straight_line_goal_vel', 0.03)
00260 
00261         self.use_jinv = rospy.get_param('~use_jinv', True)
00262         self.use_cur_joint_posture = rospy.get_param('~use_joint_posture', True)
00263 
00264         self.servo_head_during_pushing = rospy.get_param('servo_head_during_pushing', False)
00265         self.RBF = None
00266 
00267         
00268         if self.use_jinv:
00269             self.base_cart_controller_name = '_cart_jinv_push'
00270             self.controller_state_msg = JinvTeleopControllerState
00271         else:
00272             self.base_cart_controller_name = '_cart_transpose_push'
00273             self.controller_state_msg = JTTaskControllerState
00274         self.base_vel_controller_name = '_cart_jinv_push'
00275         self.vel_controller_state_msg = JinvTeleopControllerState
00276 
00277         
00278         self.arm_mode = None
00279         self.cs = ControllerSwitcher()
00280         self.init_joint_controllers()
00281         self.init_cart_controllers()
00282         self.init_vel_controllers()
00283 
00284         
00285         self.tf_listener = tf.TransformListener()
00286         rospy.loginfo('Creating pr2 object')
00287         self.robot = pr2.PR2(self.tf_listener, arms=True, base=False, use_kinematics=False)
00288 
00289         self.l_arm_cart_pub = rospy.Publisher('/l'+self.base_cart_controller_name+'/command_pose', PoseStamped)
00290         self.r_arm_cart_pub = rospy.Publisher('/r'+self.base_cart_controller_name+'/command_pose', PoseStamped)
00291         self.l_arm_cart_posture_pub = rospy.Publisher('/l'+self.base_cart_controller_name+'/command_posture',
00292                                                       Float64MultiArray)
00293         self.r_arm_cart_posture_pub = rospy.Publisher('/r'+self.base_cart_controller_name+'/command_posture',
00294                                                       Float64MultiArray)
00295         self.l_arm_cart_vel_pub = rospy.Publisher('/l'+self.base_vel_controller_name+'/command_twist', TwistStamped)
00296         self.r_arm_cart_vel_pub = rospy.Publisher('/r'+self.base_vel_controller_name+'/command_twist', TwistStamped)
00297         self.l_arm_vel_posture_pub = rospy.Publisher('/l'+self.base_vel_controller_name+'/command_posture',
00298                                                      Float64MultiArray)
00299         self.r_arm_vel_posture_pub = rospy.Publisher('/r'+self.base_vel_controller_name+'/command_posture',
00300                                                      Float64MultiArray)
00301 
00302         rospy.Subscriber('/l'+self.base_cart_controller_name+'/state', self.controller_state_msg,
00303                          self.l_arm_cart_state_callback)
00304         rospy.Subscriber('/r'+self.base_cart_controller_name+'/state', self.controller_state_msg,
00305                          self.r_arm_cart_state_callback)
00306 
00307         rospy.Subscriber('/l'+self.base_vel_controller_name+'/state', self.vel_controller_state_msg,
00308                          self.l_arm_vel_state_callback)
00309         rospy.Subscriber('/r'+self.base_vel_controller_name+'/state', self.vel_controller_state_msg,
00310                          self.r_arm_vel_state_callback)
00311 
00312         self.l_pressure_listener = pl.PressureListener('/pressure/l_gripper_motor', self.pressure_safety_limit)
00313         self.r_pressure_listener = pl.PressureListener('/pressure/r_gripper_motor', self.pressure_safety_limit)
00314 
00315         
00316         self.l_arm_ik_proxy = rospy.ServiceProxy('/pr2_left_arm_kinematics/get_ik', GetPositionIK)
00317         self.r_arm_ik_proxy = rospy.ServiceProxy('/pr2_right_arm_kinematics/get_ik', GetPositionIK)
00318         self.l_arm_ik_solver_proxy = rospy.ServiceProxy('/pr2_left_arm_kinematics/get_ik_solver_info',
00319                                                         GetKinematicSolverInfo)
00320         self.r_arm_ik_solver_proxy = rospy.ServiceProxy('/pr2_right_arm_kinematics/get_ik_solver_info',
00321                                                         GetKinematicSolverInfo)
00322 
00323         
00324         self.l_arm_pose = None
00325         self.l_arm_x_err = None
00326         self.l_arm_x_d = None
00327         self.l_arm_F = None
00328 
00329         self.r_arm_pose = None
00330         self.r_arm_x_err = None
00331         self.r_arm_x_d = None
00332         self.r_arm_F = None
00333 
00334         
00335         self.overhead_feedback_push_srv = rospy.Service(
00336             'overhead_feedback_push', FeedbackPush, self.overhead_feedback_push)
00337         self.overhead_feedback_post_push_srv = rospy.Service(
00338             'overhead_feedback_post_push', FeedbackPush,
00339             self.overhead_feedback_post_push)
00340 
00341         self.gripper_feedback_push_srv = rospy.Service(
00342             'gripper_feedback_push', FeedbackPush, self.gripper_feedback_push)
00343         self.gripper_feedback_post_push_srv = rospy.Service(
00344             'gripper_feedback_post_push', FeedbackPush,
00345             self.gripper_feedback_post_push)
00346 
00347         self.gripper_feedback_sweep_srv = rospy.Service(
00348             'gripper_feedback_sweep', FeedbackPush, self.gripper_feedback_sweep)
00349         self.gripper_feedback_post_sweep_srv = rospy.Service(
00350             'gripper_feedback_post_sweep', FeedbackPush,
00351             self.gripper_feedback_post_sweep)
00352 
00353         self.gripper_pre_push_srv = rospy.Service(
00354             'gripper_pre_push', FeedbackPush, self.gripper_pre_push)
00355         self.gripper_pre_sweep_srv = rospy.Service(
00356             'gripper_pre_sweep', FeedbackPush, self.gripper_pre_sweep)
00357         self.overhead_pre_push_srv = rospy.Service(
00358             'overhead_pre_push', FeedbackPush, self.overhead_pre_push)
00359 
00360         self.raise_and_look_serice = rospy.Service(
00361             'raise_and_look', RaiseAndLook, self.raise_and_look)
00362     
00363     
00364     
00365 
00366     
00367     
00368     
00369     def init_arm_pose(self, force_ready=False, which_arm='l'):
00370         '''
00371         Move the arm to the initial pose to be out of the way for viewing the
00372         tabletop
00373         '''
00374         if which_arm == 'l':
00375             robot_gripper = self.robot.left_gripper
00376             ready_joints = LEFT_ARM_READY_JOINTS
00377             setup_joints = LEFT_ARM_SETUP_JOINTS
00378         else:
00379             robot_gripper = self.robot.right_gripper
00380             ready_joints = RIGHT_ARM_READY_JOINTS
00381             setup_joints = RIGHT_ARM_SETUP_JOINTS
00382 
00383         rospy.loginfo('Moving %s_arm to setup pose' % which_arm)
00384         self.set_arm_joint_pose(setup_joints, which_arm)
00385         rospy.loginfo('Moved %s_arm to setup pose' % which_arm)
00386 
00387         rospy.loginfo('Closing %s_gripper' % which_arm)
00388         res = robot_gripper.close(block=True, effort=self.max_close_effort)
00389         rospy.loginfo('Closed %s_gripper' % which_arm)
00390 
00391 
00392     def reset_arm_pose(self, force_ready=False, which_arm='l',
00393                        high_arm_joints=False):
00394         '''
00395         Move the arm to the initial pose to be out of the way for viewing the
00396         tabletop
00397         '''
00398         if which_arm == 'l':
00399             robot_gripper = self.robot.left_gripper
00400             if high_arm_joints:
00401                 ready_joints = LEFT_ARM_HIGH_PUSH_READY_JOINTS
00402             else:
00403                 ready_joints = LEFT_ARM_READY_JOINTS
00404             setup_joints = LEFT_ARM_SETUP_JOINTS
00405         else:
00406             robot_gripper = self.robot.right_gripper
00407             if high_arm_joints:
00408                 ready_joints = RIGHT_ARM_HIGH_PUSH_READY_JOINTS
00409             else:
00410                 ready_joints = RIGHT_ARM_READY_JOINTS
00411             setup_joints = RIGHT_ARM_SETUP_JOINTS
00412         ready_diff = np.linalg.norm(pr2.diff_arm_pose(self.get_arm_joint_pose(which_arm),
00413                                                       ready_joints))
00414 
00415         
00416         if force_ready or ready_diff > READY_POSE_MOVE_THRESH:
00417             rospy.logdebug('Moving %s_arm to ready pose' % which_arm)
00418             self.set_arm_joint_pose(ready_joints, which_arm, nsecs=1.5)
00419             rospy.logdebug('Moved %s_arm to ready pose' % which_arm)
00420         else:
00421             rospy.logdebug('Arm in ready pose')
00422 
00423         rospy.logdebug('Moving %s_arm to setup pose' % which_arm)
00424         self.set_arm_joint_pose(setup_joints, which_arm, nsecs=1.5)
00425         rospy.logdebug('Moved %s_arm to setup pose' % which_arm)
00426 
00427     def init_head_pose(self, camera_frame):
00428         
00429         
00430 
00431         look_pt = np.asmatrix([self.look_pt_x, 0.0, -self.torso_z_offset])
00432         rospy.loginfo('Point head at ' + str(look_pt)+ ' in frame ' + camera_frame)
00433         head_res = self.robot.head.look_at(look_pt, 'torso_lift_link', camera_frame, wait=True)
00434         if head_res:
00435             rospy.loginfo('Succeeded in pointing head')
00436             return True
00437         else:
00438             rospy.logwarn('Failed to point head')
00439             return False
00440 
00441     def init_spine_pose(self):
00442         rospy.loginfo('Setting spine height to '+str(self.default_torso_height))
00443         self.robot.torso.set_pose(self.default_torso_height)
00444         new_torso_position = np.asarray(self.robot.torso.pose()).ravel()[0]
00445         rospy.loginfo('New spine height is ' + str(new_torso_position))
00446 
00447     def init_arms(self):
00448         self.init_arm_pose(True, which_arm='r')
00449         self.init_arm_pose(True, which_arm='l')
00450         rospy.loginfo('Done initializing arms')
00451 
00452     
00453     
00454     
00455     def gripper_feedback_push(self, request):
00456         feedback_cb = self.tracker_feedback_push
00457         return self.feedback_push_behavior(request, feedback_cb)
00458 
00459     def gripper_feedback_sweep(self, request):
00460         feedback_cb = self.tracker_feedback_push
00461         return self.feedback_push_behavior(request, feedback_cb)
00462 
00463     def overhead_feedback_push(self, request):
00464         feedback_cb = self.tracker_feedback_push
00465         return self.feedback_push_behavior(request, feedback_cb)
00466 
00467     def feedback_push_behavior(self, request, feedback_cb):
00468         response = FeedbackPushResponse()
00469         start_point = request.start_point.point
00470         wrist_yaw = request.wrist_yaw
00471 
00472         self.use_learn_io = (_USE_LEARN_IO and request.learn_out_file_name != '')
00473         if self.use_learn_io:
00474             self.learn_io = ControlAnalysisIO()
00475             self.learn_io.open_out_file(request.learn_out_file_name)
00476 
00477         if request.left_arm:
00478             which_arm = 'l'
00479         else:
00480             which_arm = 'r'
00481 
00482         self.active_arm = which_arm
00483         rospy.loginfo('Creating ac')
00484         ac = actionlib.SimpleActionClient('push_tracker',
00485                                           VisFeedbackPushTrackingAction)
00486         rospy.loginfo('waiting for server')
00487         if not ac.wait_for_server(rospy.Duration(5.0)):
00488             rospy.loginfo('Failed to connect to push tracker server')
00489             if self.use_learn_io:
00490                 self.learn_io.close_out_file()
00491             return response
00492         ac.cancel_all_goals()
00493         self.feedback_count = 0
00494 
00495         
00496         
00497         self.stop_moving_vel(which_arm)
00498         done_cb = None
00499         active_cb = None
00500         goal = VisFeedbackPushTrackingGoal()
00501         goal.which_arm = which_arm
00502         goal.header.frame_id = request.start_point.header.frame_id
00503         goal.desired_pose = request.goal_pose
00504         self.desired_pose = request.goal_pose
00505         goal.controller_name = request.controller_name
00506         goal.proxy_name = request.proxy_name
00507         goal.behavior_primitive = request.behavior_primitive
00508 
00509         
00510         if goal.controller_name.startswith(RBF_CONTROLLER_PREFIX):
00511             self.setupRBFController(goal.controller_name)
00512         elif goal.controller_name.startswith(AFFINE_CONTROLLER_PREFIX):
00513             self.AFFINE_A, self.AFFINE_B = self.loadAffineController(goal.controller_name)
00514 
00515         rospy.loginfo('Sending goal of: ' + str(goal.desired_pose))
00516         ac.send_goal(goal, done_cb, active_cb, feedback_cb)
00517         
00518         rospy.loginfo('Waiting for result')
00519         ac.wait_for_result(rospy.Duration(0))
00520         rospy.loginfo('Result received')
00521         self.stop_moving_vel(which_arm)
00522         result = ac.get_result()
00523         response.action_aborted = result.aborted
00524         if self.use_learn_io:
00525             self.learn_io.close_out_file()
00526         return response
00527 
00528     def tracker_feedback_push(self, feedback):
00529         if self.feedback_count == 0:
00530             self.theta0 = feedback.x.theta
00531             self.x0 = feedback.x.x
00532             self.y0 = feedback.x.y
00533         which_arm = self.active_arm
00534         if which_arm == 'l':
00535             cur_pose = self.l_arm_pose
00536         else:
00537             cur_pose = self.r_arm_pose
00538 
00539         if self.feedback_count % 5 == 0:
00540             rospy.loginfo('X_goal: (' + str(self.desired_pose.x) + ', ' +
00541                           str(self.desired_pose.y) + ', ' +
00542                           str(self.desired_pose.theta) + ')')
00543             rospy.loginfo('X: (' + str(feedback.x.x) + ', ' + str(feedback.x.y)
00544                           + ', ' + str(feedback.x.theta) + ')')
00545             rospy.loginfo('X_dot: (' + str(feedback.x_dot.x) + ', ' +
00546                           str(feedback.x_dot.y) + ', ' +
00547                           str(feedback.x_dot.theta) + ')')
00548             rospy.loginfo('X_error: (' + str(self.desired_pose.x - feedback.x.x) + ', ' +
00549                           str(self.desired_pose.y - feedback.x.y) + ', ' +
00550                           str(self.desired_pose.theta - feedback.x.theta) + ')')
00551 
00552         
00553         
00554         if feedback.controller_name == ROTATE_TO_HEADING:
00555             update_twist = self.rotateHeadingControllerPalm(feedback, self.desired_pose, which_arm, cur_pose)
00556         elif feedback.controller_name == CENTROID_CONTROLLER:
00557             update_twist = self.centroidAlignmentController(feedback, self.desired_pose,
00558                                                             cur_pose)
00559         elif feedback.controller_name == DIRECT_GOAL_CONTROLLER:
00560             update_twist = self.directGoalController(feedback, self.desired_pose)
00561         elif feedback.controller_name == DIRECT_GOAL_GRIPPER_CONTROLLER:
00562             update_twist = self.directGoalGripperController(feedback, self.desired_pose, cur_pose)
00563         elif feedback.controller_name == STRAIGHT_LINE_CONTROLLER:
00564             update_twist = self.straightLineController(feedback, self.desired_pose)
00565         elif feedback.controller_name == SPIN_COMPENSATION:
00566             update_twist = self.spinCompensationController(feedback, self.desired_pose)
00567         elif feedback.controller_name.startswith(RBF_CONTROLLER_PREFIX):
00568             update_twist = self.RBFFeedbackController(feedback)
00569         elif feedback.controller_name.startswith(AFFINE_CONTROLLER_PREFIX):
00570             update_twist = self.affineFeedbackController(feedback, self.AFFINE_A, self.AFFINE_B)
00571 
00572         if self.feedback_count % 5 == 0:
00573             rospy.loginfo('q_dot: (' + str(update_twist.twist.linear.x) + ', ' +
00574                           str(update_twist.twist.linear.y) + ', ' +
00575                           str(update_twist.twist.linear.z) + ')')
00576             rospy.loginfo('omega: (' + str(update_twist.twist.angular.x) + ', ' +
00577                           str(update_twist.twist.angular.y) + ', ' +
00578                           str(update_twist.twist.angular.z) + ')\n')
00579 
00580         if _USE_CONTROLLER_IO:
00581             self.controller_io.write_line(feedback.x, feedback.x_dot, self.desired_pose, self.theta0,
00582                                           update_twist.twist, update_twist.header.stamp.to_sec(),
00583                                           cur_pose.pose)
00584         if self.use_learn_io:
00585             self.learn_io.write_line(feedback.x, feedback.x_dot, self.desired_pose, self.theta0,
00586                                      update_twist.twist, update_twist.header.stamp.to_sec(),
00587                                      cur_pose.pose)
00588 
00589         if self.servo_head_during_pushing:
00590             look_pt = np.asmatrix([feedback.x.x,
00591                                    feedback.x.y,
00592                                    feedback.z])
00593             head_res = self.robot.head.look_at(look_pt, feedback.header.frame_id,
00594                                                self.head_pose_cam_frame)
00595 
00596         self.update_vel(update_twist, which_arm)
00597         self.feedback_count += 1
00598 
00599     
00600     
00601     
00602 
00603     def spinCompensationController(self, cur_state, desired_state):
00604         u = TwistStamped()
00605         u.header.frame_id = 'torso_lift_link'
00606         u.header.stamp = rospy.Time.now()
00607         u.twist.linear.z = 0.0
00608         u.twist.angular.x = 0.0
00609         u.twist.angular.y = 0.0
00610         u.twist.angular.z = 0.0
00611         
00612         x_error = desired_state.x - cur_state.x.x
00613         y_error = desired_state.y - cur_state.x.y
00614         t_error = subPIAngle(desired_state.theta - cur_state.x.theta)
00615         t0_error = subPIAngle(self.theta0 - cur_state.x.theta)
00616         goal_x_dot = self.k_g*x_error
00617         goal_y_dot = self.k_g*y_error
00618         
00619         goal_angle = atan2(goal_y_dot, goal_x_dot)
00620         transform_angle = goal_angle
00621         
00622         spin_x_dot = -sin(transform_angle)*(self.k_s_d*cur_state.x_dot.theta +
00623                                             -self.k_s_p*t0_error)
00624         spin_y_dot =  cos(transform_angle)*(self.k_s_d*cur_state.x_dot.theta +
00625                                             -self.k_s_p*t0_error)
00626         
00627         u.twist.linear.x = goal_x_dot + spin_x_dot
00628         u.twist.linear.y = goal_y_dot + spin_y_dot
00629         if self.feedback_count % 5 == 0:
00630             rospy.loginfo('q_goal_dot: (' + str(goal_x_dot) + ', ' +
00631                           str(goal_y_dot) + ')')
00632             rospy.loginfo('q_spin_dot: (' + str(spin_x_dot) + ', ' +
00633                           str(spin_y_dot) + ')')
00634         return u
00635 
00636     def rotateHeadingController(self, cur_state, desired_state, which_arm, ee_pose):
00637         '''
00638         TODO: Change to align to a given point in object frame while pushing in direction perpendicular
00639         to the original orientation...?
00640         '''
00641         u = TwistStamped()
00642         u.header.frame_id = 'torso_lift_link'
00643         u.header.stamp = rospy.Time.now()
00644         u.twist.linear.z = 0.0
00645         u.twist.angular.x = 0.0
00646         u.twist.angular.y = 0.0
00647         u.twist.angular.z = 0.0
00648 
00649         
00650         
00651         centroid = cur_state.x
00652         ee = ee_pose.pose.position
00653         rotate_x_dot = 0.0
00654         rotate_y_dot = 0.0
00655         
00656         x_error = desired_state.x - cur_state.x.x
00657         y_error = desired_state.y - cur_state.x.y
00658         t_error = subPIAngle(desired_state.theta - cur_state.x.theta)
00659         t0_error = subPIAngle(self.theta0 - cur_state.x.theta)
00660         goal_x_dot = self.k_g*x_error
00661         goal_y_dot = self.k_g*y_error
00662 
00663         
00664         goal_angle = atan2(goal_y_dot, goal_x_dot)
00665         transform_angle = goal_angle
00666         m = (((ee.x - centroid.x)*x_error + (ee.y - centroid.y)*y_error) /
00667              sqrt(x_error*x_error + y_error*y_error))
00668         tan_pt_x = centroid.x + m*x_error
00669         tan_pt_y = centroid.y + m*y_error
00670         contact_pt_x_dot = self.k_contact_d*(tan_pt_x - ee.x)
00671         contact_pt_y_dot = self.k_contact_d*(tan_pt_y - ee.y)
00672         
00673         u.twist.linear.x = goal_x_dot + contact_pt_x_dot
00674         u.twist.linear.y = goal_y_dot + contact_pt_y_dot
00675         if self.feedback_count % 5 == 0:
00676             rospy.loginfo('tan_pt: (' + str(tan_pt_x) + ', ' + str(tan_pt_y) + ')')
00677             rospy.loginfo('ee: (' + str(ee.x) + ', ' + str(ee.y) + ')')
00678             rospy.loginfo('q_goal_dot: (' + str(goal_x_dot) + ', ' +
00679                           str(goal_y_dot) + ')')
00680             rospy.loginfo('contact_pt_x_dot: (' + str(contact_pt_x_dot) + ', ' +
00681                           str(contact_pt_y_dot) + ')')
00682         return u
00683 
00684     def rotateHeadingControllerPalm(self, cur_state, desired_state, which_arm, ee_pose):
00685         u = TwistStamped()
00686         u.header.frame_id = which_arm+'_gripper_palm_link'
00687         u.header.stamp = rospy.Time.now()
00688         u.twist.linear.x = 0.0
00689         u.twist.linear.y = 0.0
00690         
00691         u.twist.angular.x = -self.k_rotate_spin_x*cur_state.x_dot.theta
00692         u.twist.angular.y = 0.0
00693         u.twist.angular.z = 0.0
00694         t_error = subPIAngle(desired_state.theta - cur_state.x.theta)
00695         s_theta = sign(t_error)
00696         t_dist = fabs(t_error)
00697         heading_x_dot = self.k_h_f*t_dist
00698         u.twist.linear.z = min(heading_x_dot, self.max_heading_u_x)
00699         if self.feedback_count % 5 == 0:
00700             rospy.loginfo('heading_x_dot: (' + str(heading_x_dot) + ')')
00701             rospy.loginfo('heading_rotate: (' + str(u.twist.angular.x) + ')')
00702         return u
00703 
00704     def spinCircleStuff(self, cur_state, desired_state, which_arm):
00705         r = 1.0 
00706         T = 32
00707         t = 0 
00708         theta_dot = 2*pi/T 
00709         theta = theta_dot*t 
00710         x_circle = r*sin(theta)
00711         y_circle = r*cos(theta)
00712         x_dot_circle = r*cos(theta)*theta_dot
00713         y_dot_circle = -r*sin(theta)*theta_dot
00714 
00715     def centroidAlignmentController(self, cur_state, desired_state, ee_pose):
00716         u = TwistStamped()
00717         u.header.frame_id = 'torso_lift_link'
00718         u.header.stamp = rospy.Time.now()
00719         u.twist.linear.z = 0.0
00720         u.twist.angular.x = 0.0
00721         u.twist.angular.y = 0.0
00722         u.twist.angular.z = 0.0
00723 
00724         
00725         centroid = cur_state.x
00726         ee = ee_pose.pose.position
00727         x_error = desired_state.x - centroid.x
00728         y_error = desired_state.y - centroid.y
00729         goal_x_dot = self.k_contact_g*x_error
00730         goal_y_dot = self.k_contact_g*y_error
00731 
00732         
00733         goal_angle = atan2(goal_y_dot, goal_x_dot)
00734         transform_angle = goal_angle
00735         m = (((ee.x - centroid.x)*x_error + (ee.y - centroid.y)*y_error) /
00736              sqrt(x_error*x_error + y_error*y_error))
00737         tan_pt_x = centroid.x + m*x_error
00738         tan_pt_y = centroid.y + m*y_error
00739         contact_pt_x_dot = self.k_contact_d*(tan_pt_x - ee.x)
00740         contact_pt_y_dot = self.k_contact_d*(tan_pt_y - ee.y)
00741         
00742         u.twist.linear.x = goal_x_dot + contact_pt_x_dot
00743         u.twist.linear.y = goal_y_dot + contact_pt_y_dot
00744         if self.feedback_count % 5 == 0:
00745             rospy.loginfo('tan_pt: (' + str(tan_pt_x) + ', ' + str(tan_pt_y) + ')')
00746             rospy.loginfo('ee: (' + str(ee.x) + ', ' + str(ee.y) + ')')
00747             rospy.loginfo('q_goal_dot: (' + str(goal_x_dot) + ', ' +
00748                           str(goal_y_dot) + ')')
00749             rospy.loginfo('contact_pt_x_dot: (' + str(contact_pt_x_dot) + ', ' +
00750                           str(contact_pt_y_dot) + ')')
00751         return u
00752 
00753     def directGoalController(self, cur_state, desired_state):
00754         u = TwistStamped()
00755         u.header.frame_id = 'torso_lift_link'
00756         u.header.stamp = rospy.Time.now()
00757         u.twist.linear.z = 0.0
00758         u.twist.angular.x = 0.0
00759         u.twist.angular.y = 0.0
00760         u.twist.angular.z = 0.0
00761 
00762         
00763         centroid = cur_state.x
00764         x_error = desired_state.x - centroid.x
00765         y_error = desired_state.y - centroid.y
00766         goal_x_dot = max(min(self.k_g_direct*x_error, self.max_goal_vel), -self.max_goal_vel)
00767         goal_y_dot = max(min(self.k_g_direct*y_error, self.max_goal_vel), -self.max_goal_vel)
00768 
00769         u.twist.linear.x = goal_x_dot
00770         u.twist.linear.y = goal_y_dot
00771         if self.feedback_count % 5 == 0:
00772             rospy.loginfo('q_goal_dot: (' + str(goal_x_dot) + ', ' +
00773                           str(goal_y_dot) + ')')
00774         return u
00775 
00776     def straightLineController(self, cur_state, desired_state):
00777         u = TwistStamped()
00778         u.header.frame_id = 'torso_lift_link'
00779         u.header.stamp = rospy.Time.now()
00780         u.twist.linear.z = 0.0
00781         u.twist.angular.x = 0.0
00782         u.twist.angular.y = 0.0
00783         u.twist.angular.z = 0.0
00784 
00785         
00786         centroid = cur_state.x
00787         x_error = desired_state.x - cur_state.init_x.x
00788         y_error = desired_state.y - cur_state.init_x.y
00789         goal_x_dot = x_error/(fabs(x_error)+fabs(y_error))*self.straight_v
00790         goal_y_dot = y_error/(fabs(x_error)+fabs(y_error))*self.straight_v
00791 
00792         u.twist.linear.x = goal_x_dot
00793         u.twist.linear.y = goal_y_dot
00794         if self.feedback_count % 5 == 0:
00795             rospy.loginfo('q_goal_dot: (' + str(goal_x_dot) + ', ' +
00796                           str(goal_y_dot) + ')')
00797         return u
00798 
00799     def directGoalGripperController(self, cur_state, desired_state, ee_pose):
00800         u = TwistStamped()
00801         u.header.frame_id = 'torso_lift_link'
00802         u.header.stamp = rospy.Time.now()
00803         u.twist.linear.z = 0.0
00804         u.twist.angular.x = 0.0
00805         u.twist.angular.y = 0.0
00806         u.twist.angular.z = 0.0
00807 
00808         ee = ee_pose.pose.position
00809 
00810         
00811         centroid = cur_state.x
00812         x_error = desired_state.x - ee.x
00813         y_error = desired_state.y - ee.y
00814         goal_x_dot = max(min(self.k_g_direct*x_error, self.max_goal_vel), -self.max_goal_vel)
00815         goal_y_dot = max(min(self.k_g_direct*y_error, self.max_goal_vel), -self.max_goal_vel)
00816 
00817         u.twist.linear.x = goal_x_dot
00818         u.twist.linear.y = goal_y_dot
00819         if self.feedback_count % 5 == 0:
00820             rospy.loginfo('ee_x: (' + str(ee.x) + ', ' + str(ee.y) + ', ' + str(ee.z) + ')')
00821             rospy.loginfo('q_goal_dot: (' + str(goal_x_dot) + ', ' + str(goal_y_dot) + ')')
00822         return u
00823 
00824     def affineFeedbackController(self, cur_state, A, b):
00825         u = TwistStamped()
00826         u.header.frame_id = 'torso_lift_link'
00827         u.header.stamp = rospy.Time.now()
00828         u.twist.linear.z = 0.0
00829         u.twist.angular.x = 0.0
00830         u.twist.angular.y = 0.0
00831         u.twist.angular.z = 0.0
00832 
00833         X = np.asarray(cur_state.x)
00834 
00835         u_t = A*X+b
00836         
00837         u.twist.linear.x = u_t[0]
00838         u.twist.linear.y = u_t[1]
00839         return u
00840 
00841     def RBFFeedbackController(self, cur_state):
00842         u = TwistStamped()
00843         u.header.frame_id = 'torso_lift_link'
00844         u.header.stamp = rospy.Time.now()
00845         u.twist.linear.z = 0.0
00846         u.twist.angular.x = 0.0
00847         u.twist.angular.y = 0.0
00848         u.twist.angular.z = 0.0
00849 
00850         
00851         
00852         ndx = [4]
00853         X = trigAugState(np.asarray(cur_state.x), ndx, True)
00854         D = np.zeros((P.shape[1], 1))
00855         u_t = self.RBF.feedbackControl(X)
00856         
00857         u.twist.linear.x = u_t[0]
00858         u.twist.linear.y = u_t[1]
00859         return u
00860 
00861     
00862     
00863     
00864     def overhead_feedback_post_push(self, request):
00865         response = FeedbackPushResponse()
00866         start_point = request.start_point.point
00867         wrist_yaw = request.wrist_yaw
00868 
00869         if request.left_arm:
00870             ready_joints = LEFT_ARM_READY_JOINTS
00871             if request.high_arm_init:
00872                 ready_joints = LEFT_ARM_PULL_READY_JOINTS
00873             which_arm = 'l'
00874             wrist_pitch = 0.5*pi
00875             robot_gripper = self.robot.left_gripper
00876         else:
00877             ready_joints = RIGHT_ARM_READY_JOINTS
00878             if request.high_arm_init:
00879                 ready_joints = RIGHT_ARM_PULL_READY_JOINTS
00880             which_arm = 'r'
00881             wrist_pitch = -0.5*pi
00882             robot_gripper = self.robot.right_gripper
00883 
00884         rospy.logdebug('Moving gripper up')
00885         pose_err, err_dist = self.move_relative_gripper(
00886             np.matrix([-self.gripper_raise_dist, 0.0, 0.0]).T, which_arm,
00887             move_cart_count_thresh=self.post_move_count_thresh)
00888         rospy.logdebug('Done moving up')
00889         rospy.logdebug('Pushing reverse')
00890         pose_err, err_dist = self.move_relative_gripper(
00891             np.matrix([0.0, 0.0, -self.gripper_push_reverse_dist]).T, which_arm,
00892             move_cart_count_thresh=self.post_move_count_thresh)
00893         rospy.loginfo('Done pushing reverse')
00894 
00895 
00896         rospy.logdebug('Moving up to end point')
00897         wrist_yaw = request.wrist_yaw
00898         end_pose = PoseStamped()
00899         end_pose.header = request.start_point.header
00900 
00901         
00902         if request.left_arm:
00903             cur_pose = self.l_arm_pose
00904         else:
00905             cur_pose = self.r_arm_pose
00906 
00907         end_pose.pose.position.x = cur_pose.pose.position.x
00908         end_pose.pose.position.y = cur_pose.pose.position.y
00909         end_pose.pose.position.z = self.high_arm_init_z
00910         q = tf.transformations.quaternion_from_euler(0.0, 0.5*pi, wrist_yaw)
00911         end_pose.pose.orientation.x = q[0]
00912         end_pose.pose.orientation.y = q[1]
00913         end_pose.pose.orientation.z = q[2]
00914         end_pose.pose.orientation.w = q[3]
00915         self.move_to_cart_pose(end_pose, which_arm,
00916                                self.post_move_count_thresh)
00917         rospy.loginfo('Done moving up to end point')
00918 
00919         if request.open_gripper:
00920             res = robot_gripper.close(block=True, effort=self.max_close_effort)
00921         self.reset_arm_pose(True, which_arm, request.high_arm_init)
00922         return response
00923 
00924     def gripper_feedback_post_push(self, request):
00925         response = FeedbackPushResponse()
00926         start_point = request.start_point.point
00927         wrist_yaw = request.wrist_yaw
00928         is_pull = request.behavior_primitive == GRIPPER_PULL
00929 
00930         if request.left_arm:
00931             ready_joints = LEFT_ARM_READY_JOINTS
00932             if request.high_arm_init:
00933                 ready_joints = LEFT_ARM_PULL_READY_JOINTS
00934             which_arm = 'l'
00935             robot_gripper = self.robot.left_gripper
00936         else:
00937             ready_joints = RIGHT_ARM_READY_JOINTS
00938             if request.high_arm_init:
00939                 ready_joints = RIGHT_ARM_PULL_READY_JOINTS
00940             which_arm = 'r'
00941             robot_gripper = self.robot.right_gripper
00942 
00943         if is_pull:
00944             self.stop_moving_vel(which_arm)
00945             rospy.loginfo('Opening gripper')
00946             res = robot_gripper.open(position=0.9,block=True)
00947             rospy.loginfo('Done opening gripper')
00948             rospy.logdebug('Pulling reverse')
00949             pose_err, err_dist = self.move_relative_gripper(
00950                 np.matrix([-self.gripper_pull_reverse_dist, 0.0, 0.0]).T, which_arm,
00951                 move_cart_count_thresh=self.post_pull_count_thresh)
00952             rospy.loginfo('Done pulling reverse')
00953         else:
00954             rospy.logdebug('Moving gripper up')
00955             pose_err, err_dist = self.move_relative_gripper(
00956                 np.matrix([0.0, 0.0, -self.gripper_raise_dist]).T, which_arm,
00957                 move_cart_count_thresh=self.post_move_count_thresh)
00958             rospy.logdebug('Done moving up')
00959             rospy.logdebug('Pushing reverse')
00960             pose_err, err_dist = self.move_relative_gripper(
00961                 np.matrix([-self.gripper_push_reverse_dist, 0.0, 0.0]).T, which_arm,
00962                 move_cart_count_thresh=self.post_move_count_thresh)
00963             rospy.loginfo('Done pushing reverse')
00964 
00965         rospy.logdebug('Moving up to end point')
00966         wrist_yaw = request.wrist_yaw
00967         end_pose = PoseStamped()
00968         end_pose.header = request.start_point.header
00969 
00970         
00971         if request.left_arm:
00972             cur_pose = self.l_arm_pose
00973         else:
00974             cur_pose = self.r_arm_pose
00975 
00976         end_pose.pose.position.x = cur_pose.pose.position.x
00977         end_pose.pose.position.y = cur_pose.pose.position.y
00978         end_pose.pose.position.z = self.high_arm_init_z
00979         q = tf.transformations.quaternion_from_euler(0.0, 0.0, wrist_yaw)
00980         end_pose.pose.orientation.x = q[0]
00981         end_pose.pose.orientation.y = q[1]
00982         end_pose.pose.orientation.z = q[2]
00983         end_pose.pose.orientation.w = q[3]
00984         self.move_to_cart_pose(end_pose, which_arm,
00985                                self.post_move_count_thresh)
00986         rospy.loginfo('Done moving up to end point')
00987 
00988         if request.open_gripper or is_pull:
00989             rospy.loginfo('Closing gripper')
00990             res = robot_gripper.close(block=True, effort=self.max_close_effort)
00991             rospy.loginfo('Done closing gripper')
00992 
00993         self.reset_arm_pose(True, which_arm, request.high_arm_init)
00994         return response
00995 
00996     def gripper_feedback_post_sweep(self, request):
00997         response = FeedbackPushResponse()
00998         start_point = request.start_point.point
00999         wrist_yaw = request.wrist_yaw
01000 
01001         if request.left_arm:
01002             ready_joints = LEFT_ARM_READY_JOINTS
01003             if request.high_arm_init:
01004                 ready_joints = LEFT_ARM_PULL_READY_JOINTS
01005             which_arm = 'l'
01006             robot_gripper = self.robot.left_gripper
01007         else:
01008             ready_joints = RIGHT_ARM_READY_JOINTS
01009             if request.high_arm_init:
01010                 ready_joints = RIGHT_ARM_PULL_READY_JOINTS
01011             which_arm = 'r'
01012             robot_gripper = self.robot.right_gripper
01013 
01014         
01015         rospy.logdebug('Moving gripper up')
01016         pose_err, err_dist = self.move_relative_gripper(
01017             np.matrix([0.0, -self.gripper_raise_dist, 0.0]).T, which_arm,
01018             move_cart_count_thresh=self.post_move_count_thresh)
01019         rospy.logdebug('Done moving up')
01020         rospy.logdebug('Sweeping reverse')
01021         pose_err, err_dist = self.move_relative_gripper(
01022             np.matrix([0.0, 0.0, -self.gripper_push_reverse_dist]).T, which_arm,
01023             move_cart_count_thresh=self.post_move_count_thresh)
01024         rospy.loginfo('Done sweeping reverse')
01025 
01026         rospy.logdebug('Moving up to end point')
01027         wrist_yaw = request.wrist_yaw
01028         end_pose = PoseStamped()
01029         end_pose.header = request.start_point.header
01030 
01031         
01032         if request.left_arm:
01033             cur_pose = self.l_arm_pose
01034         else:
01035             cur_pose = self.r_arm_pose
01036 
01037         end_pose.pose.position.x = cur_pose.pose.position.x
01038         end_pose.pose.position.y = cur_pose.pose.position.y
01039         end_pose.pose.position.z = self.high_arm_init_z
01040         q = tf.transformations.quaternion_from_euler(0.5*pi, 0.0, wrist_yaw)
01041         end_pose.pose.orientation.x = q[0]
01042         end_pose.pose.orientation.y = q[1]
01043         end_pose.pose.orientation.z = q[2]
01044         end_pose.pose.orientation.w = q[3]
01045         self.move_to_cart_pose(end_pose, which_arm,
01046                                self.post_move_count_thresh)
01047         rospy.loginfo('Done moving up to end point')
01048 
01049         if request.open_gripper:
01050             rospy.loginfo('Closing gripper')
01051             res = robot_gripper.close(block=True, effort=self.max_close_effort)
01052             rospy.loginfo('Done closing gripper')
01053 
01054         self.reset_arm_pose(True, which_arm, request.high_arm_init)
01055         return response
01056 
01057     
01058     
01059     
01060     def gripper_pre_push(self, request):
01061         response = FeedbackPushResponse()
01062         start_point = request.start_point.point
01063         wrist_yaw = request.wrist_yaw
01064         is_pull = request.behavior_primitive == GRIPPER_PULL
01065 
01066         if request.left_arm:
01067             ready_joints = LEFT_ARM_READY_JOINTS
01068             if request.high_arm_init:
01069                 ready_joints = LEFT_ARM_HIGH_PUSH_READY_JOINTS
01070             which_arm = 'l'
01071             robot_gripper = self.robot.left_gripper
01072         else:
01073             ready_joints = RIGHT_ARM_READY_JOINTS
01074             if request.high_arm_init:
01075                 ready_joints = RIGHT_ARM_HIGH_PUSH_READY_JOINTS
01076             which_arm = 'r'
01077             robot_gripper = self.robot.right_gripper
01078 
01079         self.set_arm_joint_pose(ready_joints, which_arm, nsecs=1.5)
01080         rospy.logdebug('Moving %s_arm to ready pose' % which_arm)
01081 
01082         start_pose = PoseStamped()
01083         start_pose.header = request.start_point.header
01084         start_pose.pose.position.x = start_point.x
01085         start_pose.pose.position.y = start_point.y
01086         start_pose.pose.position.z = start_point.z
01087 
01088         wrist_pitch = 0.0625*pi
01089         q = tf.transformations.quaternion_from_euler(0.0, wrist_pitch, wrist_yaw)
01090         start_pose.pose.orientation.x = q[0]
01091         start_pose.pose.orientation.y = q[1]
01092         start_pose.pose.orientation.z = q[2]
01093         start_pose.pose.orientation.w = q[3]
01094 
01095         
01096         if request.open_gripper:
01097             res = robot_gripper.open(block=True, position=0.05)
01098         if is_pull:
01099             res = robot_gripper.open(block=True, position=0.9)
01100 
01101         self.use_gripper_place_joint_posture = True
01102         if request.high_arm_init:
01103             start_pose.pose.position.z = self.high_arm_init_z
01104             self.move_to_cart_pose(start_pose, which_arm)
01105             rospy.logdebug('Done moving to overhead start point')
01106             
01107             start_pose.pose.position.z = self.lower_arm_init_z
01108             self.move_to_cart_pose(start_pose, which_arm)
01109             rospy.loginfo('Done moving to lower start point')
01110             start_pose.pose.position.z = start_point.z
01111             
01112 
01113         
01114         if not self.move_to_cart_pose_ik(start_pose, which_arm):
01115             rospy.logwarn('IK Failed, not at desired initial pose')
01116             response.failed_pre_position = True
01117             
01118             return response
01119         else:
01120             response.failed_pre_position = False
01121 
01122         rospy.loginfo('Done moving to start point')
01123         self.use_gripper_place_joint_posture = False
01124         if is_pull:
01125             rospy.loginfo('Moving forward to grasp pose')
01126             pose_err, err_dist = self.move_relative_gripper(
01127                 np.matrix([self.gripper_pull_forward_dist, 0, 0]).T, which_arm,
01128                 move_cart_count_thresh=self.post_move_count_thresh)
01129 
01130             rospy.loginfo('Closing grasp for pull')
01131             res = robot_gripper.close(block=True, effort=self.max_close_effort)
01132             rospy.loginfo('Done closing gripper')
01133 
01134         return response
01135 
01136     def gripper_pre_sweep(self, request):
01137         response = FeedbackPushResponse()
01138         start_point = request.start_point.point
01139         wrist_yaw = request.wrist_yaw
01140 
01141         if request.left_arm:
01142             ready_joints = LEFT_ARM_READY_JOINTS
01143             if request.high_arm_init:
01144                 ready_joints = LEFT_ARM_HIGH_SWEEP_READY_JOINTS
01145             which_arm = 'l'
01146             wrist_roll = -pi
01147             robot_gripper = self.robot.left_gripper
01148         else:
01149             ready_joints = RIGHT_ARM_READY_JOINTS
01150             if request.high_arm_init:
01151                 ready_joints = RIGHT_ARM_HIGH_SWEEP_READY_JOINTS
01152             which_arm = 'r'
01153             wrist_roll = 0.0
01154             robot_gripper = self.robot.right_gripper
01155 
01156         if request.open_gripper:
01157             res = robot_gripper.open(block=True, position=0.9)
01158             raw_input('waiting for input to close gripper: ')
01159             print '\n'
01160             res = robot_gripper.close(block=True, effort=self.max_close_effort)
01161 
01162         start_pose = PoseStamped()
01163         start_pose.header = request.start_point.header
01164         start_pose.pose.position.x = start_point.x
01165         start_pose.pose.position.y = start_point.y
01166         start_pose.pose.position.z = start_point.z
01167         q = tf.transformations.quaternion_from_euler(0.5*pi, 0.0, wrist_yaw)
01168         start_pose.pose.orientation.x = q[0]
01169         start_pose.pose.orientation.y = q[1]
01170         start_pose.pose.orientation.z = q[2]
01171         start_pose.pose.orientation.w = q[3]
01172 
01173 
01174         rospy.logdebug('Moving %s_arm to ready pose' % which_arm)
01175         self.set_arm_joint_pose(ready_joints, which_arm, nsecs=1.5)
01176         
01177         rospy.logdebug('Rotating wrist for sweep')
01178         arm_pose = self.get_arm_joint_pose(which_arm)
01179         arm_pose[-1] =  wrist_roll
01180         self.set_arm_joint_pose(arm_pose, which_arm, nsecs=1.0)
01181 
01182         if request.high_arm_init:
01183             
01184             start_pose.pose.position.z = self.high_arm_init_z
01185             self.move_to_cart_pose(start_pose, which_arm)
01186             rospy.logdebug('Done moving to overhead start point')
01187             start_pose.pose.position.z = self.lower_arm_init_z
01188             self.move_to_cart_pose(start_pose, which_arm)
01189             rospy.loginfo('Done moving to lower start point')
01190 
01191             
01192             start_pose.pose.position.z = start_point.z
01193             
01194 
01195         self.move_to_cart_pose(start_pose, which_arm, self.pre_push_count_thresh)
01196         rospy.loginfo('Done moving to start point')
01197 
01198         return response
01199 
01200     def overhead_pre_push(self, request):
01201         response = FeedbackPushResponse()
01202         start_point = request.start_point.point
01203         wrist_yaw = request.wrist_yaw
01204 
01205         if request.left_arm:
01206             ready_joints = LEFT_ARM_READY_JOINTS
01207             if request.high_arm_init:
01208                 ready_joints = LEFT_ARM_PULL_READY_JOINTS
01209             which_arm = 'l'
01210             wrist_pitch = 0.5*pi
01211             robot_gripper = self.robot.left_gripper
01212         else:
01213             ready_joints = RIGHT_ARM_READY_JOINTS
01214             if request.high_arm_init:
01215                 ready_joints = RIGHT_ARM_PULL_READY_JOINTS
01216             which_arm = 'r'
01217             wrist_pitch = -0.5*pi
01218             robot_gripper = self.robot.right_gripper
01219         start_pose = PoseStamped()
01220         start_pose.header = request.start_point.header
01221         start_pose.pose.position.x = start_point.x
01222         start_pose.pose.position.y = start_point.y
01223         start_pose.pose.position.z = start_point.z
01224         q = tf.transformations.quaternion_from_euler(0.0, fabs(wrist_pitch),
01225                                                      wrist_yaw)
01226         start_pose.pose.orientation.x = q[0]
01227         start_pose.pose.orientation.y = q[1]
01228         start_pose.pose.orientation.z = q[2]
01229         start_pose.pose.orientation.w = q[3]
01230 
01231 
01232         rospy.logdebug('Moving %s_arm to ready pose' % which_arm)
01233         self.set_arm_joint_pose(ready_joints, which_arm, nsecs=1.5)
01234 
01235         if not request.high_arm_init:
01236             
01237             rospy.logdebug('Rotating elbow for overhead push')
01238             arm_pose = self.get_arm_joint_pose(which_arm)
01239             arm_pose[-3] =  wrist_pitch
01240             self.set_arm_joint_pose(arm_pose, which_arm, nsecs=1.0)
01241 
01242         if request.open_gripper:
01243             res = robot_gripper.open(block=True, position=0.05)
01244 
01245         if request.high_arm_init:
01246             
01247             start_pose.pose.position.z = self.high_arm_init_z
01248             self.move_to_cart_pose(start_pose, which_arm, self.pre_push_count_thresh)
01249             rospy.logdebug('Done moving to overhead start point')
01250             start_pose.pose.position.z = self.lower_arm_init_z
01251             self.move_to_cart_pose(start_pose, which_arm, self.pre_push_count_thresh)
01252             rospy.loginfo('Done moving to lower start point')
01253 
01254             
01255             start_pose.pose.position.z = start_point.z
01256             
01257 
01258         
01259         if not self.move_to_cart_pose_ik(start_pose, which_arm):
01260             rospy.logwarn('IK Failed, not at desired initial pose')
01261             response.failed_pre_position = True
01262             
01263         else:
01264             response.failed_pre_position = False
01265             rospy.loginfo('Done moving to start point')
01266 
01267         return response
01268 
01269     
01270     
01271     
01272     def gripper_push(self, request):
01273         response = FeedbackPushResponse()
01274         start_point = request.start_point.point
01275         wrist_yaw = request.wrist_yaw
01276         push_dist = request.desired_push_dist
01277 
01278         if request.left_arm:
01279             ready_joints = LEFT_ARM_READY_JOINTS
01280             which_arm = 'l'
01281         else:
01282             ready_joints = RIGHT_ARM_READY_JOINTS
01283             which_arm = 'r'
01284 
01285         rospy.loginfo('Pushing forward ' + str(push_dist) + 'm')
01286         
01287         
01288         
01289         
01290         
01291         pose_err, err_dist = self.move_relative_torso_epc(wrist_yaw, push_dist,
01292                                                           which_arm)
01293         rospy.loginfo('Done pushing forward')
01294 
01295         response.dist_pushed = push_dist - err_dist
01296         return response
01297 
01298     def gripper_post_push(self, request):
01299         response = FeedbackPushResponse()
01300         start_point = request.start_point.point
01301         wrist_yaw = request.wrist_yaw
01302         push_dist = request.desired_push_dist
01303 
01304         if request.left_arm:
01305             ready_joints = LEFT_ARM_READY_JOINTS
01306             which_arm = 'l'
01307             robot_gripper = self.robot.left_gripper
01308         else:
01309             ready_joints = RIGHT_ARM_READY_JOINTS
01310             which_arm = 'r'
01311             robot_gripper = self.robot.right_gripper
01312 
01313         
01314         rospy.logdebug('Moving gripper up')
01315         pose_err, err_dist = self.move_relative_gripper(
01316             np.matrix([0.0, 0.0, self.gripper_raise_dist]).T, which_arm,
01317             move_cart_count_thresh=self.post_move_count_thresh)
01318         rospy.logdebug('Moving gripper backwards')
01319         pose_err, err_dist = self.move_relative_gripper(
01320             np.matrix([-push_dist, 0.0, 0.0]).T, which_arm,
01321             move_cart_count_thresh=self.post_move_count_thresh)
01322         rospy.loginfo('Done moving backwards')
01323         start_pose = PoseStamped()
01324         start_pose.header = request.start_point.header
01325         start_pose.pose.position.x = start_point.x
01326         start_pose.pose.position.y = start_point.y
01327         start_pose.pose.position.z = start_point.z
01328         q = tf.transformations.quaternion_from_euler(0.0, 0.0, wrist_yaw)
01329         start_pose.pose.orientation.x = q[0]
01330         start_pose.pose.orientation.y = q[1]
01331         start_pose.pose.orientation.z = q[2]
01332         start_pose.pose.orientation.w = q[3]
01333 
01334         if request.open_gripper:
01335             res = robot_gripper.close(block=True, position=0.9, effort=self.max_close_effort)
01336 
01337         if request.high_arm_init:
01338             start_pose.pose.position.z = self.high_arm_init_z
01339             rospy.logdebug('Moving up to initial point')
01340             self.move_to_cart_pose(start_pose, which_arm,
01341                                    self.post_move_count_thresh)
01342             rospy.loginfo('Done moving up to initial point')
01343 
01344         self.reset_arm_pose(True, which_arm, request.high_arm_init)
01345         return response
01346 
01347     def gripper_sweep(self, request):
01348         response = FeedbackPushResponse()
01349         start_point = request.start_point.point
01350         wrist_yaw = request.wrist_yaw
01351         push_dist = request.desired_push_dist
01352 
01353         if request.left_arm:
01354             ready_joints = LEFT_ARM_READY_JOINTS
01355             which_arm = 'l'
01356             wrist_roll = -pi
01357         else:
01358             ready_joints = RIGHT_ARM_READY_JOINTS
01359             which_arm = 'r'
01360             wrist_roll = 0.0
01361 
01362         
01363         
01364         
01365         rospy.loginfo('Sweeping gripper in ' + str(push_dist) + 'm')
01366         
01367         
01368         if wrist_yaw > -pi*0.5:
01369             push_angle = wrist_yaw + pi*0.5
01370         else:
01371             push_angle = wrist_yaw - pi*0.5
01372         
01373         
01374         
01375         pose_err, err_dist = self.move_relative_torso_epc(push_angle, push_dist,
01376                                                           which_arm)
01377 
01378         rospy.logdebug('Done sweeping in')
01379 
01380         
01381         return response
01382 
01383     def gripper_post_sweep(self, request):
01384         response = FeedbackPushResponse()
01385         start_point = request.start_point.point
01386         wrist_yaw = request.wrist_yaw
01387         push_dist = request.desired_push_dist
01388 
01389         if request.left_arm:
01390             ready_joints = LEFT_ARM_READY_JOINTS
01391             which_arm = 'l'
01392         else:
01393             ready_joints = RIGHT_ARM_READY_JOINTS
01394             which_arm = 'r'
01395 
01396         rospy.logdebug('Moving gripper up')
01397         pose_err, err_dist = self.move_relative_gripper(
01398             np.matrix([0.0, self.gripper_raise_dist, 0.0]).T, which_arm,
01399             move_cart_count_thresh=self.post_move_count_thresh)
01400         rospy.logdebug('Sweeping gripper outward')
01401         pose_err, err_dist = self.move_relative_gripper(
01402             np.matrix([0.0, 0.0, push_dist]).T, which_arm,
01403             move_cart_count_thresh=self.post_move_count_thresh)
01404         rospy.loginfo('Done sweeping outward')
01405 
01406         if request.high_arm_init:
01407             rospy.logdebug('Moving up to end point')
01408             wrist_yaw = request.wrist_yaw
01409             end_pose = PoseStamped()
01410             end_pose.header = request.start_point.header
01411             end_pose.pose.position.x = start_point.x
01412             end_pose.pose.position.y = start_point.y
01413             end_pose.pose.position.z = self.high_arm_init_z
01414             q = tf.transformations.quaternion_from_euler(0.5*pi, 0.0, wrist_yaw)
01415             end_pose.pose.orientation.x = q[0]
01416             end_pose.pose.orientation.y = q[1]
01417             end_pose.pose.orientation.z = q[2]
01418             end_pose.pose.orientation.w = q[3]
01419             self.move_to_cart_pose(end_pose, which_arm,
01420                                    self.post_move_count_thresh)
01421             rospy.loginfo('Done moving up to end point')
01422 
01423         self.reset_arm_pose(True, which_arm, request.high_arm_init)
01424         return response
01425 
01426     def overhead_push(self, request):
01427         response = FeedbackPushResponse()
01428         start_point = request.start_point.point
01429         wrist_yaw = request.wrist_yaw
01430         push_dist = request.desired_push_dist
01431 
01432         if request.left_arm:
01433             which_arm = 'l'
01434             wrist_pitch = 0.5*pi
01435         else:
01436             which_arm = 'r'
01437             wrist_pitch = -0.5*pi
01438 
01439         rospy.loginfo('Pushing forward ' + str(push_dist) + 'm')
01440         
01441         
01442         
01443         
01444         
01445         pose_err, err_dist = self.move_relative_torso_epc(wrist_yaw, push_dist,
01446                                                           which_arm)
01447 
01448         rospy.logdebug('Done pushing forward')
01449 
01450         
01451         response.dist_pushed = push_dist - err_dist
01452         return response
01453 
01454     def overhead_post_push(self, request):
01455         response = FeedbackPushResponse()
01456         start_point = request.start_point.point
01457         wrist_yaw = request.wrist_yaw
01458         push_dist = request.desired_push_dist
01459 
01460         if request.left_arm:
01461             ready_joints = LEFT_ARM_READY_JOINTS
01462             if request.high_arm_init:
01463                 ready_joints = LEFT_ARM_PULL_READY_JOINTS
01464             which_arm = 'l'
01465             wrist_pitch = 0.5*pi
01466         else:
01467             ready_joints = RIGHT_ARM_READY_JOINTS
01468             if request.high_arm_init:
01469                 ready_joints = RIGHT_ARM_PULL_READY_JOINTS
01470             which_arm = 'r'
01471             wrist_pitch = -0.5*pi
01472 
01473         rospy.logdebug('Moving gripper up')
01474         pose_err, err_dist = self.move_relative_gripper(
01475             np.matrix([-self.gripper_raise_dist, 0.0, 0.0]).T, which_arm,
01476             move_cart_count_thresh=self.post_move_count_thresh)
01477         rospy.logdebug('Done moving up')
01478         rospy.logdebug('Pushing reverse')
01479         pose_err, err_dist = self.move_relative_gripper(
01480             np.matrix([0.0, 0.0, -push_dist]).T, which_arm,
01481             move_cart_count_thresh=self.post_move_count_thresh)
01482         rospy.loginfo('Done pushing reverse')
01483 
01484         if request.high_arm_init:
01485             rospy.logdebug('Moving up to end point')
01486             wrist_yaw = request.wrist_yaw
01487             end_pose = PoseStamped()
01488             end_pose.header = request.start_point.header
01489             end_pose.pose.position.x = start_point.x
01490             end_pose.pose.position.y = start_point.y
01491             end_pose.pose.position.z = self.high_arm_init_z
01492             q = tf.transformations.quaternion_from_euler(0.0, 0.5*pi, wrist_yaw)
01493             end_pose.pose.orientation.x = q[0]
01494             end_pose.pose.orientation.y = q[1]
01495             end_pose.pose.orientation.z = q[2]
01496             end_pose.pose.orientation.w = q[3]
01497             self.move_to_cart_pose(end_pose, which_arm,
01498                                    self.post_move_count_thresh)
01499             rospy.loginfo('Done moving up to end point')
01500 
01501         self.reset_arm_pose(True, which_arm, request.high_arm_init)
01502         return response
01503 
01504     
01505     
01506     
01507     def raise_and_look(self, request):
01508         '''
01509         Service callback to raise the spine to a specific height relative to the
01510         table height and tilt the head so that the Kinect views the table
01511         '''
01512         if request.init_arms:
01513             self.init_arms()
01514 
01515         if request.point_head_only:
01516             response = RaiseAndLookResponse()
01517             response.head_succeeded = self.init_head_pose(request.camera_frame)
01518             return response
01519 
01520         if not request.have_table_centroid:
01521             response = RaiseAndLookResponse()
01522             response.head_succeeded = self.init_head_pose(request.camera_frame)
01523             self.init_spine_pose()
01524             return response
01525 
01526         
01527         (trans, rot) = self.tf_listener.lookupTransform('base_link', 'torso_lift_link', rospy.Time(0))
01528         lift_link_z = trans[2]
01529 
01530         
01531         request.table_centroid.header.stamp = rospy.Time(0)
01532         table_base = self.tf_listener.transformPose('base_link', request.table_centroid)
01533         table_z = table_base.pose.position.z
01534         goal_lift_link_z = table_z + self.torso_z_offset
01535         lift_link_delta_z = goal_lift_link_z - lift_link_z
01536         
01537         rospy.logdebug('Table height (m): ' + str(table_z))
01538         rospy.logdebug('Torso goal height (m): ' + str(goal_lift_link_z))
01539         
01540 
01541         
01542         
01543         torso_max = 0.3
01544         torso_min = 0.01
01545         current_torso_position = np.asarray(self.robot.torso.pose()).ravel()[0]
01546         torso_goal_position = current_torso_position + lift_link_delta_z
01547         torso_goal_position = (max(min(torso_max, torso_goal_position),
01548                                    torso_min))
01549         
01550         
01551         self.robot.torso.set_pose(torso_goal_position)
01552 
01553         
01554         new_torso_position = np.asarray(self.robot.torso.pose()).ravel()[0]
01555         rospy.loginfo('New spine height is ' + str(new_torso_position))
01556 
01557         
01558 
01559         (new_trans, rot) = self.tf_listener.lookupTransform('base_link',
01560                                                             'torso_lift_link',
01561                                                             rospy.Time(0))
01562         new_lift_link_z = new_trans[2]
01563         
01564         
01565         new_table_base = self.tf_listener.transformPose('base_link',
01566                                                         request.table_centroid)
01567         new_table_z = new_table_base.pose.position.z
01568         rospy.loginfo('New Table height: ' + str(new_table_z))
01569 
01570         
01571         
01572         look_pt = np.asmatrix([self.look_pt_x,
01573                                0.0,
01574                                -self.torso_z_offset])
01575         rospy.logdebug('Point head at ' + str(look_pt))
01576         head_res = self.robot.head.look_at(look_pt,
01577                                            request.table_centroid.header.frame_id,
01578                                            request.camera_frame)
01579         response = RaiseAndLookResponse()
01580         if head_res:
01581             rospy.loginfo('Succeeded in pointing head')
01582             response.head_succeeded = True
01583         else:
01584             rospy.logwarn('Failed to point head')
01585             response.head_succeeded = False
01586         return response
01587 
01588     
01589     
01590     
01591     def get_arm_joint_pose(self, which_arm):
01592         if which_arm == 'l':
01593             return self.robot.left.pose()
01594         else:
01595             return self.robot.right.pose()
01596 
01597     def set_arm_joint_pose(self, joint_pose, which_arm, nsecs=2.0):
01598         self.switch_to_joint_controllers()
01599         if which_arm == 'l':
01600             self.robot.left.set_pose(joint_pose, nsecs, block=True)
01601         else:
01602             self.robot.right.set_pose(joint_pose, nsecs, block=True)
01603 
01604     def move_to_cart_pose(self, pose, which_arm,
01605                           done_moving_count_thresh=None, pressure=1000):
01606         if done_moving_count_thresh is None:
01607             done_moving_count_thresh = self.arm_done_moving_count_thresh
01608         self.switch_to_cart_controllers()
01609         if which_arm == 'l':
01610             self.l_arm_cart_pub.publish(pose)
01611             posture_pub = self.l_arm_cart_posture_pub
01612             pl = self.l_pressure_listener
01613         else:
01614             self.r_arm_cart_pub.publish(pose)
01615             posture_pub = self.r_arm_cart_posture_pub
01616             pl = self.r_pressure_listener
01617 
01618         arm_not_moving_count = 0
01619         r = rospy.Rate(self.move_cart_check_hz)
01620         pl.rezero()
01621         pl.set_threshold(pressure)
01622         while arm_not_moving_count < done_moving_count_thresh:
01623             if not self.arm_moving_cart(which_arm):
01624                 arm_not_moving_count += 1
01625             else:
01626                 arm_not_moving_count = 0
01627             
01628             m = self.get_desired_posture(which_arm)
01629             posture_pub.publish(m)
01630 
01631             if pl.check_safety_threshold():
01632                 rospy.loginfo('Exceeded pressure safety thresh!\n')
01633                 break
01634             if pl.check_threshold():
01635                 rospy.loginfo('Exceeded pressure contact thresh...')
01636                 
01637             r.sleep()
01638 
01639         
01640         if which_arm == 'l':
01641             arm_error = self.l_arm_x_err
01642         else:
01643             arm_error = self.r_arm_x_err
01644         error_dist = sqrt(arm_error.linear.x**2 + arm_error.linear.y**2 +
01645                           arm_error.linear.z**2)
01646         rospy.loginfo('Move cart gripper error dist: ' + str(error_dist)+'\n')
01647         rospy.loginfo('Move cart gripper error: ' + str(arm_error.linear)+'\n'+str(arm_error.angular))
01648         return (arm_error, error_dist)
01649 
01650     def move_to_cart_pose_ik(self, pose, which_arm, pressure=1000, nsecs=2.0):
01651         if which_arm == 'l':
01652             ik_proxy = self.l_arm_ik_proxy
01653             solver_proxy = self.l_arm_ik_solver_proxy
01654         else:
01655             ik_proxy = self.r_arm_ik_proxy
01656             solver_proxy = self.r_arm_ik_solver_proxy
01657         wrist_name = which_arm + '_wrist_roll_link'
01658         tool_name  = which_arm + '_gripper_tool_frame'
01659 
01660         
01661         solver_req = GetKinematicSolverInfoRequest()
01662         solver_res = solver_proxy(solver_req)
01663 
01664         
01665         rospy.loginfo('Requested pose for tool link is: ' + str(pose.pose))
01666         R_wrist_to_tool = np.asmatrix(tf.transformations.quaternion_matrix(np.asarray([pose.pose.orientation.x,
01667                                                                                        pose.pose.orientation.y,
01668                                                                                        pose.pose.orientation.z,
01669                                                                                        pose.pose.orientation.w])))
01670         
01671         tool_to_wrist_vec = R_wrist_to_tool * np.asmatrix([[-0.18, 0.0, 0.0, 1.0]]).T
01672         pose.pose.position.x += tool_to_wrist_vec[0]
01673         pose.pose.position.y += tool_to_wrist_vec[1]
01674         pose.pose.position.z += tool_to_wrist_vec[2]
01675         rospy.loginfo('Requested pose for wrist link is: ' + str(pose.pose))
01676 
01677         
01678         ik_req = GetPositionIKRequest()
01679         ik_req.timeout = rospy.Duration(5) 
01680         ik_req.ik_request.pose_stamped = pose
01681         ik_req.ik_request.ik_link_name = wrist_name
01682         
01683         arm_pose = self.get_arm_joint_pose(which_arm)
01684         
01685         
01686         
01687         ik_req.ik_request.ik_seed_state.joint_state.position = []
01688         ik_req.ik_request.ik_seed_state.joint_state.name = []
01689         for i in xrange(len(solver_res.kinematic_solver_info.joint_names)):
01690             ik_req.ik_request.ik_seed_state.joint_state.position.append(arm_pose[i,0])
01691             ik_req.ik_request.ik_seed_state.joint_state.name.append(solver_res.kinematic_solver_info.joint_names[i])
01692             
01693             
01694         
01695         ik_res = ik_proxy(ik_req)
01696         
01697         if ik_res.error_code.val != ik_res.error_code.SUCCESS:
01698             try:
01699                 rospy.logwarn('IK failed with error code: ' + _ARM_ERROR_CODES[ik_res.error_code.val])
01700             except KeyError:
01701                 rospy.logwarn('IK failed with unknown error code: ' + str(ik_res.error_code.val))
01702             return False
01703         
01704         
01705         joint_pose = self.ik_robot_state_to_arm_pose(ik_res.solution)
01706         
01707         self.set_arm_joint_pose(joint_pose, which_arm, nsecs=nsecs)
01708         return True
01709 
01710     def arm_moving_cart(self, which_arm):
01711         if which_arm == 'l':
01712             x_err = self.l_arm_x_err
01713             x_d = self.l_arm_x_d
01714         else:
01715             x_err = self.r_arm_x_err
01716             x_d = self.r_arm_x_d
01717 
01718         moving = (fabs(x_d.linear.x) > self.still_moving_velocity or
01719                   fabs(x_d.linear.y) > self.still_moving_velocity or
01720                   fabs(x_d.linear.z) > self.still_moving_velocity or
01721                   fabs(x_d.angular.x) > self.still_moving_angular_velocity or
01722                   fabs(x_d.angular.y) > self.still_moving_angular_velocity or
01723                   fabs(x_d.angular.z) > self.still_moving_angular_velocity)
01724 
01725         return moving
01726 
01727     def move_relative_gripper(self, rel_push_vector, which_arm,
01728                               move_cart_count_thresh=None, pressure=1000):
01729         rel_pose = PoseStamped()
01730         rel_pose.header.stamp = rospy.Time(0)
01731         rel_pose.header.frame_id = '/'+which_arm + '_gripper_tool_frame'
01732         rel_pose.pose.position.x = float(rel_push_vector[0])
01733         rel_pose.pose.position.y = float(rel_push_vector[1])
01734         rel_pose.pose.position.z = float(rel_push_vector[2])
01735         rel_pose.pose.orientation.x = 0
01736         rel_pose.pose.orientation.y = 0
01737         rel_pose.pose.orientation.z = 0
01738         rel_pose.pose.orientation.w = 1.0
01739         return self.move_to_cart_pose(rel_pose, which_arm,
01740                                       move_cart_count_thresh, pressure)
01741 
01742     def move_relative_torso(self, rel_push_vector, which_arm,
01743                             move_cart_count_thresh=None, pressure=1000):
01744         if which_arm == 'l':
01745             cur_pose = self.l_arm_pose
01746         else:
01747             cur_pose = self.r_arm_pose
01748         rel_pose = PoseStamped()
01749         rel_pose.header.stamp = rospy.Time(0)
01750         rel_pose.header.frame_id = 'torso_lift_link'
01751         rel_pose.pose.position.x = cur_pose.pose.position.x + \
01752             float(rel_push_vector[0])
01753         rel_pose.pose.position.y = cur_pose.pose.position.y + \
01754             float(rel_push_vector[1])
01755         rel_pose.pose.position.z = cur_pose.pose.position.z + \
01756             float(rel_push_vector[2])
01757         rel_pose.pose.orientation = cur_pose.pose.orientation
01758         return self.move_to_cart_pose(rel_pose, which_arm,
01759                                       move_cart_count_thresh, pressure)
01760 
01761     def move_relative_torso_epc(self, push_angle, push_dist, which_arm,
01762                                 move_cart_count_thresh=None, pressure=1000):
01763         delta_x = cos(push_angle)*push_dist
01764         delta_y = sin(push_angle)*push_dist
01765         move_x = cos(push_angle)
01766         move_y = cos(push_angle)
01767         if which_arm == 'l':
01768             start_pose = self.l_arm_pose
01769         else:
01770             start_pose = self.r_arm_pose
01771         desired_pose = PoseStamped()
01772         desired_pose.header.stamp = rospy.Time(0)
01773         desired_pose.header.frame_id = 'torso_lift_link'
01774         desired_pose.pose.position.x = start_pose.pose.position.x + delta_x
01775         desired_pose.pose.position.y = start_pose.pose.position.y + delta_y
01776         desired_pose.pose.position.z = start_pose.pose.position.z
01777         desired_pose.pose.orientation = start_pose.pose.orientation
01778 
01779         desired_x = desired_pose.pose.position.x
01780         desired_y = desired_pose.pose.position.y
01781 
01782         start_x = start_pose.pose.position.x
01783         start_y = start_pose.pose.position.y
01784 
01785         def move_epc_generator(cur_ep, which_arm, converged_epsilon=0.01):
01786             ep = cur_ep
01787             ep.header.stamp = rospy.Time(0)
01788             step_size = 0.001
01789             ep.pose.position.x += step_size*move_x
01790             ep.pose.position.y += step_size*move_y
01791             if which_arm == 'l':
01792                 cur_pose = self.l_arm_pose
01793             else:
01794                 cur_pose = self.r_arm_pose
01795             cur_x = cur_pose.pose.position.x
01796             cur_y = cur_pose.pose.position.y
01797             arm_error_x = desired_x - cur_x
01798             arm_error_y = desired_y - cur_y
01799             error_dist = sqrt(arm_error_x**2 + arm_error_y**2)
01800 
01801             
01802             if error_dist < converged_epsilon:
01803                 stop = 'converged'
01804             elif (((start_x > desired_x and cur_x < desired_x) or
01805                    (start_x < desired_x and cur_x > desired_x)) and
01806                   ((start_y > desired_y and cur_y < desired_y) or
01807                    (start_y < desired_y and cur_y > desired_y))):
01808                 stop = 'moved_passed'
01809             else:
01810                 stop = ''
01811             return (stop, ep)
01812 
01813         return self.move_to_cart_pose_epc(desired_pose, which_arm,
01814                                           move_epc_generator,
01815                                           move_cart_count_thresh, pressure)
01816 
01817     def move_to_cart_pose_epc(self, desired_pose, which_arm, ep_gen,
01818                               done_moving_count_thresh=None, pressure=1000,
01819                               exit_on_contact=False):
01820         if done_moving_count_thresh is None:
01821             done_moving_count_thresh = self.arm_done_moving_epc_count_thresh
01822 
01823         if which_arm == 'l':
01824             pose_pub = self.l_arm_cart_pub
01825             posture_pub = self.l_arm_cart_posture_pub
01826             pl = self.l_pressure_listener
01827         else:
01828             pose_pub = self.r_arm_cart_pub
01829             posture_pub = self.r_arm_cart_posture_pub
01830             pl = self.r_pressure_listener
01831 
01832         self.switch_to_cart_controllers()
01833 
01834         arm_not_moving_count = 0
01835         r = rospy.Rate(self.move_cart_check_hz)
01836         pl.rezero()
01837         pl.set_threshold(pressure)
01838         rospy.Time()
01839         timeout = 5
01840         timeout_at = rospy.get_time() + timeout
01841         ep = desired_pose
01842         while True:
01843             if not self.arm_moving_cart(which_arm):
01844                 arm_not_moving_count += 1
01845             else:
01846                 arm_not_moving_count = 0
01847 
01848             if arm_not_moving_count > done_moving_count_thresh:
01849                 rospy.loginfo('Exiting do to no movement!')
01850                 break
01851             if pl.check_safety_threshold():
01852                 rospy.loginfo('Exceeded pressure safety thresh!')
01853                 break
01854             if pl.check_threshold():
01855                 rospy.loginfo('Exceeded pressure contact thresh...')
01856                 if exit_on_contact:
01857                     break
01858             if timeout_at < rospy.get_time():
01859                 rospy.loginfo('Exceeded time to move EPC!')
01860                 stop = 'timed out'
01861                 break
01862             
01863             m = self.get_desired_posture(which_arm)
01864             posture_pub.publish(m)
01865             
01866             pose_pub.publish(ep)
01867             r.sleep()
01868 
01869             
01870             stop, ep = ep_gen(ep, which_arm)
01871             if stop != '':
01872                 rospy.loginfo('Reached goal pose: ' + stop + '\n')
01873                 break
01874         self.stop_moving_cart(which_arm)
01875         
01876         if which_arm == 'l':
01877             arm_error = self.l_arm_x_err
01878         else:
01879             arm_error = self.r_arm_x_err
01880         error_dist = sqrt(arm_error.linear.x**2 + arm_error.linear.y**2 +
01881                           arm_error.linear.z**2)
01882         rospy.loginfo('Move cart gripper error dist: ' + str(error_dist)+'\n')
01883         return (arm_error, error_dist)
01884 
01885     def stop_moving_cart(self, which_arm):
01886         if which_arm == 'l':
01887             self.l_arm_cart_pub.publish(self.l_arm_pose)
01888         else:
01889             self.r_arm_cart_pub.publish(self.r_arm_pose)
01890 
01891     def move_down_until_contact(self, which_arm, pressure=1000):
01892         rospy.loginfo('Moving down!')
01893         down_twist = TwistStamped()
01894         down_twist.header.stamp = rospy.Time(0)
01895         down_twist.header.frame_id = 'torso_lift_link'
01896         down_twist.twist.linear.x = 0.0
01897         down_twist.twist.linear.y = 0.0
01898         down_twist.twist.linear.z = -0.1
01899         down_twist.twist.angular.x = 0.0
01900         down_twist.twist.angular.y = 0.0
01901         down_twist.twist.angular.z = 0.0
01902         return self.move_until_contact(down_twist, which_arm)
01903 
01904 
01905     def move_until_contact(self, twist, which_arm,
01906                           done_moving_count_thresh=None, pressure=1000):
01907         self.switch_to_vel_controllers()
01908         if which_arm == 'l':
01909             vel_pub = self.l_arm_cart_vel_pub
01910             posture_pub = self.l_arm_vel_posture_pub
01911             pl = self.l_pressure_listener
01912         else:
01913             vel_pub = self.r_arm_cart_vel_pub
01914             posture_pub = self.r_arm_vel_posture_pub
01915             pl = self.r_pressure_listener
01916 
01917         arm_not_moving_count = 0
01918         r = rospy.Rate(self.move_cart_check_hz)
01919         pl.rezero()
01920         pl.set_threshold(pressure)
01921         rospy.Time()
01922         timeout = 5
01923         timeout_at = rospy.get_time() + timeout
01924 
01925         while timeout_at > rospy.get_time():
01926             twist.header.stamp = rospy.Time(0)
01927             vel_pub.publish(twist)
01928             if not self.arm_moving_cart(which_arm):
01929                 arm_not_moving_count += 1
01930             else:
01931                 arm_not_moving_count = 0
01932             
01933             m = self.get_desired_posture(which_arm)
01934             posture_pub.publish(m)
01935 
01936             if pl.check_safety_threshold():
01937                 rospy.loginfo('Exceeded pressure safety thresh!\n')
01938                 break
01939             if pl.check_threshold():
01940                 rospy.loginfo('Exceeded pressure contact thresh...')
01941                 break
01942             r.sleep()
01943 
01944         self.stop_moving_vel(which_arm)
01945 
01946         
01947         return
01948 
01949     def vel_push_forward(self, which_arm, speed=0.3):
01950         self.switch_to_vel_controllers()
01951 
01952         forward_twist = TwistStamped()
01953         if which_arm == 'l':
01954             vel_pub = self.l_arm_cart_vel_pub
01955             posture_pub = self.l_arm_vel_posture_pub
01956         else:
01957             vel_pub = self.r_arm_cart_vel_pub
01958             posture_pub = self.r_arm_vel_posture_pub
01959 
01960         forward_twist.header.frame_id = '/'+which_arm + '_gripper_tool_frame'
01961         forward_twist.header.stamp = rospy.Time(0)
01962         forward_twist.twist.linear.x = speed
01963         forward_twist.twist.linear.y = 0.0
01964         forward_twist.twist.linear.z = 0.0
01965         forward_twist.twist.angular.x = 0.0
01966         forward_twist.twist.angular.y = 0.0
01967         forward_twist.twist.angular.z = 0.0
01968         m = self.get_desired_posture(which_arm)
01969         posture_pub.publish(m)
01970         vel_pub.publish(forward_twist)
01971 
01972     def update_vel(self, update_twist, which_arm):
01973         
01974         if which_arm == 'l':
01975             vel_pub = self.l_arm_cart_vel_pub
01976             posture_pub = self.l_arm_vel_posture_pub
01977         else:
01978             vel_pub = self.r_arm_cart_vel_pub
01979             posture_pub = self.r_arm_vel_posture_pub
01980 
01981         m = self.get_desired_posture(which_arm)
01982         posture_pub.publish(m)
01983         vel_pub.publish(update_twist)
01984 
01985     def stop_moving_vel(self, which_arm):
01986         rospy.loginfo('Stopping to move velocity for ' + which_arm + '_arm')
01987         self.switch_to_vel_controllers()
01988         if which_arm == 'l':
01989             vel_pub = self.l_arm_cart_vel_pub
01990             posture_pub = self.l_arm_vel_posture_pub
01991         else:
01992             vel_pub = self.r_arm_cart_vel_pub
01993             posture_pub = self.r_arm_vel_posture_pub
01994 
01995         stop_twist = TwistStamped()
01996         stop_twist.header.stamp = rospy.Time(0)
01997         stop_twist.header.frame_id = 'torso_lift_link'
01998         stop_twist.twist.linear.x = 0.0
01999         stop_twist.twist.linear.y = 0.0
02000         stop_twist.twist.linear.z = 0.0
02001         stop_twist.twist.angular.x = 0.0
02002         stop_twist.twist.angular.y = 0.0
02003         stop_twist.twist.angular.z = 0.0
02004         vel_pub.publish(stop_twist)
02005 
02006     def get_desired_posture(self, which_arm):
02007         if which_arm == 'l':
02008             posture = 'elbowupl'
02009             place_posture = 'gripper_place_l'
02010         else:
02011             posture = 'elbowupr'
02012             place_posture = 'gripper_place_r'
02013 
02014         joints = self.get_arm_joint_pose(which_arm)
02015         joints = joints.tolist()
02016         joints = [j[0] for j in joints]
02017         if self.use_gripper_place_joint_posture:
02018             m = Float64MultiArray(data=_POSTURES[place_posture])
02019         elif self.use_cur_joint_posture:
02020             m = Float64MultiArray(data=joints)
02021         else:
02022             m = Float64MultiArray(data=_POSTURES[posture])
02023         return m
02024 
02025     def l_arm_cart_state_callback(self, state_msg):
02026         x_err = state_msg.x_err
02027         x_d = state_msg.xd
02028         self.l_arm_pose = state_msg.x
02029         self.l_arm_x_err = x_err
02030         self.l_arm_x_d = x_d
02031         self.l_arm_F = state_msg.F
02032 
02033     def r_arm_cart_state_callback(self, state_msg):
02034         x_err = state_msg.x_err
02035         x_d = state_msg.xd
02036         self.r_arm_pose = state_msg.x
02037         self.r_arm_x_err = state_msg.x_err
02038         self.r_arm_x_d = state_msg.xd
02039         self.r_arm_F = state_msg.F
02040 
02041     def l_arm_vel_state_callback(self, state_msg):
02042         x_err = state_msg.x_err
02043         x_d = state_msg.xd
02044         self.l_arm_pose = state_msg.x
02045         self.l_arm_x_err = x_err
02046         self.l_arm_x_d = x_d
02047         self.l_arm_F = state_msg.F
02048 
02049     def r_arm_vel_state_callback(self, state_msg):
02050         x_err = state_msg.x_err
02051         x_d = state_msg.xd
02052         self.r_arm_pose = state_msg.x
02053         self.r_arm_x_err = state_msg.x_err
02054         self.r_arm_x_d = state_msg.xd
02055         self.r_arm_F = state_msg.F
02056 
02057     def ik_robot_state_to_arm_pose(self, robot_state):
02058         
02059         joint_pose = np.asmatrix(np.zeros((len(robot_state.joint_state.position), 1)))
02060         for i in xrange(len(robot_state.joint_state.position)):
02061             joint_pose[i,0] = robot_state.joint_state.position[i]
02062 
02063         return joint_pose
02064     
02065     
02066     
02067     def init_joint_controllers(self):
02068         self.arm_mode = 'joint_mode'
02069         prefix = roslib.packages.get_pkg_dir('hrl_pr2_arms')+'/params/'
02070         rospy.loginfo('Setting right arm controller gains')
02071         self.cs.switch("r_arm_controller", "r_arm_controller",
02072                        prefix + "pr2_arm_controllers_push.yaml")
02073         rospy.loginfo('Setting left arm controller gains')
02074         self.cs.switch("l_arm_controller", "l_arm_controller",
02075                        prefix + "pr2_arm_controllers_push.yaml")
02076         rospy.sleep(self.post_controller_switch_sleep)
02077 
02078     def init_cart_controllers(self):
02079         self.arm_mode = 'cart_mode'
02080         if self.use_jinv:
02081             self.cs.carefree_switch('r', '%s'+self.base_cart_controller_name,
02082                                     '$(find tabletop_pushing)/params/j_inverse_params_low.yaml')
02083             self.cs.carefree_switch('l', '%s'+self.base_cart_controller_name,
02084                                     '$(find tabletop_pushing)/params/j_inverse_params_low.yaml')
02085         else:
02086             self.cs.carefree_switch('r', '%s'+self.base_cart_controller_name,
02087                                     '$(find tabletop_pushing)/params/j_transpose_task_params_pos_feedback_push.yaml')
02088             self.cs.carefree_switch('l', '%s'+self.base_cart_controller_name,
02089                                     '$(find tabletop_pushing)/params/j_transpose_task_params_pos_feedback_push.yaml')
02090 
02091         rospy.sleep(self.post_controller_switch_sleep)
02092 
02093     def init_vel_controllers(self):
02094         self.arm_mode = 'vel_mode'
02095         self.cs.carefree_switch('r', '%s'+self.base_vel_controller_name,
02096                                 '$(find tabletop_pushing)/params/j_inverse_params_custom.yaml')
02097         self.cs.carefree_switch('l', '%s'+self.base_vel_controller_name,
02098                                 '$(find tabletop_pushing)/params/j_inverse_params_custom.yaml')
02099 
02100     def switch_to_cart_controllers(self):
02101         if self.arm_mode != 'cart_mode':
02102             self.cs.carefree_switch('r', '%s'+self.base_cart_controller_name)
02103             self.cs.carefree_switch('l', '%s'+self.base_cart_controller_name)
02104             self.arm_mode = 'cart_mode'
02105             rospy.sleep(self.post_controller_switch_sleep)
02106 
02107     def switch_to_joint_controllers(self):
02108         if self.arm_mode != 'joint_mode':
02109             self.cs.carefree_switch('r', '%s_arm_controller')
02110             self.cs.carefree_switch('l', '%s_arm_controller')
02111             self.arm_mode = 'joint_mode'
02112             rospy.sleep(self.post_controller_switch_sleep)
02113 
02114     def switch_to_vel_controllers(self):
02115         if self.arm_mode != 'vel_mode':
02116             self.cs.carefree_switch('r', '%s'+self.base_vel_controller_name)
02117             self.cs.carefree_switch('l', '%s'+self.base_vel_controller_name)
02118             self.arm_mode = 'vel_mode'
02119             rospy.sleep(self.post_controller_switch_sleep)
02120 
02121     def setupRBFController(self, controller_name):
02122         controller_file_path = self.learned_controller_base_path+controller_name+'.txt'
02123         self.RBF = rbf_control.RBFController()
02124         self.RBF.loadRBFController(controller_file_path)
02125 
02126     def loadAffineController(self, controller_name):
02127         controller_file = file(self.learned_controller_base_path+controller_name+'.txt','r')
02128         A = None
02129         B = None
02130         controller_file.close()
02131         return (A, B)
02132 
02133     def shutdown_hook(self):
02134         rospy.loginfo('Cleaning up node on shutdown')
02135         if _USE_CONTROLLER_IO:
02136             self.controller_io.close_out_file()
02137         if _USE_LEARN_IO:
02138             if self.learn_io is not None:
02139                 self.learn_io.close_out_file()
02140         
02141 
02142     
02143     
02144     
02145     def run(self):
02146         '''
02147         Main control loop for the node
02148         '''
02149         
02150         
02151         
02152         
02153         
02154         
02155         
02156         self.init_spine_pose()
02157         self.init_head_pose(self.head_pose_cam_frame)
02158         self.init_arms()
02159         self.switch_to_cart_controllers()
02160         rospy.loginfo('Done initializing feedback pushing node.')
02161         rospy.on_shutdown(self.shutdown_hook)
02162         rospy.spin()
02163 
02164 if __name__ == '__main__':
02165     node = PositionFeedbackPushNode()
02166     node.run()