Beispiel #1
0
def polyapprox(shape, s):
    ss = shape[0]
    accu = []
    length = 0
    for i in range(len(ss)):
        accu.append(
            norm(np.array(ss[(i + 1) % len(ss)]) - np.array(ss[i])) + length)
        length = accu[-1]
    targetlength = s * length
    ind = 0

    for i in range(len(ss)):
        if accu[i] > targetlength:
            ind = i
            break

    seglength = norm(np.array(ss[(ind + 1) % len(ss)]) - np.array(ss[ind]))
    t = (targetlength - accu[ind]) / seglength
    pos = np.array(ss[ind]) * (1 - t) + np.array(ss[(ind + 1) % len(ss)]) * t
    pos = np.append(pos, [0])
    tangent = np.array(ss[(ind + 1) % len(ss)]) - np.array(ss[ind])
    normal = np.array([tangent[1], -tangent[0]])
    normal = normal / norm(normal)  # normalize it
    normal = np.append(normal, [0])
    return (pos, normal)
Beispiel #2
0
def polyapprox_check_collision(shape, pos_start_probe_object, probe_radius):
    ss = shape[0]
    # find the closest point on the shape to pos_start_probe_object
    min_dist = 10000
    min_ind = 0
    safety_margin = 0.005
    for i in range(len(ss)):
        dist = norm(np.array(ss[i]) - np.array(pos_start_probe_object[0:2]))
        if dist < min_dist:
            min_dist = dist
            min_ind = i
            
    tangent = np.array(ss[(min_ind+1) % len(ss)])-np.array(ss[min_ind])
    normal = np.array([tangent[1], -tangent[0]]) # pointing out of shape
    normal = normal / norm(normal)  # normalize it
    d = np.dot(normal, np.array(pos_start_probe_object[0:2]) - np.array(ss[min_ind]) )
    if d < probe_radius + safety_margin:
        return True
    else:
        return False
def polyapprox_check_collision(shape, pos_start_probe_object, probe_radius):
    ss = shape[0]
    # find the closest point on the shape to pos_start_probe_object
    min_dist = 10000
    min_ind = 0
    safety_margin = 0.005
    for i in range(len(ss)):
        dist = norm(np.array(ss[i]) - np.array(pos_start_probe_object[0:2]))
        if dist < min_dist:
            min_dist = dist
            min_ind = i
            
    tangent = np.array(ss[(min_ind+1) % len(ss)])-np.array(ss[min_ind])
    normal = np.array([tangent[1], -tangent[0]]) # pointing out of shape
    normal = normal / norm(normal)  # normalize it
    d = np.dot(normal, np.array(pos_start_probe_object[0:2]) - np.array(ss[min_ind]) )
    if d < probe_radius + safety_margin:
        return True
    else:
        return False
def polyapprox(shape, s):
    ss = shape[0]
    accu = []
    length = 0
    for i in range(len(ss)):
        accu.append(norm(np.array(ss[(i+1) % len(ss)])-np.array(ss[i])) + length)
        length = accu[-1]
    targetlength = s*length
    ind = 0
    
    for i in range(len(ss)):
        if accu[i] > targetlength:
            ind = i
            break
    
    seglength = norm(np.array(ss[(ind+1) % len(ss)])-np.array(ss[ind]))
    t = (targetlength-accu[ind]) / seglength
    pos = np.array(ss[ind]) * (1-t) +  np.array(ss[(ind+1) % len(ss)]) * t
    pos = np.append(pos, [0])
    tangent = np.array(ss[(ind+1) % len(ss)])-np.array(ss[ind])
    normal = np.array([tangent[1], -tangent[0]]) 
    normal = normal / norm(normal)  # normalize it
    normal = np.append(normal, [0])
    return (pos, normal)
Beispiel #5
0
def run_it(accelerations, speeds, shape, nside, side_params, angles, nrep, shape_type, probe_radius, dir_save_bagfile, dist_after_contact, allowed_distance, opt):
    # hack to restart the script to prevent ros network issues.
    global pub
    limit = 100
    cnt = 0
    topics = ['-a']
    
    # enumerate the possible trajectories
    for cnt_acc, acc in enumerate(accelerations):
        # enumerate the side we want to push
        for i in range(nside):
            # enumerate the contact point that we want to push
            for s in side_params:
                if shape_type == 'poly':
                    pos = np.array(shape[i]) *(1-s) + np.array(shape[(i+1) % len(shape)]) *(s)
                    pos = np.append(pos, [0])
                    tangent = np.array(shape[(i+1) % len(shape)]) - np.array(shape[i])
                    normal = np.array([tangent[1], -tangent[0]]) 
                    normal = normal / norm(normal)  # normalize it
                    normal = np.append(normal, [0])
                elif shape_type == 'ellip':
                    (a,b) = shape[0][0], shape[0][1]
                    pos = [shape[0][0] * np.cos(s*2*np.pi), shape[0][1] * np.sin(s*2*np.pi), 0]
                    normal = [np.cos(s*2*np.pi)/a, np.sin(s*2*np.pi)/b, 0]
                    normal = normal / norm(normal)  # normalize it
                elif shape_type == 'polyapprox':
                    pos, normal = polyapprox(shape, s)
                    
                # enumerate the direction in which we want to push
                for t in angles:
                    for rep in xrange(nrep):
                        if nrep > 1:
                            bagfilename = 'motion_surface=%s_shape=%s_a=%.0f_v=%.0f_i=%.3f_s=%.3f_t=%.3f_rep=%04d.bag' % (opt.surface_id, opt.shape_id, acc*1000, speeds[cnt_acc], i, s, t, rep)
                        else:
                            bagfilename = 'motion_surface=%s_shape=%s_a=%.0f_v=%.0f_i=%.3f_s=%.3f_t=%.3f.bag' % (opt.surface_id, opt.shape_id, acc*1000, speeds[cnt_acc], i, s, t)
                            
                        bagfilepath = dir_save_bagfile+bagfilename
                        # if exists then skip it
                        if skip_when_exists and os.path.isfile(bagfilepath):
                            #print bagfilepath, 'exits', 'skip'
                            continue  
                        # find the probe pos in contact in object frame
                        pos_probe_contact_object = pos + normal * probe_radius
                        # find the start point
                        direc = np.dot(tfm.euler_matrix(0,0,t) , normal.tolist() + [1])[0:3] # in the direction of moving out
                        pos_start_probe_object = pos_probe_contact_object + direc * dist_before_contact
                        
                        if shape_type == 'polyapprox' and polyapprox_check_collision(shape, pos_start_probe_object, probe_radius):
                            print bagfilename, 'will be in collision', 'skip'
                            continue
                        
                        # find the end point
                        pos_end_probe_object = pos_probe_contact_object - direc * dist_after_contact
                        
                        # zero force torque sensor
                        rospy.sleep(0.1)
                        #setZero()
                        #wait_for_ft_calib()
                        
                        # transform start and end to world frame
                        if hasRobot:
                            pos_start_probe_world = coordinateFrameTransformList(pos_start_probe_object, obj_frame_id, global_frame_id, listener)
                            pos_end_probe_world = coordinateFrameTransformList(pos_end_probe_object, obj_frame_id, global_frame_id, listener)
                            pos_contact_probe_world = coordinateFrameTransformList(pos_probe_contact_object, obj_frame_id, global_frame_id, listener)
                            pos_center_obj_world = coordinateFrameTransformList([0,0,0], obj_frame_id, global_frame_id, listener)
                        else:
                            pos_start_probe_world = pos_start_probe_object + center_world
                            pos_end_probe_world = pos_end_probe_object + center_world
                            pos_contact_probe_world = pos_probe_contact_object + center_world
                            pos_center_obj_world = center_world

                        # start bag recording
                        # move to startPos
                        
                        setAcc(acc=globalhighacc, deacc=globalhighacc)
                        setSpeed(tcp=global_highvel, ori=global_highvel)
                        start_pos = copy.deepcopy(pos_start_probe_world)
                        start_pos[2] = zup
                        setCart(start_pos,ori)
            
                        setAcc(acc=globalhighacc, deacc=globalacc)
                        setSpeed(tcp=global_highvel, ori=1000)
                        start_pos = copy.deepcopy(pos_start_probe_world)
                        start_pos[2] = z
                        setCart(start_pos,ori)
                        
                        
                        
                        setSpeed(tcp=global_slow_vel, ori=1000) # some slow speed
                        mid_pos = copy.deepcopy(pos_contact_probe_world)
                        mid_pos[2] = z
                        pub.publish('move_to_mid_pos')
                        setCart(mid_pos,ori)
                        
                        rosbag_proc = helper.start_ros_bag(bagfilename, topics, dir_save_bagfile) 
                        rospy.sleep(0.5) 
                        
                        end_pos = copy.deepcopy(pos_end_probe_world)
                        end_pos[2] = z
                        if acc == 0:  # constant speed
                            setAcc(acc=globalmaxacc, deacc=globalmaxacc)
                            setSpeed(tcp=speeds[cnt_acc], ori=1000)
                        else:  # there is acceleration
                            setAcc(acc=acc, deacc=globalmaxacc)
                            setSpeed(tcp=1000, ori=1000) # some high speed
                            
                        pub.publish('start_pushing')
                        setCart(end_pos,ori)
                        pub.publish('end_pushing')
                        # end bag recording
                        helper.terminate_ros_node("/record")
                        setSpeed(tcp=global_highvel, ori=1000)
                        setAcc(acc=globalhighacc, deacc=globalhighacc)
                        
                        # move up vertically
                        end_pos = copy.deepcopy(pos_end_probe_world)
                        end_pos[2] = zup
                        setCart(end_pos,ori)
                        
                        distance_obj_center = np.linalg.norm(np.array(pos_center_obj_world)-np.array(center_world))
                        
                        # recover
                        recover(obj_slot, distance_obj_center > allowed_distance)
                        #pause()
                        cnt += 1
                        if cnt > limit:  return
def push(start_pos, end_pos):
    global frame_work_robot_2d, zup, z
    global contact_pts, contact_nms, all_contact
    global step_size

    direc = (npa(end_pos) - npa(start_pos))
    dist = np.linalg.norm(direc)
    direc = direc / dist * step_size

    setSpeed(tcp=global_slow_vel)
    setCart(list(start_pos) + [zup])
    # move down, not supposed to make contact
    setCart(list(start_pos) + [z])
    nsteps = int(dist // step_size)

    # calibrate the FT sensor
    #setZero()
    #wait_for_ft_calib()

    for i in xrange(1, nsteps + 1):
        # move
        curr_pos = (direc * i + start_pos).tolist() + [z]
        setCart(curr_pos)

        # collect vicon object pose
        box_pose_des_global = lookupTransformList(global_frame_id,
                                                  obj_frame_id, lr)

        # collect ft measurement
        rospy.sleep(sleepForFT)
        ft = getAveragedFT()

        # collect apriltag measurement
        rospy.sleep(sleepForAP)
        has_apriltag = False
        object_apriltag = [0, 0, 0, 0, 0, 0, 0]
        apriltag_detections_msg = ROS_Wait_For_Msg(
            '/apriltags/detections', AprilTagDetections).getmsg()
        for det in apriltag_detections_msg.detections:
            if det.id == 0:
                pose_webcam = transform_back([0.02, 0.02, 0.009, 0, 0, 0, 1],
                                             pose2list(det.pose))
                object_apriltag = poseTransform(pose_webcam, '/head_camera',
                                                '/map', lr)
                has_apriltag = True
                break

        # compute contact point and normal if in contact
        if norm(ft[0:2]) > threshold:
            incontact = True
            # transform ft data to global frame
            ft_global = transformFt2Global(ft)
            ft_global[2] = 0  # we don't want noise from z
            normal = ft_global[0:3] / norm(ft_global)
            contact_nms.append(normal.tolist())
            contact_pt = curr_pos - normal * probe_radius
            contact_pts.append(contact_pt.tolist())
            vizPoint(contact_pt.tolist())
            vizArrow(contact_pt.tolist(), (contact_pt + normal * 0.8).tolist())
        else:
            incontact = False
            normal = npa([0, 0, 0])
            contact_pt = npa([0, 0, 0])

        # record robot pos, object pose, contact point, contact normal, and ft measurement
        # caution: matlab uses the other quaternion order: w x y z.
        # Also the normal should point toward the object.
        all_contact.append(contact_pt.tolist()[0:2] + [0] +
                           (-normal).tolist()[0:2] + [0] +
                           box_pose_des_global[0:3] +
                           box_pose_des_global[6:7] +
                           box_pose_des_global[3:6] + curr_pos + [incontact] +
                           object_apriltag[0:3] + object_apriltag[6:7] +
                           object_apriltag[3:6] +
                           [pose3d_to_pose2d(object_apriltag)[2]] +
                           [has_apriltag])

    setCart((direc * nsteps + start_pos).tolist() + [zup])
Beispiel #7
0
def main(argv):
    parser = optparse.OptionParser()

    parser.add_option('',
                      '--avgcolorbar',
                      action="store",
                      type='float',
                      dest='avgcolorbar',
                      help='Color bar',
                      nargs=2,
                      default=(0, 1))

    (opt, args) = parser.parse_args()

    if len(args) < 1:  # no bagfile name
        parser.error("Usage: plot_friction_map.py [bag_file_path.h5]")
        return

    hdf5_filepath = args[0]
    figfname = hdf5_filepath.replace('.h5', '_fmap.png')
    figfname_std = hdf5_filepath.replace('.h5', '_fmapstd.png')
    ft_wrench = []

    max_x = 0.450
    min_x = 0.250
    rangex = [0.45, 0.35, 0.25]
    # 0.450, 0.350, 0.250
    max_y = 0.197 - 0.1
    min_y = -0.233 + 0.1
    rangey = [0.07, -0.03, -0.13]
    # -0.13, -0.03, 0.07,

    f = h5py.File(hdf5_filepath, "r")
    tip_array = f['tip_array'].value
    ft_wrench = f['ft_wrench'].value

    radius = 0.01

    image_vals = [[[], [], []], [[], [], []], [[], [], []]]
    image_avg = [[1, 2, 3], [0, 0, 0], [0, 0, 0]]
    image_std = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]

    N = 0.8374 * 9.81

    scale = (len(ft_wrench) * 1.0 / len(tip_array))
    for i in range(len(tip_array)):
        ind = None
        for idx in range(len(rangex)):
            for idy in range(len(rangey)):
                if helper.norm(
                        np.array(tip_array[i][1:3]) -
                        np.array([rangex[idx], rangey[idy]])) < radius:
                    ind = (idx, idy)
                    break
            if ind is not None:
                break

        ft_i = int(i * scale)
        if ind:
            image_vals[ind[0]][ind[1]].append(np.fabs(
                ft_wrench[ft_i][2]))  # force_y

    for idx in range(len(rangex)):
        for idy in range(len(rangey)):
            print idx, idy, len(image_vals[idx][idy])
            image_avg[idx][idy] = sum(image_vals[idx][idy]) / len(
                image_vals[idx][idy]) / N
            image_std[idx][idy] = np.std(image_vals[idx][idy]) / N

    print image_avg
    print image_std

    plt.rc('font', family='serif', size=30)
    plt.imshow(image_avg,
               extent=(rangey[0] + 0.05, rangey[2] - 0.05, rangex[2] - 0.05,
                       rangex[0] + 0.05),
               interpolation='nearest',
               cmap=cm.Greys,
               vmin=opt.avgcolorbar[0],
               vmax=opt.avgcolorbar[1])

    plt.colorbar()

    plt.savefig(figfname)

    print figfname

    plt.close()

    plt.imshow(image_std,
               extent=(rangey[0] + 0.05, rangey[2] - 0.05, rangex[2] - 0.05,
                       rangex[0] + 0.05),
               interpolation='nearest',
               cmap=cm.Greys,
               vmin=0.01,
               vmax=0.03)

    plt.colorbar()

    plt.savefig(figfname_std)
Beispiel #8
0
def main(argv):
    parser = optparse.OptionParser()
    
    parser.add_option('', '--fmt', action="store", dest='fmt', 
                      help='Figure format e.g. png, pdf', default='png')
  
    (opt, args) = parser.parse_args()
    
    
    if len(args) < 2:
        parser.error("Usage: plot_friction_change_over_time.py [file_pattern.h5]")
        return
    
    filepattern = args[0]  # ./record_surface=plywood_shape=rect1_a=-1000_v=20_rep=%3d.h5
    filenum = int(args[1])  # 100
    
    figfname = filepattern.replace('.h5', '.%s' % opt.fmt)
    
    max_x = 0.450
    min_x = 0.250
    rangex = [0.45, 0.35, 0.25]
    max_y = 0.197-0.1
    min_y = -0.233+0.1
    rangey = [0.07, -0.03, -0.13]
    
    target = [0.35, -0.03]
    
    radius = 0.01
    
    image_avgs_t = []
    image_stds_t = []
    
    N = 0.8374 * 9.81
    nan = float('nan')
    if not os.path.exists(filepattern.replace('.h5', '_fcot.h5')):
        for f_ind in range(filenum):
            hdf5_filepath = filepattern % f_ind
            print 'processing', hdf5_filepath
            
            if not os.path.exists(hdf5_filepath):  # in case the data is bad
                print 'not found'
                image_avgs_t.append([[nan,nan,nan],[nan,nan,nan],[nan,nan,nan]])
                image_stds_t.append([[nan,nan,nan],[nan,nan,nan],[nan,nan,nan]])
                continue
                
            f = h5py.File(hdf5_filepath, "r")
            tip_array = f['tip_array'].value
            ft_wrench = f['ft_wrench'].value
            
            image_vals = [[[],[],[]],[[],[],[]],[[],[],[]]]
            image_avgs = [[0,0,0],[0,0,0],[0,0,0]]
            image_stds = [[0,0,0],[0,0,0],[0,0,0]]
            scale = (len(ft_wrench)*1.0/len(tip_array))
            for i in range(len(tip_array)):
                ind = None
                for idx in range(len(rangex)):
                    for idy in range(len(rangey)):
                        if helper.norm(np.array(tip_array[i][1:3]) - np.array([rangex[idx], rangey[idy]])) < radius:
                            ind = (idx,idy)
                            break
                    if ind is not None:
                        break
                ft_i = int(i * scale)
                if ind:
                    image_vals[ind[0]][ind[1]].append(np.fabs(ft_wrench[ft_i][2]))  # force_y
              
            for idx in range(len(rangex)):
                for idy in range(len(rangey)):
                    if len(image_vals[idx][idy]) > 0:
                        image_avgs[idx][idy] = sum(image_vals[idx][idy]) / len(image_vals[idx][idy]) / N
                    image_stds[idx][idy] = np.std(image_vals[idx][idy]) / N
            
                    
            image_avgs_t.append(image_avgs)
            image_stds_t.append(image_stds)
            
            f.close()
        with h5py.File(filepattern.replace('.h5', '_fcot.h5'), "w") as f:
            f.create_dataset("image_avgs_t", data=image_avgs_t)
            f.create_dataset("image_stds_t", data=image_stds_t)
    else:
        with h5py.File(filepattern.replace('.h5', '_fcot.h5'), "r") as f:
            image_avgs_t = f['image_avgs_t'].value
            image_stds_t = f['image_stds_t'].value
    
    # for idx in range(len(rangex)):
        # for idy in range(len(rangey)):
            # tmp = []
            # for t in range(filenum):
                # tmp.append(image_avgs_t[t][idx][idy])
            # plt.errorbar(range(1,filenum+1), tmp, fmt='-o', color='k')
            
    
    rangexx = []
    vals = []
    print len(image_avgs_t)
    for t in range(filenum):
        tmp = 0
        
        for idx in range(len(rangex)):
            for idy in range(len(rangey)):
                tmp += image_avgs_t[t][idx][idy] / 9.0
        
        if not np.isnan(tmp):
            vals.append(tmp)
            rangexx.append(t+1)
        
    plt.errorbar(rangexx, vals, fmt='-o', color='k')
    
    
    plt.ylabel('Coefficient of friction')
    plt.xlabel('Push time')
    #plt.title('Change of frictional coefficient over time')
    plt.savefig(figfname)
    
    plt.show()
Beispiel #9
0
def main(argv):
    parser = optparse.OptionParser()
    
    parser.add_option('', '--avgcolorbar', action="store", type='float', dest='avgcolorbar', 
                      help='Color bar', nargs=2, default=(0,1))
                      
    (opt, args) = parser.parse_args()
    
    if len(args) < 1:  # no bagfile name
        parser.error("Usage: plot_friction_map.py [bag_file_path.h5]")
        return
    
    hdf5_filepath = args[0]
    figfname = hdf5_filepath.replace('.h5', '_fmap.png')
    figfname_std = hdf5_filepath.replace('.h5', '_fmapstd.png')
    ft_wrench = []
    
    max_x = 0.450
    min_x = 0.250
    rangex = [0.45, 0.35, 0.25]
    # 0.450, 0.350, 0.250
    max_y = 0.197-0.1
    min_y = -0.233+0.1
    rangey = [0.07, -0.03, -0.13]
    # -0.13, -0.03, 0.07, 
    
    f = h5py.File(hdf5_filepath, "r")
    tip_array = f['tip_array'].value
    ft_wrench = f['ft_wrench'].value
        
    radius = 0.01
    
    image_vals = [[[],[],[]],[[],[],[]],[[],[],[]]]
    image_avg = [[1,2,3],[0,0,0],[0,0,0]]
    image_std = [[0,0,0],[0,0,0],[0,0,0]]
    
    N = 0.8374 * 9.81
    
    scale = (len(ft_wrench)*1.0/len(tip_array))
    for i in range(len(tip_array)):
        ind = None
        for idx in range(len(rangex)):
            for idy in range(len(rangey)):
                if helper.norm(np.array(tip_array[i][1:3]) - np.array([rangex[idx], rangey[idy]])) < radius:
                    ind = (idx,idy)
                    break
            if ind is not None:
                break
            
        ft_i = int(i * scale)
        if ind:
            image_vals[ind[0]][ind[1]].append(np.fabs(ft_wrench[ft_i][2]))  # force_y
        
    for idx in range(len(rangex)):
        for idy in range(len(rangey)):
            print idx, idy, len(image_vals[idx][idy])
            image_avg[idx][idy] = sum(image_vals[idx][idy]) / len(image_vals[idx][idy]) / N
            image_std[idx][idy] = np.std(image_vals[idx][idy]) / N
    
    
    
    print image_avg
    print image_std
    
    plt.rc('font', family='serif', size=30)
    plt.imshow(image_avg, extent=(rangey[0]+0.05, rangey[2]-0.05, rangex[2]-0.05, rangex[0]+0.05),
           interpolation='nearest', cmap=cm.Greys, vmin=opt.avgcolorbar[0], vmax=opt.avgcolorbar[1])
           
    plt.colorbar()
    
    plt.savefig(figfname)
    
    print figfname
    
    plt.close()
    
    plt.imshow(image_std, extent=(rangey[0]+0.05, rangey[2]-0.05, rangex[2]-0.05, rangex[0]+0.05),
           interpolation='nearest', cmap=cm.Greys, vmin=0.01, vmax=0.03)
           
    plt.colorbar()
    
    plt.savefig(figfname_std)
def run_it(accelerations, speeds, shape, nside, side_params, angles, nrep, shape_type, probe_radius, dir_save_bagfile, dist_after_contact, allowed_distance, opt):
    # hack to restart the script to prevent ros network issues.
    global pub
    limit = 100
    cnt = 0
    topics = ['-a']
    
    # enumerate the possible trajectories
    for cnt_acc, acc in enumerate(accelerations):
        # enumerate the side we want to push
        for i in range(nside):
            # enumerate the contact point that we want to push
            for s in side_params:
                if shape_type == 'poly':
                    pos = np.array(shape[i]) *(1-s) + np.array(shape[(i+1) % len(shape)]) *(s)
                    pos = np.append(pos, [0])
                    tangent = np.array(shape[(i+1) % len(shape)]) - np.array(shape[i])
                    normal = np.array([tangent[1], -tangent[0]]) 
                    normal = normal / norm(normal)  # normalize it
                    normal = np.append(normal, [0])
                elif shape_type == 'ellip':
                    (a,b) = shape[0][0], shape[0][1]
                    pos = [shape[0][0] * np.cos(s*2*np.pi), shape[0][1] * np.sin(s*2*np.pi), 0]
                    normal = [np.cos(s*2*np.pi)/a, np.sin(s*2*np.pi)/b, 0]
                    normal = normal / norm(normal)  # normalize it
                elif shape_type == 'polyapprox':
                    pos, normal = polyapprox(shape, s)
                    
                # enumerate the direction in which we want to push
                for t in angles:
                    for rep in xrange(nrep):
                        if nrep > 1:
                            bagfilename = 'motion_surface=%s_shape=%s_a=%.0f_v=%.0f_i=%.3f_s=%.3f_t=%.3f_rep=%04d.bag' % (opt.surface_id, opt.shape_id, acc*1000, speeds[cnt_acc], i, s, t, rep)
                        else:
                            bagfilename = 'motion_surface=%s_shape=%s_a=%.0f_v=%.0f_i=%.3f_s=%.3f_t=%.3f.bag' % (opt.surface_id, opt.shape_id, acc*1000, speeds[cnt_acc], i, s, t)
                            
                        bagfilepath = dir_save_bagfile+bagfilename
                        # if exists then skip it
                        if skip_when_exists and os.path.isfile(bagfilepath):
                            #print bagfilepath, 'exits', 'skip'
                            continue  
                        # find the probe pos in contact in object frame
                        pos_probe_contact_object = pos + normal * probe_radius
                        # find the start point
                        direc = np.dot(tfm.euler_matrix(0,0,t) , normal.tolist() + [1])[0:3] # in the direction of moving out
                        pos_start_probe_object = pos_probe_contact_object + direc * dist_before_contact
                        
                        if shape_type == 'polyapprox' and polyapprox_check_collision(shape, pos_start_probe_object, probe_radius):
                            print bagfilename, 'will be in collision', 'skip'
                            continue
                        
                        # find the end point
                        pos_end_probe_object = pos_probe_contact_object - direc * dist_after_contact
                        
                        # zero force torque sensor
                        rospy.sleep(0.1)
                        setZero()
                        wait_for_ft_calib()
                        
                        # transform start and end to world frame
                        if hasRobot:
                            pos_start_probe_world = coordinateFrameTransform(pos_start_probe_object, obj_frame_id, global_frame_id, listener)
                            pos_end_probe_world = coordinateFrameTransform(pos_end_probe_object, obj_frame_id, global_frame_id, listener)
                            pos_contact_probe_world = coordinateFrameTransform(pos_probe_contact_object, obj_frame_id, global_frame_id, listener)
                            pos_center_obj_world = coordinateFrameTransform([0,0,0], obj_frame_id, global_frame_id, listener)
                        else:
                            pos_start_probe_world = pos_start_probe_object + center_world
                            pos_end_probe_world = pos_end_probe_object + center_world
                            pos_contact_probe_world = pos_probe_contact_object + center_world
                            pos_center_obj_world = center_world

                        # start bag recording
                        # move to startPos
                        
                        setAcc(acc=globalhighacc, deacc=globalhighacc)
                        setSpeed(tcp=global_highvel, ori=global_highvel)
                        start_pos = copy.deepcopy(pos_start_probe_world)
                        start_pos[2] = zup
                        setCart(start_pos,ori)
            
                        setAcc(acc=globalacc, deacc=globalacc)
                        setSpeed(tcp=globalvel, ori=1000)
                        start_pos = copy.deepcopy(pos_start_probe_world)
                        start_pos[2] = z
                        setCart(start_pos,ori)
                        
                        
                        
                        setSpeed(tcp=global_slow_vel, ori=1000) # some slow speed
                        mid_pos = copy.deepcopy(pos_contact_probe_world)
                        mid_pos[2] = z
                        pub.publish('move_to_mid_pos')
                        setCart(mid_pos,ori)
                        
                        rosbag_proc = helper.start_ros_bag(bagfilename, topics, dir_save_bagfile) 
                        rospy.sleep(0.5) 
                        
                        end_pos = copy.deepcopy(pos_end_probe_world)
                        end_pos[2] = z
                        if acc == 0:  # constant speed
                            setAcc(acc=globalmaxacc, deacc=globalmaxacc)
                            setSpeed(tcp=speeds[cnt_acc], ori=1000)
                        else:  # there is acceleration
                            setAcc(acc=acc, deacc=globalmaxacc)
                            setSpeed(tcp=1000, ori=1000) # some high speed
                            
                        pub.publish('start_pushing')
                        setCart(end_pos,ori)
                        pub.publish('end_pushing')
                        # end bag recording
                        helper.terminate_ros_node("/record")
                        setSpeed(tcp=global_highvel, ori=1000)
                        setAcc(acc=globalhighacc, deacc=globalhighacc)
                        
                        # move up vertically
                        end_pos = copy.deepcopy(pos_end_probe_world)
                        end_pos[2] = zup
                        setCart(end_pos,ori)
                        
                        distance_obj_center = np.linalg.norm(np.array(pos_center_obj_world)-np.array(center_world))
                        
                        # recover
                        recover(obj_slot, distance_obj_center > allowed_distance)
                        #pause()
                        cnt += 1
                        if cnt > limit:  return
    def run_explore(filename):
        # 0. check if collected or not
        dir_base = data_base + "/contour_following/"
        jsonfilename = dir_base + '/%s.json' % filename
        matfilename = dir_base + '/%s.mat' % filename
        if os.path.isfile(jsonfilename):
            print "skip", filename
            return

        # 1. move to startPos
        setSpeed(tcp=global_vel)
        setZone(0)
        start_pos = [center_world[0] + explore_radius, center_world[1]] + [zup]
        setCart(start_pos)

        # 2. Rough probing
        scan_contact_pts = []

        # 2.1 populate start poses for small probing in opposite direction
        start_configs = []

        jmax = (nstart + 1) // 2
        kmax = 2 if nstart > 1 else 1
        dth = 2 * np.pi / nstart
        for j in xrange(jmax):
            for k in xrange(kmax):
                i = j + k * (nstart // 2)
                start_pos = [
                    center_world[0] + explore_radius * np.cos(i * dth),
                    center_world[1] + explore_radius * np.sin(i * dth)
                ]
                direc = [-np.cos(i * dth), -np.sin(i * dth), 0]
                start_configs.append([start_pos, direc])
                print 'direc', direc

        # 2.2 move toward center till contact, and record contact points
        for i, (start_pos, direc) in enumerate(reversed(start_configs)):
            setZero()
            wait_for_ft_calib()

            setCart(start_pos + [zup])
            setCart(start_pos + [z])

            curr_pos = start_pos + [z]
            cnt = 0
            while True:
                curr_pos = np.array(curr_pos) + np.array(direc) * step_size
                setCart(curr_pos)
                # let the ft reads the force in static, not while pushing
                rospy.sleep(sleepForFT)
                ft = getFTmsglist()
                print '[ft explore]', ft
                # get box pose from vicon
                (box_pos, box_quat) = lookupTransform(global_frame_id,
                                                      obj_frame_id, lr)
                box_pose_des_global = list(box_pos) + list(box_quat)
                print 'obj_pose', box_pose_des_global

                # If in contact, break
                if norm(ft[0:2]) > threshold:
                    # transform ft data to global frame
                    ft_global = transformFt2Global(ft)
                    ft_global[2] = 0  # we don't want noise from z
                    normal = ft_global[0:3] / norm(ft_global)

                    contact_pt = curr_pos - normal * probe_radius
                    scan_contact_pts.append(contact_pt.tolist())
                    if i < len(
                            start_configs
                    ) - 1:  # if the last one, stay in contact and do exploration from there.
                        setCart([curr_pos[0], curr_pos[1], zup])
                    break

                #if too far and no contact break.
                if cnt > explore_radius * 2 / step_size:
                    break

        if len(scan_contact_pts) == 0:
            print "Error: Cannot touch the object"
            return

        # 3. Contour following, use the normal to move along the block
        setSpeed(tcp=global_slow_vel)
        index = 0
        contact_pts = []
        contact_nms = []
        all_contact = []
        while True:
            # 3.1 move
            direc = np.dot(tfm.euler_matrix(0, 0, 2),
                           normal.tolist() + [1])[0:3]
            curr_pos = np.array(curr_pos) + direc * step_size
            setCart(curr_pos)

            # 3.2 let the ft reads the force in static, not while pushing
            rospy.sleep(sleepForFT)
            ft = getAveragedFT()
            if index % 50 == 0:
                #print index #, '[ft explore]', ft
                print index
            else:
                sys.stdout.write('.')
                sys.stdout.flush()
            # get box pose from vicon
            (box_pos, box_quat) = lookupTransform(global_frame_id,
                                                  obj_frame_id, lr)
            box_pose_des_global = list(box_pos) + list(box_quat)
            #print 'box_pose', box_pose_des_global

            # 3.3 visualize it.
            vizBlock(box_pose_des_global, obj_mesh, global_frame_id)

            # 3.4 record the data if in contact
            if norm(ft[0:2]) > threshold:
                # transform ft data to global frame
                ft_global = transformFt2Global(ft)
                ft_global[2] = 0  # we don't want noise from z
                normal = ft_global[0:3] / norm(ft_global)
                contact_nms.append(normal.tolist())
                contact_pt = curr_pos - normal * probe_radius
                contact_pts.append(contact_pt.tolist())
                vizPoint(contact_pt.tolist())
                vizArrow(contact_pt.tolist(),
                         (contact_pt + normal * 0.1).tolist())
                # caution: matlab uses the other quaternion order: w x y z.
                # Also the normal should point toward the object.
                all_contact.append(contact_pt.tolist()[0:2] + [0] +
                                   (-normal).tolist()[0:2] + [0] +
                                   box_pose_des_global[0:3] +
                                   box_pose_des_global[6:7] +
                                   box_pose_des_global[3:6] +
                                   curr_pos.tolist())
                index += 1

            # 3.5 break if we collect enough
            if len(contact_pts) > limit:
                break

            # 3.6 periodically zero the ft
            if len(
                    contact_pts
            ) % 500 == 0:  # zero the ft offset, move away from block, zero it, then come back
                move_away_size = 0.01
                overshoot_size = 0  #0.0005
                setSpeed(tcp=global_super_slow_vel)
                setCart(curr_pos + normal * move_away_size)
                rospy.sleep(1)
                print 'offset ft:', getAveragedFT()
                setZero()
                wait_for_ft_calib()
                setCart(curr_pos - normal * overshoot_size)
                setSpeed(tcp=global_slow_vel)

        # 4.1 save contact_nm and contact_pt as json file

        helper.make_sure_path_exists(dir_base)
        with open(jsonfilename, 'w') as outfile:
            json.dump(
                {
                    'all_contact': all_contact,
                    'scan_contact_pts': scan_contact_pts,
                    'isreal': True,
                    '__title__': colname,
                    "surface_id": surface_id,
                    "shape_id": shape_id,
                    "probe_id": probe_id,
                    "muc": muc,
                    "probe_radius": probe_radius,
                    "offset": offset
                },
                outfile,
                sort_keys=True,
                indent=1)

        # 4.2 save all_contact as mat file
        sio.savemat(matfilename, {
            'all_contact': all_contact,
            'scan_contact_pts': scan_contact_pts
        })

        # 5. move back to startPos
        setSpeed(tcp=global_vel)
        start_pos = [curr_pos[0], curr_pos[1]] + [zup]
        setCart(start_pos)

        recover(obj_slot, True)
def turn(a):
    x = tfm.quaternion_multiply(a, ori_down)
    return list(npa(x) / norm(x))