def inverse_range_sensor_model(mx, x, z, theta_k, true_pos, true_neg, alpha = 1.0, beta = 5.0*np.pi/180.0, z_max = 150):

    r = math.sqrt((mx[0] - x[0])*(mx[0] - x[0]) + (mx[1] - x[1])*(mx[1] - x[1]))
    phi = dynamics.wrap_angle(np.arctan2(mx[1]-x[1],mx[0]-x[0]) - x[2])

    k_val = np.absolute(phi-theta_k)

    # k_val = []
    # for i in range(len(z)):
    #     k_val.append(math.fabs(phi-theta_k[i]))

    k = np.argmin(k_val)

    # k = potato(phi, theta_k)
    # k = cow(phi, theta_k)

    #maybe shouldn't be doing this here.  Could be preprocessed
    # if np.isnan(z[k][0]):
    #     z[k][0] = z_max + 1.0

    z[k][0] = part_1(z[k][0], z_max)


    if r > min(z_max, z[k][0] + alpha/2.0) or k_val[k] > beta/2.0:
        # print "1st"
        return st.log_odds(0.5)

    if z[k][0] < z_max and math.fabs(r - z[k][0]) < alpha/2.0:
        # print "2nd"
        return st.log_odds(true_pos)

    if r <= z[k][0]:
        # print "3rd"
        return st.log_odds(true_neg)
Esempio n. 2
0
def update_particle(particle, v_c, w_c, v_c_cov, w_c_cov, z, thk, motion_noise,
                    dt, true_pos, true_neg, alpha, beta, z_max, first_time,
                    num_particles):
    #sample the motion model
    x = np.array([[particle.x], [particle.y], [particle.theta]])
    x_next = dynamics.propogate_next_state(x, v_c + stat_filter.noise(v_c_cov),
                                           w_c + stat_filter.noise(w_c_cov),
                                           dt)
    # particle.x = copy.deepcopy(x_next[0][0])
    # particle.y = copy.deepcopy(x_next[1][0])
    # particle.theta = copy.deepcopy(dynamics.wrap_angle(x_next[2][0]))

    particle.x = x_next[0][0]
    particle.y = x_next[1][0]
    particle.theta = dynamics.wrap_angle(x_next[2][0])

    #calculate weights from measurement model
    if first_time:
        particle.weight = 1.0 / num_particles
    else:
        particle.weight = ogc.likelihood_field_range_finder_model(
            z, x_next, thk, z_max, particle.occ_grid)

    #update the map for the particle
    X = [particle.x, particle.y, particle.theta]
    particle.occ_grid = ogc.occupancy_grid_mapping(particle.occ_grid, X, z,
                                                   thk, true_pos, true_neg,
                                                   alpha, beta, z_max)

    return particle
Esempio n. 3
0
def ekf_slam_turtlebot(mu, sigma, v_c, w_c, ranges, bearings, correspondence,
                       dt, Q, alpha):

    num_states = len(mu)

    theta = mu[2][0]

    F = np.zeros((3, num_states))

    F[0][0] = 1
    F[1][1] = 1
    F[2][2] = 1

    mu[0:3] = dynamics.propogate_next_state(mu[0:3], v_c, w_c, dt)

    G = np.array([[
        0.0, 0.0,
        -v_c / w_c * np.cos(theta) + v_c / w_c * np.cos(theta + w_c * dt)
    ],
                  [
                      0.0, 0.0, -v_c / w_c * np.sin(theta) +
                      v_c / w_c * np.sin(theta + w_c * dt)
                  ], [0.0, 0.0, 0.0]])

    G = np.eye(num_states) + np.dot(F.T, np.dot(G, F))

    V = np.array([[(-np.sin(theta) + np.sin(theta + w_c * dt)) / w_c,
                   (v_c * (np.sin(theta) - np.sin(theta + w_c * dt))) /
                   (w_c * w_c) + (v_c * np.cos(theta + w_c * dt) * dt) / w_c],
                  [(np.cos(theta) - np.cos(theta + w_c * dt)) / w_c,
                   (-v_c * (np.cos(theta) - np.cos(theta + w_c * dt))) /
                   (w_c * w_c) + (v_c * np.sin(theta + w_c * dt) * dt) / w_c],
                  [0.0, dt]])

    M = np.array([[alpha[0] * v_c * v_c + alpha[1] * w_c * w_c, 0.0],
                  [0.0, alpha[2] * v_c * v_c + alpha[3] * w_c * w_c]])

    sigma_bar = np.dot(np.dot(G, sigma), G.T) + np.dot(
        F.T, np.dot(np.dot(np.dot(V, M), V.T), F))

    # K_plot = np.full((len(landmark_pts), 1),0.0)

    for i in range(0, len(ranges)):

        j = correspondence[i]

        if ekf_slam_turtlebot.seen.count(j) < 1:

            ekf_slam_turtlebot.seen.append(j)

            mu_j = mu[0:2] + np.array([
                ranges[i] * np.cos(bearings[i] + mu[2][0]),
                ranges[i] * np.sin(bearings[i] + mu[2][0])
            ])

            mu = np.append(mu, mu_j, axis=0)

            sigma_bar = np.append(sigma_bar,
                                  np.zeros((2, len(sigma_bar))),
                                  axis=0)
            sigma_bar = np.append(sigma_bar,
                                  np.zeros((len(sigma_bar), 2)),
                                  axis=1)
            sigma_bar[len(sigma_bar) - 1][len(sigma_bar) - 1] = 10
            sigma_bar[len(sigma_bar) - 2][len(sigma_bar) - 2] = 10

        idx = ekf_slam_turtlebot.seen.index(j)

        delta = mu[3 + 2 * idx:3 + 2 * (idx + 1)] - mu[0:2]

        q = np.dot(delta.T, delta)[0][0]

        z_hat = np.array([[math.sqrt(q)],
                          [np.arctan2(delta[1], delta[0]) - mu[2][0]]])

        Fx_j = np.zeros((6, len(mu)))

        Fx_j[0][0] = 1
        Fx_j[1][1] = 1
        Fx_j[2][2] = 1
        Fx_j[3][3 + 2 * idx] = 1
        Fx_j[4][4 + 2 * idx] = 1

        H = [[
            -1.0 * math.sqrt(q) * delta[0][0],
            -1.0 * math.sqrt(q) * delta[1][0], 0.0,
            math.sqrt(q) * delta[0][0],
            math.sqrt(q) * delta[1][0], 0.0
        ], [delta[1][0], -delta[0][0], -q, -delta[1][0], delta[0][0], 0]]

        H = 1 / q * np.dot(H, Fx_j)

        S = np.dot(np.dot(H, sigma_bar), H.T) + Q

        K = np.dot(np.dot(sigma_bar, H.T), np.linalg.inv(S))

        z = np.array([[ranges[i]], [bearings[i]]])

        z_int = z - z_hat

        z_int[1] = dynamics.wrap_angle(z_int[1])

        mu = mu + np.dot(K, (z_int))

        sigma_bar = np.dot((np.eye(len(mu)) - np.dot(K, H)), sigma_bar)

        # K_plot[j][0] = np.linalg.norm(K)

    sigma = sigma_bar

    return mu, sigma  #, K_plot
Esempio n. 4
0
def fast_slam_known_correspondence_turtlebot(v_c, w_c, ranges, bearings,
                                             correspondences, particles, dt, Q,
                                             alpha):

    #calculated a fit over experiments with values
    exponent = -0.0556 * len(ranges) + 8.5556

    scale = 10**exponent

    counter = 0

    for i in range(len(particles)):
        v_c_cov = alpha[0] * v_c * v_c + alpha[1] * w_c * w_c
        w_c_cov = alpha[2] * v_c * v_c + alpha[3] * w_c * w_c
        x = [[particles[i].x], [particles[i].y], [particles[i].theta]]
        # print "x before: ", particles[i].x
        # print "y before: ", particles[i].y
        # print "theta before: ", particles[i].theta
        x_next = dynamics.propogate_next_state(
            x, v_c + stat_filter.noise(v_c_cov),
            w_c + stat_filter.noise(w_c_cov), dt)
        particles[i].x = copy.deepcopy(x_next[0][0])
        particles[i].y = copy.deepcopy(x_next[1][0])
        particles[i].theta = copy.deepcopy(dynamics.wrap_angle(x_next[2][0]))

        # print i
        # print "x_p0: ", particles[0].x
        # print "y_p0: ", particles[0].y
        # print "theta_p0: ", particles[0].theta
        # print "x: ", particles[i].x
        # print "y: ", particles[i].y
        # print "theta: ", particles[i].theta

        # pdb.set_trace()
        particles[i].weight = 1.0

        for k in range(len(ranges)):

            j = correspondences[k]

            if particles[i].seen.count(j) < 1:
                particles[i].seen.append(j)

                # print "particle len: ", len(particles)
                # print "range len: ", len(ranges)
                # counter += 1
                # print counter
                x = particles[i].x + ranges[k] * np.cos(bearings[k] +
                                                        particles[i].theta)
                y = particles[i].y + ranges[k] * np.sin(bearings[k] +
                                                        particles[i].theta)

                ldm = landmark.Landmark(j, x, y)
                particles[i].landmarks.append(ldm)

                H = calc_H(ldm, particles[i])[0]
                H_inv = np.linalg.inv(H)
                ldm.sigma = np.dot(np.dot(H_inv, Q), H_inv.T)
                # print "sigma: ", ldm.sigma
                # print "H: ", H
                ldm.weight = scale * 1.0 / len(particles)
                particles[i].weight *= ldm.weight
                # particles[i].weight = 1.0/len(particles)

            else:
                idx = particles[i].seen.index(j)

                ldm = particles[i].landmarks[idx]

                z_hat, H = calc_z_hat_and_H(ldm, particles[i])

                S = np.dot(np.dot(H, ldm.sigma), H.T) + Q
                K = np.dot(np.dot(ldm.sigma, H.T), np.linalg.inv(S))

                z = np.array([[ranges[k]], [bearings[k]]])

                res = np.array(z - z_hat)

                res[1][0] = dynamics.wrap_angle(res[1][0])

                mu = np.array([[ldm.x], [ldm.y]]) + np.dot(K, res)

                ldm.x = mu[0][0]
                ldm.y = mu[1][0]

                ldm.sigma = np.dot(np.eye(2) - np.dot(K, H), ldm.sigma)

                particles[i].landmarks[idx] = ldm

                # particles[i].weight = np.linalg.det(2*np.pi*S)*np.exp(-.5*np.dot(np.dot(res.T,np.linalg.inv(S)),res))[0][0]
                ldm.weight = scale * (np.linalg.det(2 * np.pi * S) * np.exp(
                    -.5 * np.dot(np.dot(res.T, np.linalg.inv(S)), res))[0][0])
                particles[i].weight *= ldm.weight

                # print "Weights: ", particles[i].weight, " For: ", i

        print "Weights: ", particles[i].weight, " For: ", i

    particles = fast_slam_particle.normalize_weights(particles)
    new_particles = stat_filter.low_variance_sampler(particles)

    return new_particles
    x_err = []
    y_err = []
    theta_err = []

    x_err.append(0.0)
    y_err.append(0.0)
    theta_err.append(0.0)

    t_plot = [[], [], []]

    plt.ion()

    for i in range(0, len(v_c) - 1):
        x_next = dynamics.propogate_next_state(x[i], v[i], w[i], dt)
        x_next[2] = dynamics.wrap_angle(x_next[2])
        x.append(x_next)
        x_plot.append(x[i + 1][0])
        y_plot.append(x[i + 1][1])
        theta_plot.append(x[i + 1][2])

        ranges, bearings, correspondence = simulate_sensor_data(
            x_next, sigma_r, sigma_phi)

        # ldm_idx = i%len(ranges)

        # particles = fast_slam.fast_slam_known_correspondence_turtlebot(v_c[i], w_c[i], ranges[ldm_idx], bearings[ldm_idx], correspondence[ldm_idx], particles, dt, Q, alpha)
        particles = fast_slam.fast_slam_known_correspondence_turtlebot(
            v_c[i], w_c[i], ranges, bearings, correspondence, particles, dt, Q,
            alpha)
        # landmark_idx = i%len(landmark_pts)