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