예제 #1
0
    def __init__(self, x0=0.0, y0=0.0, theta0=0.0, odom_lin_sigma=0.025,
                 odom_ang_sigma=np.deg2rad(2), meas_rng_noise=0.2,
                 meas_ang_noise=np.deg2rad(10), xs=0.0, ys=0.0, thetas=0.0,
                 rob2sensor=[-0.087, 0.013, np.deg2rad(0.0)]):
        """
        Initializes publishers, subscribers and the particle filter.
        """

        # Transformation from robot to sensor
        self.robotToSensor = np.array([xs, ys, thetas])

        # Publishers
        self.pub_lines = rospy.Publisher("ekf_lines", Marker, queue_size=0)
        self.pub_map = rospy.Publisher("map", Marker, queue_size=0)
        self.pub_map_gt = rospy.Publisher("map_gt", Marker, queue_size=0)
        self.pub_odom = rospy.Publisher(
            "predicted_odom", Odometry, queue_size=0)
        self.pub_uncertainity = rospy.Publisher(
            "uncertainity", Marker, queue_size=0)
        self.pub_laser = rospy.Publisher("ekf_laser", LaserScan, queue_size=0)

        # Subscribers
        self.sub_odom = rospy.Subscriber("odom", Odometry, self.odom_callback)
        self.sub_scan = rospy.Subscriber("lines", Marker, self.lines_callback)

        # TF
        self.tfBroad = tf.TransformBroadcaster()

        # Incremental odometry
        self.last_odom = None
        self.odom = None

        # Flags
        self.new_odom = False
        self.new_laser = False
        self.pub = False

        # Ground truth map
        dataset = rospy.get_param("~dataset", None)
        if dataset == 1:
            self.map = get_map()
            x0 = 0.8 - 0.1908
            y0 = 0.3 + 0.08481
            theta0 = -0.034128
        elif dataset == 2:
            self.map = np.array([])
        elif dataset == 3:
            self.map = get_dataset3_map()
        else:
            self.map = np.array([])

        # Initial state
        self.x0 = np.array([x0, y0, theta0])

        # Particle filter
        self.ekf = EKF_SLAM(x0, y0, theta0, odom_lin_sigma,
                            odom_ang_sigma, meas_rng_noise, meas_ang_noise)

        # Transformation from robot to sensor
        self.robot2sensor = np.array(rob2sensor)
예제 #2
0
    def getStates(self, timestep, use_slam=False):

        delT, X, Y, xdot, ydot, psi, psidot = super().getStates(timestep)

        # Initialize the EKF SLAM estimation
        if self.counter == 0:
            # Load the map
            minX, maxX, minY, maxY = -120., 450., -350., 50.
            #minX, maxX, minY, maxY = -120., 450., -500., 50.
            map_x = np.linspace(minX, maxX, 7)
            map_y = np.linspace(minY, maxY, 7)
            map_X, map_Y = np.meshgrid(map_x, map_y)
            map_X = map_X.reshape(-1,1)
            map_Y = map_Y.reshape(-1,1)
            self.map = np.hstack((map_X, map_Y)).reshape((-1))
            
            # Parameters for EKF SLAM
            self.n = int(len(self.map)/2)             
            X_est = X + 0.5
            Y_est = Y - 0.5
            psi_est = psi - 0.02
            mu_est = np.zeros(3+2*self.n)
            mu_est[0:3] = np.array([X_est, Y_est, psi_est])
            mu_est[3:] = np.array(self.map)
            init_P = 1*np.eye(3+2*self.n)
            W = np.zeros((3+2*self.n, 3+2*self.n))
            W[0:3, 0:3] = delT**2 * 0.1 * np.eye(3)
            V = 0.1*np.eye(2*self.n)
            V[self.n:, self.n:] = 0.01*np.eye(self.n)
            # V[self.n:] = 0.01
            print(V)
            
            # Create a SLAM
            self.slam = EKF_SLAM(mu_est, init_P, delT, W, V, self.n)
            self.counter += 1
        else:
            mu = np.zeros(3+2*self.n)
            mu[0:3] = np.array([X, 
                                Y, 
                                psi])
            mu[3:] = self.map
            y = self._compute_measurements(X, Y, psi)
            mu_est, _ = self.slam.predict_and_correct(y, self.previous_u)

        self.previous_u = np.array([xdot, ydot, psidot])

        print("True      X, Y, psi:", X, Y, psi)
        print("Estimated X, Y, psi:", mu_est[0], mu_est[1], mu_est[2])
        print("-------------------------------------------------------")
        
        if use_slam == True:
            return delT, mu_est[0], mu_est[1], xdot, ydot, mu_est[2], psidot
        else:
            return delT, X, Y, xdot, ydot, psi, psidot
예제 #3
0
파일: node.py 프로젝트: evargasv/ekf-slam
    def __init__(self, x0=0,y0=0,theta0=0, odom_lin_sigma=0.025, odom_ang_sigma=np.deg2rad(2),
                        meas_rng_noise=0.2,  meas_ang_noise=np.deg2rad(10),xs = 0, ys = 0, thetas = 0):
        '''
        Initializes publishers, subscribers and the particle filter.
        '''

        # Transformation from robot to sensor
        self.robotToSensor = np.array([xs,ys,thetas])        
        
        # Publishers
        self.pub_lines = rospy.Publisher("lines", Marker)
        self.pub_odom = rospy.Publisher("predicted_odom", Odometry)
        self.pub_uncertainity = rospy.Publisher("uncertainity",  Marker)
        
        # Subscribers
        self.sub_scan = rospy.Subscriber("scan", LaserScan, self.laser_callback)
        self.sub_odom = rospy.Subscriber("odom", Odometry, self.odom_callback)
        
        # TF
        self.tfBroad = tf.TransformBroadcaster()
        
        # Incremental odometry
        self.last_odom = None
        self.odom = None
        
        # Flags
        self.new_odom = False
        self.new_laser = False
        self.pub = False
        
        # Ground truth map
#        self.map = get_map(0.8,0.3,-0.03)    
        self.map = get_map()
        
        # Initial state
        self.x0 = np.array([x0,y0,theta0])        
        
        # Particle filter
        self.ekf = EKF_SLAM(x0, y0, theta0, odom_lin_sigma, odom_ang_sigma, meas_rng_noise, meas_ang_noise)
예제 #4
0
#!/usr/bin/env python
import rospy
import sys
import os
import numpy as np
from std_msgs.msg import String
from nav_msgs.msg import Odometry
from marker_msgs.msg import MarkerDetection
from tf.transformations import euler_from_quaternion

sys.path.insert(1, '/home/ros/catkin_ws/src/moro_g12/src/')
from ekf_slam import EKF_SLAM
from csv_writer import csv_writer

previous_timestamp = None
ekf = EKF_SLAM(5, 3, 2, 2)


def get_rotation(quaternion):
    global roll, pitch, yaw
    orientation_list = [quaternion.x, quaternion.y, quaternion.z, quaternion.w]
    (roll, pitch, yaw) = euler_from_quaternion(orientation_list)
    return wrap_to_pi(yaw)


def odom_callback(msg):
    timestamp = msg.header.stamp
    x = msg.pose.pose.position.x
    y = msg.pose.pose.position.y
    theta = get_rotation(msg.pose.pose.orientation)
    v = msg.twist.twist.linear.x
예제 #5
0
from importlib import reload

# import sys
# sys.path.append("../")

import params as P
from dynamics import Dynamics
from animation import Animation
from plotData import plotData
from ekf_slam import EKF_SLAM

from copy import deepcopy

dynamics = Dynamics()
dataPlot = plotData()
ekf_slam = EKF_SLAM()
animation = Animation(ekf_slam)

estimate = np.array([])
actual = np.array([])

t = P.t_start
while t < P.t_end:
    t_next_plot = t + P.t_plot
    while t < t_next_plot:
        t = t + P.Ts
        vc = 1.25 + 0.5 * np.cos(2 * np.pi * (0.2) * t)
        omegac = -0.5 + 0.2 * np.cos(2 * np.pi * (0.6) * t)
        noise_v = vc + np.random.normal(
            0, np.sqrt(P.alpha1 * vc**2 + P.alpha2 * omegac**2))
        noise_omega = omegac + np.random.normal(
예제 #6
0
def main():
    args = get_cli_args()
    validate_cli_args(args)
    alphas = np.array(args.alphas)
    beta = np.array(args.beta)
    mean_prior = np.array([180., 50., 0.])
    Sigma_prior = 1e-12 * np.eye(3, 3)
    initial_state = Gaussian(mean_prior, Sigma_prior)

    if args.input_data_file:
        data = load_data(args.input_data_file)
    elif args.num_steps:
        # Generate data, assuming `--num-steps` was present in the CL args.
        data = generate_input_data(initial_state.mu.T, args.num_steps,
                                   args.num_landmarks_per_side,
                                   args.max_obs_per_time_step, alphas, beta,
                                   args.dt)
    else:
        raise RuntimeError('')

    store_sim_data = True if args.output_dir else False
    should_show_plots = True if args.animate else False
    should_write_movie = True if args.movie_file else False
    should_update_plots = True if should_show_plots or should_write_movie else False

    field_map = FieldMap(args.num_landmarks_per_side)

    fig = get_plots_figure(should_show_plots, should_write_movie)
    movie_writer = get_movie_writer(should_write_movie, 'Simulation SLAM',
                                    args.movie_fps, args.plot_pause_len)
    progress_bar = FillingCirclesBar('Simulation Progress', max=data.num_steps)

    if store_sim_data:
        if not os.path.exists(args.output_dir):
            os.makedirs(args.output_dir)
        save_input_data(data, os.path.join(args.output_dir, 'input_data.npy'))

    # slam object initialization
    slam = EKF_SLAM('ekf', 'known', 'batch', args, initial_state)
    mu_traj = mean_prior
    sigma_traj = []
    theta = []

    with movie_writer.saving(
            fig, args.movie_file,
            data.num_steps) if should_write_movie else get_dummy_context_mgr():
        for t in range(data.num_steps):
            # Used as means to include the t-th time-step while plotting.
            tp1 = t + 1

            # Control at the current step.
            u = data.filter.motion_commands[t]
            # Observation at the current step.
            z = data.filter.observations[t]

            # TODO SLAM predict(u)
            mu, Sigma = slam.predict(u)

            # TODO SLAM update
            mu, Sigma = slam.update(z)
            mu_traj = np.vstack((mu_traj, mu[:3]))
            sigma_traj.append(Sigma[:3, :3])
            theta.append(mu[2])

            progress_bar.next()
            if not should_update_plots:
                continue

            plt.cla()
            plot_field(field_map, z)
            plot_robot(data.debug.real_robot_path[t])
            plot_observations(data.debug.real_robot_path[t],
                              data.debug.noise_free_observations[t],
                              data.filter.observations[t])

            plt.plot(data.debug.real_robot_path[1:tp1, 0],
                     data.debug.real_robot_path[1:tp1, 1], 'm')
            plt.plot(data.debug.noise_free_robot_path[1:tp1, 0],
                     data.debug.noise_free_robot_path[1:tp1, 1], 'g')

            plt.plot([data.debug.real_robot_path[t, 0]],
                     [data.debug.real_robot_path[t, 1]], '*r')
            plt.plot([data.debug.noise_free_robot_path[t, 0]],
                     [data.debug.noise_free_robot_path[t, 1]], '*g')

            # TODO plot SLAM solution
            # robot filtered trajectory and covariance
            plt.plot(mu_traj[:, 0], mu_traj[:, 1], 'blue')
            plot2dcov(mu[:2], Sigma[:2, :2], color='b', nSigma=3, legend=None)

            # landmarks covariances and expected poses
            Sm = slam.Sigma[slam.iR:slam.iR + slam.iM,
                            slam.iR:slam.iR + slam.iM]
            mu_M = slam.mu[slam.iR:]
            for c in range(0, slam.iM, 2):
                Sigma_lm = Sm[c:c + 2, c:c + 2]
                mu_lm = mu_M[c:c + 2]
                plt.plot(mu_lm[0], mu_lm[1], 'ro')
                plot2dcov(mu_lm, Sigma_lm, color='k', nSigma=3, legend=None)

            if should_show_plots:
                # Draw all the plots and pause to create an animation effect.
                plt.draw()
                plt.pause(args.plot_pause_len)

            if should_write_movie:
                movie_writer.grab_frame()

    progress_bar.finish()

    # plt.figure(2)
    # plt.plot(theta)
    plt.show(block=True)

    if store_sim_data:
        file_path = os.path.join(args.output_dir, 'output_data.npy')
        with open(file_path, 'wb') as data_file:
            np.savez(data_file,
                     mean_trajectory=mu_traj,
                     covariance_trajectory=np.array(sigma_traj))
    scan_angle.set_theta1((twr.x_new[2, 0] - twr.fov / 2) * 180 / np.pi)
    scan_angle.set_theta2((twr.x_new[2, 0] + twr.fov / 2) * 180 / np.pi)

    fig.canvas.draw()
    plt.pause(0.01)


if __name__ == "__main__":

    plot_live = True

    # Two-Wheeled Robot Init
    twr = TWR()  # TWR model object

    # EKF SLAM filter Init
    ekf_slam = EKF_SLAM(twr)

    body_radius = 0.3
    fig, lines, lines_est, mlandmarks, robot_body, robot_head, scan_angle = InitPlot(
        twr, body_radius)
    mu = ekf_slam.mu[0:3].reshape([3, 1])
    mu_landmarks = ekf_slam.mu[3:].reshape([len(ekf_slam.mu[3:]), 1])
    w_landmarks = np.zeros((twr.nl, 1))
    h_landmarks = np.zeros((twr.nl, 1))
    ang_landmarks = np.zeros((twr.nl, 1))
    K = ekf_slam.K
    two_sig_x = np.array([[2 * np.sqrt(ekf_slam.cov.item((0, 0)))],
                          [-2 * np.sqrt(ekf_slam.cov.item((0, 0)))]])
    two_sig_y = np.array([[2 * np.sqrt(ekf_slam.cov.item((1, 1)))],
                          [-2 * np.sqrt(ekf_slam.cov.item((1, 1)))]])
    two_sig_theta = np.array([[2 * np.sqrt(ekf_slam.cov.item((2, 2)))],