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 import roslib
00033 roslib.load_manifest('equilibrium_point_control')
00034
00035
00036 import numpy as np, math
00037 import scipy.optimize as so
00038 import scipy.ndimage as ni
00039 import matplotlib_util.util as mpu
00040 import hrl_lib.util as ut
00041 import hrl_lib.transforms as tr
00042 import hrl_hokuyo.hokuyo_processing as hp
00043 import mekabot.coord_frames as mcf
00044 import util as uto
00045 from opencv.highgui import *
00046
00047
00048
00049
00050 def cartesian_to_polar(pts):
00051 r = ut.norm(pts).A1
00052 theta = np.arctan2(pts[1,:],pts[0,:]).A1
00053 return r,theta
00054
00055
00056
00057
00058
00059 def polar_to_cartesian(r,theta):
00060 x = r*np.cos(theta)
00061 y = r*np.sin(theta)
00062 return np.matrix(np.row_stack((x,y)))
00063
00064
00065
00066
00067
00068 def point_contained(mx,my,ma,cx,cy,rad,pts,start_angle,end_angle,buffer):
00069 if abs(mx)>0.2 or abs(my)>0.2 or abs(ma)>math.radians(40):
00070
00071 return np.array([[]])
00072 pts_t = pts + np.matrix([mx,my]).T
00073 pts_t = tr.Rz(-ma)[0:2,0:2]*pts_t
00074 r,t = cartesian_to_polar(pts_t-np.matrix([cx,cy]).T)
00075 t = np.mod(t,math.pi*2)
00076 if start_angle<end_angle:
00077 f = np.row_stack((r<rad+buffer,r>rad-buffer/2.,t<end_angle,t>start_angle))
00078 else:
00079 f = np.row_stack((r<rad+buffer,r>rad-buffer/2.,t<start_angle,t>end_angle))
00080 idxs = np.where(np.all(f,0))
00081
00082 r_filt = r[idxs]
00083 t_filt = t[idxs]
00084 return polar_to_cartesian(r_filt,t_filt)+np.matrix([cx,cy]).T
00085
00086 def optimize_position(cx,cy,rad,curr_pos,eq_pos,pts,bndry,start_angle,
00087 end_angle,buffer,tangential_force):
00088 scale_x,scale_y,scale_a = 1.,1.,1.
00089 b = min(abs(tangential_force),60.)
00090 if end_angle>start_angle:
00091
00092 max_alpha = math.radians(90)
00093 else:
00094
00095 max_alpha = math.radians(-90)
00096 min_alpha = max_alpha - math.radians(60-b*0.7)
00097
00098 dist_moved_weight = 0.4 - 0.3*b/60.
00099 alpha_weight = 0.4+1.0*b/60.
00100 bndry_weight = 1.
00101 pts_in_weight = 1.
00102
00103 print 'OPTIMIZE_POSITION'
00104 print 'start_angle:', math.degrees(start_angle)
00105 print 'end_angle:', math.degrees(end_angle)
00106 print 'tangential_force:', tangential_force
00107
00108 def error_function(params):
00109 mx,my,ma = params[0],params[1],params[2]
00110 mx,my,ma = mx/scale_x,my/scale_y,ma/scale_a
00111
00112 pts_in = point_contained(mx,my,ma,cx,cy,rad,pts,
00113 start_angle,end_angle,buffer)
00114 p = tr.Rz(ma)*curr_pos-np.matrix([mx,my,0.]).T
00115 p_eq = tr.Rz(ma)*eq_pos-np.matrix([mx,my,0.]).T
00116
00117 dist_moved = math.sqrt(mx*mx+my*my)+abs(ma)*0.2
00118 dist_bndry = dist_from_boundary(p_eq,bndry,pts)
00119 alpha = math.pi-(start_angle-ma)
00120
00121 if alpha<min_alpha:
00122 alpha_cost = min_alpha-alpha
00123 elif alpha>max_alpha:
00124 alpha_cost = alpha-max_alpha
00125 else:
00126 alpha_cost = 0.
00127 alpha_cost = alpha_cost * alpha_weight
00128 move_cost = dist_moved * dist_moved_weight
00129 bndry_cost = dist_bndry * bndry_weight
00130 pts_in_cost = pts_in.shape[1]/1000. * pts_in_weight
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144 err = -pts_in_cost-bndry_cost+move_cost+alpha_cost
00145
00146 return err
00147
00148 params_1 = [0.,0.,0.]
00149 res = so.fmin_bfgs(error_function,params_1,full_output=1)
00150
00151 r,f = res[0],res[1]
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162 opt_params = r
00163
00164 mx,my,ma = opt_params[0]/scale_x,opt_params[1]/scale_y,\
00165 opt_params[2]/scale_a
00166 error_function(opt_params)
00167 return mx,my,ma
00168
00169
00170
00171
00172
00173
00174 def compute_boundary(pts):
00175 npim1,nx,ny,br = hp.xy_map_to_np_image(pts,m_per_pixel=0.01,dilation_count=0,padding=10)
00176 npim1 = npim1/255
00177 npim = np.zeros(npim1.shape,dtype='int')
00178 npim[:,:] = npim1[:,:]
00179
00180 connect_structure = np.empty((3,3),dtype='int')
00181 connect_structure[:,:] = 1
00182 erim = ni.binary_erosion(npim,connect_structure,iterations=1)
00183 bim = npim-erim
00184 tup = np.where(bim>0)
00185 bpts = np.row_stack((nx-tup[0],ny-tup[1]))*0.01 + br
00186
00187
00188 return np.matrix(bpts)
00189
00190
00191
00192 def vec_from_boundary(curr_pos,bndry):
00193 p = curr_pos[0:2,:]
00194 v = p-bndry
00195 min_idx = np.argmin(ut.norm(v))
00196 return v[:,min_idx]
00197
00198
00199
00200
00201
00202
00203 def dist_from_boundary(curr_pos,bndry,pts):
00204 mv = vec_from_boundary(curr_pos,bndry)
00205
00206
00207 d = np.linalg.norm(mv)
00208
00209 p = curr_pos[0:2,:]
00210 v = p-pts
00211 min_dist = np.min(ut.norm(v))
00212
00213
00214 if min_dist >= d-0.001:
00215
00216 d = -d
00217
00218
00219
00220
00221 return d
00222
00223
00224
00225
00226 def close_to_boundary(curr_pos,bndry,pts,dist_thresh):
00227 min_dist = dist_from_boundary(curr_pos,bndry,pts)
00228 return min_dist <= dist_thresh
00229
00230 def visualize_boundary():
00231 d = ut.load_pickle('../../pkls/workspace_dict_2009Sep03_010426.pkl')
00232 z = -0.23
00233 k = d.keys()
00234 k_idx = np.argmin(np.abs(np.array(k)-z))
00235 pts = d[k[k_idx]]
00236 bpts = compute_boundary(pts)
00237
00238 cl_list = []
00239 for pt in pts.T:
00240 if close_to_boundary(pt.T,bpts,dist_thresh=0.05)==True:
00241 cl_list.append(pt.A1.tolist())
00242 clpts = np.matrix(cl_list).T
00243 print 'clpts.shape:', clpts.shape
00244
00245 mpu.plot_yx(pts[1,:].A1,pts[0,:].A1,linewidth=0)
00246 mpu.plot_yx(clpts[1,:].A1,clpts[0,:].A1,linewidth=0,color='r')
00247 mpu.plot_yx(bpts[1,:].A1,bpts[0,:].A1,linewidth=0,color='y')
00248 mpu.show()
00249
00250
00251
00252
00253
00254
00255 def tlTts(pts_ts,x,y,a):
00256 pts_ms = mcf.mecanumTglobal(mcf.globalTtorso(pts_ts))
00257 v_org_ms = np.matrix([x,y,0.]).T
00258 pts_ml = tr.Rz(a)*(pts_ms-v_org_ms)
00259 pts_tl = mcf.torsoTglobal(mcf.globalTmecanum(pts_ml))
00260 return pts_tl
00261
00262
00263
00264
00265
00266 def tsTtl(pts_tl,x,y,a):
00267 pts_ml = mcf.mecanumTglobal(mcf.globalTtorso(pts_tl))
00268 v_org_ms = np.matrix([x,y,0.]).T
00269 pts_ms = tr.Rz(-a) * pts_ml + v_org_ms
00270 pts_ts = mcf.torsoTglobal(mcf.globalTmecanum(pts_ms))
00271 return pts_ts
00272
00273
00274
00275
00276
00277 def tsRtl(vecs_tl, a):
00278 vecs_ml = mcf.mecanumTglobal(mcf.globalTtorso(vecs_tl, True), True)
00279 vecs_ms = tr.Rz(-a) * vecs_ml
00280 vecs_ts = mcf.torsoTglobal(mcf.globalTmecanum(vecs_ms, True), True)
00281 return vecs_ts
00282
00283
00284
00285
00286
00287 def tlRts(vecs_ts, a):
00288 vecs_ms = mcf.mecanumTglobal(mcf.globalTtorso(vecs_ts, True), True)
00289 vecs_ml = tr.Rz(a) * vecs_ms
00290 vecs_tl = mcf.torsoTglobal(mcf.globalTmecanum(vecs_ml, True), True)
00291 return vecs_tl
00292
00293
00294 def pts_within_dist(p,pts,min_dist,max_dist):
00295 v = p-pts
00296 d_arr = ut.norm(v).A1
00297 idxs = np.where(np.all(np.row_stack((d_arr<max_dist,d_arr>min_dist)),axis=0))
00298 pts_within = pts[:,idxs[0]]
00299 return pts_within
00300
00301
00302
00303
00304
00305 def segway_motion_repulse(curr_pos_tl, eq_pt_tl,bndry, all_pts):
00306 bndry_dist_eq = dist_from_boundary(eq_pt_tl,bndry,all_pts)
00307 bndry_dist_ee = dist_from_boundary(curr_pos_tl,bndry,all_pts)
00308 if bndry_dist_ee < bndry_dist_eq:
00309 p = curr_pos_tl[0:2,:]
00310 bndry_dist = bndry_dist_ee
00311 else:
00312 p = eq_pt_tl[0:2,:]
00313 bndry_dist = bndry_dist_eq
00314
00315
00316 pts_close = pts_within_dist(p,bndry,0.002,0.07)
00317 v = p-pts_close
00318 d_arr = ut.norm(v).A1
00319 v = v/d_arr
00320 v = v/d_arr
00321 resultant = v.sum(1)
00322 res_norm = np.linalg.norm(resultant)
00323 resultant = resultant/res_norm
00324 tvec = -resultant
00325
00326 if bndry_dist < 0.:
00327 tvec = -tvec
00328
00329 if abs(bndry_dist)<0.01 or res_norm<0.01:
00330
00331
00332 m = all_pts.mean(1)
00333 tvec = m-p
00334 tvec = -tvec/np.linalg.norm(tvec)
00335
00336 dist_move = 0.
00337 if bndry_dist > 0.05:
00338 dist_move = 0.
00339 else:
00340 dist_move = 1.
00341
00342 tvec = tvec*dist_move
00343 return tvec
00344
00345
00346 if __name__ == '__main__':
00347
00348
00349 d = ut.load_pickle('../../pkls/workspace_dict_2009Sep05_200116.pkl')
00350 z = -0.23
00351 k = d.keys()
00352 k_idx = np.argmin(np.abs(np.array(k)-z))
00353 pts = d[k[k_idx]]
00354
00355
00356 for kk in k:
00357 pts = d[kk]
00358 bpts = compute_boundary(pts)
00359 cx,cy = 0.7,-0.6
00360 rad = 0.4
00361
00362
00363
00364
00365 mpu.figure()
00366 mpu.plot_yx(pts[1,:].A1,pts[0,:].A1,linewidth=0)
00367 mpu.plot_yx(bpts[1,:].A1,bpts[0,:].A1,linewidth=0,color='y')
00368
00369
00370 mpu.show()
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403