00001
00002
00003 import sys
00004 import numpy as np, math
00005
00006 import roslib; roslib.load_manifest('hrl_common_code_darpa_m3')
00007 import hrl_lib.util as ut
00008
00009
00010 def generate_far_locations(start_y, total_num):
00011 x = np.zeros(total_num)
00012 y = np.arange(start_y*1., start_y+total_num)
00013 s = np.zeros(total_num)
00014 return x, y, s
00015
00016 def in_collision(x, y, s, x_arr, y_arr, s_arr, ctype, dim, goal):
00017
00018 if ctype == 'wall':
00019 length = dim[0]
00020 width = dim[1]
00021 slope = dim[3]
00022
00023
00024 for i in range(x_arr.size):
00025 if (np.linalg.norm([x_arr[i]-x]) < width and
00026 np.linalg.norm([y_arr[i]-y]) < length):
00027 return True
00028 if (np.linalg.norm([x-goal[0,0]]) < width/2.0 and
00029 np.linalg.norm([y-goal[1,0]]) < length/2.0):
00030 return True
00031 else:
00032 radius = dim[0]
00033
00034 for i in range(x_arr.size):
00035 if np.linalg.norm([x_arr[i]-x, y_arr[i]-y]) < 2.*radius:
00036 return True
00037 if np.linalg.norm([x-goal[0,0], y-goal[1,0]]) < 2.*radius:
00038 return True
00039
00040 return False
00041
00042 def in_collision_set(dim, pos, ctype, dim_arr, pos_arr, ctype_list):
00043
00044 if len(ctype_list) == 0: return False
00045
00046 for i in range(len(ctype_list)):
00047
00048 if ctype == 'cylinder' and ctype_list[i] == 'cylinder':
00049 if np.linalg.norm([pos_arr[i][0]-pos[0], pos_arr[i][1]-pos[1]]) < dim[0] + dim_arr[i][0]:
00050 return True
00051
00052 elif ctype == 'cylinder' and ctype_list[i] == 'wall':
00053
00054 slope = pos_arr[i][3]
00055 mRot = np.matrix([[np.cos(slope), -np.sin(slope)],
00056 [np.sin(slope), np.cos(slope)]])
00057
00058 length = dim_arr[i][0]
00059 width = dim_arr[i][1]
00060 mEdge = np.matrix([[pos_arr[i][0]-length/2.0, pos_arr[i][0]+length/2.0],
00061 [pos_arr[i][1], pos_arr[i][1]]])
00062
00063 mNewEdge = mRot*mEdge
00064
00065 if dist_segment_point(mNewEdge[0,0],mNewEdge[1,0], mNewEdge[0,1],mNewEdge[1,1], pos[0],pos[1]) < dim[0] + width:
00066 return True
00067
00068 elif ctype == 'wall' and ctype_list[i] == 'cylinder':
00069
00070 slope = pos[3]
00071 mRot = np.matrix([[np.cos(slope), -np.sin(slope)],
00072 [np.sin(slope), np.cos(slope)]])
00073
00074 length = dim[0]
00075 width = dim[1]
00076 mEdge = np.matrix([[pos[0]-length/2.0, pos[0]+length/2.0],
00077 [pos[1], pos[1]]])
00078
00079 mNewEdge = mRot*mEdge
00080
00081 if dist_segment_point(mNewEdge[0,0],mNewEdge[1,0], mNewEdge[0,1],mNewEdge[1,1], pos_arr[i][0],pos_arr[i][1]) < width + dim_arr[i][1]:
00082 return True
00083
00084 elif ctype == 'wall' and ctype_list[i] == 'wall':
00085
00086
00087 slope = pos[3]
00088 mRot = np.matrix([[np.cos(slope), -np.sin(slope)],
00089 [np.sin(slope), np.cos(slope)]])
00090
00091 length = dim[0]
00092 width = dim[1]
00093 mEdge = np.matrix([[pos[0]-length/2.0, pos[0]+length/2.0],
00094 [pos[1], pos[1]]])
00095
00096 mNewEdge_1 = mRot*mEdge
00097
00098
00099 slope = pos_arr[i][3]
00100 mRot = np.matrix([[np.cos(slope), -np.sin(slope)],
00101 [np.sin(slope), np.cos(slope)]])
00102
00103 length = dim_arr[i][0]
00104 width = dim_arr[i][1]
00105 mEdge = np.matrix([[pos_arr[i][0]-length/2.0, pos_arr[i][0]+length/2.0],
00106 [pos_arr[i][1], pos_arr[i][1]]])
00107
00108 mNewEdge_2 = mRot*mEdge
00109
00110 if intersect_segments(mNewEdge_1[0,0],mNewEdge_1[1,0], mNewEdge_1[0,1],mNewEdge_1[1,1],
00111 mNewEdge_2[0,0],mNewEdge_2[1,0], mNewEdge_2[0,1],mNewEdge_2[1,1]):
00112 return True
00113
00114 return False
00115
00116
00117
00118
00119 def dist_segment_point(x1,y1, x2,y2, x3,y3):
00120 px = x2-x1
00121 py = y2-y1
00122
00123 length = px*px + py*py
00124
00125 u = ((x3 - x1) * px + (y3 - y1) * py) / float(length)
00126
00127 if u > 1:
00128 u = 1
00129 elif u < 0:
00130 u = 0
00131
00132 x = x1 + u * px
00133 y = y1 + u * py
00134
00135 dx = x - x3
00136 dy = y - y3
00137
00138 dist = np.sqrt(dx*dx + dy*dy)
00139
00140 return dist
00141
00142
00143
00144
00145 def intersect_segments(x11, y11, x12, y12, x21, y21, x22, y22):
00146 dx1 = x12 - x11
00147 dy1 = y12 - y11
00148 dx2 = x22 - x21
00149 dy2 = y22 - y21
00150 delta = dx2 * dy1 - dy2 * dx1
00151 if delta == 0: return False
00152 s = (dx1 * (y21 - y11) + dy1 * (x11 - x21)) / delta
00153 t = (dx2 * (y11 - y21) + dy2 * (x21 - x11)) / (-delta)
00154 return (0 <= s <= 1) and (0 <= t <= 1)
00155
00156
00157
00158 def generate_random_obstacles(x_lim, y_lim, num_move_used, num_compliant_used,
00159 num_fixed_used, total_num, ctype, dim, goal, multi_obstacle=False):
00160
00161 dim_arr = []
00162 pos_arr = []
00163 ctype_list = []
00164
00165 if multi_obstacle:
00166 d = ut.load_pickle('reach_problem_dict.pkl')
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187 if d['num_fixed_used'] > 0:
00188 dim_arr += d['fixed_dimen']
00189 pos_arr += d['fixed_position']
00190 ctype_list += d.get('fixed_ctype', ['cylinder']*d['num_fixed_used'])
00191
00192 if d['num_compliant_used'] > 0:
00193 dim_arr += d['compliant_dimen']
00194 pos_arr += d['compliant_position']
00195 ctype_list += d.get('compliant_ctype', ['cylinder']*d['num_compliant_used'])
00196
00197 if d['num_move_used'] > 0:
00198 dim_arr += d['moveable_dimen']
00199 pos_arr += d['moveable_position']
00200 ctype_list += d.get('moveable_ctype', ['cylinder']*d['num_move_used'])
00201
00202 z = np.ones(num_move_used) * 0.0
00203 x_move, y_move, s_move = generate_far_locations(-100, num_move_used)
00204
00205 for i in range(num_move_used):
00206 collision = True
00207 while collision:
00208 if ctype == 'wall':
00209 x = (x_lim[0] + x_lim[1]) / 2.0
00210 y = np.random.uniform(y_lim[0], y_lim[1], 1)
00211 s = np.random.uniform(-dim[3], dim[3], 1)
00212 else:
00213 x = np.random.uniform(x_lim[0], x_lim[1], 1)
00214 y = np.random.uniform(y_lim[0], y_lim[1], 1)
00215 s = 0.0
00216
00217 pos = [x,y,0.0,s]
00218 collision = in_collision_set(dim, pos, ctype, dim_arr, pos_arr, ctype_list)
00219
00220
00221 dim_arr.append(dim)
00222 pos_arr.append(pos)
00223 ctype_list.append(ctype)
00224
00225 x_move[i] = x
00226 y_move[i] = y
00227 s_move[i] = s
00228
00229 moveable_position = np.row_stack((x_move,y_move,z,s_move)).T.tolist()
00230
00231 z = np.ones(num_compliant_used) * 0.0
00232 x_compliant, y_compliant, s_compliant = generate_far_locations(-200, num_compliant_used)
00233 for i in range(num_compliant_used):
00234 collision = True
00235 while collision:
00236 if ctype == 'wall':
00237 x = (x_lim[0] + x_lim[1]) / 2.0
00238 y = np.random.uniform(y_lim[0], y_lim[1], 1)
00239 s = np.random.uniform(-dim[3], dim[3], 1)
00240 else:
00241 x = np.random.uniform(x_lim[0], x_lim[1], 1)
00242 y = np.random.uniform(y_lim[0], y_lim[1], 1)
00243 s = 0.0
00244
00245 pos = [x,y,0.0,s]
00246 collision = in_collision_set(dim, pos, ctype, dim_arr, pos_arr, ctype_list)
00247
00248
00249
00250 dim_arr.append(dim)
00251 pos_arr.append(pos)
00252 ctype_list.append(ctype)
00253
00254 x_compliant[i] = x
00255 y_compliant[i] = y
00256 s_compliant[i] = s
00257
00258 compliant_position = np.row_stack((x_compliant,y_compliant,z,s_compliant)).T.tolist()
00259
00260 z = np.ones(num_fixed_used) * 0.0
00261 x_fix, y_fix, s_fix = generate_far_locations(100, num_fixed_used)
00262 for i in xrange(num_fixed_used):
00263 collision = True
00264 while collision:
00265 if ctype == 'wall':
00266 x = (x_lim[0] + x_lim[1]) / 2.0
00267 y = np.random.uniform(y_lim[0], y_lim[1], 1)
00268 s = np.random.uniform(-dim[3], dim[3], 1)
00269 else:
00270 x = np.random.uniform(x_lim[0], x_lim[1], 1)
00271 y = np.random.uniform(y_lim[0], y_lim[1], 1)
00272 s = 0.0
00273
00274 pos = [x,y,0.0,s]
00275 collision = in_collision_set(dim, pos, ctype, dim_arr, pos_arr, ctype_list)
00276
00277
00278
00279 dim_arr.append(dim)
00280 pos_arr.append(pos)
00281 ctype_list.append(ctype)
00282
00283 x_fix[i] = x
00284 y_fix[i] = y
00285 s_fix[i] = s
00286
00287 fixed_position = np.row_stack((x_fix, y_fix, z, s_fix)).T.tolist()
00288
00289 return moveable_position, compliant_position, fixed_position
00290
00291 def upload_to_param_server(d):
00292
00293 rospy.set_param('m3/software_testbed/goal', d['goal'])
00294 rospy.set_param('m3/software_testbed/num_total', d['num_total'])
00295
00296 rospy.set_param('m3/software_testbed/num_fixed', d['num_fixed_used'])
00297 rospy.set_param('m3/software_testbed/fixed_dimen', d['fixed_dimen'])
00298 rospy.set_param('m3/software_testbed/fixed_position', d['fixed_position'])
00299 rospy.set_param('m3/software_testbed/fixed_ctype', d.get('fixed_ctype', ['cylinder']*d['num_fixed_used']))
00300
00301 rospy.set_param('m3/software_testbed/num_compliant', d.get('num_compliant_used', 0))
00302 rospy.set_param('m3/software_testbed/compliant_dimen', d.get('compliant_dimen', []))
00303 rospy.set_param('m3/software_testbed/compliant_position', d.get('compliant_position', []))
00304 rospy.set_param('m3/software_testbed/compliant_stiffness_value', d.get('stiffness_value',[]))
00305
00306 rospy.set_param('m3/software_testbed/num_movable', d['num_move_used'])
00307 rospy.set_param('m3/software_testbed/movable_max_force', d.get('moveable_max_force', [2.0]*d['num_move_used']))
00308 rospy.set_param('m3/software_testbed/movable_position', d['moveable_position'])
00309
00310
00311 rospy.set_param('m3/software_testbed/movable_dimen', d['moveable_dimen'])
00312 rospy.set_param('m3/software_testbed/movable_ctype', d.get('moveable_ctype', ['cylinder']*d['num_move_used']))
00313
00314 def dict_from_param_server():
00315 d = {}
00316 d['num_fixed_used'] = rospy.get_param('m3/software_testbed/num_fixed')
00317 d['fixed_dimen'] = rospy.get_param('m3/software_testbed/fixed_dimen')
00318 d['fixed_position'] = rospy.get_param('m3/software_testbed/fixed_position')
00319 d['fixed_ctype'] = rospy.get_param('m3/software_testbed/fixed_ctype')
00320
00321 d['num_move_used'] = rospy.get_param('m3/software_testbed/num_movable')
00322 d['moveable_dimen'] = rospy.get_param('m3/software_testbed/movable_dimen')
00323 d['moveable_position'] = rospy.get_param('m3/software_testbed/movable_position')
00324 d['moveable_ctype'] = rospy.get_param('m3/software_testbed/movable_ctype')
00325
00326 d['num_total'] = rospy.get_param('m3/software_testbed/num_total')
00327 d['goal'] = rospy.get_param('m3/software_testbed/goal')
00328 return d
00329
00330
00331 if __name__ == '__main__':
00332 import roslib; roslib.load_manifest('hrl_common_code_darpa_m3')
00333 import rospy
00334
00335 import optparse
00336 p = optparse.OptionParser()
00337
00338 p.add_option('--fixed', action='store', dest='fixed',type='int',
00339 default=0, help='number of fixed obstacles')
00340 p.add_option('--sliding', action='store', dest='sliding',type='int',
00341 default=0, help='number of sliding obstacles')
00342 p.add_option('--compliant', action='store', dest='compliant',type='int',
00343 default=0, help='number of compliant obstacles')
00344
00345 p.add_option('--stiffness_value', action='store', dest='sv',
00346 type='float', default=100, help='stiffness value for compliant obstacles')
00347 p.add_option('--sliding_max_force', action='store', dest='sliding_max_force',type='float',
00348 default=2.0, help='max force for sliding obstacles')
00349
00350
00351 p.add_option('--xmin', action='store', dest='xmin',type='float',
00352 default=0.2, help='min x coord for random obstacles')
00353 p.add_option('--xmax', action='store', dest='xmax',type='float',
00354 default=0.6, help='max x coord for random obstacles')
00355 p.add_option('--ymin', action='store', dest='ymin',type='float',
00356 default=-0.3, help='min y coord for random obstacles')
00357 p.add_option('--ymax', action='store', dest='ymax',type='float',
00358 default=0.3, help='max y coord for random obstacles')
00359
00360 p.add_option('--radius', action='store', dest='radius',type='float',
00361 default=0.01, help='radius of the obstacles')
00362
00363 p.add_option('--check_openrave', action='store_true', dest='co',
00364 help='regenerate if openrave does not find a solution')
00365
00366 p.add_option('--save_pkl', action='store_true', dest='s_pkl',
00367 help='save config as pkl, instead of on the param server')
00368 p.add_option('--pkl', action='store', dest='pkl', default=None,
00369 help='pkl to read and load to the param server')
00370 p.add_option('--get_param_server', action='store_true',
00371 dest='gps',
00372 help='get params from param server and save as pkl')
00373
00374 p.add_option('--add_stuff', action='store', dest='add_stuff', default=None,
00375 help='add X number of obstacles to pickle, needs manual tweaking in file as well')
00376
00377 p.add_option('--c', '--class_type', action='store', dest='ctype', type='string',
00378 default='cylinder')
00379 p.add_option('--width', action='store', dest='width', type='float',
00380 default=0.02, help='width of the obstacles')
00381 p.add_option('--length', action='store', dest='length', type='float',
00382 default=0.6, help='length of the obstacles')
00383 p.add_option('--slope', action='store', dest='slope', type='float',
00384 default=np.pi/4.0, help='max slope of the obstacles')
00385
00386
00387 opt, args = p.parse_args()
00388
00389
00390 total_num = opt.fixed + opt.compliant + opt.sliding
00391
00392
00393 ctype = opt.ctype
00394 if ctype == 'wall':
00395 length = opt.length
00396 width = opt.width
00397 slope = opt.slope
00398 dim = [length, width, 0.2, slope]
00399 else:
00400 radius = opt.radius
00401 dim = [radius, radius, 0.2]
00402
00403 moveable_dimen = [dim for i in range(opt.sliding)]
00404 fixed_dimen = [dim for i in range(opt.fixed)]
00405 compliant_dimen = [dim for i in range(opt.compliant)]
00406
00407
00408 x_goal = float(np.random.uniform(opt.xmin, opt.xmax, 1)[0])
00409 y_goal = float(np.random.uniform(opt.ymin, opt.ymax, 1)[0])
00410 goal = np.matrix([x_goal, y_goal, 0]).T
00411
00412 x_lim = [opt.xmin, opt.xmax]
00413 y_lim = [opt.ymin, opt.ymax]
00414
00415
00416 if opt.s_pkl != None and opt.add_stuff != None:
00417 multi_obstacle = True
00418 else:
00419 multi_obstacle = False
00420
00421 sliding_pos, compliant_pos, fixed_pos = generate_random_obstacles(x_lim,
00422 y_lim, opt.sliding, opt.compliant, opt.fixed,
00423 total_num, ctype, dim, goal, multi_obstacle)
00424
00425 stiff_ls = [opt.sv] * opt.compliant
00426
00427
00428 if opt.pkl != None and opt.add_stuff != None and opt.s_pkl == None:
00429 x_new = []
00430 y_new = []
00431 move_pos = np.array(d['moveable_position'])
00432 fixed_pos = np.array(d['fixed_position'])
00433 print "size of move_pos is: ", move_pos.shape
00434 print move_pos[:,0]
00435 z_new = np.ones(opt.add_stuff) * 0.0
00436 for i in xrange(opt.add_stuff):
00437 collision = True
00438 while collision:
00439 if xmin == None or xmax == None or ymin == None or ymax == None:
00440 print "need to specify x, y max and min for this argument"
00441 x = np.random.uniform(xmin, xmax, 1)
00442 y = np.random.uniform(ymin, ymax, 1)
00443
00444 collision = in_collision(x, y, move_pos[:,0], move_pos[:,1], ctype, dim, goal) \
00445 or in_collision(x, y, fixed_pos[:,0], fixed_pos[:,1], ctype, dim, goal)
00446
00447 x_new.append(x[0])
00448 y_new.append(y[0])
00449
00450 movable_position = np.row_stack((np.array(x_new), np.array(y_new), z_new)).T.tolist()
00451
00452
00453 d['moveable_position'][11] = movable_position[0]
00454 d['moveable_position'][12] = movable_position[1]
00455 d['moveable_position'][13] = movable_position[2]
00456 d['moveable_position'][14] = movable_position[3]
00457 d['moveable_position'][15] = movable_position[4]
00458 d['goal'] = goal.A1.tolist()
00459 upload_to_param_server(d)
00460 elif opt.pkl != None:
00461 d = ut.load_pickle(opt.pkl)
00462 upload_to_param_server(d)
00463 elif opt.s_pkl != None and opt.add_stuff != None:
00464 d = ut.load_pickle('reach_problem_dict.pkl')
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494 d['num_fixed_used'] += opt.fixed
00495 d['fixed_dimen'] += fixed_dimen
00496 d['fixed_position'] += fixed_pos
00497 d['fixed_ctype'] += [ctype] * opt.fixed
00498
00499 d['num_compliant_used'] += opt.compliant
00500 d['compliant_dimen'] += compliant_dimen
00501 d['compliant_position'] += compliant_pos
00502 d['compliant_ctype'] += [ctype] * opt.compliant
00503 d['stiffness_value'] += stiff_ls
00504
00505 d['num_move_used'] += opt.sliding
00506 d['moveable_dimen'] += moveable_dimen
00507 d['moveable_position'] += sliding_pos
00508 d['moveable_ctype'] += [ctype] * opt.sliding
00509 d['moveable_max_force'] += [opt.sliding_max_force]*opt.sliding
00510
00511
00512 d['num_total'] += total_num
00513
00514
00515 ut.save_pickle(d, 'reach_problem_dict.pkl')
00516
00517 else:
00518 if opt.gps:
00519 d = dict_from_param_server()
00520 ut.save_pickle(d, 'reach_problem_dict.pkl')
00521 else:
00522 d = {}
00523 d['num_fixed_used'] = opt.fixed
00524 d['fixed_dimen'] = fixed_dimen
00525 d['fixed_position'] = fixed_pos
00526 d['fixed_ctype'] = [ctype] * opt.fixed
00527
00528 d['num_compliant_used'] = opt.compliant
00529 d['compliant_dimen'] = compliant_dimen
00530 d['compliant_position'] = compliant_pos
00531 d['compliant_ctype'] = [ctype] * opt.compliant
00532 d['stiffness_value'] = stiff_ls
00533
00534 d['num_move_used'] = opt.sliding
00535 d['moveable_dimen'] = moveable_dimen
00536 d['moveable_position'] = sliding_pos
00537 d['moveable_ctype'] = [ctype] * opt.sliding
00538 d['moveable_max_force'] = [opt.sliding_max_force]*opt.sliding
00539
00540
00541 d['num_total'] = total_num
00542 d['goal'] = goal.A1.tolist()
00543
00544 if opt.co:
00545
00546 print 'Calling OpenRAVE to ceck if path exists'
00547 import geometric_search.planar_openrave as gspo
00548 res = gspo.setup_openrave_and_plan(d, True, True,
00549 'openrave_result_ignore_moveable.pkl')
00550 print 'OpenRAVE result:', res
00551 if not res:
00552 sys.exit(1)
00553
00554 if opt.s_pkl:
00555 ut.save_pickle(d, 'reach_problem_dict.pkl')
00556 else:
00557 upload_to_param_server(d)
00558
00559
00560