예제 #1
0
def update (t, P, MAP, N):
    # remove points
    angles = np.arange(lidar_angle_min,lidar_angle_max+lidar_angle_increment-1e-3,lidar_angle_increment)
    ranges = lidar_ranges[:,t]
    valid = np.logical_and((ranges < lidar_range_max), (ranges > lidar_range_min))
    angles = angles[valid]
    ranges = ranges[valid]
   
    # from lidar frame to world frame
    x_b = ranges * np.cos(angles)
    y_b = ranges * np.sin(angles)
    
    for i in range(N):
        [X,Y,theta] = P[i,:]
        x_w = x_b * np.cos(theta) - y_b * np.sin(theta) + X
        y_w = x_b * np.sin(theta) + y_b * np.cos(theta) + Y
        vp = np.stack((x_w,y_w))
        corr[i] = np.max(mapCorrelation(MAP['map'],x_im,y_im,vp,x_range,y_range))
   
    W = softmax(corr)
    ind = np.argmax(W)
    [X,Y,theta] = P[ind,:]
    state = [X,Y,theta]
    
    # resample
    if 1/(W**2).sum() < 0.1:
        W, P = resampling (W, P, N)
# =============================================================================
#     print(W)
# =============================================================================
    return P,state,W
예제 #2
0
def update(mus, alphas, z, maps):
    map_corr = np.zeros(len(mus))
    for i in range(len(mus)):
        x_old, y_old, theta_old = mus[i]
        d_position = 2 * update_sigma_position / update_n_dposition
        d_angle = 2 * update_sigma_angle / update_n_dangle
        x_range = np.arange(-update_sigma_position,
                            update_sigma_position + d_position, d_position)
        y_range = np.arange(-update_sigma_position,
                            update_sigma_position + d_position, d_position)
        theta_range = np.arange(-update_sigma_angle, update_sigma_angle +
                                d_angle, d_angle) + theta_old
        for theta in theta_range:
            wTb = np.matrix([[np.cos(theta), -np.sin(theta), x_old],
                             [np.sin(theta),
                              np.cos(theta), y_old], [0, 0, 1]])
            xs0w = wTb * np.vstack(
                (z * np.cos(angles), z * np.sin(angles), np.ones(
                    angles.shape)))
            Y = xs0w[:2]
            x_im = np.arange(MAP['xmin'], MAP['xmax'] + MAP['res'],
                             MAP['res'])  #x-positions of each pixel of the map
            y_im = np.arange(MAP['ymin'], MAP['ymax'] + MAP['res'],
                             MAP['res'])  #y-positions of each pixel of the map
            c = map_utils.mapCorrelation(maps[i], x_im, y_im, Y, x_range,
                                         y_range)
            if map_corr[i] < c.max():
                j, k = np.unravel_index(c.argmax(), c.shape)
                mus[i][0] = x_range[j] + x_old
                mus[i][1] = y_range[k] + y_old
                mus[i][2] = theta
                map_corr[i] = float(np.max(c))
    alphas *= np.exp(map_corr - map_corr.max())
    alphas /= alphas.sum()
    return alphas, mus
예제 #3
0
def update(MAP, Sw, weight, ranges, angles, bTl):
    # grid cells representing walls with 1
    map_wall = ((1 - 1 / (1 + np.exp(MAP['map']))) > 0.5).astype(np.int)
    x_im = np.arange(MAP['xmin'], MAP['xmax'] + MAP['res'],
                     MAP['res'])  # x-positions of each pixel of the map
    y_im = np.arange(MAP['ymin'], MAP['ymax'] + MAP['res'],
                     MAP['res'])  # y-positions of each pixel of the map
    # 9 x 9
    x_range = np.arange(-4 * MAP['res'], 5 * MAP['res'],
                        MAP['res'])  # x deviation
    y_range = np.arange(-4 * MAP['res'], 5 * MAP['res'],
                        MAP['res'])  # y deviation

    # end point of laser beam in phisical units in laser frame
    ex = ranges * np.cos(angles)
    ey = ranges * np.sin(angles)
    # convert to homogenized coordinates in body frame
    s_h = np.ones((4, np.size(ex)))
    s_h[0, :] = ex
    s_h[1, :] = ey
    s_h = np.dot(bTl, s_h)

    numofparticles = np.shape(Sw)[1]
    correlation = np.zeros(numofparticles)
    for i in range(numofparticles):
        xt = Sw[:, i]
        # body to world transform
        x_w = xt[0]
        y_w = xt[1]
        theta_w = xt[2]
        wTb = np.array([[np.cos(theta_w), -np.sin(theta_w), 0, x_w],
                        [np.sin(theta_w),
                         np.cos(theta_w), 0, y_w], [0, 0, 1, 0], [0, 0, 0, 1]])
        # transformed into world frame
        s_w = np.dot(wTb, s_h)
        ex_w = s_w[0, :]
        ey_w = s_w[1, :]
        Y = np.stack((ex_w, ey_w))
        # calculate correlation
        c = map_utils.mapCorrelation(map_wall, x_im, y_im, Y, x_range, y_range)
        # find best correlation
        correlation[i] = np.max(c)
        # ind = np.unravel_index(np.argmax(c, axis=None), c.shape)
        # Sw[0,:]+=x_range[ind[0]]
        # Sw[1,:]+=x_range[ind[1]]

    # update particle weight
    ph = softmax(correlation)
    weight = weight * ph / np.sum(weight * ph)

    return Sw, weight
예제 #4
0
    def predict(self, pose, scan):
        '''
        Prediction of particle filter.

        Args:
            pose: encoder pose (x, y, theta)
            scan: lidar ranges

        Returns:
            Updated `cor_mle`.
        '''
        # particles
        pose_diff = pose - self.prev_pose
        self.prev_pose = pose
        self.particles += pose_diff + randn(self.N, 3) * self.noise
        self.particles[:, 2] %= 2 * np.pi
        self.cor_mle = np.zeros(self.N)

        # index of x and y coordinate
        x_im, y_im = np.arange(
            self.grid.shape[0]), np.arange(self.grid.shape[1])

        # 5x5 window
        xs, ys = np.arange(-2*self.res, 3*self.res,
                           self.res), np.arange(-2*self.res, 3*self.res, self.res)

        # temp grid for computing map correlation
        temp = np.zeros_like(self.grid)
        temp[self.grid > 0] = 1
        temp[self.grid < 0] = -1

        # iterate N particles
        for j in range(self.N):
            # pose in world frame
            theta = (self.lidar_angles + self.particles[j][2]).reshape((-1, 1))
            x = scan * np.cos(theta) / self.res + self.grid.shape[0]//2
            y = scan * np.sin(theta) / self.res + self.grid.shape[1]//2
            # map correlation
            mpcor = mapCorrelation(temp, x_im, y_im, np.vstack(
                (x, y)), self.particles[j][0]+xs, self.particles[j][1]+ys)
            self.cor_mle[j] = np.max(mpcor)
예제 #5
0
    def update_particles(self, MAP, particles, lidar_range, angles):
        '''
        From current location of the particles and the lidar scan
        update the new map
        '''
        from TEST import Mapping
        mp = Mapping()
        angles, ranges = mp.rm_ld(angles, lidar_range)
        (x_l, y_l) = mp.pol2car(angles, ranges)
        h_l = mp.car2hom(x_l, y_l)
        h_b = mp.trans_l2b(h_l)

        cor_max = []

        for i in range(particles.shape[0]):
            x_p = particles[i, 0]
            y_p = particles[i, 1]
            theta_p = particles[i, 2]

            hp_w = mp.trans_b2w(h_b, x_p, y_p, theta_p)
            xp_w, yp_w = mp.hom2car(hp_w)

            # convert position in the map frame here
            Y = np.stack((xp_w, yp_w))

            x_im = np.arange(MAP['xmin'], MAP['xmax'] + MAP['res'],
                             MAP['res'])  #x-positions of each pixel of the map
            y_im = np.arange(MAP['ymin'], MAP['ymax'] + MAP['res'],
                             MAP['res'])  #y-positions of each pixel of the map

            x_range = np.arange(-0.2, 0.2 + 0.05, 0.05)
            y_range = np.arange(-0.2, 0.2 + 0.05, 0.05)

            cor = abs(
                map_utils.mapCorrelation(MAP['map'], x_im, y_im, Y, x_range,
                                         y_range))

            cor_max.append(np.max(cor))

        return cor, cor_max
def slam(X,W,encoder_stamps,encoder_pos,lidar_stamsp,lidar_ranges,grid,res,SLAM_MAP,WALK_MAP,Texture_map):
    
    #video = cv2.VideoWriter('test.avi', -1, 1, (grid.shape[0], grid.shape[1]), isColor=3)
    now_list = []
    pred_pos = encoder_pos[0]
    noise = np.array([0.02, 0.02, 0.5 * np.pi /180])
    for t, lidar in enumerate(lidar_stamsp[::10]):
        
        print('\n')
        print(t)
        scan = lidar_ranges[:,t*10]
        
        # time alignment
        encoder_idx = np.argmin(np.abs(lidar-encoder_stamps))
        encoder_delta = encoder_pos[encoder_idx] - pred_pos 
        
        
        # predict
        noises = np.random.randn(N,3)*noise   # maybe scale here
        X = X + encoder_delta + noises
        X[:,2] %= 2*math.pi
    
        
        x_im,y_im = np.arange(grid.shape[0]),np.arange(grid.shape[1])
        xs = ys = np.arange(-res*4,res*4+res,res)
        tem = np.zeros_like(grid)
        tem[grid>0] = 1
        tem[grid<0] = -1
        
        corr_max = []
        for i in range(len(X)):
            angles = lidar_angle + X[i,2]
            valid_scan = np.logical_and(scan>=0.1,scan<=30)
            ranges = scan[valid_scan]
            
            
            theta = angles[valid_scan]
            
            # turn to Cartesian coordinate system
            xx, yy = ranges * np.cos(theta), ranges * np.sin(theta)
            # turn to cells
            xx = xx/res + grid.shape[0]//2
            yy = yy/res + grid.shape[1]//2
                
            cor = mapCorrelation(grid,x_im,y_im,np.vstack((xx,yy)), (X[i,0]+xs)/res, (X[i,1]+ys)/res)
            corr_max.append(np.max(cor))
            
            
        # update particle weights
        corr_max = W * np.array(corr_max)
        e_x = np.exp(corr_max-np.max(corr_max))
        W = e_x / e_x.sum()
        
        # find best particle
        best_particle = np.where(W == np.max(W))[0][0]
        now_best = X[best_particle].copy()
        now_best = now_best.ravel()
        test = now_best.copy()
        now_best[0]/= res
        now_best[1]/= res

        
        grid = mapping(grid,scan,now_best,res,lidar_angle)
        
        
        img = np.zeros((grid_size, grid_size, 3))
        img[:, :, 0] = grid 
        img[:, :, 1] = grid
        img[:, :, 2] = grid 
        cv2.circle(img,(int(now_best[1]) + grid.shape[1]//2,int(now_best[0]) + grid.shape[0]//2),4,(0,0,255),-1)
        
        if t% 50 == 1:
            cv2.imwrite(f"data\\test_{t}.png",img.astype(np.uint8))
        #video.write(img.astype(np.uint8))
        
        
        if 1/(W**2).sum() < (0.85 * N):
            idx = stratified_resample(W)
            W.fill(1.0 / N)
			X[:] = X[idx]
            
    
        SLAM_MAP[int(now_best[0]) + SLAM_MAP.shape[0]//2, int(now_best[1]) + SLAM_MAP.shape[1]//2] = 1
        WALK_MAP[int(encoder_pos[encoder_idx][0]/res) + WALK_MAP.shape[0]//2, int(encoder_pos[encoder_idx][1]/res) + WALK_MAP.shape[1]//2] = 1
        
        now_list.append(now_best)
        pred_pos = encoder_pos[encoder_idx]
예제 #7
0
    cors = []

    x_im, y_im = np.arange(grid.shape[0]), np.arange(grid.shape[1])
    l = 1
    xs, ys = np.arange(-res * l, res * l + res,
                       res), np.arange(-res * l, res * l + res, res)
    temp = np.zeros_like(grid)
    temp[grid > 0] = 1
    temp[grid < 0] = -1

    for i in range(len(X)):
        world_angles = lidar_angles + X[i][2]
        x, y = lidar * np.cos(world_angles), lidar * np.sin(world_angles)
        x, y = x / res + grid.shape[0] // 2, y / res + grid.shape[1] // 2
        cor = mapCorrelation(temp, x_im, y_im, np.vstack((x, y)),
                             (X[i][0] + xs) / res, (X[i][1] + ys) / res)
        cors.append(np.max(cor))

    cors = W * np.array(cors)
    W = softmax(cors)

    best = np.where(W == np.max(W))[0][0]
    now = X[best].copy()
    now[0] /= res
    now[1] /= res
    img_name = 'rgb%d_%d.png' % (dataset, cor_rgb[lidar_index])
    depth_name = 'disparity%d_%d.png' % (dataset, cor_depth[lidar_index])

    grid = mapping(grid, lidar, now, res, lidar_angles)
    now_texture = now.copy()
예제 #8
0
 def ParticleFilter(self,particles_number):
     newranges = self.lidar_ranges
     # take valid indices
     valid = np.logical_and((newranges[:,0] < 30),(newranges[:,0]> 0.1))
     newranges = newranges[valid]
     angles = self.angles[valid]
     
     newranges = uniformscandata(newranges,self.lidar_stamps,self.encoder_stamps)
     lamda = np.zeros((self.frame_size,self.frame_size))
     walkmap = np.zeros((self.frame_size,self.frame_size))
     slammap = np.zeros((self.frame_size,self.frame_size))
     now_tra = np.zeros((3,np.size(newranges,1)))
     x,y,theta,v,w = self.InputMotion()
     
     #particle number
     N=particles_number
     particle = np.zeros((N,3))
     W = np.ones(N)/N
     res = 0.05
     dif = 2
     x_im = np.arange(-30,30)
     y_im = np.arange(-30,30)
     x_dif,y_dif = np.arange(-dif*res,dif*res,res),np.arange(-dif*res,dif*res,res)
     now = np.zeros((3,))
     noise1 = np.array([0.05, 0.05, 0.1*np.pi/180])
     noise2 = np.array([0.01, 0.01, 0.03*np.pi/180])
     cors = []
     
     for j in range(N):
         noises = np.random.randn(1,3)*noise1  
         particle[j,:] = [x[0],y[0],theta[0]]+noises
         
         #
     for i in range(1,np.size(newranges,1)): 
         for j in range(N):
             #        print('particle'+str(j))
             noises = np.random.randn(1,3)*noise2
             dx,dy,dtheta = motion_diff(v,w,particle[j,2],i,self.encoder_stamps[i]-self.encoder_stamps[i-1])
             particle[j,:] = [particle[j,0]+dx,particle[j,1]+dy,particle[j,2]+dtheta]+noises
             
         particle[:,2] %= 2*np.pi
         xs = newranges[:,i]*np.cos(angles)+self.lidaroriginx
         ys = newranges[:,i]*np.sin(angles)+self.lidaroriginy
         [xs,ys,z]= BodytoWorld(xs,ys,theta[i])
         cors = []
         temp = np.zeros_like(lamda)
         temp[lamda>0] = 1
         temp[lamda<0] = -1
         for j in range(N):    
             particle_cor_x, particle_cor_y = x_dif+particle[j,0], y_dif+particle[j,1]
             cor = mapCorrelation(temp,x_im,y_im,np.vstack((xs, ys)),particle_cor_x,particle_cor_y)
             cors.append(np.max(cor))
     
     
         cors = W * np.array(cors)
         W = softmax(cors)
         best = np.argmax(W)    
         now = particle[best,:].copy()
         now_tra[:,i] = [now[0],now[1],now[2]]
         now_map_x,now_map_y = WorldtoMap(now[0],now[1])
         best_lidar_map_x,best_lidar_map_y = WorldtoMap(now[0]+0.298*math.cos(now[2]),now[1]+0.298*math.sin(now[2]))
         
         xis,yis =  WorldtoMap(xs+x[i],ys+y[i])
         lamda = mapping(lamda,best_lidar_map_x,best_lidar_map_y,xis,yis)
         bodyxis,bodyyis = WorldtoMap(x[i],y[i])
         walkmap[bodyxis,bodyyis] = 1
         slammap[now_map_x,now_map_y] = 1
         
     return lamda,now_tra,walkmap,slammap