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