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 import roslib; roslib.load_manifest('tabletop_pushing')
00034 from geometry_msgs.msg import Point, Pose2D, Twist
00035 import tf.transformations as tr
00036 from push_primitives import *
00037 from tabletop_pushing.srv import *
00038 from tabletop_pushing.msg import *
00039 import rospy
00040 import cv2
00041 import numpy as np
00042 import sys
00043 from math import sin, cos, pi, sqrt, fabs, atan2, hypot, acos, isnan
00044 
00045 import matplotlib.pyplot as plotter
00046 import random
00047 import os
00048 import subprocess
00049 
00050 _VERSION_LINE = '# v0.6'
00051 _LEARN_TRIAL_HEADER_LINE = '# object_id/trial_id init_x init_y init_z init_theta final_x final_y final_z final_theta goal_x goal_y goal_theta push_start_point.x push_start_point.y push_start_point.z behavior_primitive controller proxy which_arm push_time precondition_method score [shape_descriptors]'
00052 _CONTROL_HEADER_LINE = '# x.x x.y x.theta x_dot.x x_dot.y x_dot.theta x_desired.x x_desired.y x_desired.theta theta0 u.linear.x u.linear.y u.linear.z u.angular.x u.angular.y u.angular.z time hand.x hand.y hand.z'
00053 _BAD_TRIAL_HEADER_LINE='#BAD_TRIAL'
00054 _DEBUG_IO = False
00055 
00056 def subPIAngle(theta):
00057     while theta < -pi:
00058         theta += 2.0*pi
00059     while theta > pi:
00060         theta -= 2.0*pi
00061     return theta
00062 
00063 def point_line_dist(pt, a, b):
00064     '''
00065     Get the perpendicular distance from pt to the line defined through (a,b)
00066     '''
00067     A = np.asarray(a)
00068     B = np.asarray(b)
00069     P = np.asarray(pt)
00070     q = A - P
00071     n = B-A
00072     n_hat = n / np.linalg.norm(n)
00073     return np.linalg.norm(q-np.dot(q,n_hat)*n_hat)
00074 
00075 class PushTrial:
00076     def __init__(self):
00077         self.object_id = ''
00078         self.controller = ''
00079         self.behavior_primitive = ''
00080         self.proxy = ''
00081         self.which_arm = ''
00082         self.precondition_method = ''
00083         self.init_centroid = Point()
00084         self.init_orientation = 0.0
00085         self.final_centroid = Point()
00086         self.final_orientation = 0.0
00087         self.goal_pose = Pose2D()
00088         self.start_point = Point()
00089         self.push_time = 0.0
00090         
00091         self.push_angle = 0.0
00092         self.push_dist = 0.0
00093         self.continuation = False
00094         self.score = -1.0
00095         self.shape_descriptor = []
00096 
00097     def __str__(self):
00098         return (self.object_id +
00099                 ' (' + self.proxy + ', ' + self.controller + ', ' + self.behavior_primitive + ', ' +
00100                 self.which_arm + '_arm'+', ' +self.precondition_method+'):\n' +
00101                 'init_centroid:\n' + str(self.init_centroid) + '\n'+
00102                 'init_orientation: ' + str(self.init_orientation) +'\n'+
00103                 'final_centroid:\n' + str(self.final_centroid) + '\n'+
00104                 'final_orientation: ' + str(self.final_orientation) + '\n'+
00105                 'goal_pose:\n' + str(self.goal_pose) + '\n'+
00106                 'push_time: ' + str(self.push_time))
00107 
00108 class ControlTimeStep:
00109     def __init__(self, x, x_dot, x_desired, theta0, u, t):
00110         self.x = x
00111         self.x_dot = x_dot
00112         self.x_desired = x_desired
00113         self.theta0 = theta0
00114         self.u = u
00115         self.t = t
00116 
00117 class PushCtrlTrial:
00118     def __init__(self):
00119         self.trial_start = None
00120         self.trial_end = None
00121         self.trial_trajectory = []
00122 
00123     def __str__(self):
00124         return (str(self.trial_start) + '\n' + str(self.trial_trajectory) + '\n' + str(self.trial_end))
00125 
00126 class PushLearningIO:
00127     def __init__(self):
00128         self.data_out = None
00129         self.data_in = None
00130 
00131     def write_line(self, init_centroid, init_orientation, final_centroid,
00132                    final_orientation, goal_pose, push_start_point, behavior_primitive,
00133                    controller, proxy, which_arm, push_time, object_id,
00134                    push_point, precondition_method='centroid_push', push_score=-1):
00135         if self.data_out is None:
00136             rospy.logerr('Attempting to write to file that has not been opened.')
00137             return
00138         rospy.logdebug('Writing output line.\n')
00139         data_line = object_id+' '+str(init_centroid.x)+' '+str(init_centroid.y)+' '+str(init_centroid.z)+' '+\
00140             str(init_orientation)+' '+str(final_centroid.x)+' '+str(final_centroid.y)+' '+\
00141             str(final_centroid.z)+' '+str(final_orientation)+' '+\
00142             str(goal_pose.x)+' '+str(goal_pose.y)+' '+str(goal_pose.theta)+' '+\
00143             str(push_start_point.x)+' '+str(push_start_point.y)+' '+str(push_start_point.z)+' '+\
00144             behavior_primitive+' '+controller+' '+proxy+' '+which_arm+' '+str(push_time)+' '+precondition_method+' '+\
00145             str(push_score)+'\n'
00146         self.data_out.write(_LEARN_TRIAL_HEADER_LINE+'\n')
00147         self.data_out.write(data_line)
00148         self.data_out.flush()
00149 
00150     def parse_line(self, line):
00151         if line.startswith('#'):
00152             return None
00153         l  = line.split()
00154         l.reverse()
00155         num_objs = len(l)
00156         push = PushTrial()
00157         push.object_id = l.pop()
00158         push.init_centroid.x = float(l.pop())
00159         push.init_centroid.y = float(l.pop())
00160         push.init_centroid.z = float(l.pop())
00161         push.init_orientation = float(l.pop())
00162         push.final_centroid.x = float(l.pop())
00163         push.final_centroid.y = float(l.pop())
00164         push.final_centroid.z = float(l.pop())
00165         push.final_orientation = float(l.pop())
00166         push.goal_pose.x = float(l.pop())
00167         push.goal_pose.y = float(l.pop())
00168         push.goal_pose.theta = float(l.pop())
00169         push.start_point.x = float(l.pop())
00170         push.start_point.y = float(l.pop())
00171         push.start_point.z = float(l.pop())
00172         push.behavior_primitive = l.pop()
00173         push.controller = l.pop()
00174         push.proxy = l.pop()
00175         push.which_arm = l.pop()
00176         push.push_time = float(l.pop())
00177         if len(l) > 0:
00178             push.precondition_method = l.pop()
00179         else:
00180             push.precondition_method = 'push_centroid'
00181         if len(l) > 0:
00182             push.score = float(l.pop())
00183         else:
00184             push.score = -1.0
00185         push.shape_descriptor = []
00186         while len(l) > 0:
00187             push.shape_descriptor.append(float(l.pop()))
00188 
00189         push.push_angle = atan2(push.goal_pose.y-push.init_centroid.y,
00190                                 push.goal_pose.x-push.init_centroid.x)
00191         push.push_dist = hypot(push.goal_pose.y-push.init_centroid.y,
00192                                push.goal_pose.x-push.init_centroid.x)
00193         if push.init_centroid.x > 1.0:
00194             print 'Greater than 1.0 x: ', str(push)
00195         return push
00196 
00197     def write_pre_push_line(self, init_centroid, init_orientation, goal_pose, push_start_point, behavior_primitive,
00198                             controller, proxy, which_arm, object_id, precondition_method,
00199                             predicted_score=-1.0, shape_descriptor=None):
00200         if self.data_out is None:
00201             rospy.logerr('Attempting to write to file that has not been opened.')
00202             return
00203         rospy.logdebug('Writing pre push output line.\n')
00204         data_line = object_id+' '+str(init_centroid.x)+' '+str(init_centroid.y)+' '+str(init_centroid.z)+' '+\
00205             str(init_orientation)+' '+str(0.0)+' '+str(0.0)+' '+\
00206             str(0.0)+' '+str(0.0)+' '+\
00207             str(goal_pose.x)+' '+str(goal_pose.y)+' '+str(goal_pose.theta)+' '+\
00208             str(push_start_point.x)+' '+str(push_start_point.y)+' '+str(push_start_point.z)+' '+\
00209             behavior_primitive+' '+controller+' '+proxy+' '+which_arm+' '+str(0.0)+' '+precondition_method+ ' ' +\
00210             str(predicted_score)
00211 
00212         if shape_descriptor is not None:
00213             for s in shape_descriptor:
00214                 data_line += ' '+str(s)
00215         data_line+='\n'
00216         self.data_out.write(_LEARN_TRIAL_HEADER_LINE+'\n')
00217         self.data_out.write(data_line)
00218         self.data_out.flush()
00219 
00220     def write_bad_trial_line(self):
00221         self.data_out.write(_BAD_TRIAL_HEADER_LINE+'\n')
00222         self.data_out.flush()
00223 
00224     def read_in_data_file(self, file_name):
00225         data_in = file(file_name, 'r')
00226         x = [self.parse_line(l) for l in data_in.readlines()]
00227         data_in.close()
00228         x = filter(None, x)
00229         return self.link_repeat_trials(x)
00230 
00231     def link_repeat_trials(self, trials):
00232         for i in range(1,len(trials)):
00233             if (trials[i].goal_pose.y == trials[i-1].goal_pose.y and
00234                 trials[i].goal_pose.x == trials[i-1].goal_pose.x and
00235                 trials[i].behavior_primitive == trials[i-1].behavior_primitive and
00236                 trials[i].proxy == trials[i-1].proxy and
00237                 trials[i].controller == trials[i-1].controller):
00238                 if trials[i].which_arm == trials[i-1].which_arm:
00239                     
00240                     pass
00241                 else:
00242                     trials[i].continuation = True
00243         return trials
00244 
00245     def open_out_file(self, file_name):
00246         self.data_out = file(file_name, 'a')
00247         self.data_out.write(_VERSION_LINE+'\n')
00248         
00249         self.data_out.flush()
00250 
00251     def close_out_file(self):
00252         self.data_out.close()
00253 
00254 class ControlAnalysisIO:
00255     def __init__(self):
00256         self.data_out = None
00257         self.data_in = None
00258 
00259     def write_line(self, x, x_dot, x_desired, theta0, u, time, hand_pose):
00260         if self.data_out is None:
00261             rospy.logerr('Attempting to write to file that has not been opened.')
00262             return
00263         data_line = str(x.x)+' '+str(x.y)+' '+str(x.theta)+' '+\
00264             str(x_dot.x)+' '+str(x_dot.y)+' '+str(x_dot.theta)+' '+\
00265             str(x_desired.x)+' '+str(x_desired.y)+' '+str(x_desired.theta)+' '+\
00266             str(theta0)+' '+str(u.linear.x)+' '+str(u.linear.y)+' '+str(u.linear.z)+' '+\
00267             str(u.angular.x)+' '+str(u.angular.y)+' '+str(u.angular.z)+' '+str(time)+' '+\
00268             str(hand_pose.position.x)+' '+str(hand_pose.position.y)+' '+str(hand_pose.position.z)+\
00269             '\n'
00270         self.data_out.write(data_line)
00271         self.data_out.flush()
00272 
00273     def parse_line(self, line):
00274         if line.startswith('#'):
00275             return None
00276         data = [float(s) for s in line.split()]
00277         x = Pose2D()
00278         x_dot = Pose2D()
00279         x_desired = Pose2D()
00280         u = Twist()
00281         x.x = data[0]
00282         x.y = data[1]
00283         x.theta = data[2]
00284         x_dot.x = data[3]
00285         x_dot.y = data[4]
00286         x_dot.theta = data[5]
00287         x_desired.x = data[6]
00288         x_desired.y = data[7]
00289         x_desired.theta = data[8]
00290         theta0 = data[9]
00291         u.linear.x = data[10]
00292         u.linear.y = data[11]
00293         u.linear.z = data[12]
00294         u.angular.x = data[13]
00295         u.angular.y = data[14]
00296         u.angular.z = data[15]
00297         t = data[16]
00298         ee_x = data[17]
00299         ee_y = data[18]
00300         ee_z = data[19]
00301         cts = ControlTimeStep(x, x_dot, x_desired, theta0, u, t)
00302         return cts
00303 
00304     def read_in_data_file(self, file_name):
00305         data_in = file(file_name, 'r')
00306         x = [self.parse_line(l) for l in data_in.readlines()[1:]]
00307         data_in.close()
00308         return filter(None, x)
00309 
00310     def open_out_file(self, file_name):
00311         self.data_out = file(file_name, 'a')
00312         self.data_out.write(_CONTROL_HEADER_LINE+'\n')
00313         self.data_out.flush()
00314 
00315     def close_out_file(self):
00316         self.data_out.close()
00317 
00318 class CombinedPushLearnControlIO:
00319     def __init__(self):
00320         self.pl_io = PushLearningIO()
00321         self.ctrl_io = ControlAnalysisIO()
00322         self.push_trials = []
00323 
00324     def read_in_data_file(self, file_name):
00325         data_in = file(file_name, 'r')
00326         read_pl_trial_line = False
00327         read_ctrl_line = False
00328         trial_is_start = True
00329 
00330         trial_starts = 0
00331         bad_stops = 0
00332         object_comments = 0
00333         control_headers = 0
00334 
00335         self.push_trials = []
00336         current_trial = PushCtrlTrial()
00337         for line in  data_in.readlines():
00338             if line.startswith(_VERSION_LINE):
00339                 if _DEBUG_IO:
00340                     print 'Ignoring version line'
00341                 continue
00342             elif line.startswith(_LEARN_TRIAL_HEADER_LINE):
00343                 object_comments += 1
00344 
00345                 if _DEBUG_IO:
00346                     print 'Read learn trial header'
00347                 if trial_is_start:
00348                     trial_starts += 1
00349                 read_pl_trial_line = True
00350                 read_ctrl_line = False
00351             elif line.startswith(_CONTROL_HEADER_LINE):
00352                 if _DEBUG_IO:
00353                     print 'Read control header'
00354                 control_headers += 1
00355                 read_ctrl_line = True
00356             elif line.startswith(_BAD_TRIAL_HEADER_LINE):
00357                 bad_stops += 1
00358                 if _DEBUG_IO:
00359                     print 'BAD TRIAL: not adding current trial to list'
00360                 
00361                 current_trial = PushCtrlTrial()
00362                 trial_is_start = True
00363             elif read_pl_trial_line:
00364                 if _DEBUG_IO:
00365                     print 'Reading trial'
00366                 trial = self.pl_io.parse_line(line)
00367                 read_pl_trial_line = False
00368                 if trial_is_start:
00369                     current_trial.trial_start = trial
00370                     if _DEBUG_IO:
00371                         print 'Trial is start trial'
00372                 else:
00373                     if _DEBUG_IO:
00374                         print 'Trial is end trial'
00375                     current_trial.trial_end = trial
00376                     self.push_trials.append(current_trial)
00377                     current_trial = PushCtrlTrial()
00378                 trial_is_start = not trial_is_start
00379             elif read_ctrl_line:
00380                 if _DEBUG_IO:
00381                     print 'Read ctrl pt'
00382                 traj_pt = self.ctrl_io.parse_line(line)
00383                 current_trial.trial_trajectory.append(traj_pt)
00384             else:
00385                 if _DEBUG_IO:
00386                     print 'None of these?'
00387         data_in.close()
00388         
00389         print 'Read in', file_name
00390         print 'trial_starts',trial_starts
00391         print 'bad_stops',bad_stops
00392         
00393         print 'num trials', len(self.push_trials), '\n'
00394 
00395     def write_example_file(self, file_name, X, Y, normalize=False, debug=False):
00396         data_out = file(file_name, 'w')
00397         
00398         k = 0
00399         for x,y in zip(X,Y):
00400             k += 1
00401             if debug:
00402                 print y, x
00403             if isnan(y):
00404                 print 'Skipping writing example: ', k
00405                 continue
00406             data_line = str(y)
00407             if normalize:
00408                 feature_sum = 0.0
00409                 for xi in x:
00410                     feature_sum += xi
00411                 for i, xi in enumerate(x):
00412                     if xi > 0:
00413                         data_line += ' ' + str(i+1)+':'+str(sqrt(xi/float(feature_sum)))
00414             else:
00415                 for i, xi in enumerate(x):
00416                     if xi > 0:
00417                         data_line += ' ' + str(i+1)+':'+str(xi)
00418             data_line +='\n'
00419             data_out.write(data_line)
00420         print 'Wrote', k, 'examples'
00421         data_out.close()
00422 
00423     def read_example_file(self, file_name):
00424         data_in = file(file_name, 'r')
00425         lines = [l.split() for l in data_in.readlines()]
00426         data_in.close()
00427         Y = []
00428         X = []
00429         for line in lines:
00430             y = float(line.pop(0))
00431             Y.append(y)
00432             x = []
00433             for pair in line:
00434                 idx, val = pair.split(':')
00435                 idx = int(idx) - 1
00436                 val = float(val)
00437                 while len(x) < idx:
00438                     x.append(0)
00439                 x.append(val)
00440             X.append(x)
00441         return (X,Y)
00442 
00443     def read_regression_prediction_file(self, file_name):
00444         data_in = file(file_name, 'r')
00445         Y_hat = [float(y.strip()) for y in data_in.readlines()]
00446         data_in.close()
00447         return Y_hat
00448 
00449 class StartLocPerformanceAnalysis:
00450 
00451     def __init__(self):
00452         self.analyze_straight_line_push = self.analyze_straight_line_push_line_dist
00453         self.analyze_spin_push = self.analyze_spin_push_net_spin
00454         
00455 
00456     def compare_predicted_and_observed_push_scores(self, in_file_name, out_file_name=None, use_spin=False):
00457         
00458         plio = CombinedPushLearnControlIO()
00459         plio.read_in_data_file(in_file_name)
00460         file_out = None
00461         if out_file_name is not None:
00462             file_out = file(out_file_name, 'w')
00463         for i, p in enumerate(plio.push_trials):
00464             pred_score = p.trial_start.score
00465             
00466             if use_spin:
00467                 observed_score = self.analyze_spin_push(p)
00468             else:
00469                 observed_score = self.analyze_straight_line_push(p)
00470             print 'Trial [',i,'] : Pred: ', pred_score, '\tObserved: ', observed_score
00471             if file_out is not None:
00472                 trial_line = str(pred_score) + ' ' + str(observed_score) + '\n'
00473                 file_out.write(trial_line)
00474         if file_out is not None:
00475             file_out.close()
00476 
00477     def compute_observed_push_scores_final_errors(self, in_file_name, out_file_name=None, use_spin=False):
00478         
00479         plio = CombinedPushLearnControlIO()
00480         plio.read_in_data_file(in_file_name)
00481         file_out = None
00482         if out_file_name is not None:
00483             file_out = file(out_file_name, 'w')
00484         for i, p in enumerate(plio.push_trials):
00485             final_pose = p.trial_end.final_centroid
00486             final_orientation = p.trial_end.final_orientation
00487             goal_pose = p.trial_start.goal_pose
00488             if use_spin:
00489                 final_error = abs(subPIAngle(goal_pose.theta - final_orientation))
00490             else:
00491                 
00492                 err_x = goal_pose.x - final_pose.x
00493                 err_y = goal_pose.y - final_pose.y
00494                 final_error = hypot(err_x, err_y)
00495             if file_out is not None:
00496                 trial_line = str(final_error)+'\n'
00497                 file_out.write(trial_line)
00498         if file_out is not None:
00499             file_out.close()
00500 
00501     def get_trial_features(self, file_name, use_spin=False):
00502         self.plio = CombinedPushLearnControlIO()
00503         self.plio.read_in_data_file(file_name)
00504         Y = []
00505         X = []
00506         for i, p in enumerate(self.plio.push_trials):
00507             if use_spin:
00508                 y = self.analyze_spin_push(p)
00509             else:
00510                 y = self.analyze_straight_line_push(p)
00511             if y < 0:
00512                 continue
00513             x = p.trial_start.shape_descriptor
00514             Y.append(y)
00515             X.append(x)
00516         return (X,Y)
00517 
00518     def generate_example_file(self, file_in_name, file_out_name, normalize=False, set_train=False,
00519                               set_test=False, use_spin=False):
00520         (X, Y) = self.get_trial_features(file_in_name, use_spin)
00521         print 'Read in', len(X), 'sample locations'
00522         self.plio.write_example_file(file_out_name, X, Y, normalize)
00523         if set_train:
00524             self.X_train = X[:]
00525             self.Y_train = Y[:]
00526         if set_test:
00527             self.X_test = X[:]
00528             self.Y_test = Y[:]
00529 
00530     def generate_train_and_test_files(self, file_in, file_out, normalize=False, train_percent=0.6,
00531                                       must_move_epsilon=0.05):
00532         (X,Y) = self.get_trial_features(file_in)
00533         Z = zip(X,Y)
00534         
00535         if file_out.endswith('.txt'):
00536             train_file_out = file_out[:-4]+'_train'+'.txt'
00537             test_file_out = file_out[:-4]+'_test'+'.txt'
00538         else:
00539             train_file_out = file_out+'_train'
00540             test_file_out = file_out+'_test'
00541 
00542         
00543         num_train_examples = int(train_percent*len(X))
00544         print 'Read in', len(X), 'examples'
00545         print 'Training file has', num_train_examples, 'examples'
00546         print 'Test file has', len(X)-num_train_examples, 'examples'
00547         self.Y_train = []
00548         self.X_train = []
00549         self.Y_test = []
00550         self.X_test = []
00551 
00552         for i, xy in enumerate(Z):
00553             x = xy[0]
00554             y = xy[1]
00555             if i < num_train_examples:
00556                 self.Y_train.append(y)
00557                 self.X_train.append(x)
00558             else:
00559                 self.Y_test.append(y)
00560                 self.X_test.append(x)
00561         print 'len(Y_train)', len(self.Y_train)
00562         self.plio.write_example_file(train_file_out, self.X_train, self.Y_train, normalize)
00563         print 'len(Y_test)', len(self.Y_test)
00564         self.plio.write_example_file(test_file_out, self.X_test, self.Y_test, normalize)
00565 
00566     def plot_svm_results(self, pred_file):
00567         self.Y_hat = self.plio.read_regression_prediction_file(pred_file)
00568 
00569         max_score = 0.0
00570         Y_test_norm = self.Y_test[:]
00571         Y_hat_norm = self.Y_hat[:]
00572         Y_diffs = []
00573         for i in xrange(len(Y_test_norm)):
00574             
00575             if self.Y_test[i] > max_score:
00576                 max_score = self.Y_test[i]
00577             if self.Y_hat[i] > max_score:
00578                 max_score = self.Y_hat[i]
00579             Y_diffs.append(fabs(self.Y_hat[i]-self.Y_test[i]))
00580         for i in xrange(len(Y_test_norm)):
00581             Y_test_norm[i] = self.Y_test[i]/max_score
00582             Y_hat_norm[i] = self.Y_hat[i]/max_score
00583         print 'Average error is', sum(Y_diffs)/len(Y_diffs)
00584         print 'Max error is', max(Y_diffs)
00585         print 'Min error is', min(Y_diffs)
00586         p1, = plotter.plot(Y_test_norm, Y_hat_norm,'bx')
00587         plotter.xlabel('True Score')
00588         plotter.ylabel('Predicted score')
00589         plotter.title('Push Scoring Evaluation')
00590         plotter.xlim((0.0,1.0))
00591         plotter.ylim((0.0,1.0))
00592         plotter.show()
00593 
00594     def plot_svm_results_old(self, pred_file):
00595         self.Y_hat = self.plio.read_regression_prediction_file(pred_file)
00596 
00597         Ys_ordered = zip(self.Y_test[:], self.Y_hat[:])
00598         Ys_ordered.sort(key=lambda test_value: test_value[0])
00599         Y_test_ordered = []
00600         Y_hat_ordered = []
00601         Y_diffs = []
00602         for Ys in Ys_ordered:
00603             Y_test_ordered.append(Ys[0])
00604             Y_hat_ordered.append(Ys[1])
00605             Y_diffs.append(fabs(Ys[0]-Ys[1]))
00606         print 'Average error is', sum(Y_diffs)/len(Y_diffs)
00607         print 'Max error is', max(Y_diffs)
00608         print 'Min error is', min(Y_diffs)
00609         p1, = plotter.plot(Y_test_ordered,'bx')
00610         p2, = plotter.plot(Y_hat_ordered, 'r+')
00611         plotter.xlabel('Test index')
00612         plotter.ylabel('Straight push score')
00613         plotter.title('Push Scoring Evaluation')
00614         plotter.legend([p1,p2],['True Score', 'Predicted Score'], loc=2)
00615         plotter.show()
00616 
00617     def lookup_push_trial_by_shape_descriptor(self, trials, descriptor):
00618         for t in trials:
00619             match = True
00620             for a,b in zip(t.trial_start.shape_descriptor, descriptor):
00621                 if a != b:
00622                     match = False
00623             if match:
00624                 print t
00625                 return t
00626         return None
00627 
00628     def analyze_straight_line_push_delta_theta(self, push_trial):
00629         '''
00630         Compute the average frame to frame change in orientation while pushing
00631         '''
00632         init_theta = push_trial.trial_start.init_orientation
00633         angle_errs = []
00634         for i, pt in enumerate(push_trial.trial_trajectory):
00635             if i == 0:
00636                 theta_prev = init_theta
00637             else:
00638                 theta_prev = push_trial.trial_trajectory[i-1].x.theta
00639             angle_errs.append(abs(subPIAngle(pt.x.theta - theta_prev)))
00640 
00641         if len(angle_errs) < 1:
00642             return -1
00643         mean_angle_errs = sum(angle_errs)/len(angle_errs)
00644         
00645 
00646         return mean_angle_errs
00647 
00648     def analyze_straight_line_push_line_dist(self, push_trial):
00649         '''
00650         Get the average distance of the current point to the desired straight line path
00651         '''
00652         init_pose = push_trial.trial_start.init_centroid
00653         goal_pose = push_trial.trial_start.goal_pose
00654         init_loc = (init_pose.x, init_pose.y)
00655         goal_loc = (goal_pose.x, goal_pose.y)
00656 
00657         line_dists = []
00658         for i, pt in enumerate(push_trial.trial_trajectory):
00659             cur_pt = (pt.x.x, pt.x.y)
00660             line_dist = point_line_dist(cur_pt, init_loc, goal_loc)
00661             line_dists.append(line_dist)
00662 
00663         if len(line_dists) < 1:
00664             return -1
00665         mean_line_dist = sum(line_dists)/len(line_dists)
00666         return mean_line_dist
00667 
00668     def analyze_straight_line_push_goal_vector_diff(self, push_trial, normalize_score=False):
00669         '''
00670         Get the average angler error between the instantaneous velocity direction of the object and the
00671         direction towards the goal
00672         '''
00673         init_pose = push_trial.trial_start.init_centroid
00674         goal_pose = push_trial.trial_start.goal_pose
00675         final_pose = push_trial.trial_end.final_centroid
00676         push_trial.trial_trajectory
00677         err_x = goal_pose.x - final_pose.x
00678         err_y = goal_pose.y - final_pose.y
00679         final_error =  hypot(err_x, err_y)
00680         total_change = hypot(final_pose.x - init_pose.x, final_pose.y - init_pose.y)
00681         angle_errs = []
00682         init_goal_vector = np.asarray([goal_pose.x - init_pose.x, goal_pose.y - init_pose.y])
00683         init_final_vector = np.asarray([final_pose.x - init_pose.x, final_pose.y - init_pose.y])
00684         final_angle_diff = self.angle_between_vectors(init_goal_vector, init_final_vector)
00685         final_angle_area = 0.5*fabs(init_goal_vector[0]*init_final_vector[1]-
00686                                     init_goal_vector[1]*init_final_vector[0])
00687         for i, pt in enumerate(push_trial.trial_trajectory):
00688             if i == 0:
00689                 continue
00690             prev_pt = push_trial.trial_trajectory[i-1]
00691             goal_vector = np.asarray([goal_pose.x - prev_pt.x.x, goal_pose.y - prev_pt.x.y])
00692             push_vector = np.asarray([pt.x.x - prev_pt.x.x, pt.x.y - prev_pt.x.y])
00693             if hypot(push_vector[0], push_vector[1]) == 0:
00694                 continue
00695             else:
00696                 angle_errs.append(self.angle_between_vectors(goal_vector, push_vector))
00697         mean_angle_errs = sum(angle_errs)/len(angle_errs)
00698         
00699         
00700         if normalize_score:
00701             score = 1.0-mean_angle_errs/pi
00702         else:
00703             score = mean_angle_errs
00704 
00705         return (score, final_error, total_change, final_angle_diff, final_angle_area)
00706 
00707     def analyze_spin_push_total_spin(self, push_trial):
00708         '''
00709         Get the average change in heading aggregated over the entire trial
00710         '''
00711         init_theta = push_trial.trial_start.init_orientation
00712         goal_theta = push_trial.trial_start.goal_pose.theta
00713 
00714         delta_thetas = []
00715         prev_theta = init_theta
00716         for i, pt in enumerate(push_trial.trial_trajectory):
00717             cur_theta = pt.x.theta
00718             delta_thetas.append(abs(cur_theta-prev_theta))
00719             prev_theta = cur_theta
00720 
00721         if len(delta_thetas) < 1:
00722             return -1
00723         mean_delta_theta = sum(delta_thetas)/len(line_dists)
00724         return mean_delta_theta
00725 
00726     def analyze_spin_push_net_spin(self, push_trial):
00727         init_theta = push_trial.trial_start.init_orientation
00728         final_theta = push_trial.trial_end.final_orientation
00729         return abs(subPIAngle(final_theta - init_theta))
00730 
00731     def analyze_spin_push_net_spin_signed(self, push_trial):
00732         init_theta = push_trial.trial_start.init_orientation
00733         final_theta = push_trial.trial_end.final_orientation
00734         return subPIAngle(final_theta - init_theta)
00735 
00736     def angle_between_vectors(self, a, b):
00737         a_dot_b = sum(a*b)
00738         norm_a = hypot(a[0], a[1])
00739         norm_b = hypot(b[0], b[1])
00740         if norm_a == 0 or norm_b == 0:
00741             
00742             return pi
00743         return acos(a_dot_b/(norm_a*norm_b))
00744 
00745     def show_data_affinity(self):
00746         X = self.X_train[:]
00747         X.extend(self.X_test[:])
00748         Y = self.Y_train[:]
00749         Y.extend(self.Y_test[:])
00750         X_aff = np.zeros((len(X),len(X)))
00751         Y_aff = np.zeros((len(Y),len(Y)))
00752         for r in xrange(len(X)):
00753             for c in range(r, len(X)):
00754                 X_aff[r,c] = sum(np.fabs(np.asarray(X[r]) - np.asarray(X[c])))
00755                 Y_aff[r,c] = fabs(Y[r] - Y[c])
00756                 print '(',r,',',c,'): ', X_aff[r,c], '\t', Y_aff[r,c]
00757         plotter.imshow(X_aff, plotter.cm.gray,interpolation='nearest')
00758         plotter.title('Xaff')
00759         plotter.figure()
00760         plotter.imshow(Y_aff, plotter.cm.gray, interpolation='nearest')
00761         plotter.title('Yaff')
00762         plotter.show()
00763         return X_aff,Y_aff
00764 
00765 class BruteForceKNN:
00766     def __init__(self, data):
00767         self.data = data
00768 
00769     def find_k_neighbors(self, element, k=3, comp_func=None):
00770         if comp_func is None:
00771             comp_func = self.xy_dist
00772         k_closest = []
00773         k_dists = []
00774         for d in self.data:
00775             comp_dist = comp_func(element, d)
00776             inserted = False
00777             for i, close in enumerate(k_closest):
00778                 if comp_dist < close:
00779                     k_closest.insert(d, i)
00780                     k_dists.insert(comp_dist,i)
00781                     inserted = True
00782             if not inserted and len(k_closest) < k:
00783                 k_closest.append(d)
00784                 k_dists.append(comp_dist)
00785             elif len(k_closest) > k:
00786                 k_closest = k_closest[:k]
00787                 k_dists = k_dists[:k]
00788         return (k_closest, k_dists)
00789 
00790     def xy_dist(self, a, b):
00791         return hypot(a.init_centroid.x - b.init_centroid.x,
00792                      a.init_centroid.y - b.init_centroid.y)
00793 
00794 class PushLearningAnalysis:
00795 
00796     def __init__(self):
00797         self.raw_data = None
00798         self.io = PushLearningIO()
00799         self.xy_hash_precision = 20.0 
00800         self.num_angle_bins = 8
00801 
00802     def workspace_span(self, push):
00803         
00804         score_fnc = self.compute_push_error_xy
00805         
00806         
00807         for t in self.all_trials:
00808             t.score = score_fnc(t)
00809         knn = BruteForceKNN(self.all_trials)
00810         neighbors, dists = knn.find_k_neighbors(push)
00811         
00812 
00813     
00814     
00815     
00816     def workspace_ranking(self):
00817         
00818         
00819         likelihood_arg=['behavior_primitive','proxy','controller']
00820         score_fnc=self.compute_change_in_push_error_xy
00821         score_fnc=self.compute_push_error_xy
00822         workspace_ranks = self.rank_avg_pushes(trial_hash_fnc=self.hash_push_xy_angle,
00823                                                likelihood_arg=likelihood_arg,
00824                                                mean_push_fnc=self.get_mean_workspace_push,
00825                                                score_fnc=score_fnc)
00826         
00827         for ranks in workspace_ranks:
00828             self.output_push_ranks(ranks,
00829                                    ['init_centroid.x','init_centroid.y','push_angle'],
00830                                    likelihood_arg, n=3)
00831         return workspace_ranks
00832 
00833     def object_ranking(self, use_raw=False, count_successes=True):
00834         '''
00835         Method to find the best performing (on average) behavior_primitive as a function of object_id
00836         '''
00837         cond_arg='object_id'
00838         likelihood_arg=['behavior_primitive','proxy','controller']
00839         
00840         score_fnc=self.compute_push_error_xy
00841         
00842         if use_raw:
00843             rankings = self.rank_raw_pushes(trial_grouping_arg=cond_arg,
00844                                             score_fnc=score_fnc)
00845             print "\Raw object behavior rankings:"
00846             for ranks in rankings:
00847                 self.output_push_ranks(ranks, cond_arg, likelihood_arg, n=5)
00848         elif count_successes:
00849             rankings = self.count_successful_pushes(trial_grouping_arg=cond_arg,
00850                                                     likelihood_arg=likelihood_arg,
00851                                                     score_fnc=score_fnc)
00852             print "\Successful counts for affordance-behaviors on different objects:"
00853             total_good = 0
00854             total_attempts = 0
00855             for ranks in rankings:
00856                 num_good, num_attempts = self.output_push_counts(ranks, cond_arg, likelihood_arg, n=50)
00857                 total_good += num_good
00858                 total_attempts += num_attempts
00859             print 'Total good', total_good
00860             print 'Total attempts', total_attempts
00861         else:
00862             rankings = self.rank_avg_pushes(trial_grouping_arg=cond_arg,
00863                                             likelihood_arg=likelihood_arg,
00864                                             score_fnc=score_fnc)
00865             print "\nObject behavior rankings:"
00866             for ranks in rankings:
00867                 self.output_push_ranks(ranks, cond_arg, likelihood_arg, n=1)
00868         return rankings
00869 
00870     def object_proxy_ranking(self):
00871         '''
00872         Method to find the best performing (on average) behavior_primitive as a function of object_id
00873         '''
00874         cond_arg='object_id'
00875         likelihood_arg='proxy'
00876         
00877         
00878         score_fnc=self.compute_change_in_push_error_xy
00879         rankings = self.rank_avg_pushes(trial_grouping_arg=cond_arg,
00880                                         likelihood_arg=likelihood_arg,
00881                                         score_fnc=score_fnc)
00882         print "\nObject proxy rankings:"
00883         for ranks in rankings:
00884             self.output_push_ranks(ranks, cond_arg, likelihood_arg, n=3)
00885         return rankings
00886 
00887     def angle_ranking(self):
00888         '''
00889         Method to find the best performing (on average) behavior_primitive as a function of push_angle
00890         '''
00891         likelihood_arg=['behavior_primitive','proxy','controller']
00892         angle_ranks = self.rank_avg_pushes(
00893             trial_hash_fnc=self.hash_push_angle, likelihood_arg=likelihood_arg,
00894             mean_push_fnc=self.get_mean_angle_push)
00895         print "Angle push rankings:"
00896         for rank in angle_ranks:
00897             self.output_push_ranks(rank, 'push_angle', likelihood_arg, n=3)
00898         return angle_ranks
00899 
00900     def rank_avg_pushes(self, trial_hash_fnc=None, trial_grouping_arg=None,
00901                         likelihood_arg=None, mean_push_fnc=None,score_fnc=None):
00902         '''
00903         '''
00904         
00905         if score_fnc is None:
00906             score_fnc = self.compute_push_error_xy
00907         for t in self.all_trials:
00908             t.score = score_fnc(t)
00909         
00910         if trial_hash_fnc is not None:
00911             trial_groups = self.group_trials(self.all_trials, hash_function=trial_hash_fnc)
00912         else:
00913             trial_groups = self.group_trials(self.all_trials, trial_grouping_arg)
00914 
00915         
00916         mean_groups = []
00917         for i, group_key in enumerate(trial_groups):
00918             trial_group = trial_groups[group_key]
00919             likelihood_arg_dict = self.group_trials(trial_group, likelihood_arg)
00920             
00921             mean_group = []
00922             for arg_key in likelihood_arg_dict:
00923                 if trial_grouping_arg is not None:
00924                     mean_push = self.get_mean_push(likelihood_arg_dict[arg_key],
00925                                                    trial_grouping_arg, likelihood_arg)
00926                 else:
00927                     mean_push = mean_push_fnc(likelihood_arg_dict[arg_key])
00928                 mean_group.append(mean_push)
00929             mean_groups.append(mean_group)
00930 
00931         
00932         ranked_pushes = []
00933         for i, group in enumerate(mean_groups):
00934             group.sort(compare_pushes)
00935             ranked_pushes.append(group)
00936         return ranked_pushes
00937 
00938     def count_successful_pushes(self, trial_hash_fnc=None, trial_grouping_arg=None,
00939                                 likelihood_arg=None, mean_push_fnc=None,score_fnc=None, score_thresh=0.02):
00940         '''
00941         '''
00942         
00943         if score_fnc is None:
00944             score_fnc = self.compute_push_error_xy
00945         for t in self.all_trials:
00946             t.score = score_fnc(t)
00947         
00948         if trial_hash_fnc is not None:
00949             trial_groups = self.group_trials(self.all_trials, hash_function=trial_hash_fnc)
00950         else:
00951             trial_groups = self.group_trials(self.all_trials, trial_grouping_arg)
00952 
00953         
00954         count_groups = []
00955         for i, group_key in enumerate(trial_groups):
00956             trial_group = trial_groups[group_key]
00957             likelihood_arg_dict = self.group_trials(trial_group, likelihood_arg)
00958             
00959             count_group = []
00960             for arg_key in likelihood_arg_dict:
00961                 push_count = self.get_count_push(likelihood_arg_dict[arg_key],
00962                                                  trial_grouping_arg, likelihood_arg, score_thresh)
00963                 count_group.append(push_count)
00964             count_groups.append(count_group)
00965 
00966         
00967         ranked_pushes = []
00968         for i, group in enumerate(count_groups):
00969             group.sort(compare_counts)
00970             ranked_pushes.append(group)
00971         return ranked_pushes
00972 
00973     def get_successful_pushes(self, trial_hash_fnc=None, trial_grouping_arg=None,
00974                               likelihood_arg=None, mean_push_fnc=None,score_fnc=None, score_thresh=0.02):
00975         '''
00976         '''
00977         
00978         if score_fnc is None:
00979             score_fnc = self.compute_push_error_xy
00980         for t in self.all_trials:
00981             t.score = score_fnc(t)
00982         
00983         if trial_hash_fnc is not None:
00984             trial_groups = self.group_trials(self.all_trials, hash_function=trial_hash_fnc)
00985         else:
00986             trial_groups = self.group_trials(self.all_trials, trial_grouping_arg)
00987 
00988         
00989         count_groups = []
00990         for i, group_key in enumerate(trial_groups):
00991             trial_group = trial_groups[group_key]
00992             likelihood_arg_dict = self.group_trials(trial_group, likelihood_arg)
00993             
00994             count_group = []
00995             for arg_key in likelihood_arg_dict:
00996                 for push in likelihood_arg_dict[arg_key]:
00997                     if push.score < score_thresh:
00998                         count_group.append(push)
00999             count_groups.append(count_group)
01000         return count_groups
01001 
01002     def rank_raw_pushes(self, trial_hash_fnc=None, trial_grouping_arg=None, score_fnc=None):
01003         '''
01004         '''
01005         
01006         if score_fnc is None:
01007             score_fnc = self.compute_push_error_xy
01008         for t in self.all_trials:
01009             t.score = score_fnc(t)
01010         
01011         if trial_hash_fnc is not None:
01012             trial_groups = self.group_trials(self.all_trials, hash_function=trial_hash_fnc)
01013         else:
01014             trial_groups = self.group_trials(self.all_trials, trial_grouping_arg)
01015 
01016         
01017         ranked_pushes = []
01018         for i, group_key in enumerate(trial_groups):
01019             trial_group = trial_groups[group_key]
01020             trial_group.sort(compare_pushes)
01021             ranked_pushes.append(trial_group)
01022         return ranked_pushes
01023 
01024     def get_mean_push(self, arg_list, trial_grouping_arg, likelihood_arg):
01025         mean_push = PushTrial()
01026         mean_score, score_var = self.mean_and_variance(arg_list)
01027         mean_push.score = mean_score
01028         mean_push.var = score_var
01029         if type(trial_grouping_arg) is not list:
01030             trial_grouping_arg = [trial_grouping_arg]
01031         if type(likelihood_arg) is not list:
01032             likelihood_arg = [likelihood_arg]
01033         for arg in trial_grouping_arg:
01034             setattr(mean_push,arg, get_attr(arg_list[0],arg))
01035         for arg in likelihood_arg:
01036             setattr(mean_push,arg, get_attr(arg_list[0],arg))
01037         return mean_push
01038 
01039 
01040     def get_count_push(self, pushes, trial_grouping_arg, likelihood_arg, score_thresh):
01041         count_push = PushTrial()
01042         successful_count = 0
01043         for push in pushes:
01044             if push.score < score_thresh:
01045                 successful_count += 1
01046         count_push.successful_count = successful_count
01047         count_push.total_count = len(pushes)
01048         if type(trial_grouping_arg) is not list:
01049             trial_grouping_arg = [trial_grouping_arg]
01050         if type(likelihood_arg) is not list:
01051             likelihood_arg = [likelihood_arg]
01052         for arg in trial_grouping_arg:
01053             setattr(count_push,arg, get_attr(pushes[0],arg))
01054         for arg in likelihood_arg:
01055             setattr(count_push,arg, get_attr(pushes[0],arg))
01056         return count_push
01057 
01058     def get_mean_angle_push(self, arg_list):
01059         mean_push = PushTrial()
01060         mean_score, score_var = self.mean_and_variance(arg_list)
01061         mean_push.score = mean_score
01062         mean_push.var = score_var
01063         mean_push.push_angle = self.hash_angle(arg_list[0].push_angle)
01064         mean_push.behavior_primitive = arg_list[0].behavior_primitive
01065         mean_push.controller = arg_list[0].controller
01066         mean_push.proxy = arg_list[0].proxy
01067         return mean_push
01068 
01069     def get_mean_workspace_push(self, arg_list):
01070         mean_push = PushTrial()
01071         mean_score, score_var = self.mean_and_variance(arg_list)
01072         mean_push.score = mean_score
01073         mean_push.var = score_var
01074         mean_push.init_centroid.x, mean_push.init_centroid.y = self.hash_xy(
01075             arg_list[0].init_centroid.x, arg_list[0].init_centroid.y)
01076         mean_push.push_angle = self.hash_angle(arg_list[0].push_angle)
01077         mean_push.behavior_primitive = arg_list[0].behavior_primitive
01078         mean_push.controller = arg_list[0].controller
01079         mean_push.proxy = arg_list[0].proxy
01080         mean_push.which_arm = arg_list[0].which_arm
01081         return mean_push
01082 
01083     def mean_and_variance(self, pushes):
01084         n = len(pushes)
01085         mean_score = 0
01086         for push in pushes:
01087             mean_score += push.score
01088         mean_score = mean_score / n
01089 
01090         if n <= 1:
01091             return (mean_score, 0)
01092 
01093         var_sum = 0
01094         for push in pushes:
01095             var_sum += push.score**2
01096         score_var = (var_sum-n*mean_score**2)/(n-1)
01097 
01098         return (mean_score, score_var)
01099     
01100     
01101     
01102     def group_trials(self, all_trials, hash_attribute=None, hash_function=None):
01103         group_dict = {}
01104         
01105         for t in all_trials:
01106             if hash_function is not None:
01107                 group_key = hash_function(t)
01108             elif type(hash_attribute) == list and len(hash_attribute) > 1:
01109                 group_key = []
01110                 for attr in hash_attribute:
01111                     group_key.append(get_attr(t,attr))
01112                 group_key = tuple(group_key)
01113             elif type(hash_attribute) == list:
01114                 group_key = get_attr(t, hash_attribute[0])
01115             else:
01116                 group_key = get_attr(t, hash_attribute)
01117             try:
01118                 group_dict[group_key].append(t)
01119             except KeyError:
01120                 group_dict[group_key] = [t]
01121         return group_dict
01122 
01123     def group_trials_by_xy_and_push_angle(self, all_trials):
01124         '''
01125         Method to group all trials by initial table location and push angle
01126         '''
01127         groups = {}
01128         
01129         for t in all_trials:
01130             angle_key = self.hash_angle(t.push_angle)
01131             x_key, y_key = self.hash_xy(t.init_centroid.x, t.init_centroid.y)
01132             group_key = (x_key, y_key, angle_key)
01133             try:
01134                 groups[group_key].append(t)
01135             except KeyError:
01136                 groups[group_key] = [t]
01137         return groups
01138 
01139     def group_trials_by_push_angle(self, all_trials):
01140         '''
01141         Method to group all trials by initial table location and push angle
01142         '''
01143         return self.group_trials(all_trials, hash_function=self.hash_push_angle)
01144 
01145     def group_trials_by_xy(self, all_trials):
01146         '''
01147         Method to group all trials by initial table location and push angle
01148         '''
01149         xy_dict = {}
01150         for t in all_trials:
01151             xy_key = self.hash_xy(t.init_centroid.x, t.init_centroid.y)
01152             
01153             try:
01154                 xy_dict[xy_key].append(t)
01155             except KeyError:
01156                 xy_dict[xy_key] = [t]
01157         return xy_dict
01158     
01159     
01160     
01161     def visualize_push_choices(self, ranks, score_threshold=None, object_id=None):
01162         choices = []
01163         for rank in ranks:
01164             choices.append(rank[0])
01165         
01166         disp_img = cv2.imread('/u/thermans/Dropbox/Data/choose_push/use_for_display.png')
01167 
01168         xy_groups = self.group_trials_by_xy(choices)
01169 
01170         for group_key in xy_groups:
01171             disp_img = self.draw_push_choices_on_image(xy_groups[group_key], disp_img,
01172                                                        score_threshold=score_threshold)
01173         cv2.imshow('Chosen pushes', disp_img)
01174         file_name = '/u/thermans/Desktop/push_learn_out'
01175         if object_id is not None:
01176             file_name += '_'+object_id
01177         if score_threshold is not None:
01178             file_name += '_'+str(score_threshold)
01179 
01180         file_name += '.png'
01181         cv2.imwrite(file_name, disp_img)
01182         cv2.waitKey()
01183 
01184     def draw_push_choices_on_image(self, choices, img, score_threshold=None):
01185         
01186         
01187         K = np.matrix([[525, 0, 319.5, 0.0],
01188                        [0, 525, 239.5, 0.0],
01189                        [0, 0, 1, 0.0]])
01190         tl = np.asarray([-0.0115423, 0.441939, 0.263569])
01191         q = np.asarray([0.693274, -0.685285, 0.157732, 0.157719])
01192         num_downsamples = 0
01193         table_height = -0.3
01194         P_w = np.matrix([[choices[0].init_centroid.x], [choices[0].init_centroid.y],
01195                          [table_height], [1.0]])
01196         
01197         T = (np.matrix(tr.translation_matrix(tl)) *
01198              np.matrix(tr.quaternion_matrix(q)))
01199         P_c = T*P_w
01200         
01201         P_i = K*P_c
01202         P_i = P_i / P_i[2]
01203         u = P_i[0]/pow(2,num_downsamples)
01204         v = P_i[1]/pow(2,num_downsamples)
01205 
01206         valid_choices = 0
01207         for c in choices:
01208             if score_threshold is None:
01209                 valid_choices += 1
01210             elif c.score < score_threshold:
01211                 valid_choices += 1
01212         if valid_choices == 0:
01213             return img
01214         
01215         radius = 13
01216         cv2.circle(img, (u,v), 3, [0.0,0.0,0.0],3)
01217         cv2.circle(img, (u,v), 3, [255.0,255.0,255.0], 1)
01218         
01219         for c in choices:
01220             if score_threshold is None:
01221                 pass
01222             elif c.score > score_threshold:
01223                 continue
01224             end_point = (u-sin(c.push_angle)*(radius), v-cos(c.push_angle)*(radius))
01225             color = [0.0, 0.0, 0.0] 
01226             
01227         for c in choices:
01228             if score_threshold is None:
01229                 pass
01230             elif c.score > score_threshold:
01231                 continue
01232             
01233             if True or c.which_arm == 'l':
01234                 if c.behavior_primitive == GRIPPER_PUSH:
01235                     color = [255.0, 0.0, 0.0] 
01236                 elif c.behavior_primitive == GRIPPER_SWEEP:
01237                     color = [0.0, 255.0, 0.0] 
01238                 elif c.behavior_primitive == OVERHEAD_PUSH:
01239                     color = [0.0, 0.0, 255.0] 
01240                 elif c.behavior_primitive == GRIPPER_PULL:
01241                     color = [0.0, 255.0, 255.0] 
01242                 
01243             else:
01244                 if c.behavior_primitive == GRIPPER_PUSH:
01245                     color = [128.0, 0.0, 128.0] 
01246                 elif c.behavior_primitive == GRIPPER_SWEEP:
01247                     color = [0.0, 64.0, 129.0] 
01248                 elif c.behavior_primitive == OVERHEAD_PUSH:
01249                     color = [128.0, 128.0, 0.0] 
01250                 elif c.behavior_primitive == GRIPPER_PULL:
01251                     color = [200.0, 200.0, 200.0] 
01252                 
01253             
01254             end_point = (u-sin(c.push_angle)*(radius), v-cos(c.push_angle)*(radius))
01255             cv2.line(img, (u,v), end_point, color, 2)
01256         return img
01257 
01258     def visualize_angle_push_choices(self, ranks, score_threshold=None):
01259         choices = []
01260         for rank in ranks:
01261             choices.append(rank[0])
01262         
01263         disp_img = cv2.imread('/u/thermans/Dropbox/Data/choose_push/use_for_display.png')
01264 
01265         
01266 
01267         for x in x_locs:
01268             for y in y_locs:
01269                 for c in choices:
01270                     c.init_centroid.x = x
01271                     c.init_centroid.y = y
01272                     disp_img = self.draw_push_choices_on_image(choices,
01273                                                                disp_img,
01274                                                                score_threshold=score_threshold)
01275         cv2.imshow('Chosen pushes', disp_img)
01276         cv2.imwrite('/u/thermans/Desktop/push_learn_angle_out.png', disp_img)
01277         cv2.waitKey()
01278 
01279     
01280     
01281     
01282     def read_in_push_trials(self, file_name, object_id=None):
01283         self.all_trials = []
01284         object_ids = {}
01285         if object_id is not None:
01286             all_trials = self.io.read_in_data_file(file_name)
01287             for t in all_trials:
01288                 if t.object_id in object_ids:
01289                     pass
01290                 else:
01291                     object_ids[t.object_id] = t.object_id
01292                     print "object_id is:", t.object_id
01293                 if object_id == t.object_id:
01294                     self.all_trials.append(t)
01295         else:
01296             self.all_trials = self.io.read_in_data_file(file_name)
01297 
01298 
01299 
01300     def output_push_choice(self, c, conditional_value, arg_value):
01301         '''
01302         Method takes strings [or lists of strings] of what attributes of PushTrail instance c to display
01303         '''
01304         if type(conditional_value) == list:
01305             conditional_str = ''
01306             for val in conditional_value:
01307                 conditional_str += str(get_attr(c,val))+', '
01308             conditional_str = conditional_str[:-2]
01309         else:
01310             conditional_str = str(get_attr(c,conditional_value))
01311         if type(arg_value) == list:
01312             arg_str = ''
01313             for val in arg_value:
01314                 arg_str += str(get_attr(c,val))+', '
01315             arg_str = arg_str[:-2]
01316         else:
01317             arg_str = str(get_attr(c,arg_value))
01318         print 'Choice for (' +  conditional_str + '): ('+ arg_str+ ') : ' + str(c.score) + ', ' + str(c.var)
01319 
01320     def output_push_ranks(self, ranks, conditional_value, arg_value, n=3):
01321         '''
01322         Method takes strings [or lists of strings] of what attributes of PushTrail instance c to display
01323         '''
01324         if len(ranks) == 0:
01325             return
01326         if type(conditional_value) == list:
01327             conditional_str = ''
01328             for val in conditional_value:
01329                 conditional_str += str(get_attr(ranks[0], val))+', '
01330             conditional_str = conditional_str[:-2]
01331         else:
01332             conditional_str = str(get_attr(ranks[0], conditional_value))
01333         
01334         for i, c in enumerate(ranks):
01335             if i >= n:
01336                 break
01337             if type(arg_value) == list:
01338                 arg_str = ''
01339                 for val in arg_value:
01340                     arg_str += str(get_attr(c,val))+', '
01341                 arg_str = arg_str[:-2]
01342             else:
01343                 arg_str = str(get_attr(c,arg_value))
01344             
01345 
01346     def output_push_counts(self, ranks, conditional_value, arg_value, n=3):
01347         '''
01348         Method takes strings [or lists of strings] of what attributes of PushTrail instance c to display
01349         '''
01350         total_good = 0
01351         total_attempts = 0
01352         if len(ranks) == 0:
01353             return
01354         if type(conditional_value) == list:
01355             conditional_str = ''
01356             for val in conditional_value:
01357                 conditional_str += str(get_attr(ranks[0], val))+', '
01358             conditional_str = conditional_str[:-2]
01359         else:
01360             conditional_str = str(get_attr(ranks[0], conditional_value))
01361         print conditional_str + ''
01362         for i, c in enumerate(ranks):
01363             if i >= n:
01364                 break
01365             if type(arg_value) == list:
01366                 arg_str = ''
01367                 for val in arg_value:
01368                     arg_str += str(get_attr(c,val))+' & '
01369                 arg_str = arg_str[:-3]
01370             else:
01371                 arg_str = str(get_attr(c,arg_value))
01372             if c.successful_count > 0:
01373                 total_good += c.successful_count
01374                 total_attempts += c.total_count
01375             
01376         
01377         
01378         return total_good, total_attempts
01379     def output_loc_push_choices(self, choices):
01380         print "Loc push choices:"
01381         for c in choices:
01382             self.output_push_choice(c, ['init_centroid.x','init_centroid.y','push_angle'],
01383                                     ['behavior_primitive','controller','proxy'])
01384 
01385     
01386     
01387     
01388 
01389     def hash_push_angle(self, push):
01390         return self.hash_angle(push.push_angle)
01391 
01392     def hash_push_xy_angle(self, push):
01393         x_prime, y_prime = self.hash_xy(push.init_centroid.x, push.init_centroid.y)
01394         return (x_prime, y_prime, self.hash_angle(push.push_angle))
01395 
01396     def hash_angle(self, theta):
01397         
01398         bin = int((theta + pi)/(2.0*pi)*self.num_angle_bins)
01399         bin = max(min(bin, self.num_angle_bins-1), 0)
01400         return -pi+(2.0*pi)*float(bin)/self.num_angle_bins
01401 
01402     def hash_xy(self, x,y):
01403         
01404         x_prime = (round(x*self.xy_hash_precision)-1)/self.xy_hash_precision
01405         y_prime = (round(y*self.xy_hash_precision)-1)/self.xy_hash_precision
01406         return (x_prime, y_prime)
01407 
01408     
01409     
01410     
01411 
01412     def compute_push_error_xy(self, push):
01413         err_x = push.goal_pose.x - push.final_centroid.x
01414         err_y = push.goal_pose.y - push.final_centroid.y
01415         return hypot(err_x,err_y)
01416 
01417     def compute_change_in_push_error_xy(self, push):
01418         init_x_error = push.goal_pose.x - push.init_centroid.x
01419         init_y_error = push.goal_pose.y - push.init_centroid.y
01420         final_x_error = push.goal_pose.x - push.final_centroid.x
01421         final_y_error = push.goal_pose.y - push.final_centroid.y
01422 
01423         if push.final_centroid == 0.0 and push.final_centroid.y == 0.0:
01424             print 'Knocked off object'
01425             return 100.0
01426         init_error = hypot(init_x_error, init_y_error)
01427         final_error = hypot(final_x_error, final_y_error)
01428         return final_error / init_error
01429 
01430     def compute_push_error_push_dist_diff(self, push):
01431         desired_x = push.init_centroid.x + cos(push.push_angle)*push.push_dist
01432         desired_y = push.init_centroid.y + sin(push.push_angle)*push.push_dist
01433         d_x = push.final_centroid.x - push.init_centroid.x
01434         d_y = push.final_centroid.y - push.init_centroid.y
01435         actual_dist = sqrt(d_x*d_x + d_y*d_y)
01436         return fabs(actual_dist - push.push_dist)
01437 
01438     def compute_normalized_push_time(self, push):
01439         return push.push_time / push.push_dist
01440 
01441 
01442 def get_attr(instance, attribute):
01443     '''
01444     A wrapper for the builtin python getattr which handles recursive attributes of attributes
01445     '''
01446     attr_list = attribute.split('.')
01447     def get_nested_attr(instance, attr_list):
01448         if len(attr_list) == 1:
01449             return getattr(instance, attr_list[0])
01450         return get_nested_attr(getattr(instance, attr_list[0]), attr_list[1:])
01451     return get_nested_attr(instance, attr_list)
01452 
01453 def compare_pushes(a, b):
01454     if a.score < b.score:
01455         return -1
01456     elif a.score > b.score:
01457         return 1
01458     else:
01459         return 0
01460 
01461 def compare_counts(a, b):
01462     if a.successful_count > b.successful_count:
01463         return -1
01464     elif a.successful_count < b.successful_count:
01465         return 1
01466     else:
01467         return 0
01468 
01469 def plot_controller_results(file_name, spin=False):
01470     
01471     io = ControlAnalysisIO()
01472     controls = io.read_in_data_file(file_name)
01473     XS = [c.x.x for c in controls]
01474     YS = [c.x.y for c in controls]
01475     Thetas = [c.x.y for c in controls]
01476     init_x = XS[0]
01477     init_y = YS[0]
01478     goal_x = controls[0].x_desired.x
01479     goal_y = controls[0].x_desired.y
01480     goal_theta = controls[0].x_desired.theta
01481     plotter.figure()
01482     plotter.plot(XS,YS)
01483     plotter.scatter(XS,YS)
01484     ax = plotter.gca()
01485     print ylim()
01486     print ax.set_xlim(xlim()[1]-(ylim()[1]-ylim()[0]), xlim()[1])
01487     headings = [plotter.Arrow(c.x.x, c.x.y, cos(c.x.theta)*0.01, sin(c.x.theta)*0.01, 0.05, axes=ax) for c in controls]
01488     arrows = [ax.add_patch(h) for h in headings]
01489     init_arrow = plotter.Arrow(controls[0].x.x, controls[0].x.y,
01490                                cos(controls[0].x.theta)*0.01,
01491                                sin(controls[0].x.theta)*0.01, 0.05,
01492                                axes=ax, facecolor='red')
01493     goal_arrow = plotter.Arrow(controls[0].x_desired.x, controls[0].x_desired.y,
01494                                cos(controls[0].x_desired.theta)*0.01,
01495                                sin(controls[0].x_desired.theta)*0.01, 0.05,
01496                                axes=ax, facecolor='green')
01497     ax.add_patch(goal_arrow)
01498     ax.add_patch(init_arrow)
01499     plotter.scatter(init_x, init_y, c='r')
01500     plotter.scatter(goal_x, goal_y, c='g')
01501     plotter.xlabel('x (meters)')
01502     plotter.ylabel('y (meters)')
01503     plotter.title('Tracker Ouput')
01504     plotter.savefig('/home/thermans/sandbox/tracker-output.png')
01505     plotter.figure()
01506     ux = [c.u.linear.x for c in controls]
01507     uy = [c.u.linear.y for c in controls]
01508     if spin:
01509         uy = [c.u.linear.z for c in controls]
01510     plotter.plot(ux)
01511     plotter.plot(uy)
01512     plotter.xlabel('Time')
01513     plotter.ylabel('Velocity (m/s)')
01514     plotter.legend(['u_x', 'u_y'])
01515     plotter.title('Feedback Controller - Input Velocities')
01516     plotter.savefig('/home/thermans/sandbox/feedback-input.png')
01517     plotter.figure()
01518     xdots = [c.x_dot.x for c in controls]
01519     ydots = [c.x_dot.y for c in controls]
01520     plotter.plot(xdots)
01521     plotter.plot(ydots)
01522     plotter.xlabel('Time')
01523     plotter.ylabel('Velocity (m/s)')
01524     plotter.title('Tracker Velocities')
01525     plotter.legend(['x_dot', 'y_dot'])
01526     plotter.savefig('/home/thermans/sandbox/tracker-velocities.png')
01527     plotter.figure()
01528     thetadots = [c.x_dot.theta for c in controls]
01529     plotter.plot(thetadots,c='r')
01530     plotter.xlabel('Time')
01531     plotter.ylabel('Velocity (rad/s)')
01532     plotter.title('Tracker Velocities')
01533     plotter.legend(['theta_dot'])
01534     plotter.savefig('/home/thermans/sandbox/tracker-theta-vel.png')
01535     plotter.figure()
01536     x_err = [c.x_desired.x - c.x.x for c in controls]
01537     y_err = [c.x_desired.y - c.x.y for c in controls]
01538     plotter.plot(x_err)
01539     plotter.plot(y_err)
01540     plotter.xlabel('Time')
01541     plotter.ylabel('Error (meters)')
01542     plotter.title('Position Error')
01543     plotter.legend(['x_err', 'y_err'])
01544     plotter.savefig('/home/thermans/sandbox/pos-err.png')
01545     plotter.figure()
01546     if spin:
01547         theta_err = [c.x_desired.theta - c.x.theta for c in controls]
01548     else:
01549         theta_err = [c.theta0 - c.x.theta for c in controls]
01550     plotter.plot(theta_err, c='r')
01551     plotter.xlabel('Time')
01552     plotter.ylabel('Error (radians)')
01553     if spin:
01554         plotter.title('Error in Orientation')
01555     else:
01556         plotter.title('Heading Deviation from Initial')
01557     plotter.savefig('/home/thermans/sandbox/theta-err.png')
01558     plotter.show()
01559 
01560 def plot_junk():
01561     
01562     req_object_id = None
01563     thresh = 1.0
01564     
01565     if len(sys.argv) > 1:
01566         data_path = str(sys.argv[1])
01567     else:
01568         print 'Usage:',sys.argv[0],'input_file [object_id] [distance_thresh]'
01569         quit()
01570     if len(sys.argv) > 2:
01571         req_object_id = str(sys.argv[2])
01572         if req_object_id == "None":
01573             req_object_id = None
01574     if len(sys.argv) > 3:
01575         thresh = float(sys.argv[3])
01576         print "thresh:", thresh
01577 
01578     pla = PushLearningAnalysis()
01579     pla.read_in_push_trials(data_path, req_object_id)
01580 
01581     
01582     workspace_ranks = pla.workspace_ranking()
01583     pla.visualize_push_choices(workspace_ranks, thresh, object_id=req_object_id)
01584     
01585     
01586     
01587     print 'Num trials: ' + str(len(pla.all_trials))
01588 
01589 def read_example_file(file_name):
01590     data_in = file(file_name, 'r')
01591     lines = [l.split() for l in data_in.readlines()]
01592     data_in.close()
01593     Y = []
01594     X = []
01595     for line in lines:
01596         y = float(line.pop(0))
01597         Y.append(y)
01598         x = []
01599         for pair in line:
01600             idx, val = pair.split(':')
01601             idx = int(idx) - 1
01602             val = float(val)
01603             while len(x) < idx:
01604                 x.append(0)
01605             x.append(val)
01606         X.append(x)
01607     return (X,Y)
01608 
01609 def read_feature_file(file_name):
01610     data_in = file(file_name, 'r')
01611     lines = [l.split() for l in data_in.readlines()]
01612     data_in.close()
01613     X = []
01614     for line in lines:
01615         x = []
01616         for val in line:
01617             x.append(float(val))
01618         X.append(x)
01619     return X
01620 
01621 def write_example_file(file_name, X, Y, normalize=False, debug=False):
01622     data_out = file(file_name, 'w')
01623     
01624     i = 0
01625     for x,y in zip(X,Y):
01626         i += 1
01627         if debug:
01628             print y, x
01629         if isnan(y):
01630             print 'Skipping writing example: ', i
01631             continue
01632         data_line = str(y)
01633         if normalize:
01634             feature_sum = 0.0
01635             for xi in x:
01636                 feature_sum += xi
01637             for i, xi in enumerate(x):
01638                 if xi > 0:
01639                     data_line += ' ' + str(i+1)+':'+str(sqrt(xi/float(feature_sum)))
01640         else:
01641             for i, xi in enumerate(x):
01642                 if xi > 0:
01643                     data_line += ' ' + str(i+1)+':'+str(xi)
01644         data_line +='\n'
01645         data_out.write(data_line)
01646     data_out.close()
01647     return (X,Y)
01648 
01649 def rewrite_example_file_features(original_file_name, feat_file_name, out_file_name, normalize=False, debug=False):
01650     old_X, Y = read_example_file(original_file_name)
01651     X = read_feature_file(feat_file_name)
01652     write_example_file(out_file_name, X, Y, normalize, debug)
01653 
01654 def extract_shape_features_batch():
01655   base_dir = '/home/thermans/Dropbox/Data/ichr2013-results/icdl_data/'
01656   class_dirs = ['camcorder3', 'food_box3', 'large_brush3', 'small_brush3','soap_box3', 'toothpaste3']
01657   
01658   
01659   base_dir = '/home/thermans/Dropbox/Data/ichr2013-results/rotate_to_heading_train_and_validate/'
01660   class_dirs = ['camcorder0', 'food_box0', 'large_brush0', 'small_brush0','soap_box0', 'toothpaste0']
01661 
01662   out_dir = base_dir+'examples_line_dist/'
01663   feat_dir = base_dir+'examples_line_dist/'
01664 
01665   for c in class_dirs:
01666       print 'Class:', c
01667       class_dir = base_dir+c+'/'
01668       files = os.listdir(class_dir)
01669       data_file = None
01670       for f in files:
01671           if f.startswith('aff_learn_out'):
01672               data_file = f
01673       if data_file is None:
01674           print 'ERROR: No data file in directory:', c
01675           continue
01676       aff_file = class_dir+data_file
01677       score_file = base_dir+'example_files/'+c+'.txt'
01678       
01679       file_out = base_dir+'analysis/'+c+'_gt_scores.png'
01680       print '/home/thermans/src/gt-ros-pkg/cpl/tabletop_pushing/bin/extract_shape_features', aff_file, \
01681           class_dir, file_out, score_file
01682       p = subprocess.Popen(['/home/thermans/src/gt-ros-pkg/cpl/tabletop_pushing/bin/extract_shape_features',
01683                             aff_file, class_dir, file_out, score_file], shell=False)
01684       p.wait()
01685 
01686 def read_and_score_raw_files():
01687   
01688   
01689   
01690   base_dir = '/home/thermans/Dropbox/Data/ichr2013-results/rotate_to_heading_train_and_validate/'
01691   class_dirs = ['camcorder0', 'food_box0', 'large_brush0', 'small_brush0','soap_box0', 'toothpaste0']
01692   out_dir = base_dir+'example_files/'
01693   use_spin = True
01694   for i, c in enumerate(class_dirs):
01695       in_dir = base_dir+c+'/'
01696       files = os.listdir(in_dir)
01697       file_name = None
01698       for f in files:
01699           if f.startswith('aff_learn_out'):
01700               file_name = f
01701       if file_name is None:
01702           continue
01703       file_in = in_dir+file_name
01704       file_out = out_dir+c+'.txt'
01705       print 'Out file:', file_out
01706       slp = StartLocPerformanceAnalysis()
01707       slp.generate_example_file(file_in, file_out, use_spin=use_spin)
01708 
01709 def compare_predicted_and_observed_push_scores(in_file_name, out_file_name=None, use_spin=False):
01710     slp = StartLocPerformanceAnalysis()
01711     slp.compare_predicted_and_observed_push_scores(in_file_name, out_file_name, use_spin)
01712 
01713 def compute_predicted_and_observed_push_scores(in_file_name, out_file_name=None, use_spin=False):
01714     slp = StartLocPerformanceAnalysis()
01715     slp.compute_observed_push_scores_final_errors(in_file_name, out_file_name, use_spin)
01716 
01717 def analyze_predicted_and_observed_batch():
01718   
01719   
01720   
01721   base_dir = '/home/thermans/Dropbox/Data/ichr2013-results/rotate_to_heading_rand_results/'
01722   
01723   class_dirs = ['camcorder0', 'food_box0', 'large_brush0', 'small_brush0','soap_box0', 'toothpaste0']
01724   out_dir = base_dir+'analysis/'
01725   use_spin = True
01726 
01727   for c in class_dirs:
01728       in_dir = base_dir+c+'/'
01729       files = os.listdir(in_dir)
01730       file_name = None
01731       for f in files:
01732           if f.startswith('aff_learn_out'):
01733               file_name = f
01734       if file_name is None:
01735           continue
01736       file_in = in_dir+file_name
01737       file_out = out_dir+c+'.txt'
01738       file_out_final_error = out_dir+c+'-final-error.txt'
01739       compare_predicted_and_observed_push_scores(file_in, file_out, use_spin)
01740       compute_predicted_and_observed_push_scores(file_in, file_out_final_error, use_spin)
01741 
01742 def rank_straw_scores(file_path):
01743     straw_file = file(file_path, 'r')
01744     lines = [l.split() for l in straw_file.readlines()]
01745     scores = [float(l[0])*100 for l in lines]
01746     major_dists = [float(l[1]) for l in lines]
01747     minor_dists = [float(l[2]) for l in lines]
01748     min_major_dist = 10000
01749     major_dist_idx = 0
01750     min_minor_dist = 10000
01751     minor_dist_idx = 0
01752     for i in xrange(len(major_dists)):
01753         if major_dists[i] < min_major_dist:
01754             min_major_dist = major_dists[i]
01755             major_dist_idx = i
01756         if minor_dists[i] < min_minor_dist:
01757             min_minor_dist = minor_dists[i]
01758             minor_dist_idx = i
01759     major_score = scores[major_dist_idx]
01760     minor_score = scores[minor_dist_idx]
01761     scores.sort()
01762     print 'Major idx score: ' + str(major_score) + ' is ranked ' + str(scores.index(major_score)+1)
01763     print 'Minor idx score: ' + str(minor_score) + ' is ranked ' + str(scores.index(minor_score)+1)
01764     print 'Scores are: ' + str(scores)
01765 
01766 def rank_straw_scores_batch():
01767   base_dir = '/home/thermans/Dropbox/Data/start_loc_learning/point_push/major_minor_axis_point_data/'
01768   classes = ['camcorder3', 'food_box3', 'large_brush3', 'small_brush3','soap_box3', 'toothpaste3']
01769   for c in classes:
01770       file_path = base_dir + 'straw_scores_' + c + '.txt'
01771       print 'Ranks for: ', c
01772       rank_straw_scores(file_path)
01773       print '\n'
01774 
01775 def convert_robot_attempts_to_example_file(in_file_name, out_file_name):
01776     scores = []
01777     feats = []
01778     loc = []
01779     in_file = file(in_file_name,'r')
01780     raw_lines = in_file.readlines()
01781     in_file.close()
01782     for i, l in enumerate(raw_lines):
01783         line = l.split()
01784         loc.append((float(line[0]), float(line[1])))
01785         scores.append(float(line[2]))
01786         feats.append([float(f) for f in line[3:]])
01787         print i, len(feats[i])
01788     normalize = False
01789     debug = False
01790     return write_example_file(out_file_name, feats, scores, normalize, debug)
01791 
01792 def convert_robot_attempts_file_batch():
01793     pass
01794 
01795 def rank_straw_scores(file_path):
01796     straw_file = file(file_path, 'r')
01797     lines = [l.split() for l in straw_file.readlines()]
01798     scores = [float(l[0])*100 for l in lines]
01799     major_dists = [float(l[1]) for l in lines]
01800     minor_dists = [float(l[2]) for l in lines]
01801     min_major_dist = 10000
01802     major_dist_idx = 0
01803     min_minor_dist = 10000
01804     minor_dist_idx = 0
01805     for i in xrange(len(major_dists)):
01806         if major_dists[i] < min_major_dist:
01807             min_major_dist = major_dists[i]
01808             major_dist_idx = i
01809         if minor_dists[i] < min_minor_dist:
01810             min_minor_dist = minor_dists[i]
01811             minor_dist_idx = i
01812     major_score = scores[major_dist_idx]
01813     minor_score = scores[minor_dist_idx]
01814     scores.sort()
01815     print 'Major idx score: ' + str(major_score) + ' is ranked ' + str(scores.index(major_score)+1)
01816     print 'Minor idx score: ' + str(minor_score) + ' is ranked ' + str(scores.index(minor_score)+1)
01817     print 'Scores are: ' + str(scores)
01818 
01819 def rank_straw_scores_batch():
01820   base_dir = '/home/thermans/Dropbox/Data/start_loc_learning/point_push/major_minor_axis_point_data/'
01821   classes = ['camcorder3', 'food_box3', 'large_brush3', 'small_brush3','soap_box3', 'toothpaste3']
01822   for c in classes:
01823       file_path = base_dir + 'straw_scores_' + c + '.txt'
01824       print 'Ranks for: ', c
01825       rank_straw_scores(file_path)
01826       print '\n'
01827 
01828 if __name__ == '__main__':
01829     analyze_predicted_and_observed_batch()
01830     
01831     
01832