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 import roslib; roslib.load_manifest('hrl_tilting_hokuyo')
00031 import hrl_hokuyo.hokuyo_processing as hp
00032 import sys, optparse, os
00033 import hrl_lib.util as ut
00034 import hrl_lib.transforms as tr
00035 import numpy as np,math
00036 import time
00037
00038 import display_3d_mayavi as d3m
00039
00040 import occupancy_grid_3d as og3d
00041 import scipy.ndimage as ni
00042
00043 import copy
00044 import pylab as pl
00045
00046 color_list = [(1.,1.,0),(1.,0,0),(0,1.,1.),(0,1.,0),(0,0,1.),(0,0.4,0.4),(0.4,0.4,0),
00047 (0.4,0,0.4),(0.4,0.8,0.4),(0.8,0.4,0.4),(0.4,0.4,0.8),(0.4,0,0.8),(0,0.8,0.4),
00048 (0,0.4,0.8),(0.8,0,0.4),(0.4,0,0.4),(1.,0.6,0.02) ]
00049
00050
00051
00052
00053
00054
00055
00056 def points_within_cuboid(pts,brf,tlb):
00057 idx = np.where(np.min(np.multiply(pts>brf,pts<tlb),0))[1]
00058 if idx.shape[1] == 0:
00059 within_pts = np.empty((3,0))
00060 else:
00061 within_pts = pts[:,idx.A1.tolist()]
00062
00063 return within_pts
00064
00065
00066 def generate_pointcloud(pos_list, scan_list, min_angle, max_angle, l1, l2,save_scan=False,
00067 max_dist=np.Inf, min_dist=-np.Inf,min_tilt=-np.Inf,max_tilt=np.Inf, get_intensities=False, reject_zero_ten=True):
00068 ''' pos_list - list of motor positions (in steps)
00069 scan_list - list of UrgScan objects at the corres positions.
00070 l1,l2 - parameterizing the transformation (doc/ folder)
00071 save_scan - pickle 3xN numpy matrix of points.
00072 max_dist - ignore points at distance > max_dist
00073 min_dist - ignore points at distance < max_dist
00074
00075 min_tilt, max_tilt - min and max tilt angles (radians)
00076 +ve tilts the hokuyo down.
00077 get_intensites - additionally return intensity values
00078 returns 3xN numpy matrix of 3d coords of the points, returns (3xN, 1xN) including the intensity values if get_intensites=True
00079 '''
00080 t0 = time.time()
00081 allpts = []
00082 allintensities = []
00083
00084 pos_arr = np.array(pos_list)
00085 scan_arr = np.array(scan_list)
00086 idxs = np.where(np.multiply(pos_arr<=max_tilt,pos_arr>=min_tilt))
00087 pos_list = pos_arr[idxs].tolist()
00088 scan_list = scan_arr[idxs].tolist()
00089
00090 n_scans = len(scan_list)
00091
00092 if n_scans>1:
00093 scan_list = copy.deepcopy(scan_list)
00094
00095
00096 ranges_mat = []
00097 for s in scan_list:
00098 ranges_mat.append(s.ranges.T)
00099 ranges_mat = np.column_stack(ranges_mat)
00100
00101 start_index = hp.angle_to_index(scan_list[0],min_angle)
00102 end_index = hp.angle_to_index(scan_list[0],max_angle)
00103 for r in ranges_mat[start_index:end_index+1]:
00104 hp.remove_graze_effect(r,np.matrix(pos_list),skip=1,graze_angle_threshold=math.radians(169.))
00105
00106 for i,s in enumerate(scan_list):
00107 s.ranges = ranges_mat[:,i].T
00108
00109 for p,s in zip(pos_list,scan_list):
00110 mapxydata = hp.get_xy_map(s,min_angle,max_angle,max_dist=max_dist,min_dist=min_dist,reject_zero_ten=reject_zero_ten,sigmoid_hack=True,get_intensities=get_intensities)
00111
00112 if get_intensities == True:
00113 pts, intensities = mapxydata
00114 allintensities.append(intensities)
00115 else:
00116 pts = mapxydata
00117
00118 pts = np.row_stack((pts,np.zeros(pts.shape[1])))
00119 pts = tr.Ry(-p)*(pts+np.matrix((l1,0,-l2)).T)
00120 allpts.append(pts)
00121
00122
00123 allpts = np.column_stack(allpts)
00124
00125
00126 if save_scan:
00127 date_name = ut.formatted_time()
00128 ut.save_pickle(allpts,date_name+'_cloud.pkl')
00129
00130 t1 = time.time()
00131
00132
00133 if get_intensities == True:
00134 allintensities = np.column_stack(allintensities)
00135 return allpts, allintensities
00136 else:
00137 return allpts
00138
00139
00140
00141 def max_fwd_without_collision(all_pts,z_height,max_dist,display_list=None):
00142 ''' find the max distance that it is possible to move fwd by
00143 without collision.
00144 all_pts - 3xN matrix of 3D points in thok frame.
00145 z - height of zenither while taking the scan.
00146 max_dist - how far do I want to check for a possible collision.
00147 returns max_dist that the thok can be moved fwd without collision.
00148 '''
00149 brf = np.matrix([0.2,-0.4,-z_height-0.1]).T
00150 tlb = np.matrix([max_dist, 0.4,-z_height+1.8]).T
00151 resolution = np.matrix([0.05,0.05,0.02]).T
00152
00153 gr = og3d.occupancy_grid_3d(brf,tlb,resolution)
00154 gr.fill_grid(all_pts)
00155
00156 gr.to_binary(4)
00157 ground_z = tr.thok0Tglobal(np.matrix([0,0,-z_height]).T)[2,0]
00158
00159 gr.remove_horizontal_plane(extra_layers=2)
00160 collide_pts = np.row_stack(np.where(gr.grid!=0))
00161 x_coords = collide_pts[0]
00162
00163 if x_coords.shape[0] == 0:
00164 max_x = max_dist
00165
00166 else:
00167 max_x_gr = np.min(x_coords)
00168
00169
00170 max_x = max_x_gr*gr.resolution[0,0]+gr.brf[0,0]
00171
00172 if display_list != None:
00173 collide_grid = gr.grid_to_points()
00174 display_list.append(pu.PointCloud(all_pts,(200,200,200)))
00175 display_list.append(pu.CubeCloud(collide_grid,(200,200,200),resolution))
00176 display_list.append(pu.CubeCloud(np.matrix((max_x,0.,0.)).T,(0,0,200),size=np.matrix([0.05,.05,0.05]).T))
00177
00178
00179 return max_x
00180
00181 def find_goto_point_surface_1(grid,pt,display_list=None):
00182 ''' returns p_erratic,p_edge,surface_height
00183 p_erratic - point where the erratic's origin should go to. (in thok0 frame)
00184 p_edge - point on the edge closest to pt.
00185 p_erratic,p_edge are 3x1 matrices.
00186 surface_height - in thok0 coord frame.
00187 '''
00188 pt_thok = pt
00189
00190
00191 close_pt,approach_vector = find_approach_direction(grid,pt_thok,display_list)
00192 if close_pt == None:
00193 return None,None,None
00194
00195
00196
00197
00198 lam = -0.4
00199 goto_pt = close_pt[0:2,0] + lam*approach_vector
00200
00201 err_to_thok = tr.erraticTglobal(tr.globalTthok0(np.matrix([0,0,0]).T))
00202 goto_pt_erratic = -err_to_thok[0,0]*approach_vector + goto_pt
00203
00204
00205
00206 if display_list != None:
00207 display_list.append(pu.CubeCloud(np.row_stack((goto_pt,close_pt[2,0])),color=(0,250,250), size=(0.012,0.012,0.012)))
00208 display_list.append(pu.Line(np.row_stack((goto_pt,close_pt[2,0])).A1,close_pt.A1,color=(255,20,0)))
00209
00210 p_erratic = np.row_stack((goto_pt_erratic,np.matrix((close_pt[2,0]))))
00211 print 'p_erratic in thok0:', p_erratic.T
00212
00213 return p_erratic,close_pt,close_pt[2,0]
00214
00215
00216
00217 def find_closest_pt_index(pts2d,pt):
00218 ''' returns index (of pts2d) of closest point to pt.
00219 pts2d - 2xN matrix, pt - 2x1 matrix
00220 '''
00221 pt_to_edge_dists = ut.norm(pts2d-pt)
00222 closest_pt_index = np.argmin(pt_to_edge_dists)
00223 return closest_pt_index
00224
00225 def find_closest_pt(pts2d,pt,pt_closer=False):
00226 ''' returns closest point to edge (2x1 matrix)
00227 can return None also
00228 '''
00229 dist_pt = np.linalg.norm(pt[0:2,0])
00230 pts2d_r = ut.norm(pts2d)
00231 pts2d_a = np.arctan2(pts2d[1,:],pts2d[0,:])
00232 if pt_closer == False:
00233 k_idxs = np.where(pts2d_r<=dist_pt)
00234 else:
00235 k_idxs = np.where(pts2d_r>dist_pt)
00236
00237 pts2d_r = pts2d_r[k_idxs]
00238 pts2d_a = pts2d_a[k_idxs]
00239 pts2d = ut.cart_of_pol(np.matrix(np.row_stack((pts2d_r,pts2d_a))))
00240
00241 if pt_closer == False:
00242 edge_to_pt = pt[0:2,0]-pts2d
00243 else:
00244 edge_to_pt = pts2d-pt[0:2,0]
00245
00246 edge_to_pt_a = np.arctan2(edge_to_pt[1,:],edge_to_pt[0,:])
00247 keep_idxs = np.where(np.abs(edge_to_pt_a)<math.radians(70))[1].A1
00248
00249 if keep_idxs.shape[0] == 0:
00250 return None
00251
00252 pts2d = pts2d[:,keep_idxs]
00253
00254
00255
00256 closest_pt_index = find_closest_pt_index(pts2d,pt[0:2,0])
00257 closest_pt = pts2d[:,closest_pt_index]
00258 return closest_pt
00259
00260 def pushback_edge(pts2d,pt):
00261 ''' push pt away from the edge defined by pts2d.
00262 pt - 2x1, pts2d - 2xN
00263 returns the pushed point.
00264 '''
00265 closest_idx = find_closest_pt_index(pts2d,pt)
00266 n_push_points = min(min(5,pts2d.shape[1]-closest_idx-1),closest_idx)
00267 if closest_idx<n_push_points or (pts2d.shape[1]-closest_idx-1)<n_push_points:
00268 print 'processing_3d.pushback_edge: pt is too close to the ends of the pts2d array.'
00269 return None
00270
00271 edge_to_pt = pt-pts2d[:,closest_idx-n_push_points:closest_idx+n_push_points]
00272 edge_to_pt_r = ut.norm(edge_to_pt)
00273 edge_to_pt_a = np.arctan2(edge_to_pt[1,:],edge_to_pt[0,:])
00274
00275 non_zero_idxs = np.where(edge_to_pt_r>0.005)
00276 edge_to_pt_r = edge_to_pt_r[non_zero_idxs]
00277 edge_to_pt_r[0,:] = 1
00278 edge_to_pt_a = edge_to_pt_a[non_zero_idxs]
00279 edge_to_pt_unit = ut.cart_of_pol(np.row_stack((edge_to_pt_r,edge_to_pt_a)))
00280 push_vector = edge_to_pt_unit.mean(1)
00281 push_vector = push_vector/np.linalg.norm(push_vector)
00282 print 'push_vector:', push_vector.T
00283 pt_pushed = pt + push_vector*0.05
00284
00285 return pt_pushed
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295 def find_approach_direction(grid,pt,display_list=None):
00296 z_plane,max_count = grid.argmax_z(search_up=True)
00297 z_plane_meters = z_plane*grid.resolution[2,0]+grid.brf[2,0]
00298
00299 l = grid.find_plane_indices(assume_plane=True)
00300 print '------------ min(l)',min(l)
00301
00302 z_plane_argmax,max_count = grid.argmax_z(search_up=False)
00303 z_plane_below = max(0,z_plane_argmax-5)
00304 print 'z_plane_argmax',z_plane_argmax
00305 print 'z_plane_below',z_plane_below
00306 print 'l:',l
00307
00308 copy_grid = copy.deepcopy(grid)
00309 plane_slices = grid.grid[:,:,l]
00310 copy_grid.grid[:,:,:] = 0
00311 copy_grid.grid[:,:,l] = copy.copy(plane_slices)
00312
00313
00314
00315 grid_2d = np.max(grid.grid[:,:,l],2)
00316 grid_2d = ni.binary_dilation(grid_2d,iterations=4)
00317 grid_2d = ni.binary_fill_holes(grid_2d)
00318
00319 labeled_arr,n_labels = ni.label(grid_2d)
00320 labels_list = range(1,n_labels+1)
00321 count_objects = ni.sum(grid_2d,labeled_arr,labels_list)
00322 if n_labels == 1:
00323 count_objects = [count_objects]
00324 max_label = np.argmax(np.matrix(count_objects))
00325 grid_2d[np.where(labeled_arr!=max_label+1)] = 0
00326
00327
00328
00329
00330
00331
00332
00333
00334 labeled_arr_3d = copy_grid.grid.swapaxes(2,0)
00335 labeled_arr_3d = labeled_arr_3d.swapaxes(1,2)
00336 labeled_arr_3d = labeled_arr_3d*grid_2d
00337 labeled_arr_3d = labeled_arr_3d.swapaxes(2,0)
00338 labeled_arr_3d = labeled_arr_3d.swapaxes(1,0)
00339 copy_grid.grid = labeled_arr_3d
00340 pts3d = copy_grid.grid_to_points()
00341 pts2d = pts3d[0:2,:]
00342
00343 dist_pt = np.linalg.norm(pt[0:2,0])
00344 pts2d_r = ut.norm(pts2d)
00345 pts2d_a = np.arctan2(pts2d[1,:],pts2d[0,:])
00346
00347 max_angle = np.max(pts2d_a)
00348 min_angle = np.min(pts2d_a)
00349
00350 max_angle = min(max_angle,math.radians(50))
00351 min_angle = max(min_angle,math.radians(-50))
00352
00353 ang_res = math.radians(1.)
00354 n_bins = int((max_angle-min_angle)/ang_res)
00355 print 'n_bins:', n_bins
00356 n_bins = min(50,n_bins)
00357
00358 ang_res = (max_angle-min_angle)/n_bins
00359 print 'n_bins:', n_bins
00360
00361
00362 angle_list = []
00363 range_list = []
00364 for i in range(n_bins):
00365 angle = min_angle+ang_res*i
00366 idxs = np.where(np.multiply(pts2d_a<(angle+ang_res/2.),pts2d_a>(angle-ang_res/2.)))
00367 r_mat = pts2d_r[idxs]
00368 a_mat = pts2d_a[idxs]
00369 if r_mat.shape[1] == 0:
00370 continue
00371 min_idx = np.argmin(r_mat.A1)
00372 range_list.append(r_mat[0,min_idx])
00373 angle_list.append(a_mat[0,min_idx])
00374
00375 if range_list == []:
00376 print 'processing_3d.find_approach_direction: No edge points found'
00377 return None,None
00378
00379 pts2d = ut.cart_of_pol(np.matrix(np.row_stack((range_list,angle_list))))
00380
00381 closest_pt_1 = find_closest_pt(pts2d,pt,pt_closer=False)
00382 if closest_pt_1 == None:
00383 dist1 = np.Inf
00384 else:
00385 approach_vector_1 = pt[0:2,0] - closest_pt_1
00386 dist1 = np.linalg.norm(approach_vector_1)
00387 approach_vector_1 = approach_vector_1/dist1
00388
00389 closest_pt_2 = find_closest_pt(pts2d,pt,pt_closer=True)
00390 if closest_pt_2 == None:
00391 dist2 = np.Inf
00392 else:
00393 approach_vector_2 = closest_pt_2 - pt[0:2,0]
00394 dist2 = np.linalg.norm(approach_vector_2)
00395 approach_vector_2 = approach_vector_2/dist2
00396
00397 if dist1 == np.Inf and dist2 == np.Inf:
00398 approach_vector_1 = np.matrix([1.,0.,0.]).T
00399 approach_vector_2 = np.matrix([1.,0.,0.]).T
00400 print 'VERY STRANGE: processing_3d.find_approach_direction: both distances are Inf'
00401
00402 if dist1<0.05 or dist2<0.05:
00403 print 'dist1,dist2:',dist1,dist2
00404 t_pt = copy.copy(pt)
00405 if dist1<dist2 and dist1<0.02:
00406 t_pt[0,0] += 0.05
00407 elif dist2<0.02:
00408 t_pt[0,0] -= 0.05
00409
00410 pt_new = pushback_edge(pts2d,t_pt[0:2,0])
00411 if display_list != None:
00412 pt_new_3d = np.row_stack((pt_new,np.matrix([z_plane_meters])))
00413 display_list.append(pu.CubeCloud(pt_new_3d,color=(200,000,0),size=(0.009,0.009,0.009)))
00414
00415 closest_pt_1 = find_closest_pt(pts2d,pt_new,pt_closer=False)
00416 if closest_pt_1 == None:
00417 dist1 = np.Inf
00418 else:
00419 approach_vector_1 = pt_new - closest_pt_1
00420 dist1 = np.linalg.norm(approach_vector_1)
00421 approach_vector_1 = approach_vector_1/dist1
00422
00423 closest_pt_2 = find_closest_pt(pts2d,pt_new,pt_closer=True)
00424 if closest_pt_2 == None:
00425 dist2 = np.Inf
00426 else:
00427 approach_vector_2 = closest_pt_2 - pt_new
00428 dist2 = np.linalg.norm(approach_vector_2)
00429 approach_vector_2 = approach_vector_2/dist2
00430
00431 print '----------- dist1,dist2:',dist1,dist2
00432 if dist2<dist1:
00433 closest_pt = closest_pt_2
00434 approach_vector = approach_vector_2
00435 else:
00436 closest_pt = closest_pt_1
00437 approach_vector = approach_vector_1
00438
00439 print '----------- approach_vector:',approach_vector.T
00440 closest_pt = np.row_stack((closest_pt,np.matrix([z_plane_meters])))
00441
00442 if display_list != None:
00443 z = np.matrix(np.empty((1,pts2d.shape[1])))
00444 z[:,:] = z_plane_meters
00445 pts3d_front = np.row_stack((pts2d,z))
00446
00447 display_list.append(pu.CubeCloud(closest_pt,color=(255,255,0),size=(0.020,0.020,0.020)))
00448 display_list.append(pu.CubeCloud(pts3d_front,color=(255,0,255),size=grid.resolution))
00449
00450
00451 return closest_pt,approach_vector
00452
00453
00454 def vertical_plane_points(grid):
00455 ''' changes grid
00456 '''
00457 plane_indices,ver_plane_slice = grid.remove_vertical_plane()
00458 grid.grid[:,:,:] = 0
00459 grid.grid[plane_indices,:,:] = ver_plane_slice
00460
00461
00462 def find_door_handle(grid,pt,list = None,rotation_angle=math.radians(0.),
00463 occupancy_threshold=None,resolution=None):
00464 grid.remove_vertical_plane()
00465 pts = grid.grid_to_points()
00466
00467 rot_mat = tr.Rz(rotation_angle)
00468 t_pt = rot_mat*pt
00469 brf = t_pt+np.matrix([-0.2,-0.3,-0.2]).T
00470 tlb = t_pt+np.matrix([0.2, 0.3,0.2]).T
00471
00472 grid = og3d.occupancy_grid_3d(brf,tlb,resolution,rotation_z=rotation_angle)
00473
00474 if pts.shape[1] == 0:
00475 return None
00476
00477 grid.fill_grid(tr.Rz(rotation_angle)*pts)
00478 grid.to_binary(occupancy_threshold)
00479
00480 labeled_arr,n_labels = grid.find_objects()
00481
00482 if list == None:
00483 object_points_list = []
00484 else:
00485 object_points_list = list
00486
00487 for l in range(n_labels):
00488 pts = grid.labeled_array_to_points(labeled_arr,l+1)
00489 obj_height = np.max(pts[2,:])-np.min(pts[2,:])
00490 print 'object_height:', obj_height
00491 if obj_height > 0.1:
00492
00493 grid.grid[np.where(labeled_arr==l+1)] = 0
00494
00495 connect_structure = np.empty((3,3,3),dtype='int')
00496 connect_structure[:,:,:] = 0
00497 connect_structure[1,:,1] = 1
00498
00499
00500 grid.grid = ni.binary_dilation(grid.grid,connect_structure,iterations=7)
00501
00502 labeled_arr,n_labels = grid.find_objects()
00503 for l in range(n_labels):
00504 pts = grid.labeled_array_to_points(labeled_arr,l+1)
00505
00506 pts2d = pts[1:3,:]
00507
00508 obj_width = (pts2d.max(1)-pts2d.min(1))[0,0]
00509 print 'processing_3d.find_door_handle: object width = ', obj_width
00510 if obj_width < 0.05:
00511 continue
00512
00513 pts2d_zeromean = pts2d-pts2d.mean(1)
00514 e_vals,e_vecs = np.linalg.eig(pts2d_zeromean*pts2d_zeromean.T)
00515 max_index = np.argmax(e_vals)
00516 max_evec = e_vecs[:,max_index]
00517 ang = math.atan2(max_evec[1,0],max_evec[0,0])
00518 print 'processing_3d.find_door_handle: ang = ', math.degrees(ang)
00519 if (ang>math.radians(45) and ang<math.radians(135)) or \
00520 (ang>math.radians(-135) and ang<math.radians(-45)):
00521
00522 continue
00523
00524 object_points_list.append(pts)
00525 print 'processing_3d.find_door_handle: found %d objects'%(len(object_points_list))
00526
00527 closest_obj = find_closest_object(object_points_list,pt)
00528 return closest_obj
00529
00530
00531
00532 def find_closest_object(obj_pts_list,pt,return_idx=False):
00533 ''' obj_pts_list - list of 3xNi matrices of points.
00534 pt - point of interest. (3x1) matrix.
00535 return_idx - whether to return the index (in obj_pts_list) of
00536 the closest object.
00537 returns 3xNj matrix of points which is the closest object to pt.
00538 None if obj_pts_list is empty.
00539 '''
00540 min_dist_list = []
00541 for obj_pts in obj_pts_list:
00542 min_dist_list.append(np.min(ut.norm(obj_pts-pt)))
00543
00544 if obj_pts_list == []:
00545 return None
00546 min_idx = np.argmin(np.matrix(min_dist_list))
00547 cl_obj = obj_pts_list[min_idx]
00548 print 'processing_3d.find_closest_object: closest_object\'s centroid',cl_obj.mean(1).T
00549
00550 if return_idx:
00551 return cl_obj,min_idx
00552 return cl_obj
00553
00554 def segment_objects_points(grid,return_labels_list=False,
00555 twod=False):
00556 ''' grid - binary occupancy grid.
00557 returns list of 3xNi numpy matrices where Ni is the number of points
00558 in the ith object. Point refers to center of the cell of occupancy grid.
00559 return_labels_list - return a list of labels of the objects in
00560 the grid.
00561 returns None if there is no horizontal surface
00562 '''
00563 labeled_arr,n_labels = grid.segment_objects(twod=twod)
00564 if n_labels == None:
00565
00566 return None
00567
00568 object_points_list = []
00569 labels_list = []
00570
00571 for l in range(n_labels):
00572 pts = grid.labeled_array_to_points(labeled_arr,l+1)
00573
00574 pts_zeromean = pts-pts.mean(1)
00575 e_vals,e_vecs = np.linalg.eig(pts_zeromean*pts_zeromean.T)
00576
00577 max_index = np.argmax(e_vals)
00578 max_evec = e_vecs[:,max_index]
00579 print 'max eigen vector:', max_evec.T
00580 pts_1d = max_evec.T * pts
00581 size = pts_1d.max() - pts_1d.min()
00582 print 'size:', size
00583 print 'n_points:', pts.shape[1]
00584 ppsoe = pts.shape[1]/(e_vals[0]+e_vals[1]+e_vals[2])
00585 print 'points per sum of eigenvalues:',ppsoe
00586
00587
00588 if size<0.05 or size>0.5:
00589 continue
00590 object_points_list.append(pts)
00591 labels_list.append(l+1)
00592
00593 if return_labels_list:
00594 return object_points_list, labels_list
00595
00596 return object_points_list
00597
00598 def create_grid(brf,tlb,resolution,pos_list,scan_list,l1,l2,
00599 display_flag=False,show_pts=True,rotation_angle=0.,
00600 occupancy_threshold=1):
00601 ''' rotation angle - about the Z axis.
00602 '''
00603 max_dist = np.linalg.norm(tlb) + 0.2
00604 min_dist = brf[0,0]
00605 min_angle,max_angle=math.radians(-60),math.radians(60)
00606
00607 all_pts = generate_pointcloud(pos_list, scan_list, min_angle, max_angle, l1, l2,
00608 max_dist=max_dist,min_dist=min_dist)
00609 rot_mat = tr.Rz(rotation_angle)
00610 all_pts_rot = rot_mat*all_pts
00611
00612 gr = og3d.occupancy_grid_3d(brf,tlb,resolution,rotation_z=rotation_angle)
00613
00614 gr.fill_grid(all_pts_rot)
00615 gr.to_binary(occupancy_threshold)
00616
00617 if display_flag == True:
00618 if show_pts:
00619 d3m.plot_points(all_pts,color=(0.,0.,0.))
00620 cube_tups = gr.grid_lines(rotation_angle=rotation_angle)
00621 d3m.plot_cuboid(cube_tups)
00622
00623 return gr
00624
00625 def create_vertical_plane_grid(pt,pos_list,scan_list,l1,l2,rotation_angle,display_list=None):
00626 rot_mat = tr.Rz(rotation_angle)
00627 t_pt = rot_mat*pt
00628 brf = t_pt+np.matrix([-0.2,-0.3,-0.2]).T
00629 tlb = t_pt+np.matrix([0.2, 0.3,0.2]).T
00630 resolution = np.matrix([0.005,0.02,0.02]).T
00631 return create_grid(brf,tlb,resolution,pos_list,scan_list,l1,l2,display_list,rotation_angle=rotation_angle,occupancy_threshold=1)
00632
00633 def create_scooping_grid(pt,pos_list,scan_list,l1,l2,display_flag=False):
00634 brf = pt+np.matrix([-0.15,-0.4,-0.2]).T
00635 brf[0,0] = max(0.07,brf[0,0])
00636 tlb = pt+np.matrix([0.25, 0.4,0.2]).T
00637 resolution = np.matrix([0.01,0.01,0.0025]).T
00638 return create_grid(brf,tlb,resolution,pos_list,scan_list,l1,l2,display_flag)
00639
00640 def create_segmentation_grid(pt,pos_list,scan_list,l1,l2,display_flag=False):
00641 brf = pt+np.matrix([-0.15,-0.2,-0.2]).T
00642 brf[0,0] = max(0.07,brf[0,0])
00643 tlb = pt+np.matrix([0.25, 0.2,0.2]).T
00644
00645
00646
00647
00648
00649
00650 resolution = np.matrix([0.01,0.01,0.0025]).T
00651
00652
00653 return create_grid(brf,tlb,resolution,pos_list,scan_list,l1,l2,display_flag)
00654
00655 def create_approach_grid(pt,pos_list,scan_list,l1,l2,display_list=None,show_pts=True):
00656 brf = pt + np.matrix([-0.5,-0.2,-0.3]).T
00657 brf[0,0] = max(0.10,brf[0,0])
00658
00659 tlb = pt + np.matrix([0.3, 0.2,0.2]).T
00660
00661 resolution = np.matrix([0.01,0.01,0.0025]).T
00662
00663 return create_grid(brf,tlb,resolution,pos_list,scan_list,l1,l2,display_list,show_pts)
00664
00665 def create_overhead_grasp_choice_grid(pt,pos_list,scan_list,l1,l2,far_dist,display_list=None):
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675 y_pos = 0.1
00676 y_neg = -0.1
00677
00678 r = np.linalg.norm(pt[0:2,0])
00679 brf = np.matrix([0.25,y_neg,0.0]).T
00680 tlb = np.matrix([r+far_dist,y_pos,pt[2,0]+0.75]).T
00681
00682 resolution = np.matrix([0.02,0.02,0.02]).T
00683 rotation_angle = math.atan2(pt[1,0],pt[0,0])
00684 print 'rotation_angle:', math.degrees(rotation_angle)
00685
00686 gr = create_grid(brf,tlb,resolution,pos_list,scan_list,l1,l2,display_list,rotation_angle=rotation_angle)
00687
00688 if display_list != None:
00689 collide_pts = gr.grid_to_points()
00690 if collide_pts.shape[1] > 0:
00691 collide_pts = tr.Rz(rotation_angle).T*gr.grid_to_points()
00692 display_list.insert(0,pu.PointCloud(collide_pts,color=(0,0,0)))
00693 return gr
00694
00695
00696 def overhead_grasp_collision(pt,grid):
00697 print 'collision points:', grid.grid.sum()
00698 if grid.grid.sum()>15:
00699 return True
00700 else:
00701 return False
00702
00703
00704 def grasp_location_on_object(obj,display_list=None):
00705 ''' obj - 3xN numpy matrix of points of the object.
00706 '''
00707
00708 pts_2d = obj[0:2,:]
00709 centroid_2d = pts_2d.mean(1)
00710 pts_2d_zeromean = pts_2d-centroid_2d
00711 e_vals,e_vecs = np.linalg.eig(pts_2d_zeromean*pts_2d_zeromean.T)
00712
00713
00714 min_index = np.argmin(e_vals)
00715 min_evec = e_vecs[:,min_index]
00716
00717 print 'min eigenvector:', min_evec.T
00718 pts_1d = min_evec.T * pts_2d
00719 min_size = pts_1d.max() - pts_1d.min()
00720 print 'spread along min eigenvector:', min_size
00721
00722 max_height = obj[2,:].max()
00723
00724 tlb = obj.max(1)
00725 brf = obj.min(1)
00726 print 'tlb:', tlb.T
00727 print 'brf:', brf.T
00728
00729 resolution = np.matrix([0.005,0.005,0.005]).T
00730 gr = og3d.occupancy_grid_3d(brf,tlb,resolution)
00731 gr.fill_grid(obj)
00732 gr.to_binary(1)
00733 obj = gr.grid_to_points()
00734
00735 grid_2d = gr.grid.max(2)
00736 grid_2d_filled = ni.binary_fill_holes(grid_2d)
00737 gr.grid[:,:,0] = gr.grid[:,:,0]+grid_2d_filled-grid_2d
00738
00739 p = np.matrix(np.row_stack(np.where(grid_2d_filled==1))).astype('float')
00740 p[0,:] = p[0,:]*gr.resolution[0,0]
00741 p[1,:] = p[1,:]*gr.resolution[1,0]
00742 p += gr.brf[0:2,0]
00743 print 'new mean:', p.mean(1).T
00744 print 'centroid_2d:', centroid_2d.T
00745 centroid_2d = p.mean(1)
00746
00747
00748 if min_size<0.12:
00749
00750 grasp_point = np.row_stack((centroid_2d,np.matrix([max_height+gr.resolution[2,0]*2])))
00751
00752 gripper_angle = -math.atan2(-min_evec[0,0],min_evec[1,0])
00753 grasp_vec = min_evec
00754
00755 if display_list != None:
00756 max_index = np.argmax(e_vals)
00757 max_evec = e_vecs[:,max_index]
00758 pts_1d = max_evec.T * pts_2d
00759 max_size = pts_1d.max() - pts_1d.min()
00760
00761 v = np.row_stack((max_evec,np.matrix([0.])))
00762 max_end_pt1 = grasp_point + v*max_size/2.
00763 max_end_pt2 = grasp_point - v*max_size/2.
00764 display_list.append(pu.Line(max_end_pt1,max_end_pt2,color=(0,0,0)))
00765 else:
00766
00767
00768 for i in range(gr.grid_shape[2,0]):
00769 gr.grid[:,:,i] = gr.grid[:,:,i]*(i+1)
00770
00771 height_map = gr.grid.max(2) * gr.resolution[2,0]
00772
00773 print 'height std deviation:',math.sqrt(height_map[np.where(height_map>0.)].var())
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788 high_pts_2d = obj[0:2,np.where(obj[2,:]>max_height-0.005)[1].A1]
00789
00790 high_pts_1d = ut.norm(high_pts_2d)
00791 idx1 = np.argmin(high_pts_1d)
00792 pt1 = high_pts_2d[:,idx1]
00793
00794 idx2 = np.argmax(high_pts_1d)
00795 pt2 = high_pts_2d[:,idx2]
00796
00797 if np.linalg.norm(pt1)<np.linalg.norm(pt2):
00798 grasp_point = np.row_stack((pt1,np.matrix([max_height])))
00799 else:
00800 grasp_point = np.row_stack((pt2,np.matrix([max_height])))
00801
00802 vec = centroid_2d-grasp_point[0:2,0]
00803 gripper_angle = -math.atan2(-vec[0,0],vec[1,0])
00804 grasp_vec = vec/np.linalg.norm(vec)
00805
00806 if display_list != None:
00807 pt1 = np.row_stack((pt1,np.matrix([max_height])))
00808 pt2 = np.row_stack((pt2,np.matrix([max_height])))
00809
00810
00811
00812
00813 if display_list != None:
00814 pts = gr.grid_to_points()
00815 size = resolution
00816
00817
00818
00819 display_list.append(pu.CubeCloud(pts,color=(200,0,0),size=size))
00820 display_list.append(pu.CubeCloud(grasp_point,(0,200,200),size=(0.007,0.007,0.007)))
00821
00822 v = np.row_stack((grasp_vec,np.matrix([0.])))
00823 min_end_pt1 = grasp_point + v*min_size/2.
00824 min_end_pt2 = grasp_point - v*min_size/2.
00825
00826 max_evec = np.matrix((min_evec[1,0],-min_evec[0,0])).T
00827 pts_1d = max_evec.T * pts_2d
00828 max_size = pts_1d.max() - pts_1d.min()
00829
00830 display_list.append(pu.Line(min_end_pt1,min_end_pt2,color=(0,255,0)))
00831
00832 return grasp_point,gripper_angle
00833
00834
00835
00836
00837
00838 def test_vertical_plane_finding():
00839 display_list = []
00840 rot_angle = dict['rot_angle']
00841 gr = create_vertical_plane_grid(pt,pos_list,scan_list,l1,l2,rotation_angle=rot_angle,
00842 display_list=display_list)
00843
00844 vertical_plane_points(gr)
00845 plane_cloud = pu.PointCloud(gr.grid_to_points(),color=(0,150,0))
00846 display_list.insert(0,plane_cloud)
00847 po3d.run(display_list)
00848
00849 def test_find_door_handle():
00850 display_list = []
00851 rot_angle = dict['rot_angle']
00852
00853 print 'pt:',pt.A1.tolist()
00854 gr = create_vertical_plane_grid(pt,pos_list,scan_list,l1,l2,rotation_angle=rot_angle,
00855 display_list=display_list)
00856 grid_pts_cloud = pu.PointCloud(gr.grid_to_points(),(0,0,255))
00857 display_list.insert(0,grid_pts_cloud)
00858 copy_gr = copy.deepcopy(gr)
00859
00860 obj_pts_list = []
00861 print 'pt:',pt.A1.tolist()
00862
00863
00864 handle_object = find_door_handle(gr,pt,obj_pts_list,rotation_angle=rot_angle,
00865 occupancy_threshold=1,resolution=np.matrix([0.02,0.0025,0.02]).T)
00866
00867 copy_gr.remove_vertical_plane()
00868 stickout_pts_cloud = pu.PointCloud(copy_gr.grid_to_points(),(100,100,100))
00869 display_list.insert(0,stickout_pts_cloud)
00870
00871
00872 for i,obj_pts in enumerate(obj_pts_list):
00873 print 'mean:', obj_pts.mean(1).A1.tolist()
00874 size = [0.02,0.0025,0.02]
00875
00876 size[0] = size[0]*2
00877 size[1] = size[1]*2
00878
00879 display_list.append(pu.CubeCloud(obj_pts,color=color_list[i%len(color_list)],size=size))
00880
00881 laser_point_cloud = pu.CubeCloud(pt,color=(0,200,0),size=(0.005,0.005,0.005))
00882 po3d.run(display_list)
00883
00884
00885 def test_segmentation():
00886 gr = create_segmentation_grid(pt,pos_list,scan_list,l1,l2,
00887 display_flag=True)
00888 obj_pts_list = segment_objects_points(gr)
00889 if obj_pts_list == None:
00890 print 'There is no plane'
00891 obj_pts_list = []
00892
00893
00894 pts = gr.grid_to_points()
00895 d3m.plot_points(pts,color=(1.,1.,1.))
00896 d3m.plot_points(pt,color=(0,1,0.),mode='sphere')
00897
00898 for i,obj_pts in enumerate(obj_pts_list):
00899 size=gr.resolution.A1.tolist()
00900 size[2] = size[2]*2
00901 d3m.plot_points(obj_pts,color=color_list[i%len(color_list)])
00902
00903
00904 print 'mean:', obj_pts.mean(1).T
00905
00906 d3m.show()
00907
00908
00909 def test_grasp_location_on_object():
00910 display_list = []
00911
00912 gr = create_segmentation_grid(pt,pos_list,scan_list,l1,l2,display_list=display_list)
00913 obj_pts_list = segment_objects_points(gr)
00914 closest_obj = find_closest_object(obj_pts_list,pt)
00915 grasp_location_on_object(closest_obj,display_list)
00916
00917 po3d.run(display_list)
00918
00919 def test_plane_finding():
00920 ''' visualize plane finding.
00921 '''
00922
00923
00924
00925
00926
00927
00928
00929 brf = pt+np.matrix([-0.15,-0.25,-0.2]).T
00930 brf[0,0] = max(0.07,brf[0,0])
00931 tlb = pt+np.matrix([0.25, 0.25,0.2]).T
00932
00933 resolution = np.matrix([0.01,0.01,0.0025]).T
00934
00935 max_dist = np.linalg.norm(tlb) + 0.2
00936 min_dist = brf[0,0]
00937
00938 all_pts = generate_pointcloud(pos_list, scan_list, min_angle, max_angle, l1, l2,save_scan=False,
00939 max_dist=max_dist,min_dist=min_dist)
00940
00941
00942 gr = og3d.occupancy_grid_3d(brf,tlb,resolution)
00943 gr.fill_grid(all_pts)
00944 gr.to_binary(1)
00945 l = gr.find_plane_indices(assume_plane=True)
00946 z_min = min(l)*gr.resolution[2,0]+gr.brf[2,0]
00947 z_max = max(l)*gr.resolution[2,0]+gr.brf[2,0]
00948 print 'height of plane:', (z_max+z_min)/2
00949 pts = gr.grid_to_points()
00950
00951 plane_pts_bool = np.multiply(pts[2,:]>=z_min,pts[2,:]<=z_max)
00952 plane_pts = pts[:,np.where(plane_pts_bool)[1].A1.tolist()]
00953 above_pts =pts[:,np.where(pts[2,:]>z_max)[1].A1.tolist()]
00954 below_pts =pts[:,np.where(pts[2,:]<z_min)[1].A1.tolist()]
00955
00956
00957 d3m.plot_points(pt,color=(0,1,0.),mode='sphere')
00958 d3m.plot_points(plane_pts,color=(0,0,1.))
00959 d3m.plot_points(above_pts,color=(1.0,1.0,1.0))
00960 d3m.plot_points(below_pts,color=(1.,0.,0.))
00961
00962 cube_tups = gr.grid_lines()
00963 d3m.plot_cuboid(cube_tups)
00964
00965 d3m.show()
00966
00967
00968 def test_approach():
00969 display_list=[]
00970
00971
00972 gr = create_approach_grid(pt,pos_list,scan_list,l1,l2,display_list=display_list,show_pts=True)
00973 t0 = time.time()
00974 p_erratic,p_edge,h = find_goto_point_surface_1(gr,pt,display_list)
00975 t1 = time.time()
00976 print 'aaaaaaaaaaaaaah:', t1-t0
00977
00978 l = gr.find_plane_indices(assume_plane=True)
00979 z_min = min(l)*gr.resolution[2,0]+gr.brf[2,0]
00980 z_max = max(l)*gr.resolution[2,0]+gr.brf[2,0]
00981 print 'height of plane:', (z_max+z_min)/2
00982
00983 print 'height of surface in thok0 coord frame:', h
00984 print 'p_erratic in thok0:', p_erratic.T
00985 display_list.append(pu.CubeCloud(pt,color=(0,255,0),size=(0.018,0.018,0.018)))
00986
00987 display_list.insert(0,pu.PointCloud(gr.grid_to_points(),color=(100,100,100)))
00988
00989 po3d.run(display_list)
00990
00991 def test_max_forward():
00992 max_dist = math.sqrt(pt[0,0]**2+pt[1,0]**2+2.0**1) + 0.3
00993
00994 min_angle,max_angle=math.radians(-40),math.radians(40)
00995
00996 all_pts = generate_pointcloud(pos_list, scan_list, min_angle, max_angle, l1, l2, max_dist=max_dist,
00997 min_tilt=math.radians(-90))
00998
00999 display_list = []
01000 max_x = max_fwd_without_collision(all_pts,0.20,max_dist,display_list)
01001 po3d.run(display_list)
01002
01003 print 'max_x:', max_x
01004
01005 dict = {'pos_list':pos_list, 'scan_list':scan_list,'l1':l1, 'l2':l2, 'pt':pt}
01006
01007
01008 def test_choose_grasp_strategy():
01009 display_list = []
01010 far_dist = 0.15
01011 pt[1,0] += 0.0
01012 gr = create_overhead_grasp_choice_grid(pt,pos_list,scan_list,l1,l2,far_dist,display_list)
01013 print 'overhead collide?',overhead_grasp_collision(pt,gr)
01014 display_list.append(pu.CubeCloud(pt,color=(0,200,0),size=(0.005,0.005,0.005)))
01015
01016
01017
01018
01019 po3d.run(display_list)
01020
01021 def test_different_surfaces():
01022 display_list = []
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039 gr = create_approach_grid(pt,pos_list,scan_list,l1,l2,display_list)
01040
01041 l = gr.find_plane_indices(assume_plane=True)
01042 max_index = min(max(l)+5,gr.grid_shape[2,0]-1)
01043 min_index = max(min(l)-5,0)
01044 l = range(min_index,max_index+1)
01045
01046 n_points_list = []
01047 height_list = []
01048 for idx in l:
01049 n_points_list.append(gr.grid[:,:,idx].sum())
01050 height_list.append(idx*gr.resolution[2,0]+gr.brf[2,0])
01051
01052 pl.bar(height_list,n_points_list,width=gr.resolution[2,0],linewidth=0,align='center',color='y')
01053 max_occ = max(n_points_list)
01054 thresh = max_occ/5
01055 xmin,xmax = pl.xlim()
01056 t = pl.axis()
01057 t = (xmin+0.0017,xmax-0.001,t[2],t[3]+50)
01058
01059
01060 pl.plot([xmin,xmax],[thresh,thresh],c='b')
01061 pl.title('Histogram of number of points vs z-coordinate of points')
01062 pl.xlabel('z-coordinate (relative to the laser range finder) (meters)')
01063 pl.ylabel('Number of points')
01064 pl.axis(t)
01065 pl.savefig(pkl_file_name+'.png')
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084 def test_occ_grid():
01085
01086 gr = create_approach_grid(pt,pos_list,scan_list,l1,l2,display_list=None,show_pts=True)
01087
01088 pts = gr.grid_to_points()
01089 display_list=[]
01090 display_list.append(pu.CubeCloud(pt,color=(0,255,0),size=(0.007,0.007,0.007)))
01091 display_list.append(pu.PointCloud(pts,color=(200,0,0)))
01092 po3d.run(display_list)
01093
01094
01095 if __name__ == '__main__':
01096
01097 p = optparse.OptionParser()
01098 p.add_option('-f', action='store', type='string', dest='pkl_file_name',
01099 help='file.pkl File with the scan,pos dict.')
01100 p.add_option('--all_pts', action='store_true', dest='show_all_pts',
01101 help='show all the points in light grey')
01102
01103 opt, args = p.parse_args()
01104 pkl_file_name = opt.pkl_file_name
01105 show_full_cloud = opt.show_all_pts
01106
01107 str_parts = pkl_file_name.split('.')
01108 raw_name = str_parts[-2]
01109 str_parts = raw_name.split('/')
01110 raw_name = str_parts[-1]
01111
01112 dict = ut.load_pickle(pkl_file_name)
01113 pos_list = dict['pos_list']
01114 scan_list = dict['scan_list']
01115 min_angle = math.radians(-40)
01116 max_angle = math.radians(40)
01117
01118 l1 = dict['l1']
01119 l2 = dict['l2']
01120
01121
01122
01123 if dict.has_key('pt'):
01124 pt = dict['pt']
01125 print 'dict has key pt'
01126 else:
01127 print 'dict does NOT have key pt'
01128 pt = np.matrix([0.35,0.0,-0.3]).T
01129 dict['pt'] = pt
01130 ut.save_pickle(dict,pkl_file_name)
01131
01132
01133
01134
01135
01136
01137
01138 test_segmentation()
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148