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_lib.tf_utils as tfu
00039 import tf
00040 import numpy as np
00041 from tabletop_pushing.srv import *
00042 from tabletop_pushing.msg import *
00043 from math import sin, cos, pi, fabs, sqrt, hypot
00044 import sys
00045 from select import select
00046 from push_learning import PushLearningIO
00047 from geometry_msgs.msg import Pose2D
00048 import time
00049 import random
00050 from push_primitives import *
00051 
00052 _OFFLINE = False
00053 _USE_LEARN_IO = False
00054 _TEST_START_POSE = False
00055 _USE_FIXED_GOAL = False
00056 
00057 class TabletopExecutive:
00058 
00059     def __init__(self, use_singulation, use_learning):
00060         self.previous_rand_pose = None
00061 
00062         rospy.init_node('tabletop_executive_node',log_level=rospy.INFO)
00063         self.min_push_dist = rospy.get_param('~min_push_dist', 0.07)
00064         self.max_push_dist = rospy.get_param('~mix_push_dist', 0.3)
00065         self.use_overhead_x_thresh = rospy.get_param('~use_overhead_x_thresh', 0.55)
00066         self.use_sweep_angle_thresh = rospy.get_param('~use_sweep_angle_thresh', pi*0.4)
00067         self.use_pull_angle_thresh = rospy.get_param('~use_sweep_angle_thresh', pi*0.525)
00068         self.use_same_side_y_thresh = rospy.get_param('~use_same_side_y_thresh', 0.3)
00069         self.use_same_side_x_thresh = rospy.get_param('~use_same_side_x_thresh', 0.8)
00070 
00071         self.gripper_offset_dist = rospy.get_param('~gripper_push_offset_dist', 0.05)
00072         self.gripper_start_z = rospy.get_param('~gripper_push_start_z', -0.29)
00073 
00074         self.pincher_offset_dist = rospy.get_param('~pincher_push_offset_dist', 0.05)
00075         self.pincher_start_z = rospy.get_param('~pincher_push_start_z', -0.29)
00076 
00077         self.sweep_face_offset_dist = rospy.get_param('~gripper_sweep_face_offset_dist', 0.03)
00078         self.sweep_wrist_offset_dist = rospy.get_param('~gripper_sweep_wrist_offset_dist', 0.01)
00079         self.sweep_start_z = rospy.get_param('~gripper_sweep_start_z', -0.30)
00080 
00081         self.overhead_offset_dist = rospy.get_param('~overhead_push_offset_dist', 0.05)
00082         self.overhead_start_z = rospy.get_param('~overhead_push_start_z', -0.29)
00083 
00084         self.gripper_pull_offset_dist = rospy.get_param('~gripper_push_offset_dist', 0.05)
00085         self.gripper_pull_start_z = rospy.get_param('~gripper_push_start_z', -0.29)
00086 
00087         self.max_restart_limit = rospy.get_param('~max_restart_limit', 2)
00088 
00089         self.min_new_pose_dist = rospy.get_param('~min_new_pose_dist', 0.2)
00090         self.min_workspace_x = rospy.get_param('~min_workspace_x', 0.5)
00091         self.max_workspace_x = rospy.get_param('~max_workspace_x', 0.8)
00092         self.max_workspace_y = rospy.get_param('~max_workspace_y', 0.4)
00093         self.min_workspace_y = -self.max_workspace_y
00094 
00095         self.goal_y_base_delta = 0.01
00096         self.num_start_loc_clusters = 5
00097         self.start_loc_use_fixed_goal = rospy.get_param('start_loc_use_fixed_goal', False)
00098         self.servo_head_during_pushing = rospy.get_param('servo_head_during_pushing', False)
00099         self.learn_file_base = rospy.get_param('push_learn_file_base_path', '/u/thermans/data/new/aff_learn_out_')
00100 
00101         
00102         if not _OFFLINE:
00103             if use_singulation:
00104                 self.gripper_push_proxy = rospy.ServiceProxy('gripper_push',
00105                                                              GripperPush)
00106                 self.gripper_pre_push_proxy = rospy.ServiceProxy('gripper_pre_push',
00107                                                                  GripperPush)
00108                 self.gripper_post_push_proxy = rospy.ServiceProxy('gripper_post_push',
00109                                                                   GripperPush)
00110                 self.gripper_pre_sweep_proxy = rospy.ServiceProxy('gripper_pre_sweep',
00111                                                                   GripperPush)
00112                 self.gripper_sweep_proxy = rospy.ServiceProxy('gripper_sweep',
00113                                                               GripperPush)
00114                 self.gripper_post_sweep_proxy = rospy.ServiceProxy('gripper_post_sweep',
00115                                                                    GripperPush)
00116                 self.overhead_pre_push_proxy = rospy.ServiceProxy('overhead_pre_push',
00117                                                                   GripperPush)
00118                 self.overhead_push_proxy = rospy.ServiceProxy('overhead_push',
00119                                                               GripperPush)
00120                 self.overhead_post_push_proxy = rospy.ServiceProxy('overhead_post_push',
00121                                                                    GripperPush)
00122             if use_learning:
00123                 
00124                 self.overhead_feedback_push_proxy = rospy.ServiceProxy(
00125                     'overhead_feedback_push', FeedbackPush)
00126                 self.overhead_feedback_post_push_proxy = rospy.ServiceProxy(
00127                     'overhead_feedback_post_push', FeedbackPush)
00128                 self.gripper_feedback_push_proxy = rospy.ServiceProxy(
00129                     'gripper_feedback_push', FeedbackPush)
00130                 self.gripper_feedback_post_push_proxy = rospy.ServiceProxy(
00131                     'gripper_feedback_post_push', FeedbackPush)
00132                 self.gripper_feedback_sweep_proxy = rospy.ServiceProxy(
00133                     'gripper_feedback_sweep', FeedbackPush)
00134                 self.gripper_feedback_post_sweep_proxy = rospy.ServiceProxy(
00135                     'gripper_feedback_post_sweep', FeedbackPush)
00136                 self.overhead_feedback_pre_push_proxy = rospy.ServiceProxy('overhead_pre_push',
00137                                                                            FeedbackPush)
00138                 self.gripper_feedback_pre_push_proxy = rospy.ServiceProxy('gripper_pre_push',
00139                                                                           FeedbackPush)
00140                 self.gripper_feedback_pre_sweep_proxy = rospy.ServiceProxy('gripper_pre_sweep',
00141                                                                            FeedbackPush)
00142             
00143             self.raise_and_look_proxy = rospy.ServiceProxy('raise_and_look',
00144                                                            RaiseAndLook)
00145         self.table_proxy = rospy.ServiceProxy('get_table_location', LocateTable)
00146         self.learn_io = None
00147 
00148         if use_singulation:
00149             self.use_singulation = True
00150             self.init_singulation()
00151         else:
00152             self.use_singulation = False
00153         if use_learning:
00154             self.use_learning = True
00155             self.init_learning()
00156         else:
00157             self.use_learning = False
00158         rospy.on_shutdown(self.shutdown_hook)
00159 
00160     def init_singulation(self):
00161         
00162         self.singulation_push_vector_proxy = rospy.ServiceProxy(
00163             'get_singulation_push_vector', SingulationPush)
00164 
00165     def init_learning(self):
00166         self.learning_push_vector_proxy = rospy.ServiceProxy(
00167             'get_learning_push_vector', LearnPush)
00168         
00169         if not _OFFLINE:
00170             self.raise_and_look()
00171         
00172         initialized = False
00173         r = rospy.Rate(0.5)
00174         while not initialized:
00175             initialized = self.initialize_learning_push()
00176             r.sleep()
00177         rospy.loginfo('Done initializing learning')
00178 
00179     def init_loc_learning(self):
00180         
00181         self.push_loc_shape_features = []
00182         self.push_count = 0
00183         self.base_trial_id = str(rospy.get_time())
00184 
00185         if _USE_LEARN_IO:
00186             self.learn_io = PushLearningIO()
00187             learn_file_name = self.learn_file_base+str(self.base_trial_id)+'.txt'
00188             self.learn_out_file_name = learn_file_name
00189             rospy.loginfo('Opening learn file: '+learn_file_name)
00190             self.learn_io.open_out_file(learn_file_name)
00191 
00192     def finish_learning(self):
00193         rospy.loginfo('Done with learning pushes and such.')
00194         if _USE_LEARN_IO and self.learn_io is not None:
00195             self.learn_io.close_out_file()
00196 
00197     def run_singulation(self, num_pushes=1, use_guided=True):
00198         
00199         if not _OFFLINE:
00200             self.raise_and_look()
00201         
00202         self.initialize_singulation_push_vector();
00203 
00204         
00205         for i in xrange(num_pushes):
00206             if _OFFLINE:
00207                 code_in = raw_input("Press <Enter> to determine next singulation push: ")
00208                 if code_in.startswith('q'):
00209                     break
00210             pose_res = self.request_singulation_push(use_guided)
00211             if pose_res is None:
00212                 rospy.logwarn("pose_res is None. Exiting pushing");
00213                 break
00214             if pose_res.no_push:
00215                 rospy.loginfo("No push. Exiting pushing.");
00216                 break
00217             rospy.loginfo('Performing push #' + str(i+1))
00218             
00219             rospy.loginfo('Push start_point: (' + str(pose_res.start_point.x) +
00220                           ', ' + str(pose_res.start_point.y) +
00221                           ', ' + str(pose_res.start_point.z) + ')')
00222             rospy.loginfo('Push angle: ' + str(pose_res.push_angle))
00223             rospy.loginfo('Push dist: ' + str(pose_res.push_dist))
00224 
00225             behavior_primitive = self.choose_singulation_primitive(pose_res)
00226             
00227             
00228             
00229 
00230             
00231             which_arm = self.choose_singulation_arm(pose_res)
00232             push_dist = pose_res.push_dist
00233             push_dist = max(min(push_dist, self.max_push_dist),
00234                             self.min_push_dist)
00235 
00236             if _OFFLINE:
00237                 continue
00238             if behavior_primitive == GRIPPER_PUSH:
00239                 self.gripper_push_object(push_dist, which_arm, pose_res, True)
00240             if behavior_primitive == GRIPPER_SWEEP:
00241                 self.sweep_object(push_dist, which_arm, pose_res, True)
00242             if behavior_primitive == OVERHEAD_PUSH:
00243                 self.overhead_push_object(push_dist, which_arm, pose_res, True)
00244             rospy.loginfo('Done performing push behavior.\n')
00245 
00246         if not (pose_res is None):
00247             rospy.loginfo('Singulated objects: ' + str(pose_res.singulated))
00248             rospy.loginfo('Final estimate of ' + str(pose_res.num_objects) +
00249                           ' objects')
00250 
00251     def run_start_loc_learning(self, object_id, num_pushes_per_sample, num_sample_locs, start_loc_param_path=''):
00252         self.push_loc_shape_features = []
00253         for controller in CONTROLLERS:
00254             for behavior_primitive in BEHAVIOR_PRIMITIVES[controller]:
00255                 for proxy in PERCEPTUAL_PROXIES[controller]:
00256                     for arm in ROBOT_ARMS:
00257                         res = self.explore_push_start_locs(num_pushes_per_sample, num_sample_locs, behavior_primitive,
00258                                                            controller, proxy, object_id, arm, start_loc_param_path)
00259                         if res == 'quit':
00260                             rospy.loginfo('Quiting on user request')
00261                             return False
00262         return True
00263 
00264     def run_push_exploration(self, object_id):
00265         for controller in CONTROLLERS:
00266             for behavior_primitive in BEHAVIOR_PRIMITIVES[controller]:
00267                 for proxy in PERCEPTUAL_PROXIES[controller]:
00268                     for arm in ROBOT_ARMS:
00269                         precondition_method = PRECONDITION_METHODS[behavior_primitive]
00270                         res = self.explore_push(behavior_primitive, controller, proxy, object_id,
00271                                                 precondition_method, arm)
00272                         if res == 'quit':
00273                             rospy.loginfo('Quiting on user request')
00274                             return False
00275         return True
00276 
00277     def explore_push(self, behavior_primitive, controller_name, proxy_name, object_id,
00278                      precondition_method=CENTROID_PUSH_PRECONDITION, input_arm=None):
00279         if input_arm is not None:
00280             rospy.loginfo('Exploring push behavior: (' + behavior_primitive + ', '
00281                           + controller_name + ', ' + proxy_name + ', ' + input_arm + ')')
00282         else:
00283             rospy.loginfo('Exploring push triple: (' + behavior_primitive + ', '
00284                           + controller_name + ', ' + proxy_name + ')')
00285         timeout = 2
00286         rospy.loginfo("Enter something to pause before pushing: ")
00287         rlist, _, _ = select([sys.stdin], [], [], timeout)
00288         if rlist:
00289             s = sys.stdin.readline()
00290             code_in = raw_input('Move object and press <Enter> to continue: ')
00291             if code_in.lower().startswith('q'):
00292                 return 'quit'
00293         else:
00294             rospy.loginfo("No input. Moving on...")
00295 
00296         
00297         if self.servo_head_during_pushing:
00298             self.raise_and_look(point_head_only=True)
00299 
00300         init_pose = self.get_feedback_push_initial_obj_pose()
00301         while not _OFFLINE and self.out_of_workspace(init_pose):
00302             rospy.loginfo('Object out of workspace at pose: (' + str(init_pose.x) + ', ' +
00303                           str(init_pose.y) + ')')
00304             code_in = raw_input('Move object inside workspace and press <Enter> to continue: ')
00305             if code_in.lower().startswith('q'):
00306                 return 'quit'
00307             init_pose = self.get_feedback_push_initial_obj_pose()
00308         goal_pose = self.generate_random_table_pose(init_pose)
00309 
00310         restart_count = 0
00311         done_with_push = False
00312         while not done_with_push:
00313             start_time = time.time()
00314             push_vec_res = self.get_feedback_push_start_pose(goal_pose, controller_name,
00315                                                              proxy_name, behavior_primitive,
00316                                                              learn_start_loc=False)
00317 
00318             if push_vec_res is None:
00319                 return None
00320             elif push_vec_res == 'quit':
00321                 return push_vec_res
00322 
00323             if input_arm is None:
00324                 which_arm = self.choose_arm(push_vec_res.push, controller_name)
00325             else:
00326                 which_arm = input_arm
00327 
00328             if _USE_LEARN_IO:
00329                 self.learn_io.write_pre_push_line(push_vec_res.centroid, push_vec_res.theta,
00330                                                   goal_pose, push_vec_res.push.start_point,
00331                                                   behavior_primitive, controller_name,
00332                                                   proxy_name, which_arm, object_id, precondition_method)
00333 
00334             res, push_res = self.perform_push(which_arm, behavior_primitive,
00335                                               push_vec_res, goal_pose,
00336                                               controller_name, proxy_name)
00337             push_time = time.time() - start_time
00338             if push_res.failed_pre_position:
00339                 if _USE_LEARN_IO:
00340                     self.learn_io.write_bad_trial_line()
00341             else:
00342                 self.analyze_push(behavior_primitive, controller_name, proxy_name, which_arm, push_time,
00343                                   push_vec_res, goal_pose, object_id, precondition_method)
00344 
00345             if res == 'quit':
00346                 return res
00347             elif res == 'aborted':
00348                 if self.servo_head_during_pushing:
00349                     self.raise_and_look(point_head_only=True)
00350                 restart_count += 1
00351                 if restart_count <= self.max_restart_limit:
00352                     rospy.loginfo('Continuing after push was aborted')
00353                     continue
00354                 else:
00355                     done_with_push = True
00356                     rospy.loginfo('Stopping push attempt because of too many restarts\n')
00357             else:
00358                 rospy.loginfo('Stopping push attempt because reached goal\n')
00359                 done_with_push = True
00360         return res
00361 
00362     def explore_push_start_locs(self, num_pushes_per_sample, num_sample_locs, behavior_primitive, controller_name,
00363                                 proxy_name, object_id, which_arm, start_loc_param_path='',
00364                                 precondition_method=CENTROID_PUSH_PRECONDITION):
00365         rospy.loginfo('Exploring push start locs for triple: (' + behavior_primitive + ', ' +
00366                       controller_name + ', ' + proxy_name + ')')
00367         timeout = 2
00368         rospy.loginfo("Enter something to pause before pushing: ")
00369         rlist, _, _ = select([sys.stdin], [], [], timeout)
00370         if rlist:
00371             s = sys.stdin.readline()
00372             code_in = raw_input('Move object and press <Enter> to continue: ')
00373             if code_in.lower().startswith('q'):
00374                 return 'quit'
00375         else:
00376             rospy.loginfo("No input. Moving on...")
00377 
00378         if self.servo_head_during_pushing:
00379             self.raise_and_look(point_head_only=True)
00380 
00381         start_loc_trials = 0
00382         self.start_loc_goal_y_delta = 0
00383         N_PUSH = num_sample_locs
00384         
00385         
00386         i = 0
00387         while i < N_PUSH:
00388             rospy.loginfo('Performing push at new pose: ' + str(i))
00389             i += 1
00390             
00391             goal_pose = self.generate_random_table_pose()
00392             j = 0
00393             position_worked = True
00394             while j  < num_pushes_per_sample:
00395                 rospy.loginfo('Performing push iteration: '+str(start_loc_trials))
00396                 rospy.loginfo('Performing sample push ' + str(j) + ' for pose: ' + str(i-1))
00397                 rospy.loginfo('Sending param_path: ' + start_loc_param_path)
00398                 
00399                 init_pose = self.get_feedback_push_initial_obj_pose()
00400                 if self.start_loc_use_fixed_goal: 
00401                     reset = False
00402                     while not reset:
00403                         code_in = raw_input('Move object to initial test pose and press <Enter> to continue: ')
00404                         if code_in.lower().startswith('q'):
00405                             return 'quit'
00406                         reset = True
00407                         init_pose = self.get_feedback_push_initial_obj_pose()
00408                 elif not _OFFLINE:
00409                     while self.out_of_workspace(init_pose):
00410                         rospy.loginfo('Object out of workspace at pose: (' + str(init_pose.x) + ', ' +
00411                                       str(init_pose.y) + ')')
00412                         code_in = raw_input('Move object inside workspace and press <Enter> to continue: ')
00413                         if code_in.lower().startswith('q'):
00414                             return 'quit'
00415                         init_pose = self.get_feedback_push_initial_obj_pose()
00416 
00417                 trial_id = str(object_id) +'_'+ str(self.base_trial_id) + '_' + str(self.push_count)
00418                 self.push_count += 1
00419                 start_time = time.time()
00420                 push_vec_res = self.get_feedback_push_start_pose(goal_pose, controller_name, proxy_name,
00421                                                                  behavior_primitive, learn_start_loc=True,
00422                                                                  new_object=(not start_loc_trials),
00423                                                                  num_clusters=self.num_start_loc_clusters,
00424                                                                  trial_id=trial_id,
00425                                                                  num_sample_locs=num_sample_locs,
00426                                                                  num_pushes_per_sample=num_pushes_per_sample,
00427                                                                  start_loc_param_path=start_loc_param_path,
00428                                                                  position_worked=position_worked)
00429                 if push_vec_res is None:
00430                     rospy.logwarn('Push vector Response is none, exiting')
00431                     return None
00432                 elif push_vec_res == 'quit':
00433                     return push_vec_res
00434 
00435                 
00436                 if len(start_loc_param_path) > 0:
00437                     which_arm = self.choose_arm(push_vec_res.push, controller_name)
00438 
00439                 goal_pose = push_vec_res.goal_pose
00440                 shape_descriptor = push_vec_res.shape_descriptor[:]
00441                 self.push_loc_shape_features.append(shape_descriptor)
00442 
00443                 if _USE_LEARN_IO:
00444                     
00445                     rospy.loginfo('Predicted score: ' + str(push_vec_res.predicted_score))
00446                     self.learn_io.write_pre_push_line(push_vec_res.centroid, push_vec_res.theta,
00447                                                       goal_pose, push_vec_res.push.start_point, behavior_primitive,
00448                                                       controller_name, proxy_name, which_arm, trial_id,
00449                                                       precondition_method, push_vec_res.predicted_score,
00450                                                       shape_descriptor)
00451 
00452                 res, push_res = self.perform_push(which_arm, behavior_primitive, push_vec_res, goal_pose,
00453                                                   controller_name, proxy_name)
00454                 push_time = time.time() - start_time
00455 
00456                 if _USE_LEARN_IO and not _OFFLINE:
00457                     timeout = 2
00458                     rospy.loginfo("Enter something to not save the previous push trial: ")
00459                     rlist, _, _ = select([sys.stdin], [], [], timeout)
00460                     if rlist:
00461                         self.learn_io.write_bad_trial_line()
00462                         s = sys.stdin.readline()
00463                         rospy.loginfo('Not saving previous trial.')
00464                         if s.lower().startswith('q'):
00465                             return 'quit'
00466                         position_worked = True
00467                     elif push_res.failed_pre_position:
00468                         self.learn_io.write_bad_trial_line()
00469                         rospy.loginfo('Not saving previous trial because of failed hand placement')
00470                         position_worked = False
00471                         
00472                     else:
00473                         rospy.loginfo("No input. Saving trial data")
00474                         self.analyze_push(behavior_primitive, controller_name, proxy_name, which_arm, push_time,
00475                                           push_vec_res, goal_pose, trial_id, precondition_method)
00476                         start_loc_trials += 1
00477                         j += 1
00478                         position_worked = True
00479                 else:
00480                     j += 1
00481                     position_worked = True
00482 
00483                 if res == 'quit':
00484                     return res
00485                 elif res == 'aborted' or res == 'done':
00486                     if self.servo_head_during_pushing:
00487                         self.raise_and_look(point_head_only=True)
00488         rospy.loginfo('Done performing push loc exploration!')
00489         return res
00490 
00491     def get_feedback_push_initial_obj_pose(self):
00492         get_push = True
00493         while get_push:
00494             goal_pose = Pose2D()
00495             controller_name = CENTROID_CONTROLLER
00496             proxy_name = ELLIPSE_PROXY
00497             behavior_primitive = OVERHEAD_PUSH
00498             push_vec_res = self.request_feedback_push_start_pose(goal_pose, controller_name,
00499                                                                  proxy_name, behavior_primitive,
00500                                                                  get_pose_only=True)
00501 
00502             if push_vec_res is None:
00503                 return None
00504             if push_vec_res.no_objects:
00505                 code_in = raw_input('No objects found. Place object and press <Enter>: ')
00506                 if code_in.lower().startswith('q'):
00507                     return 'quit'
00508             else:
00509                 return push_vec_res.centroid
00510 
00511 
00512     def get_feedback_push_start_pose(self, goal_pose, controller_name, proxy_name,
00513                                      behavior_primitive,
00514                                      learn_start_loc=False, new_object=False, num_clusters=1,
00515                                      trial_id='',num_sample_locs=1, num_pushes_per_sample=1,
00516                                      start_loc_param_path='', position_worked=True):
00517         get_push = True
00518         while get_push:
00519             push_vec_res = self.request_feedback_push_start_pose(goal_pose, controller_name,
00520                                                                  proxy_name, behavior_primitive,
00521                                                                  learn_start_loc=learn_start_loc,
00522                                                                  new_object=new_object,
00523                                                                  num_clusters=num_clusters,
00524                                                                  trial_id=trial_id,
00525                                                                  num_sample_locs=num_sample_locs,
00526                                                                  num_pushes_per_sample=num_pushes_per_sample,
00527                                                                  start_loc_param_path=start_loc_param_path,
00528                                                                  position_worked=position_worked)
00529 
00530             if push_vec_res is None:
00531                 return None
00532             if push_vec_res.no_objects:
00533                 code_in = raw_input('No objects found. Place object and press <Enter>: ')
00534                 if code_in.lower().startswith('q'):
00535                     return 'quit'
00536             else:
00537                 return push_vec_res
00538 
00539     def choose_arm(self, push_vec, controller_name):
00540         if controller_name == ROTATE_TO_HEADING:
00541             if (push_vec.start_point.y < 0):
00542                 which_arm = 'r'
00543             else:
00544                 which_arm = 'l'
00545             return which_arm
00546         elif controller_name == DIRECT_GOAL_CONTROLLER:
00547             if push_vec.push_angle > 0:
00548                 which_arm = 'r'
00549             else:
00550                 which_arm = 'l'
00551         elif (fabs(push_vec.start_point.y) > self.use_same_side_y_thresh or
00552               push_vec.start_point.x > self.use_same_side_x_thresh):
00553             if (push_vec.start_point.y < 0):
00554                 which_arm = 'r'
00555             else:
00556                 which_arm = 'l'
00557         elif push_vec.push_angle > 0:
00558             which_arm = 'r'
00559         else:
00560             which_arm = 'l'
00561 
00562         return which_arm
00563 
00564     def choose_singulation_primitive(self, pose_res):
00565         
00566         if fabs(pose_res.push_angle) > self.use_pull_angle_thresh:
00567             behavior_primitive = OVERHEAD_PUSH
00568         elif pose_res.start_point.x < self.use_overhead_x_thresh:
00569             behavior_primitive = OVERHEAD_PUSH
00570         elif fabs(pose_res.push_angle) > self.use_sweep_angle_thresh:
00571             behavior_primitive = GRIPPER_SWEEP
00572         else:
00573             behavior_primitive = GRIPPER_PUSH
00574         return behavior_primitive
00575 
00576     def choose_singulation_arm(self, pose_res):
00577         if (fabs(pose_res.start_point.y) > self.use_same_side_y_thresh or
00578             pose_res.start_point.x > self.use_same_side_x_thresh):
00579             if (pose_res.start_point.y < 0):
00580                 which_arm = 'r'
00581                 rospy.loginfo('Setting arm to right because of limits')
00582             else:
00583                 which_arm = 'l'
00584                 rospy.loginfo('Setting arm to left because of limits')
00585         elif pose_res.push_angle > 0:
00586             which_arm = 'r'
00587             rospy.loginfo('Setting arm to right because of angle')
00588         else:
00589             which_arm = 'l'
00590             rospy.loginfo('Setting arm to left because of angle')
00591         return which_arm
00592 
00593     def perform_push(self, which_arm, behavior_primitive, push_vector_res, goal_pose,
00594                      controller_name, proxy_name, high_init = True):
00595         push_angle = push_vector_res.push.push_angle
00596         
00597         if push_vector_res is None:
00598             rospy.logwarn("push_vector_res is None. Exiting pushing");
00599             return ('quit', None)
00600         if push_vector_res.no_push:
00601             rospy.loginfo("No push. Exiting pushing.");
00602             return ('quit', None)
00603         
00604         rospy.loginfo('Push start_point: (' +
00605                       str(push_vector_res.push.start_point.x) + ', ' +
00606                       str(push_vector_res.push.start_point.y) + ', ' +
00607                       str(push_vector_res.push.start_point.z) + ')')
00608         rospy.loginfo('Push angle: ' + str(push_angle))
00609         if not _OFFLINE:
00610             if behavior_primitive == OVERHEAD_PUSH or behavior_primitive == OPEN_OVERHEAD_PUSH:
00611                 result = self.overhead_feedback_push_object(which_arm,
00612                                                             push_vector_res.push, goal_pose,
00613                                                             controller_name, proxy_name, behavior_primitive)
00614             elif behavior_primitive == GRIPPER_SWEEP:
00615                 result = self.feedback_sweep_object(which_arm, push_vector_res.push,
00616                                                     goal_pose, controller_name, proxy_name, behavior_primitive)
00617             elif behavior_primitive == GRIPPER_PUSH or behavior_primitive == PINCHER_PUSH or behavior_primitive == GRIPPER_PULL:
00618                 result = self.gripper_feedback_push_object(which_arm,
00619                                                            push_vector_res.push, goal_pose,
00620                                                            controller_name, proxy_name, behavior_primitive)
00621             else:
00622                 rospy.logwarn('Unknown behavior_primitive: ' + str(behavior_primitive))
00623                 result = None
00624         else:
00625             result = FeedbackPushResponse()
00626 
00627         
00628         if result.action_aborted:
00629             rospy.logwarn('Push was aborted. Calling push behavior again.')
00630             return ('aborted', result)
00631 
00632         rospy.loginfo('Done performing push behavior.')
00633         
00634         
00635         
00636         
00637         return ('done', result)
00638 
00639     def analyze_push(self, behavior_primitive, controller_name, proxy_name,
00640                      which_arm, push_time, push_vector_res, goal_pose, object_id,
00641                      precondition_method=CENTROID_PUSH_PRECONDITION):
00642         push_angle = push_vector_res.push.push_angle
00643         analysis_res = self.request_learning_analysis()
00644         rospy.loginfo('Done getting analysis response.')
00645         rospy.loginfo('Primitive: ' + str(behavior_primitive))
00646         rospy.loginfo('Controller: ' + str(controller_name))
00647         rospy.loginfo('Proxy: ' + str(proxy_name))
00648         rospy.loginfo('Arm: ' + str(which_arm))
00649         rospy.loginfo('Push time: ' + str(push_time) + 's')
00650         rospy.loginfo('Init (X,Y,Theta): (' + str(push_vector_res.centroid.x) +
00651                       ', ' + str(push_vector_res.centroid.y) + ', ' +
00652                       str(push_vector_res.theta) +')')
00653         rospy.loginfo('Final (X,Y,Theta): (' + str(analysis_res.centroid.x) + ', ' +
00654                        str(analysis_res.centroid.y) + ', ' + str(analysis_res.theta)+ ')')
00655         rospy.loginfo('Desired (X,Y,Theta): (' + str(goal_pose.x) + ', ' +
00656                        str(goal_pose.y) + ', ' + str(goal_pose.theta) + ')')
00657         rospy.loginfo('Error (X,Y,Theta): (' + str(fabs(goal_pose.x-analysis_res.centroid.x)) +
00658                       ', ' + str(fabs(goal_pose.y-analysis_res.centroid.y)) + ', ' +
00659                       str(fabs(goal_pose.theta-analysis_res.theta)) + ')\n')
00660         if _USE_LEARN_IO:
00661             self.learn_io.write_line(
00662                 push_vector_res.centroid, push_vector_res.theta,
00663                 analysis_res.centroid, analysis_res.theta,
00664                 goal_pose, push_vector_res.push.start_point, behavior_primitive, controller_name, proxy_name,
00665                 which_arm, push_time, object_id, precondition_method)
00666 
00667     def request_singulation_push(self, use_guided=True):
00668         push_vector_req = SingulationPushRequest()
00669         push_vector_req.use_guided = use_guided
00670         push_vector_req.initialize = False
00671         push_vector_req.no_push_calc = False
00672         rospy.loginfo("Calling singulation push vector service")
00673         try:
00674             push_vector_res = self.singulation_push_vector_proxy(push_vector_req)
00675             return push_vector_res
00676         except rospy.ServiceException, e:
00677             rospy.logwarn("Service did not process request: %s"%str(e))
00678             return None
00679 
00680     def request_feedback_push_start_pose(self, goal_pose, controller_name, proxy_name,
00681                                          behavior_primitive,
00682                                          get_pose_only=False, learn_start_loc=False,
00683                                          new_object=False, num_clusters=1, trial_id='',
00684                                          num_sample_locs=1, num_pushes_per_sample=1,start_loc_param_path='',
00685                                          position_worked=True):
00686         push_vector_req = LearnPushRequest()
00687         push_vector_req.initialize = False
00688         push_vector_req.analyze_previous = False
00689         push_vector_req.goal_pose = goal_pose
00690         push_vector_req.controller_name = controller_name
00691         push_vector_req.proxy_name = proxy_name
00692         push_vector_req.behavior_primitive = behavior_primitive
00693         push_vector_req.get_pose_only = get_pose_only
00694         push_vector_req.learn_start_loc = learn_start_loc
00695         push_vector_req.new_object = new_object
00696         push_vector_req.trial_id = trial_id
00697         push_vector_req.num_start_loc_clusters = num_clusters
00698         push_vector_req.num_start_loc_sample_locs = num_sample_locs
00699         push_vector_req.num_start_loc_pushes_per_sample = num_pushes_per_sample
00700         push_vector_req.start_loc_param_path=start_loc_param_path
00701         push_vector_req.previous_position_worked = position_worked
00702         try:
00703             rospy.loginfo("Calling feedback push start service")
00704             push_vector_res = self.learning_push_vector_proxy(push_vector_req)
00705             return push_vector_res
00706         except rospy.ServiceException, e:
00707             rospy.logwarn("Service did not process request: %s"%str(e))
00708             return None
00709 
00710     def request_learning_analysis(self):
00711         push_vector_req = LearnPushRequest()
00712         push_vector_req.initialize = False
00713         push_vector_req.analyze_previous = True
00714         rospy.loginfo("Calling learning push vector service")
00715         try:
00716             push_vector_res = self.learning_push_vector_proxy(push_vector_req)
00717             return push_vector_res
00718         except rospy.ServiceException, e:
00719             rospy.logwarn("Service did not process request: %s"%str(e))
00720             return None
00721 
00722     def initialize_singulation_push_vector(self):
00723         push_vector_req = SingulationPushRequest()
00724         push_vector_req.initialize = True
00725         push_vector_req.use_guided = True
00726         push_vector_req.no_push_calc = False
00727         rospy.loginfo('Initializing singulation push vector service.')
00728         self.singulation_push_vector_proxy(push_vector_req)
00729 
00730     def initialize_learning_push(self):
00731         push_vector_req = LearnPushRequest()
00732         push_vector_req.initialize = True
00733         push_vector_req.analyze_previous = False
00734         rospy.loginfo('Initializing learning push vector service.')
00735         try:
00736             self.learning_push_vector_proxy(push_vector_req)
00737         except rospy.ServiceException, e:
00738             rospy.logwarn("Service did not process request: %s"%str(e))
00739             return False
00740         return True
00741 
00742     def raise_and_look(self, request_table=True, init_arms=False, point_head_only=False):
00743         if request_table:
00744             table_req = LocateTableRequest()
00745             table_req.recalculate = True
00746         raise_req = RaiseAndLookRequest()
00747         raise_req.point_head_only = True
00748         raise_req.camera_frame = 'head_mount_kinect_rgb_link'
00749         
00750         
00751         
00752         raise_req.init_arms = True
00753         rospy.loginfo("Moving head")
00754         raise_res = self.raise_and_look_proxy(raise_req)
00755         if point_head_only:
00756             return
00757         if request_table:
00758             raise_req.have_table_centroid = True
00759             try:
00760                 rospy.loginfo("Getting table pose")
00761                 table_res = self.table_proxy(table_req);
00762             except rospy.ServiceException, e:
00763                 rospy.logwarn("Service did not process request: %s"%str(e))
00764                 return
00765             if not table_res.found_table:
00766                 return
00767             raise_req.table_centroid = table_res.table_centroid
00768         else:
00769             raise_req.have_table_centroid = False
00770 
00771         rospy.loginfo("Raising spine");
00772         raise_req.point_head_only = False
00773         raise_req.init_arms = init_arms
00774         raise_res = self.raise_and_look_proxy(raise_req)
00775 
00776     def overhead_feedback_push_object(self, which_arm, push_vector, goal_pose, controller_name,
00777                                       proxy_name, behavior_primitive, high_init=True, open_gripper=False):
00778         
00779         push_req = FeedbackPushRequest()
00780         push_req.start_point.header = push_vector.header
00781         push_req.start_point.point = push_vector.start_point
00782         push_req.open_gripper = open_gripper
00783         push_req.goal_pose = goal_pose
00784         if behavior_primitive == OPEN_OVERHEAD_PUSH:
00785             push_req.open_gripper = True
00786         if _USE_LEARN_IO:
00787             push_req.learn_out_file_name = self.learn_out_file_name
00788 
00789         
00790         wrist_yaw = push_vector.push_angle
00791         push_req.wrist_yaw = wrist_yaw
00792 
00793         
00794         push_req.start_point.point.x += -self.gripper_offset_dist*cos(wrist_yaw)
00795         push_req.start_point.point.y += -self.gripper_offset_dist*sin(wrist_yaw)
00796         push_req.start_point.point.z = self.overhead_start_z
00797         push_req.left_arm = (which_arm == 'l')
00798         push_req.right_arm = not push_req.left_arm
00799         push_req.high_arm_init = high_init
00800         push_req.controller_name = controller_name
00801         push_req.proxy_name = proxy_name
00802         push_req.behavior_primitive = behavior_primitive
00803 
00804         rospy.loginfo('Overhead push augmented start_point: (' +
00805                       str(push_req.start_point.point.x) + ', ' +
00806                       str(push_req.start_point.point.y) + ', ' +
00807                       str(push_req.start_point.point.z) + ')')
00808 
00809         rospy.loginfo("Calling overhead feedback pre push service")
00810         pre_push_res = self.overhead_feedback_pre_push_proxy(push_req)
00811         rospy.loginfo("Calling overhead feedback push service")
00812 
00813         if _TEST_START_POSE:
00814             raw_input('waiting for input to recall arm: ')
00815             push_res = FeedbackPushResponse()
00816         elif pre_push_res.failed_pre_position:
00817             rospy.logwarn('Failed to properly position in pre-push, aborting push')
00818             push_res = pre_push_res
00819         else:
00820             push_res = self.overhead_feedback_push_proxy(push_req)
00821         rospy.loginfo("Calling overhead feedback post push service")
00822         post_push_res = self.overhead_feedback_post_push_proxy(push_req)
00823         return push_res
00824 
00825     def gripper_feedback_push_object(self, which_arm, push_vector, goal_pose, controller_name,
00826                                      proxy_name, behavior_primitive, high_init=True, open_gripper=False):
00827         
00828         push_req = FeedbackPushRequest()
00829         push_req.start_point.header = push_vector.header
00830         push_req.start_point.point = push_vector.start_point
00831         push_req.open_gripper = open_gripper
00832         push_req.goal_pose = goal_pose
00833         if _USE_LEARN_IO:
00834             push_req.learn_out_file_name = self.learn_out_file_name
00835 
00836         
00837         wrist_yaw = push_vector.push_angle
00838         push_req.wrist_yaw = wrist_yaw
00839         
00840         if behavior_primitive == GRIPPER_PULL:
00841             offset_dist = self.gripper_pull_offset_dist
00842             start_z = self.gripper_pull_start_z
00843         elif behavior_primitive == PINCHER_PUSH:
00844             offset_dist = self.pincher_offset_dist
00845             start_z = self.pincher_start_z
00846             push_req.open_gripper = True
00847         else:
00848             offset_dist = self.gripper_offset_dist
00849             start_z = self.gripper_start_z
00850 
00851         rospy.loginfo('Gripper push pre-augmented start_point: (' +
00852                       str(push_req.start_point.point.x) + ', ' +
00853                       str(push_req.start_point.point.y) + ', ' +
00854                       str(push_req.start_point.point.z) + ')')
00855 
00856         push_req.start_point.point.x += -offset_dist*cos(wrist_yaw)
00857         push_req.start_point.point.y += -offset_dist*sin(wrist_yaw)
00858         push_req.start_point.point.z = start_z
00859         push_req.left_arm = (which_arm == 'l')
00860         push_req.right_arm = not push_req.left_arm
00861         push_req.high_arm_init = high_init
00862         push_req.controller_name = controller_name
00863         push_req.proxy_name = proxy_name
00864         push_req.behavior_primitive = behavior_primitive
00865 
00866         rospy.loginfo('Gripper push augmented start_point: (' +
00867                       str(push_req.start_point.point.x) + ', ' +
00868                       str(push_req.start_point.point.y) + ', ' +
00869                       str(push_req.start_point.point.z) + ')')
00870 
00871         rospy.loginfo("Calling gripper feedback pre push service")
00872         pre_push_res = self.gripper_feedback_pre_push_proxy(push_req)
00873 
00874         if _TEST_START_POSE:
00875             raw_input('waiting for input to recall arm: ')
00876             push_res = FeedbackPushResponse()
00877         elif pre_push_res.failed_pre_position:
00878             rospy.logwarn('Failed to properly position in pre-push, aborting push')
00879             push_res = pre_push_res
00880         else:
00881             rospy.loginfo("Calling gripper feedback push service")
00882             push_res = self.gripper_feedback_push_proxy(push_req)
00883 
00884         rospy.loginfo("Calling gripper feedback post push service")
00885         post_push_res = self.gripper_feedback_post_push_proxy(push_req)
00886         return push_res
00887 
00888     def feedback_sweep_object(self, which_arm, push_vector, goal_pose, controller_name,
00889                               proxy_name, behavior_primitive, high_init=True, open_gripper=False):
00890         
00891         push_req = FeedbackPushRequest()
00892         push_req.start_point.header = push_vector.header
00893         push_req.start_point.point = push_vector.start_point
00894         push_req.open_gripper = open_gripper
00895         push_req.goal_pose = goal_pose
00896         if _USE_LEARN_IO:
00897             push_req.learn_out_file_name = self.learn_out_file_name
00898 
00899         
00900         if push_vector.push_angle > 0:
00901             y_offset_dir = -1
00902             wrist_yaw = push_vector.push_angle - pi/2.0
00903         else:
00904             y_offset_dir = +1
00905             wrist_yaw = push_vector.push_angle + pi/2.0
00906         if abs(push_vector.push_angle) > pi/2:
00907             x_offset_dir = +1
00908         else:
00909             x_offset_dir = -1
00910 
00911         
00912         push_req.wrist_yaw = wrist_yaw
00913         face_x_offset = self.sweep_face_offset_dist*x_offset_dir*abs(sin(wrist_yaw))
00914         face_y_offset = y_offset_dir*self.sweep_face_offset_dist*cos(wrist_yaw)
00915         wrist_x_offset = self.sweep_wrist_offset_dist*cos(wrist_yaw)
00916         wrist_y_offset = self.sweep_wrist_offset_dist*sin(wrist_yaw)
00917         rospy.loginfo('wrist_yaw: ' + str(wrist_yaw))
00918         rospy.loginfo('Face offset: (' + str(face_x_offset) + ', ' + str(face_y_offset) +')')
00919         rospy.loginfo('Wrist offset: (' + str(wrist_x_offset) + ', ' + str(wrist_y_offset) +')')
00920 
00921         push_req.start_point.point.x += face_x_offset + wrist_x_offset
00922         push_req.start_point.point.y += face_y_offset + wrist_y_offset
00923         push_req.start_point.point.z = self.sweep_start_z
00924         push_req.left_arm = (which_arm == 'l')
00925         push_req.right_arm = not push_req.left_arm
00926         push_req.high_arm_init = high_init
00927         push_req.controller_name = controller_name
00928         push_req.proxy_name = proxy_name
00929         push_req.behavior_primitive = behavior_primitive
00930 
00931         rospy.loginfo('Gripper sweep augmented start_point: (' +
00932                       str(push_req.start_point.point.x) + ', ' +
00933                       str(push_req.start_point.point.y) + ', ' +
00934                       str(push_req.start_point.point.z) + ')')
00935 
00936         rospy.loginfo("Calling feedback pre sweep service")
00937         pre_push_res = self.gripper_feedback_pre_sweep_proxy(push_req)
00938         rospy.loginfo("Calling feedback sweep service")
00939 
00940         if _TEST_START_POSE:
00941             raw_input('waiting for input to recall arm: ')
00942             push_res = FeedbackPushResponse()
00943         else:
00944             push_res = self.gripper_feedback_sweep_proxy(push_req)
00945         rospy.loginfo("Calling feedback post sweep service")
00946         post_push_res = self.gripper_feedback_post_sweep_proxy(push_req)
00947         return push_res
00948 
00949     def gripper_push_object(self, push_dist, which_arm, pose_res, high_init):
00950         
00951         push_req = GripperPushRequest()
00952         push_req.start_point.header = pose_res.header
00953         push_req.start_point.point = pose_res.start_point
00954         push_req.arm_init = True
00955         push_req.arm_reset = True
00956         push_req.high_arm_init = True
00957 
00958         
00959         wrist_yaw = pose_res.push_angle
00960         push_req.wrist_yaw = wrist_yaw
00961         push_req.desired_push_dist = push_dist + abs(self.gripper_x_offset)
00962 
00963         
00964         push_req.start_point.point.x += self.gripper_x_offset*cos(wrist_yaw)
00965         push_req.start_point.point.y += self.gripper_x_offset*sin(wrist_yaw)
00966         push_req.start_point.point.z = self.gripper_start_z
00967         push_req.left_arm = (which_arm == 'l')
00968         push_req.right_arm = not push_req.left_arm
00969 
00970         rospy.loginfo("Calling gripper pre push service")
00971         pre_push_res = self.gripper_pre_push_proxy(push_req)
00972         rospy.loginfo("Calling gripper push service")
00973         push_res = self.gripper_push_proxy(push_req)
00974         rospy.loginfo("Calling gripper post push service")
00975         post_push_res = self.gripper_post_push_proxy(push_req)
00976 
00977     def sweep_object(self, push_dist, which_arm, pose_res, high_init):
00978         
00979         sweep_req = GripperPushRequest()
00980         sweep_req.left_arm = (which_arm == 'l')
00981         sweep_req.right_arm = not sweep_req.left_arm
00982         sweep_req.high_arm_init = True
00983 
00984         
00985         if pose_res.push_angle > 0.0:
00986             y_offset_dir = -1
00987             wrist_yaw = pose_res.push_angle - pi/2
00988         else:
00989             wrist_yaw = pose_res.push_angle + pi/2
00990             y_offset_dir = +1
00991         if abs(pose_res.push_angle) > pi/2:
00992             x_offset_dir = +1
00993         else:
00994             x_offset_dir = -1
00995 
00996         
00997         sweep_req.wrist_yaw = wrist_yaw
00998         face_x_offset = self.sweep_face_offset_dist*x_offset_dir*abs(sin(wrist_yaw))
00999         face_y_offset = y_offset_dir*self.sweep_face_offset_dist*cos(wrist_yaw)
01000         wrist_x_offset = self.sweep_wrist_offset_dist*cos(wrist_yaw)
01001         wrist_y_offset = self.sweep_wrist_offset_dist*sin(wrist_yaw)
01002 
01003         sweep_req.start_point.header = pose_res.header
01004         sweep_req.start_point.point = pose_res.start_point
01005         sweep_req.start_point.point.x += face_x_offset + wrist_x_offset
01006         sweep_req.start_point.point.y += face_y_offset + wrist_y_offset
01007         sweep_req.start_point.point.z = self.sweep_start_z
01008         sweep_req.arm_init = True
01009         sweep_req.arm_reset = True
01010 
01011         sweep_req.desired_push_dist = -y_offset_dir*(self.sweep_face_offset_dist + push_dist)
01012 
01013 
01014         rospy.loginfo("Calling gripper pre sweep service")
01015         pre_sweep_res = self.gripper_pre_sweep_proxy(sweep_req)
01016         rospy.loginfo("Calling gripper sweep service")
01017         sweep_res = self.gripper_sweep_proxy(sweep_req)
01018         rospy.loginfo("Calling gripper post sweep service")
01019         post_sweep_res = self.gripper_post_sweep_proxy(sweep_req)
01020 
01021     def overhead_push_object(self, push_dist, which_arm, pose_res, high_init):
01022         
01023         push_req = GripperPushRequest()
01024         push_req.start_point.header = pose_res.header
01025         push_req.start_point.point = pose_res.start_point
01026         push_req.arm_init = True
01027         push_req.arm_reset = True
01028         push_req.high_arm_init = high_init
01029 
01030         
01031         wrist_yaw = pose_res.push_angle
01032         push_req.wrist_yaw = wrist_yaw
01033         push_req.desired_push_dist = push_dist
01034 
01035         
01036         push_req.start_point.point.x += self.overhead_offset_dist*cos(wrist_yaw)
01037         push_req.start_point.point.y += self.overhead_offset_dist*sin(wrist_yaw)
01038         push_req.start_point.point.z = self.overhead_start_z
01039         push_req.left_arm = (which_arm == 'l')
01040         push_req.right_arm = not push_req.left_arm
01041 
01042         rospy.loginfo("Calling pre overhead push service")
01043         pre_push_res = self.overhead_pre_push_proxy(push_req)
01044         rospy.loginfo("Calling overhead push service")
01045         push_res = self.overhead_push_proxy(push_req)
01046         rospy.loginfo("Calling post overhead push service")
01047         post_push_res = self.overhead_post_push_proxy(push_req)
01048 
01049     def out_of_workspace(self, init_pose):
01050         return (init_pose.x < self.min_workspace_x or init_pose.x > self.max_workspace_x or
01051                 init_pose.y < self.min_workspace_y or init_pose.y > self.max_workspace_y)
01052 
01053     def generate_random_table_pose(self, init_pose=None):
01054         if _USE_FIXED_GOAL or self.start_loc_use_fixed_goal:
01055             goal_pose = Pose2D()
01056             goal_pose.x = 0.65
01057             goal_pose.y = -0.3
01058             goal_pose.theta = 0
01059             if self.start_loc_use_fixed_goal:
01060                 goal_pose.y += self.start_loc_goal_y_delta
01061             return goal_pose
01062         min_x = self.min_workspace_x
01063         max_x = self.max_workspace_x
01064         min_y = self.min_workspace_y
01065         max_y = self.max_workspace_y
01066         max_theta = pi
01067         min_theta = -pi
01068 
01069         pose_not_found = True
01070         while pose_not_found:
01071             rand_pose = Pose2D()
01072             rand_pose.x = random.uniform(min_x, max_x)
01073             rand_pose.y = random.uniform(min_y, max_y)
01074             rand_pose.theta = random.uniform(min_theta, max_theta)
01075             pose_not_found = False
01076             
01077             
01078             
01079             
01080             if (init_pose is not None and
01081                 hypot(init_pose.x-rand_pose.x, init_pose.y-rand_pose.y) < self.min_new_pose_dist):
01082                 pose_not_found = True
01083 
01084         rospy.loginfo('Rand table pose is: (' + str(rand_pose.x) + ', ' + str(rand_pose.y) +
01085                       ', ' + str(rand_pose.theta) + ')')
01086         self.previous_rand_pose = rand_pose
01087         return rand_pose
01088 
01089     def shutdown_hook(self):
01090         rospy.loginfo('Cleaning up tabletop_executive_node on shutdown')
01091         if self.use_learning:
01092             self.finish_learning()
01093 
01094 if __name__ == '__main__':
01095     random.seed()
01096     learn_start_loc = False
01097     
01098     
01099     
01100     num_start_loc_sample_locs = 5
01101     num_start_loc_pushes_per_sample = 3
01102     use_singulation = False
01103     use_learning = True
01104     use_guided = True
01105     running = True
01106     max_pushes = 500
01107     node = TabletopExecutive(use_singulation, use_learning)
01108     
01109     hold_out_objects = ['small_brush', 'soap_box', 'camcorder', 'toothpaste', 'food_box', 'large_brush']
01110     for hold_out_object in hold_out_objects:
01111         if not running:
01112             break
01113         
01114         rospy.loginfo('Testing with hold out object ' + hold_out_object)
01115         
01116         
01117         
01118         start_loc_param_path = roslib.packages.get_pkg_dir('tabletop_pushing')+'/cfg/ichr_rotate/push_svm_no_'+\
01119             hold_out_object+'.model'
01120         
01121         
01122         if use_singulation:
01123             node.run_singulation(max_pushes, use_guided)
01124         elif use_learning:
01125             running = True
01126             need_object_id = True
01127             while need_object_id:
01128                 code_in = raw_input('Place object on table, enter id, and press <Enter>: ')
01129                 if len(code_in) > 0:
01130                     need_object_id = False
01131                 else:
01132                     rospy.logwarn("No object id given.")
01133             if code_in.lower().startswith('q'):
01134                 running = False
01135                 break
01136             if learn_start_loc:
01137                 node.init_loc_learning()
01138                 clean_exploration = node.run_start_loc_learning(code_in, num_start_loc_pushes_per_sample,
01139                                                                 num_start_loc_sample_locs, start_loc_param_path)
01140                 node.finish_learning()
01141             else:
01142                 node.start_loc_use_fixed_goal = False
01143                 node.init_loc_learning()
01144                 rospy.loginfo('Running push exploration')
01145                 clean_exploration = node.run_push_exploration(object_id=code_in)
01146                 node.finish_learning()
01147             if not clean_exploration:
01148                 rospy.loginfo('Not clean end to pushing stuff')
01149                 running = False
01150                 node.finish_learning()
01151                 break
01152