Esempio n. 1
0
def test_robot_move_right_from_non_zero_position_and_45_deg_angle_when_applying_forward_control_input_without_noise():
    x, y, alpha = 1., 3., np.deg2rad(45.)
    r = np.array([x, y, alpha])
    u = np.array([1, np.deg2rad(-90.)])
    n = np.array([0, 0.])

    r_new = move(r, u, n)

    assert assert_array_equal(r_new, np.array([1.+1./np.sqrt(2), 3.-1./np.sqrt(2), np.deg2rad(-45.)])) is None
Esempio n. 2
0
def test_robot_move_forward_from_zero_position_when_applying_forward_control_input_without_noise():
    x, y, alpha = 0., 0, 0
    r = np.array([x, y, alpha])
    u = np.array([1, 0.])
    n = np.array([0, 0.])

    r_new = move(r, u, n)

    assert assert_array_equal(r_new, [1, 0, 0.]) is None
Esempio n. 3
0
def test_robot_move_left_from_non_zero_position_when_applying_left_control_input_without_noise():
    x, y, alpha = 1., 3., 0.
    r = np.array([x, y, alpha])
    u = np.array([1, np.deg2rad(90.)])
    n = np.array([0, 0.])

    r_new = move(r, u, n)

    assert assert_array_equal(r_new, np.array([1., 4., np.deg2rad(90.)])) is None
Esempio n. 4
0
    def state_propagation(X, U, n=None):
        """
        Propagate the state estimates forward one time step using the control input

        :param X: previous states
        :param U: control input (d_x, d_alpha)
        :param n: perturbation to control input (d_x, d_alpha)
        :return:
        """

        # ----------  propagate state vector (update robot pose but leave landmarks unchanged) -------

        r = X[:3]
        if n is None:
            n = np.array([0, 0])
        r_new = move(r, U, n)
        # X[:3] = r_new
        X_new = np.concatenate((r_new, X[3:]))

        return X_new
def main():
    # random seed
    random.seed(20)
    np.random.seed(20)

    # simulation time step (Kalman filter propagation frequency) [s]
    time_step = 0.020

    # measurement update period [s]
    measurement_period = 0.5

    # total simulation duration [s]
    sim_duration = 5.

    # initial robot pose (x [m]; y [m]; alpha [deg])
    r_true = [0., 0., np.deg2rad(90.)]

    # angular_velocity [rad/sec]. Used to simulate random walk on the angle control
    d_alpha = 0

    # process noise (for control input [x; alpha])
    u_x_stddev = 2.0 * time_step                    # [m]
    u_alpha_stddev = np.deg2rad(4.0 * time_step)    # [rad]

    # measurement noise
    range_meas_stddev = 0.1                 # [m]
    bearing_meas_stddev = np.deg2rad(5.)    # [rad]

    # landmarks ([meters])
    min_x = -5.
    max_x = 5.
    min_y = 0.
    max_y = 10.
    num_landmarks = 2
    landmarks_true = np.random.random_sample((num_landmarks, 2))
    landmarks_true[:, 0] = min_x + landmarks_true[:, 0] * (max_x - min_x)
    landmarks_true[:, 1] = min_y + landmarks_true[:, 1] * (max_y - min_y)

    # EKF-SLAM estimator

    est = EKFSLAM()
    est.X = np.concatenate([r_true, est.X[3:]])     # we know the true robot pose initially
    est.P = np.zeros((3, 3)) * 1.
    est.Q = np.array([[u_x_stddev ** 2, 0], [0, u_alpha_stddev ** 2]])
    est.R = np.array([[range_meas_stddev ** 2, 0], [0, bearing_meas_stddev ** 2]])

    # simulate robot
    for i in range(int(sim_duration / time_step)):
        t_start = time.time()

        # generate control input
        control_input_type = "straight_with_noise"

        if control_input_type == "straight_with_noise":
            u = [2. * time_step, 0]

            # generate perturbation
            n = [u_x_stddev * np.random.randn(), d_alpha]
        elif control_input_type == "straight_with_random_walk_angle_noise":
            u = [2. * time_step, 0]

            # generate perturbation
            d_alpha = d_alpha + u_alpha_stddev * np.random.randn()
            n = [u_x_stddev * np.random.randn(), d_alpha]
        elif control_input_type == "straight_without_noise":
            u = [2. * time_step, 0]

            # generate perturbation
            n = [0, 0]
        elif control_input_type == "circle_with_noise":
            u = [2. * time_step, np.deg2rad(15.) * time_step]
            n = [u_x_stddev * np.random.randn(), d_alpha]
        elif control_input_type == "circle_without_noise":
            u = [2. * time_step, np.deg2rad(15.) * time_step]
            n = [0, 0]
        else:
            raise ValueError("Use valid control input motion type")

        # move robot
        r_true = move(r_true, u, n)

        # propagate EKF
        est.state_and_state_cov_propagation(u)

        print("States:", est.X, "\nP:", est.P)

        # sensor readings of environment
        raw_measurements = [rbs.observe_range_bearing(r_true, landmarks_true[j, :])
                            for j in range(landmarks_true.shape[0])]        # TODO: add some noise to the measurements

        # measurement update of EKF
        # TODO: need to first add the landmarks before we can update them
        # [est.measurement_update_range_bearing(y, ii) for ii, y in enumerate(raw_measurements)]

        # estimated landmark positions (by using estimated robot pose and inverse sensor measurements)
        landmarks_est = [rbs.inv_observe_range_bearing(r_true, m) for m in raw_measurements]        # TODO: use estimated robot pose?

        print(time.time() - t_start)

        # plot robot and map
        if i % 5 == 0:
            print(i, "current pose:", r_true, ", control input:", u, ", noise:", n)
            display(r_true, est, landmarks_true, landmarks_est, raw_measurements, i)