Ejemplo n.º 1
0
def test_linear_1d():
    """ should work like a linear KF if problem is linear """
    def fx(x, dt):
        F = np.array([[1., dt], [0, 1]])

        return np.dot(F, x)

    def hx(x):
        return np.array([x[0]])

    dt = 0.1
    points = MerweScaledSigmaPoints(2, .1, 2., -1)
    kf = UKF(dim_x=2, dim_z=1, dt=dt, fx=fx, hx=hx, points=points)

    kf.x = np.array([1, 2])
    kf.P = np.array([[1, 1.1], [1.1, 3]])
    kf.R *= 0.05
    kf.Q = np.array([[0., 0], [0., .001]])

    z = np.array([2.])
    kf.predict()
    kf.update(z)

    zs = []
    for i in range(50):
        z = np.array([i + randn() * 0.1])
        zs.append(z)

        kf.predict()
        kf.update(z)
        print('K', kf.K.T)
        print('x', kf.x)
Ejemplo n.º 2
0
def test_saver_UKF():
    def fx(x, dt):
        F = np.array(
            [[1, dt, 0, 0], [0, 1, 0, 0], [0, 0, 1, dt], [0, 0, 0, 1]],
            dtype=float)

        return np.dot(F, x)

    def hx(x):
        return np.array([x[0], x[2]])

    dt = 0.1
    points = MerweScaledSigmaPoints(4, .1, 2., -1)
    kf = UnscentedKalmanFilter(dim_x=4,
                               dim_z=2,
                               dt=dt,
                               fx=fx,
                               hx=hx,
                               points=points)

    z_std = 0.1
    kf.R = np.diag([z_std**2, z_std**2])  # 1 standard
    kf.x = np.array([-1., 1., -1., 1])
    kf.P *= 1.

    zs = [[i, i] for i in range(40)]
    s = Saver(kf, skip_private=False, skip_callable=False, ignore=['z_mean'])
    for z in zs:
        kf.predict()
        kf.update(z)
        #print(kf.x, kf.log_likelihood, kf.P.diagonal())
        s.save()
    s.to_array()
Ejemplo n.º 3
0
def test_saver_UKF():
    def fx(x, dt):
        F = np.array([[1, dt, 0, 0],
                      [0, 1, 0, 0],
                      [0, 0, 1, dt],
                      [0, 0, 0, 1]], dtype=float)

        return np.dot(F, x)

    def hx(x):
        return np.array([x[0], x[2]])

    dt = 0.1
    points = MerweScaledSigmaPoints(4, .1, 2., -1)
    kf = UnscentedKalmanFilter(dim_x=4, dim_z=2, dt=dt, fx=fx, hx=hx, points=points)

    z_std = 0.1
    kf.R = np.diag([z_std**2, z_std**2]) # 1 standard
    kf.x = np.array([-1., 1., -1., 1])
    kf.P *= 1.

    zs = [[i, i] for i in range(40)]
    s = Saver(kf, skip_private=False, skip_callable=False, ignore=['z_mean'])
    for z in zs:
        kf.predict()
        kf.update(z)
        #print(kf.x, kf.log_likelihood, kf.P.diagonal())
        s.save()
    s.to_array()
def creat_batch3(min_dn,max_dn,pos_noise,vel_noise,BN):
    batch_size = int(100*BN)
    my_traj, my_obser, Tran_m = trajectory_batch_generator(batch_size,data_len)
    Traj_r = my_traj
    Obser = my_obser
    
    Traj_s = np.array([[[0 for i in range(4)] for j in range(data_len)] for k in range(batch_size)],'float64')
    for i in range(batch_size): 
        my_SP = SP(dim_state,kappa=0.)
        my_UKF = UKF(dim_x=dim_state, dim_z=dim_obser, dt=sT, hx=my_hx, fx=my_fx, points=my_SP)
        my_UKF.Q *= var_m
        my_UKF.R *= np.array([[azi_var,0],[0,dis_var]])
        x0_noise = np.array([np.random.normal(0,pos_noise,2),np.random.normal(0,vel_noise,2)])
        my_UKF.x = Traj_r[i,0,:] + np.reshape(x0_noise,[4,])
        my_UKF.P *= 1.
        
        #tracking results of UKF
        xs = []
        xs.append(my_UKF.x)
        for j in range(data_len-1):
            my_UKF.predict()
            my_UKF.update(Obser[i,j+1,:])
            xs.append(my_UKF.x.copy())    
        Traj_s[i] = np.asarray(xs)
        
    return Traj_r, Obser, Traj_s, Traj_r-Traj_s
Ejemplo n.º 5
0
def main():
    [t, dt, s, v, a, theta, omega, alpha] = build_real_values()
    zs = build_measurement_values(t, [a, omega])
    u = build_control_values(t, v)
    [F, B, H, Q, R] = init_kalman(t, dt)

    sigmas = MerweScaledSigmaPoints(n=9, alpha=.1, beta=2., kappa=-1)
    kf = UKF(dim_x=9, dim_z=3, fx=f_bot, hx=h_bot, dt=0.2, points=sigmas)
    kf.x = np.array([0., 0., 0., 0., 0., 0., 0., 0., 0.])
    kf.R = R
    kf.F = F
    kf.H = H
    kf.Q = Q

    xs, cov = [], []
    for zk, uk in zip(zs, u):
        kf.predict(fx_args=uk)
        kf.update(z=zk)
        xs.append(kf.x.copy())
        cov.append(kf.P)

    xs, cov = np.array(xs), np.array(cov)
    xground = construct_xground(s, v, a, theta, omega, alpha, xs.shape)
    nees = NEES(xground, xs, cov)
    print(np.mean(nees))
    plot_results(t, xs, xground, zs, nees)
Ejemplo n.º 6
0
class Filter:
    def __init__(self, fx, hx):
        self.sigmas = MerweScaledSigmaPoints(n=3, alpha=.3, beta=2., kappa=.1)
        self.ukf = UnscentedKalmanFilter(dim_x=3,
                                         dim_z=2,
                                         dt=.02,
                                         hx=hx,
                                         fx=fx,
                                         points=self.sigmas)

    def initialize(self, p0, a0, p_std, a_std):
        self.p_std = p_std
        self.a_std = a_std
        height = 44330 * (1 - pow((p0 / 101325), 0.1902))
        self.ukf.x = np.array([height, 0, a0])
        self.ukf.P *= np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
        self.ukf.R = np.array([[p_std**2, 0], [0, a_std**2]])
        self.ukf.Q = Q_discrete_white_noise(3, dt=.02, var=0.03)

    def run(self, raw_p, raw_a):
        heights, varios, accs = [], [], []

        for i in range(len(raw_p) - 1):
            meas = [raw_p[i + 1], raw_a[i + 1]]
            self.ukf.predict()
            self.ukf.update(meas)

            heights.append(self.ukf.x[0])
            varios.append(self.ukf.x[1])
            accs.append(self.ukf.x[2])

        return heights, varios, accs
Ejemplo n.º 7
0
 def unscented_kf(self, number=NUMBER):
     global Time
     P0 = np.diag([
         3e-2, 3e-2, 3e-2, 3e-6, 3e-6, 3e-6, 3e-2, 3e-2, 3e-2, 3e-6, 3e-6,
         3e-6
     ])
     error = np.random.multivariate_normal(mean=np.zeros(12), cov=P0)
     X0 = np.hstack((HPOP_1[0], HPOP_2[0])) + error
     points = MerweScaledSigmaPoints(n=12, alpha=0.001, beta=2.0, kappa=-9)
     ukf = UKF(dim_x=12,
               dim_z=4,
               fx=self.state_equation,
               hx=self.measure_equation,
               dt=STEP,
               points=points)
     ukf.x = X0
     ukf.P = P0
     ukf.R = Rk
     ukf.Q = Qk
     XF, XP = [X0], [X0]
     print(error, "\n", Qk[0][0], "\n", Rk[0][0])
     for i in range(1, number + 1):
         ukf.predict()
         Z = nav.measure_stk(i)
         ukf.update(Z)
         X_Up = ukf.x.copy()
         XF.append(X_Up)
         Time = Time + STEP
     XF = np.array(XF)
     return XF
Ejemplo n.º 8
0
def _test_log_likelihood():

    from filterpy.common import Saver

    def fx(x, dt):
        F = np.array(
            [[1, dt, 0, 0], [0, 1, 0, 0], [0, 0, 1, dt], [0, 0, 0, 1]],
            dtype=float)

        return np.dot(F, x)

    def hx(x):
        return np.array([x[0], x[2]])

    dt = 0.1
    points = MerweScaledSigmaPoints(4, .1, 2., -1)
    kf = UKF(dim_x=4, dim_z=2, dt=dt, fx=fx, hx=hx, points=points)

    z_std = 0.1
    kf.R = np.diag([z_std**2, z_std**2])  # 1 standard
    kf.Q = Q_discrete_white_noise(dim=2, dt=dt, var=1.1**2, block_size=2)

    kf.x = np.array([-1., 1., -1., 1])
    kf.P *= 1.

    zs = [[i + randn() * z_std, i + randn() * z_std] for i in range(40)]
    s = Saver(kf)
    for z in zs:
        kf.predict()
        kf.update(z)
        print(kf.x, kf.log_likelihood, kf.P.diagonal())
        s.save()
    s.to_array()
    plt.plot(s.x[:, 0], s.x[:, 2])
Ejemplo n.º 9
0
def test_rts():
    def fx(x, dt):
        A = np.eye(3) + dt * np.array([[0, 1, 0], [0, 0, 0], [0, 0, 0]])
        f = np.dot(A, x)
        return f

    def hx(x):
        return np.sqrt(x[0]**2 + x[2]**2)

    dt = 0.05

    sp = JulierSigmaPoints(n=3, kappa=1.)
    kf = UKF(3, 1, dt, fx=fx, hx=hx, points=sp)

    kf.Q *= 0.01
    kf.R = 10
    kf.x = np.array([0., 90., 1100.])
    kf.P *= 100.
    radar = RadarSim(dt)

    t = np.arange(0, 20 + dt, dt)

    n = len(t)

    xs = np.zeros((n, 3))

    random.seed(200)
    rs = []
    #xs = []
    for i in range(len(t)):
        r = radar.get_range()
        #r = GetRadar(dt)
        kf.predict()
        kf.update(z=[r])

        xs[i, :] = kf.x
        rs.append(r)

    kf.x = np.array([0., 90., 1100.])
    kf.P = np.eye(3) * 100
    M, P = kf.batch_filter(rs)
    assert np.array_equal(M, xs), "Batch filter generated different output"

    Qs = [kf.Q] * len(t)
    M2, P2, K = kf.rts_smoother(Xs=M, Ps=P, Qs=Qs)

    if DO_PLOT:
        print(xs[:, 0].shape)

        plt.figure()
        plt.subplot(311)
        plt.plot(t, xs[:, 0])
        plt.plot(t, M2[:, 0], c='g')
        plt.subplot(312)
        plt.plot(t, xs[:, 1])
        plt.plot(t, M2[:, 1], c='g')
        plt.subplot(313)

        plt.plot(t, xs[:, 2])
        plt.plot(t, M2[:, 2], c='g')
def run_localization(
    cmds, landmarks, sigma_vel, sigma_steer, sigma_range, 
    sigma_bearing, ellipse_step=1, step=10):

    plt.figure()
    points = MerweScaledSigmaPoints(n=3, alpha=.00001, beta=2, kappa=0, 
                                    subtract=residual_x)
    ukf = UKF(dim_x=3, dim_z=2*len(landmarks), fx=fx, hx=Hx,
              dt=dt, points=points, x_mean_fn=state_mean, 
              z_mean_fn=z_mean, residual_x=residual_x, 
              residual_z=residual_h)

    ukf.x = np.array([2, 6, .3])
    ukf.P = np.diag([.1, .1, .05])
    ukf.R = np.diag([sigma_range**2, 
                     sigma_bearing**2]*len(landmarks))
    ukf.Q = np.eye(3)*0.0001
    
    sim_pos = ukf.x.copy()
    
    # plot landmarks
    if len(landmarks) > 0:
        plt.scatter(landmarks[:, 0], landmarks[:, 1], 
                    marker='s', s=60)
    
    track = []
    for i, u in enumerate(cmds):     
        sim_pos = move(sim_pos, u, dt/step, wheelbase) 
        track.append(sim_pos)

        if i % step == 0:
            ukf.predict(fx_args=u)

            if i % ellipse_step == 0:
                plot_covariance_ellipse(
                    (ukf.x[0], ukf.x[1]), ukf.P[0:2, 0:2], std=6,
                     facecolor='k', alpha=0.3)

            x, y = sim_pos[0], sim_pos[1]
            z = []
            for lmark in landmarks:
                dx, dy = lmark[0] - x, lmark[1] - y
                d = sqrt(dx**2 + dy**2) + randn()*sigma_range
                bearing = atan2(lmark[1] - y, lmark[0] - x)
                a = (normalize_angle(bearing - sim_pos[2] + 
                     randn()*sigma_bearing))
                z.extend([d, a])            
            ukf.update(z, hx_args=(landmarks,))

            if i % ellipse_step == 0:
                plot_covariance_ellipse(
                    (ukf.x[0], ukf.x[1]), ukf.P[0:2, 0:2], std=6,
                     facecolor='g', alpha=0.8)
    track = np.array(track)
    plt.plot(track[:, 0], track[:,1], color='k', lw=2)
    plt.axis('equal')
    plt.title("UKF Robot localization")
    plt.show()
    return ukf
def run_localization(
    cmds, landmarks, sigma_vel, sigma_steer, sigma_range,
    sigma_bearing, ellipse_step=1, step=10):

    plt.figure()
    points = MerweScaledSigmaPoints(n=3, alpha=.00001, beta=2, kappa=0,
                                    subtract=residual_x)
    ukf = UKF(dim_x=3, dim_z=2*len(landmarks), fx=fx, hx=Hx,
              dt=dt, points=points, x_mean_fn=state_mean,
              z_mean_fn=z_mean, residual_x=residual_x,
              residual_z=residual_h)

    ukf.x = np.array([2, 6, .3])
    ukf.P = np.diag([.1, .1, .05])
    ukf.R = np.diag([sigma_range**2,
                     sigma_bearing**2]*len(landmarks))
    ukf.Q = np.eye(3)*0.0001

    sim_pos = ukf.x.copy()

    # plot landmarks
    if len(landmarks) > 0:
        plt.scatter(landmarks[:, 0], landmarks[:, 1],
                    marker='s', s=60)

    track = []
    for i, u in enumerate(cmds):
        sim_pos = move(sim_pos, u, dt/step, wheelbase)
        track.append(sim_pos)

        if i % step == 0:
            ukf.predict(fx_args=u)

            if i % ellipse_step == 0:
                plot_covariance_ellipse(
                    (ukf.x[0], ukf.x[1]), ukf.P[0:2, 0:2], std=6,
                     facecolor='k', alpha=0.3)

            x, y = sim_pos[0], sim_pos[1]
            z = []
            for lmark in landmarks:
                dx, dy = lmark[0] - x, lmark[1] - y
                d = sqrt(dx**2 + dy**2) + randn()*sigma_range
                bearing = atan2(lmark[1] - y, lmark[0] - x)
                a = (normalize_angle(bearing - sim_pos[2] +
                     randn()*sigma_bearing))
                z.extend([d, a])
            ukf.update(z, hx_args=(landmarks,))

            if i % ellipse_step == 0:
                plot_covariance_ellipse(
                    (ukf.x[0], ukf.x[1]), ukf.P[0:2, 0:2], std=6,
                     facecolor='g', alpha=0.8)
    track = np.array(track)
    plt.plot(track[:, 0], track[:,1], color='k', lw=2)
    plt.axis('equal')
    plt.title("UKF Robot localization")
    plt.show()
    return ukf
Ejemplo n.º 12
0
class MagPredictor():
    stateNum = 7  # x, y, z, q0, q1, q2, q3

    def __init__(self):
        self.points = MerweScaledSigmaPoints(n=self.stateNum,
                                             alpha=0.3,
                                             beta=2.,
                                             kappa=3 - self.stateNum)
        self.dt = 0.03  # 时间间隔[s]
        self.ukf = UKF(dim_x=self.stateNum,
                       dim_z=SLAVES * 3,
                       dt=self.dt,
                       points=self.points,
                       fx=self.f,
                       hx=h)
        self.ukf.x = np.array([0.0, 0.0, 0.04, 1, 0, 0, 0])  # 初始值
        self.ukf.R *= 3  # 先初始化为3,后面自适应赋值

        self.ukf.P = np.eye(self.stateNum) * 0.016

        self.ukf.Q = np.eye(
            self.stateNum) * 0.01 * self.dt  # 将速度作为过程噪声来源,Qi = [v*dt]

        for i in range(3, 7):
            self.ukf.Q[i, i] = 0.0001

    def f(self, x, dt):
        A = np.eye(self.stateNum)
        return np.hstack(np.dot(A, x.reshape(self.stateNum, 1)))

    def run(self, magData, Bg, state):
        pos = (round(self.ukf.x[0], 3), round(self.ukf.x[1],
                                              3), round(self.ukf.x[2], 3))
        m = q2m(self.ukf.x[3], self.ukf.x[4], self.ukf.x[5], self.ukf.x[6])
        # print(r'pos={}m, e_moment={}'.format(pos, m))

        z = np.hstack(magData[:])
        # 自适应 R
        for i in range(SLAVES * 3):
            # 1.sensor的方差随B的关系式为:Bvar =  2*E(-16)*B^4 - 2*E(-27)*B^3 + 2*E(-8)*B^2 + 1*E(-18)*B + 10
            # Bm = magData[i] + Bg[i]
            # self.ukf.R[i, i] = (2 * 10**(-16) * Bm ** 4 - 2 * 10**(-27) * Bm ** 3 + 2 * 10**(-8) * Bm * Bm + 10**(-18) * Bm + 10) * 0.005

            # 2.sensor的方差随B的关系式为:Bvar =  1*E(-8)*B^2 - 2*E(-6)*B + 0.84
            Bm = magData[i] + Bg[i]
            self.ukf.R[i, i] = (math.exp(-8) * Bm**2 - 2 * math.exp(-6) * Bm +
                                0.84) * 1

            # 3.sensor的方差随B的关系式为:Bvar =  1*E(-8)*B^2 + 6*E(-6)*B + 3.221
            # Bm = magData[i] + Bg[i]
            # self.ukf.R[i, i] = 10**(-8) * Bm ** 2 + 6 * 10**(-6) * Bm + 3.221

        t0 = datetime.datetime.now()
        self.ukf.predict()
        self.ukf.update(z)
        timeCost = (datetime.datetime.now() - t0).total_seconds()

        state[:] = np.concatenate((mp.ukf.x, np.array([MOMENT, timeCost,
                                                       1])))  # 输出的结果
Ejemplo n.º 13
0
def test_radar():
    def fx(x, dt):
        A = np.eye(3) + dt * np.array([[0, 1, 0],
                                       [0, 0, 0],
                                       [0, 0, 0]])
        return A.dot(x)

    def hx(x):
        return [np.sqrt(x[0]**2 + x[2]**2)]

    dt = 0.05

    sp = JulierSigmaPoints(n=3, kappa=0.)
    kf = UnscentedKalmanFilter(3, 1, dt, fx=fx, hx=hx, points=sp)
    assert np.allclose(kf.x, kf.x_prior)
    assert np.allclose(kf.P, kf.P_prior)

    # test __repr__ doesn't crash
    str(kf)

    kf.Q *= 0.01
    kf.R = 10
    kf.x = np.array([0., 90., 1100.])
    kf.P *= 100.
    radar = RadarSim(dt)

    t = np.arange(0, 20+dt, dt)
    n = len(t)
    xs = np.zeros((n, 3))

    random.seed(200)
    rs = []
    for i in range(len(t)):
        r = radar.get_range()
        kf.predict()
        kf.update(z=[r])

        xs[i, :] = kf.x
        rs.append(r)

        # test mahalanobis
        a = np.zeros(kf.y.shape)
        maha = scipy_mahalanobis(a, kf.y, kf.SI)
        assert kf.mahalanobis == approx(maha)

    if DO_PLOT:
        print(xs[:, 0].shape)

        plt.figure()
        plt.subplot(311)
        plt.plot(t, xs[:, 0])
        plt.subplot(312)
        plt.plot(t, xs[:, 1])
        plt.subplot(313)
        plt.plot(t, xs[:, 2])
Ejemplo n.º 14
0
def test_radar():
    def fx(x, dt):
        A = np.eye(3) + dt * np.array([[0, 1, 0], [0, 0, 0], [0, 0, 0]])
        return A.dot(x)

    def hx(x):
        return np.sqrt(x[0]**2 + x[2]**2)

    dt = 0.05

    sp = JulierSigmaPoints(n=3, kappa=0.)
    # sp = SimplexSigmaPoints(n=3)
    kf = UKF(3, 1, dt, fx=fx, hx=hx, points=sp)
    assert np.allclose(kf.x, kf.x_prior)
    assert np.allclose(kf.P, kf.P_prior)

    # test __repr__ doesn't crash
    str(kf)

    kf.Q *= 0.01
    kf.R = 10
    kf.x = np.array([0., 90., 1100.])
    kf.P *= 100.
    radar = RadarSim(dt)

    t = np.arange(0, 20 + dt, dt)

    n = len(t)

    xs = np.zeros((n, 3))

    random.seed(200)
    rs = []
    #xs = []
    for i in range(len(t)):
        r = radar.get_range()
        #r = GetRadar(dt)
        kf.predict()
        kf.update(z=[r])

        xs[i, :] = kf.x
        rs.append(r)

    if DO_PLOT:
        print(xs[:, 0].shape)

        plt.figure()
        plt.subplot(311)
        plt.plot(t, xs[:, 0])
        plt.subplot(312)
        plt.plot(t, xs[:, 1])
        plt.subplot(313)
        plt.plot(t, xs[:, 2])
Ejemplo n.º 15
0
def test_kalman_motion(testname, vel_s, vel_p, turn_rad, dangle_tot, variance_diag,
                       start_angle=0, manual_p=None, manual_x=None, t_total=5.0):
    dt = 0.05               # 50 ms, robot control period
    kf = TankKalman2(dt, 2.0, 0.0, 0.0)
    kf.Q = np.zeros((6, 6))

    omega = dangle_tot / t_total
    kf.x = np.array([0, 0, vel_s, vel_p, start_angle, omega])
    kf.P = np.diag(variance_diag)
    for i in range(int(t_total / dt)):
        UnscentedKalmanFilter.predict(kf)

    if manual_x is not None:
        x_expect = manual_x
    elif dangle_tot < 0.0001:
        x = vel_s * t_total
        y = vel_p * t_total
        if abs(start_angle) > 0.0001:
            x2 = x * math.cos(start_angle) - y * math.sin(start_angle)
            y2 = x * math.sin(start_angle) + y * math.cos(start_angle)
            x = x2
            y = y2
        x_expect = np.array([x, y, vel_s, vel_p, start_angle, omega])
    else:
        raise Exception('not implemented')

    # print('kf.x =', kf.x)
    # print('kf.P =', kf.P)

    cmp_arrays(kf.x, x_expect, 0.015, testname + ' x')

    if manual_p is not None:
        cmp_arrays(kf.P, manual_p, 1e-3, testname + ' manual_P')
    else:
        encoders = TankEncoderTracker(kf.wheel_base, 0, 0)

        p_enc0 = np.diag([variance_diag[0], variance_diag[1], variance_diag[TankKalman2.STATE_THETA]])
        if dangle_tot < 0.0001:
            p_sp = encoders.propagate_line(vel_s * t_total, p_enc0)
        else:
            dl = TankEncoderTracker.dl_func(turn_rad, kf.x[TankKalman2.STATE_THETA], kf.wheel_base)
            dr = TankEncoderTracker.dr_func(turn_rad, kf.x[TankKalman2.STATE_THETA], kf.wheel_base)
            p_sp = encoders.propagate_arc(dl, dr, p_enc0)

        t_rot = TankEncoderTracker.t_matrix(kf.x[TankKalman2.STATE_THETA])
        p_xy = t_rot @ p_sp @ t_rot.T
        t_expand = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 0], [0, 0, 0], [0, 0, 1], [0, 0, 0]])
        p_expect = t_expand @ p_xy @ t_expand.T

        cmp_arrays(kf.P, p_expect, 1e-3, testname + ' encoder_P')

    return kf
Ejemplo n.º 16
0
def test_vhartman():
    """
    Code provided by vhartman on github #172

    https://github.com/rlabbe/filterpy/issues/172
    """
    def fx(x, dt):
        # state transition function - predict next state based
        # on constant velocity model x = vt + x_0
        F = np.array([[1.]], dtype=np.float32)
        return np.dot(F, x)

    def hx(x):
        # measurement function - convert state into a measurement
        # where measurements are [x_pos, y_pos]
        return np.array([x[0]])

    dt = 1.0
    # create sigma points to use in the filter. This is standard for Gaussian processes
    points = MerweScaledSigmaPoints(1, alpha=1, beta=2., kappa=0.1)

    kf = UnscentedKalmanFilter(dim_x=1,
                               dim_z=1,
                               dt=dt,
                               fx=fx,
                               hx=hx,
                               points=points)
    kf.x = np.array([0.])  # initial state
    kf.P = np.array([[1]])  # initial uncertainty
    kf.R = np.diag([1])  # 1 standard
    kf.Q = np.diag([1])  # 1 standard

    ekf = ExtendedKalmanFilter(dim_x=1, dim_z=1)
    ekf.F = np.array([[1]])

    ekf.x = np.array([0.])  # initial state
    ekf.P = np.array([[1]])  # initial uncertainty
    ekf.R = np.diag([1])  # 1 standard
    ekf.Q = np.diag([1])  # 1 standard

    np.random.seed(0)
    zs = [[np.random.randn()] for i in range(50)]  # measurements
    for z in zs:
        kf.predict()
        ekf.predict()
        assert np.allclose(ekf.P, kf.P)
        assert np.allclose(ekf.x, kf.x)

        kf.update(z)
        ekf.update(z, lambda x: np.array([[1]]), hx)
        assert np.allclose(ekf.P, kf.P)
        assert np.allclose(ekf.x, kf.x)
Ejemplo n.º 17
0
def test_radar():
    def fx(x, dt):
        A = np.eye(3) + dt * np.array ([[0, 1, 0],
                                        [0, 0, 0],
                                        [0, 0, 0]])
        return A.dot(x)

    def hx(x):
        return np.sqrt (x[0]**2 + x[2]**2)

    dt = 0.05

    sp = JulierSigmaPoints(n=3, kappa=0.)
    kf = UKF(3, 1, dt, fx=fx, hx=hx, points=sp)

    kf.Q *= 0.01
    kf.R = 10
    kf.x = np.array([0., 90., 1100.])
    kf.P *= 100.
    radar = RadarSim(dt)

    t = np.arange(0,20+dt, dt)

    n = len(t)

    xs = np.zeros((n,3))

    random.seed(200)
    rs = []
    #xs = []
    for i in range(len(t)):
        r = radar.get_range()
        #r = GetRadar(dt)
        kf.predict()
        kf.update(z=[r])

        xs[i,:] = kf.x
        rs.append(r)

    if DO_PLOT:
        print(xs[:,0].shape)

        plt.figure()
        plt.subplot(311)
        plt.plot(t, xs[:,0])
        plt.subplot(312)
        plt.plot(t, xs[:,1])
        plt.subplot(313)

        plt.plot(t, xs[:,2])
Ejemplo n.º 18
0
def estimateUKF(camPoses):
    points = MerweScaledSigmaPoints(3,.1,2.,0.)
    filter = UKF(3,3,0,h, f, points, sqrt_fn=None, x_mean_fn=state_mean, z_mean_fn=state_mean, residual_x=residual, residual_z=residual)
    filter.P = np.diag([0.04,0.04,0.003])
    filter.Q = np.diag([(0.2)**2,(0.2)**2,(1*3.14/180)**2])
    filter.R = np.diag([100,100,0.25])
    Uposes = [[],[]]
    for i in range(len(speed)):
        x = filter.x
        Uposes[0].append(x[0])
        Uposes[1].append(x[1])
        filter.predict(fx_args=[speed[i],angle[i]*0.01745])
        filter.update(z = [camPoses[0][i],camPoses[1][i],camPoses[2][i]])
    return Uposes
Ejemplo n.º 19
0
def test_radar():
    def fx(x, dt):
        A = np.eye(3) + dt * np.array ([[0, 1, 0],
                                        [0, 0, 0],
                                        [0, 0, 0]])
        return A.dot(x)

    def hx(x):
        return np.sqrt (x[0]**2 + x[2]**2)

    dt = 0.05

    kf = UKF(3, 1, dt, fx=fx, hx=hx, kappa=0.)

    kf.Q *= 0.01
    kf.R = 10
    kf.x = np.array([0., 90., 1100.])
    kf.P *= 100.
    radar = RadarSim(dt)

    t = np.arange(0,20+dt, dt)

    n = len(t)

    xs = np.zeros((n,3))

    random.seed(200)
    rs = []
    #xs = []
    for i in range(len(t)):
        r = radar.get_range()
        #r = GetRadar(dt)
        kf.predict()
        kf.update(z=[r])

        xs[i,:] = kf.x
        rs.append(r)

    if DO_PLOT:
        print(xs[:,0].shape)

        plt.figure()
        plt.subplot(311)
        plt.plot(t, xs[:,0])
        plt.subplot(312)
        plt.plot(t, xs[:,1])
        plt.subplot(313)

        plt.plot(t, xs[:,2])
Ejemplo n.º 20
0
    def predict(self, dt, motors=None, nsteps=1):
        # save the previous state for use during update()
        self.prev_x = np.copy(self.x)

        dt_step = dt / nsteps
        for _ in range(nsteps):
            # set Q and predict
            self.Q = self.Q_func(dt_step, self.x[self.STATE_THETA])

            accelerations = None
            if motors and self.control_model:
                accelerations = self.control_model.accelerations(motors, self.x[self.STATE_VS], self.x[self.STATE_OMEGA])

            UnscentedKalmanFilter.predict(self, dt=dt_step, accelerations=accelerations)
        return
Ejemplo n.º 21
0
def test_rts():
    def fx(x, dt):
        A = np.eye(3) + dt * np.array ([[0, 1, 0],
                                        [0, 0, 0],
                                        [0, 0, 0]])
        f = np.dot(A, x)
        return f

    def hx(x):
        return np.sqrt (x[0]**2 + x[2]**2)

    dt = 0.05

    sp = JulierSigmaPoints(n=3, kappa=1.)
    kf = UKF(3, 1, dt, fx=fx, hx=hx, points=sp)

    kf.Q *= 0.01
    kf.R = 10
    kf.x = np.array([0., 90., 1100.])
    kf.P *= 100.
    radar = RadarSim(dt)

    t = np.arange(0,20+dt, dt)

    n = len(t)

    xs = np.zeros((n,3))

    random.seed(200)
    rs = []
    #xs = []
    for i in range(len(t)):
        r = radar.get_range()
        #r = GetRadar(dt)
        kf.predict()
        kf.update(z=[r])

        xs[i,:] = kf.x
        rs.append(r)


    kf.x = np.array([0., 90., 1100.])
    kf.P = np.eye(3)*100
    M, P = kf.batch_filter(rs)
    assert np.array_equal(M, xs), "Batch filter generated different output"

    Qs = [kf.Q]*len(t)
    M2, P2, K = kf.rts_smoother(Xs=M, Ps=P, Qs=Qs)
Ejemplo n.º 22
0
class filterr:
    def __init__(self, current_temp, dt):
        """Unscented kalman filter"""
        self._interval = 0
        self._last_update = time.time()
        # sigmas = JulierSigmaPoints(n=2, kappa=0)
        sigmas = MerweScaledSigmaPoints(n=2, alpha=0.001, beta=2, kappa=0)
        self._kf_temp = UnscentedKalmanFilter(
            dim_x=2, dim_z=1, dt=dt, hx=hx, fx=fx, points=sigmas
        )
        self._kf_temp.x = np.array([float(current_temp), 0.0])
        self._kf_temp.P *= 0.2  # initial uncertainty
        self.interval = dt

    def kf_predict(self):
        dt = time.time() - self._last_update
        self._last_update = time.time()
        self._kf_temp.predict(dt=dt)

    def kf_update(self, current_temp):
        self._kf_temp.update(float(current_temp))

    @property
    def get_temp(self):
        return float(self._kf_temp.x[0])

    @property
    def get_vel(self):
        return float(self._kf_temp.x[1])

    def set_Q_R(self, dt=None):
        """ process noise """
        self._kf_temp.Q = Q_discrete_white_noise(
            dim=2, dt=self._interval, var=(0.005 / (self._interval ** 1.2)) ** 2
        )

        """measurement noise std**2 """
        self._kf_temp.R = np.diag([(4 * (1800 / self._interval) ** 0.8) ** 2])

    @property
    def interval(self):
        return self._interval

    @interval.setter
    def interval(self, dt):
        if dt != self.interval:
            self._interval = dt
            self.set_Q_R()
Ejemplo n.º 23
0
class KF:
    def __init__(self, initial_x, initial_y, initial_vx, initial_vy):
        self.dt = 0.05
        # create sigma points to use in the filter. This is standard for Gaussian processes
        self.points = MerweScaledSigmaPoints(4, alpha=.1, beta=2., kappa=-1)

        self.kf = UnscentedKalmanFilter(dim_x=4,
                                        dim_z=2,
                                        dt=self.dt,
                                        fx=fx,
                                        hx=hx,
                                        points=self.points)
        self.kf.x = np.array([initial_x, 0, initial_y, 0])  # initial state
        self.kf.P *= 0.1  # initial uncertainty
        self.z_std = 0.1
        self.kf.R = np.diag([self.z_std**2, self.z_std**2])  # 1 standard
        self.kf.Q = Q_discrete_white_noise(dim=2,
                                           dt=self.dt,
                                           var=0.01**2,
                                           block_size=2)

    def predict(self):
        return self.kf.predict()

    def update(self, meas_value):
        self.kf.update([meas_value[0], meas_value[1]])

    @property
    def calulatedmean(self):
        return self.kf.x
Ejemplo n.º 24
0
def run_ukf(zs, dt=1.0):
    sigmas = MerweScaledSigmaPoints(4, alpha=0.1, beta=2.0, kappa=1.0)
    ukf = UKF(dim_x=4, dim_z=2, fx=f, hx=h, dt=dt, points=sigmas)
    ukf.x = np.array([0.0, 0.0, 0.0, 0.0])
    ukf.R = np.diag([0.09, 0.09])
    ukf.Q[0:2, 0:2] = Q_discrete_white_noise(2, dt=1, var=0.02)
    ukf.Q[2:4, 2:4] = Q_discrete_white_noise(2, dt=1, var=0.02)

    uxs = []
    for z in zs:
        ukf.predict()
        ukf.update(z)
        uxs.append(ukf.x.copy())
    uxs = np.array(uxs)

    return uxs
Ejemplo n.º 25
0
def test_1d():

    def fx(x, dt):
        F = np.array([[1., dt],
                      [0,  1]])

        return np.dot(F, x)

    def hx(x):
        return np.array([[x[0]]])



    ckf = CKF(dim_x=2, dim_z=1, dt=0.1, hx=hx, fx=fx)

    ckf.x = np.array([[1.], [2.]])
    ckf.P = np.array([[1, 1.1],
                      [1.1, 3]])

    ckf.R = np.eye(1) * .05
    ckf.Q = np.array([[0., 0], [0., .001]])

    dt = 0.1
    points = MerweScaledSigmaPoints(2, .1, 2., -1)
    kf = UKF(dim_x=2, dim_z=1, dt=dt, fx=fx, hx=hx, points=points)


    kf.x = np.array([1, 2])
    kf.P = np.array([[1, 1.1],
                     [1.1, 3]])
    kf.R *= 0.05
    kf.Q = np.array([[0., 0], [0., .001]])


    for i in range(50):
        z = np.array([[i+randn()*0.1]])
        #xx, pp, Sx = predict(f, x, P, Q)
        #x, P = update(h, z, xx, pp, R)
        ckf.predict()
        ckf.update(z)
        kf.predict()
        kf.update(z[0])
        assert abs(ckf.x[0] -kf.x[0]) < 1e-10
        assert abs(ckf.x[1] -kf.x[1]) < 1e-10


    plt.show()
Ejemplo n.º 26
0
def test_1d():
    def fx(x, dt):
        F = np.array([[1., dt],
                      [0,  1]])

        return np.dot(F, x)

    def hx(x):
        return x[0:1]

    ckf = CKF(dim_x=2, dim_z=1, dt=0.1, hx=hx, fx=fx)

    ckf.x = np.array([[1.], [2.]])
    ckf.P = np.array([[1, 1.1],
                      [1.1, 3]])

    ckf.R = np.eye(1) * .05
    ckf.Q = np.array([[0., 0], [0., .001]])

    dt = 0.1
    points = MerweScaledSigmaPoints(2, .1, 2., -1)
    kf = UKF(dim_x=2, dim_z=1, dt=dt, fx=fx, hx=hx, points=points)

    kf.x = np.array([1, 2])
    kf.P = np.array([[1, 1.1],
                     [1.1, 3]])
    kf.R *= 0.05
    kf.Q = np.array([[0., 0], [0., .001]])

    s = Saver(kf)
    for i in range(50):
        z = np.array([[i+randn()*0.1]])
        ckf.predict()
        ckf.update(z)
        kf.predict()
        kf.update(z[0])
        assert abs(ckf.x[0] - kf.x[0]) < 1e-10
        assert abs(ckf.x[1] - kf.x[1]) < 1e-10
        s.save()

        # test mahalanobis
        a = np.zeros(kf.y.shape)
        maha = scipy_mahalanobis(a, kf.y, kf.SI)
        assert kf.mahalanobis == approx(maha)

    s.to_array()
Ejemplo n.º 27
0
    def predict(self, dt):
        # save the previous state for use during update()
        self.prev_x = np.copy(self.x)

        # set Q and predict
        self.Q = self.Q_func(dt, self.x[self.STATE_THETA])

        return UnscentedKalmanFilter.predict(self)
Ejemplo n.º 28
0
def test_ukf_ekf_comparison():
    def fx(x, dt):
        # state transition function - predict next state based
        # on constant velocity model x = vt + x_0
        F = np.array([[1.]], dtype=np.float32)
        return np.dot(F, x)

    def hx(x):
        # measurement function - convert state into a measurement
        # where measurements are [x_pos, y_pos]
        return np.array([x[0]])

    dt = 1.0
    # create sigma points to use in the filter. This is standard for Gaussian processes
    points = MerweScaledSigmaPoints(1, alpha=1, beta=2., kappa=0.1)

    ukf = UnscentedKalmanFilter(dim_x=1,
                                dim_z=1,
                                dt=dt,
                                fx=fx,
                                hx=hx,
                                points=points)
    ukf.x = np.array([0.])  # initial state
    ukf.P = np.array([[1]])  # initial uncertainty
    ukf.R = np.diag([1])  # 1 standard
    ukf.Q = np.diag([1])  # 1 standard

    ekf = ExtendedKalmanFilter(dim_x=1, dim_z=1)
    ekf.F = np.array([[1]])

    ekf.x = np.array([0.])  # initial state
    ekf.P = np.array([[1]])  # initial uncertainty
    ekf.R = np.diag([1])  # 1 standard
    ekf.Q = np.diag([1])  # 1 standard

    np.random.seed(0)
    zs = [[np.random.randn()] for i in range(50)]  # measurements
    for z in zs:
        ukf.predict()
        ekf.predict()
        assert np.allclose(ekf.P, ukf.P), 'ekf and ukf differ after prediction'

        ukf.update(z)
        ekf.update(z, lambda x: np.array([[1]]), hx)
        assert np.allclose(ekf.P, ukf.P), 'ekf and ukf differ after update'
Ejemplo n.º 29
0
def iniciar_ukf(list_z):
    dt = 1
    # create sigma points to use in the filter. This is standard for Gaussian processes
    points = MerweScaledSigmaPoints(4, alpha=.1, beta=2., kappa=-1)

    kf = UnscentedKalmanFilter(dim_x=4,
                               dim_z=2,
                               dt=dt,
                               fx=fx,
                               hx=hx,
                               points=points)
    kf.x = np.array([1., 1., 1., 1])  # initial state
    kf.P *= 0.2  # initial uncertainty
    z_std = 0.1
    kf.R = np.diag([z_std**2, z_std**2])  # 1 standard
    kf.Q = Q_discrete_white_noise(dim=2, dt=dt, var=0.01**2, block_size=2)

    zs = list_z
    x_predichas = []
    y_predichas = []
    x_estimadas = []
    y_estimadas = []
    for z in zs:
        # Predicción
        kf.predict()
        xp = kf.x[0]
        yp = kf.x[1]
        x_predichas.append(xp)
        y_predichas.append(yp)
        print("PREDICCION: x:", xp, "y:", yp)

        # Actualización
        kf.update(z)
        xe = kf.x[0]
        ye = kf.x[1]
        x_estimadas.append(xe)
        y_estimadas.append(ye)
        print("ESTIMADO: x:", xe, "y:", ye)
        print("--------------------------------------")

    plt.plot(x_predichas, y_predichas, linestyle="-", color='orange')
    plt.plot(x_estimadas, y_estimadas, linestyle="-", color='b')

    plt.show()
Ejemplo n.º 30
0
def filter(measurements):

    dt = 0.1

    # x = [x, x', x'' y, y', y'']
    x = np.array([measurements[0][0], 0., 0., measurements[0][1], 0., 0.])

    G = np.array([[0.19*(dt**2)],
                  [dt],
                  [1.],
                  [0.19*(dt**2)],
                  [dt],
                  [1.]])
     
    Q = G*G.T*0.1**2

    # Info available http://nbviewer.ipython.org/github/rlabbe/Kalman-and-Bayesian-Filters-in-Python/blob/master/05_Multivariate_Kalman_Filters.ipynb
    sigmas = MerweScaledSigmaPoints(n=6, alpha=1., beta=2., kappa=-3.)
    
    bot_filter = UKF(dim_x=6, dim_z=2, fx=f_cv, hx=h_cv, dt=dt, points=sigmas)
    bot_filter.x = np.array([measurements[0][0], 0., 0, measurements[0][1], 0., 0.])
    #bot_filter.F = F
    bot_filter.H = np.array([[1., 0., 0., 1., 0., 0.]])
    #bot_filter.Q = Q
    bot_filter.Q[0:3, 0:3] = Q_discrete_white_noise(3, dt=1, var=0.0002)
    bot_filter.Q[3:6, 3:6] = Q_discrete_white_noise(3, dt=1, var=0.0002)
    bot_filter.P *= 500
    bot_filter.R = np.diag([0.0001, 0.0001])

    observable_meas = measurements[0:len(measurements)-60]

    pos, cov = [], []
    for z in observable_meas:
        pos.append(bot_filter.x)
        cov.append(bot_filter.P)
        
        bot_filter.predict()
        bot_filter.update(z)

    for i in range(0,60):
        bot_filter.predict()
        pos.append(bot_filter.x)
        
    return pos
Ejemplo n.º 31
0
def test_1d():
    def fx(x, dt):
        F = np.array([[1., dt], [0, 1]])

        return np.dot(F, x)

    def hx(x):
        return x[0:1]

    ckf = CKF(dim_x=2, dim_z=1, dt=0.1, hx=hx, fx=fx)

    ckf.x = np.array([[1.], [2.]])
    ckf.P = np.array([[1, 1.1], [1.1, 3]])

    ckf.R = np.eye(1) * .05
    ckf.Q = np.array([[0., 0], [0., .001]])

    dt = 0.1
    points = MerweScaledSigmaPoints(2, .1, 2., -1)
    kf = UKF(dim_x=2, dim_z=1, dt=dt, fx=fx, hx=hx, points=points)

    kf.x = np.array([1, 2])
    kf.P = np.array([[1, 1.1], [1.1, 3]])
    kf.R *= 0.05
    kf.Q = np.array([[0., 0], [0., .001]])

    s = Saver(kf)
    for i in range(50):
        z = np.array([[i + randn() * 0.1]])
        ckf.predict()
        ckf.update(z)
        kf.predict()
        kf.update(z[0])
        assert abs(ckf.x[0] - kf.x[0]) < 1e-10
        assert abs(ckf.x[1] - kf.x[1]) < 1e-10
        s.save()

        # test mahalanobis
        a = np.zeros(kf.y.shape)
        maha = scipy_mahalanobis(a, kf.y, kf.SI)
        assert kf.mahalanobis == approx(maha)

    s.to_array()
Ejemplo n.º 32
0
def linear_filter(measurements):

    dt = 1.0

    # x = [x, x', y, y']
    x = np.array([measurements[0][0], 0., measurements[0][1], 0.])

    H = np.array([[1., 0., 1., 0.]])

    # Info available http://nbviewer.ipython.org/github/rlabbe/Kalman-and-Bayesian-Filters-in-Python/blob/master/05_Multivariate_Kalman_Filters.ipynb
    sigmas = MerweScaledSigmaPoints(n=4, alpha=0.3, beta=2., kappa=-3.)

    bot_filter = UKF(dim_x=4,
                     dim_z=2,
                     fx=f_linear,
                     hx=h_linear,
                     dt=dt,
                     points=sigmas)
    bot_filter.x = np.array([measurements[0][0], 0., measurements[0][1], 0.])
    #bot_filter.F = F
    bot_filter.H = np.asarray(H)
    #bot_filter.Q = Q
    bot_filter.Q[0:2, 0:2] = Q_discrete_white_noise(2, dt=1, var=0.1)
    bot_filter.Q[2:4, 2:4] = Q_discrete_white_noise(2, dt=1, var=0.1)
    bot_filter.P *= 10
    bot_filter.R = np.diag([0.0001, 0.0001])

    observable_meas = measurements[0:len(measurements) - 60]

    pos, cov = [], []
    for z in observable_meas:
        pos.append(bot_filter.x)
        cov.append(bot_filter.P)

        bot_filter.predict()
        bot_filter.update(z)

    for i in range(0, 60):
        bot_filter.predict()
        pos.append(bot_filter.x)

    return pos
Ejemplo n.º 33
0
def filter(measurements):

    dt = 0.1

    # x = [x, x', x'' y, y', y'']
    x = np.array([measurements[0][0], 0., 0., measurements[0][1], 0., 0.])

    G = np.array([[0.19 * (dt**2)], [dt], [1.], [0.19 * (dt**2)], [dt], [1.]])

    Q = G * G.T * 0.1**2

    # Info available http://nbviewer.ipython.org/github/rlabbe/Kalman-and-Bayesian-Filters-in-Python/blob/master/05_Multivariate_Kalman_Filters.ipynb
    sigmas = MerweScaledSigmaPoints(n=6, alpha=1., beta=2., kappa=-3.)

    bot_filter = UKF(dim_x=6, dim_z=2, fx=f_cv, hx=h_cv, dt=dt, points=sigmas)
    bot_filter.x = np.array(
        [measurements[0][0], 0., 0, measurements[0][1], 0., 0.])
    #bot_filter.F = F
    bot_filter.H = np.array([[1., 0., 0., 1., 0., 0.]])
    #bot_filter.Q = Q
    bot_filter.Q[0:3, 0:3] = Q_discrete_white_noise(3, dt=1, var=0.0002)
    bot_filter.Q[3:6, 3:6] = Q_discrete_white_noise(3, dt=1, var=0.0002)
    bot_filter.P *= 500
    bot_filter.R = np.diag([0.0001, 0.0001])

    observable_meas = measurements[0:len(measurements) - 60]

    pos, cov = [], []
    for z in observable_meas:
        pos.append(bot_filter.x)
        cov.append(bot_filter.P)

        bot_filter.predict()
        bot_filter.update(z)

    for i in range(0, 60):
        bot_filter.predict()
        pos.append(bot_filter.x)

    return pos
Ejemplo n.º 34
0
def test_1d():
    def fx(x, dt):
        F = np.array([[1., dt], [0, 1]])

        return np.dot(F, x)

    def hx(x):
        return x[0:1]

    ckf = CKF(dim_x=2, dim_z=1, dt=0.1, hx=hx, fx=fx)

    ckf.x = np.array([[1.], [2.]])
    ckf.P = np.array([[1, 1.1], [1.1, 3]])

    ckf.R = np.eye(1) * .05
    ckf.Q = np.array([[0., 0], [0., .001]])

    dt = 0.1
    points = MerweScaledSigmaPoints(2, .1, 2., -1)
    kf = UKF(dim_x=2, dim_z=1, dt=dt, fx=fx, hx=hx, points=points)

    kf.x = np.array([1, 2])
    kf.P = np.array([[1, 1.1], [1.1, 3]])
    kf.R *= 0.05
    kf.Q = np.array([[0., 0], [0., .001]])

    s = Saver(kf)
    for i in range(50):
        z = np.array([[i + randn() * 0.1]])
        #xx, pp, Sx = predict(f, x, P, Q)
        #x, P = update(h, z, xx, pp, R)
        ckf.predict()
        ckf.update(z)
        kf.predict()
        kf.update(z[0])
        assert abs(ckf.x[0] - kf.x[0]) < 1e-10
        assert abs(ckf.x[1] - kf.x[1]) < 1e-10
        s.save()
    s.to_array()
Ejemplo n.º 35
0
def plot_filtered(log_data):
    def f(x, dt):
        """ state transition function """
        F = np.array([[1, dt, 0, 0], [0, 1, 0, 0], [0, 0, 1, dt], [0, 0, 0,
                                                                   1]])
        return np.dot(F, x)

    def h(x):
        """ measurement function (state to measurement transform) """
        return np.array(x[0], x[2])

    dt = 1.
    points = MerweScaledSigmaPoints(n=4, alpha=.1, beta=2., kappa=-1)
    ukf = UnscentedKalmanFilter(dim_x=4,
                                dim_z=2,
                                fx=f,
                                hx=h,
                                dt=dt,
                                points=points)
    ukf.x = np.array([0., 0., 0., 0.])
    ukf.R = np.diag([0.09, 0.09])
    ukf.Q[0:2, 0:2] = Q_discrete_white_noise(2, dt=1, var=0.02)
    ukf.Q[2:4, 2:4] = Q_discrete_white_noise(2, dt=1, var=0.02)

    uxs = []
    zs = np.stack((log_data['longitude'], log_data['latitude']), axis=-1)
    for z in zs:
        ukf.predict()
        ukf.update(z)
        uxs.append(ukf.x.copy())
    uxs = np.array(uxs)

    plt.subplot(211)
    plt.plot(log_data['longitude'], log_data['latitude'])

    plt.subplot(212)
    plt.plot(uxs[:, 0], uxs[:, 2])

    plt.show()
Ejemplo n.º 36
0
def test_linear_1d():
    """ should work like a linear KF if problem is linear """


    def fx(x, dt):
        F = np.array([[1., dt],
                      [0,  1]], dtype=float)

        return np.dot(F, x)

    def hx(x):
        return np.array([x[0]])


    dt = 0.1
    points = MerweScaledSigmaPoints(2, .1, 2., -1)
    kf = UKF(dim_x=2, dim_z=1, dt=dt, fx=fx, hx=hx, points=points)


    kf.x = np.array([1, 2])
    kf.P = np.array([[1, 1.1],
                     [1.1, 3]])
    kf.R *= 0.05
    kf.Q = np.array([[0., 0], [0., .001]])

    z = np.array([2.])
    kf.predict()
    kf.update(z)

    zs = []
    for i in range(50):
        z = np.array([i+randn()*0.1])
        zs.append(z)

        kf.predict()
        kf.update(z)
        print('K', kf.K.T)
        print('x', kf.x)
def UKF_tracking(x0, Obser):
    #定义UKF
    dim_state = len(x0)
    [data_len, dim_obser] = Obser.shape
    my_SP = SP(dim_state, kappa=0.)
    my_UKF = UKF(dim_x=dim_state,
                 dim_z=dim_obser,
                 dt=sT,
                 hx=my_hx,
                 fx=my_fx,
                 points=my_SP)
    my_UKF.Q *= var_m
    my_UKF.R *= np.array([[azi_var, 0], [0, dis_var]])
    my_UKF.x = x0
    my_UKF.P *= 1.
    #跟踪的航迹结果
    xs = []
    xs.append(my_UKF.x.copy())
    for i in range(data_len - 1):
        my_UKF.predict()
        my_UKF.update(Obser[i + 1, :])
        xs.append(my_UKF.x.copy())
    return np.asarray(xs)
Ejemplo n.º 38
0
def linear_filter(measurements):
    
    dt = 1.0

    # x = [x, x', y, y']
    x = np.array([measurements[0][0], 0., measurements[0][1], 0.])

    H = np.array([[1., 0., 1., 0.]])

    # Info available http://nbviewer.ipython.org/github/rlabbe/Kalman-and-Bayesian-Filters-in-Python/blob/master/05_Multivariate_Kalman_Filters.ipynb
    sigmas = MerweScaledSigmaPoints(n=4, alpha=0.3, beta=2., kappa=-3.)
    
    bot_filter = UKF(dim_x=4, dim_z=2, fx=f_linear, hx=h_linear, dt=dt, points=sigmas)
    bot_filter.x = np.array([measurements[0][0], 0., measurements[0][1], 0.])
    #bot_filter.F = F
    bot_filter.H = np.asarray(H)
    #bot_filter.Q = Q
    bot_filter.Q[0:2, 0:2] = Q_discrete_white_noise(2, dt=1, var=0.1)
    bot_filter.Q[2:4, 2:4] = Q_discrete_white_noise(2, dt=1, var=0.1)
    bot_filter.P *= 10
    bot_filter.R = np.diag([0.0001, 0.0001])

    observable_meas = measurements[0:len(measurements)-60]

    pos, cov = [], []
    for z in observable_meas:
        pos.append(bot_filter.x)
        cov.append(bot_filter.P)
        
        bot_filter.predict()
        bot_filter.update(z)

    for i in range(0,60):
        bot_filter.predict()
        pos.append(bot_filter.x)
        
    return pos
class UKF_estimate(object):
    """ UKF_estimate """
    def __init__(self, env, dim_x, dim_y, X_0, P, Q, R, mn):
        # self.sigmas = JulierSigmaPoints(dim_x, alpha=.1, beta=2., kappa=1.)
        self.sigmas = JulierSigmaPoints(dim_x, kappa=0.1)
        self.env = env
        self.measure_nums = mn
        self.ukf = UnscentedKalmanFilter(dim_x=dim_x,
                                         dim_z=dim_y,
                                         dt=env.tau,
                                         hx=self.measurement,
                                         fx=UKF_model,
                                         points=self.sigmas)
        self.ukf.x = X_0[:, 0]
        # print(self.ukf.x.shape)
        self.ukf.P = np.copy(P)
        self.ukf.R = np.copy(R)
        self.ukf.Q = np.copy(Q)

# estimate states from input of measurement

    def state_estimate(self, force, y):
        # update estimation from kalman filter
        self.ukf.predict(env=self.env, u=force)
        self.ukf.update(y)
        # print(self.ukf.x)
        # return updated estimated state
        return self.ukf.x

    def measurement(self, x):
        if self.measure_nums is 2:
            y = np.array([x[0], x[3]])
        elif self.measure_nums is 1:
            y = np.array([x[0]])

        return y
Ejemplo n.º 40
0
def estimateUKF(camPoses):
    points = MerweScaledSigmaPoints(3, .1, 2., 0.)
    filter = UKF(3,
                 3,
                 0,
                 h,
                 f,
                 points,
                 sqrt_fn=None,
                 x_mean_fn=state_mean,
                 z_mean_fn=state_mean,
                 residual_x=residual,
                 residual_z=residual)
    filter.P = np.diag([0.04, 0.04, 0.003])
    filter.Q = np.diag([(0.2)**2, (0.2)**2, (1 * 3.14 / 180)**2])
    filter.R = np.diag([100, 100, 0.25])
    Uposes = [[], []]
    for i in range(len(speed)):
        x = filter.x
        Uposes[0].append(x[0])
        Uposes[1].append(x[1])
        filter.predict(fx_args=[speed[i], angle[i] * 0.01745])
        filter.update(z=[camPoses[0][i], camPoses[1][i], camPoses[2][i]])
    return Uposes
Ejemplo n.º 41
0
txs = []
cxs = []
radius = 100
delta = 2*np.pi/360*5
for i in range(70):
    # 真实位置
    target_pos_x = math.cos(i*delta)*radius + random.randn()*0.0001
    target_pos_y = math.sin(i*delta)*radius + random.randn()*0.0001
    txs.append((target_pos_x, target_pos_y))
    
    # 测量位置
    zx = target_pos_x + random.randn()*5
    zy = target_pos_y + random.randn()*5
    zs.append([zx,zy])
    
    ukf.predict()
    ukf.update([zx,zy])
    
    ckf.predict()
    ckf.update([zx,zy])
    cxs.append(ckf.x.copy())
    print "第%d轮结果:" % (i),ckf.x
    
    #pukf
    pSigma = e(ukf.sigmas_f)
    dHat = np.sum(pSigma)/len(pSigma)
    pddPukf = 0
    pxdPukf = np.zeros((1,4))
    for i in range(len(pSigma)):
        pddPukf += ukf.W[i]*(
            (pSigma[i] - dHat)*(pSigma[i] - dHat))
kf.x = np.array([100, 100.])
kf.P *= 40
hx.p = kf.x - np.array([50,50])

d = ((kf.x[0] - hx.p[0])**2 + (kf.x[1] - hx.p[1])**2)**.5

stats.plot_covariance_ellipse(
       kf.x, cov=kf.P, axis_equal=True, 
       facecolor='y', edgecolor=None, alpha=0.6)
plt.scatter([100], [100], c='y', label='Initial')

kf.R[0,0] = radians (1)**2
kf.R[1,1] = 2.**2


kf.predict()
kf.update(np.array([radians(45), d]))

print(kf.x)
print(kf.P)

stats.plot_covariance_ellipse(
       kf.x, cov=kf.P, axis_equal=True, 
       facecolor='g', edgecolor=None, alpha=0.6)
plt.scatter([100], [100], c='g', label='45 degrees')
       
       
p = (13, -11)
hx.p = kf.x - np.array([-50,50])
d = ((kf.x[0] - hx.p[0])**2 + (kf.x[1] - hx.p[1])**2)**.5
Ejemplo n.º 43
0
    dt = 0.05
    points_obj=MerweScaledSigmaPoints(n=3)
    radarUKF = UKF(dim_x=3, dim_z=1, dt=dt,hx= hx,fx=fx, points=points_obj)
    radarUKF.Q *= Q_discrete_white_noise(3, 1, .01)
    radarUKF.R *= 10
    radarUKF.x = np.array([0., 90., 1100.])
    radarUKF.P *= 100.

    t = np.arange(0, 20+dt, dt)
    n = len(t)
    xs = []
    rs = []
    for i in range(n):
        r = GetRadar.GetRadar(dt)
        rs.append(r)
        radarUKF.predict()
        radarUKF.update(r)
        xs.append(radarUKF.x)

    xs = np.asarray(xs)
    plt.plot(rs)
    plt.show()

    plt.subplot(311)
    plt.plot(t, xs[:, 0])
    plt.title('distance')

    plt.subplot(312)
    plt.plot(t, xs[:, 1])
    plt.title('velocity')
Ejemplo n.º 44
0
class RearEndKalman:
    def __init__(self, trueTrajectory, dt=.1, noise = 0.):
        from filterpy.kalman import UnscentedKalmanFilter as UKF  
        from filterpy.kalman import MerweScaledSigmaPoints as SigmaPoints
        self.dt = dt
        sigmas = SigmaPoints(3, alpha=.1, beta=2., kappa=0.)
        self.KF = UKF(dim_x=3, dim_z=2, fx=f_kal_a, hx=h_kal,
                  dt=dt, points=sigmas)
        self.KF.Q = np.diag([1., 0.5, 0.2])
        self.KF.R = np.diag([2., 1.12])*noise + np.diag([.05, .05])
        self.first = True
            
        
    def predict(self, vData, predictTimes):
        nobs = vData.shape[0]        
        vcurrentState = vData.iloc[nobs-1].copy()
        
        # first check if vehicle has already stopped, don't need KF then     
        if np.mean(vData['speed'].iloc[nobs-2:nobs]) <= 0:
            returnedStates = vData[vData['time']<0] # empty
            for time in predictTimes:
                vNextState = vcurrentState.copy()
                vNextState.time = time
                vNextState.y = -8.25
                returnedStates = returnedStates.append(vNextState)
            return returnedStates
        
#        # train KF
#        self.KF.x[0] = vData.iloc[0].x
#        self.KF.x[1] = vData.iloc[0].speed
#        self.KF.predict()
#        
#        for time in np.arange(1,nobs-1):
#            vState = vData.iloc[time]
#            self.KF.update(np.array([vState.x,vState.speed]))
#            self.KF.predict()
#        self.KF.update(np.array([vData.iloc[nobs-1].x,vData.iloc[nobs-1].speed]))
        
        vState = vData.iloc[nobs-1]
        if self.first:
            self.KF.x[0] = vState.x
            self.KF.x[1] = vState.speed
            #self.KF.predict()
            self.first = False
        else:
            if vState.speed < 0:
                self.KF.update(np.array([vState.x, 0.]))
            else:
                self.KF.update(np.array([vState.x,vState.speed]))        
        
        # now you can predict
        # return a dataframe of answers
        vcurrentState = vData.iloc[vData.shape[0]-1].copy()
        vcurrentState.x = self.KF.x[0]
        vcurrentState.speed = self.KF.x[1]
        returnedStates = vData[vData['time']<0] # empty
        for time in predictTimes:
            vNextState = movePhysics(vcurrentState, self.KF.x[2]/self.dt, time)
            returnedStates = returnedStates.append(vNextState)
            
        self.KF.predict()
        return returnedStates
Ejemplo n.º 45
0
def test_rts():
    def fx(x, dt):
        A = np.eye(3) + dt * np.array ([[0, 1, 0],
                                        [0, 0, 0],
                                        [0, 0, 0]])
        f = np.dot(A, x)
        return f

    def hx(x):
        return np.sqrt (x[0]**2 + x[2]**2)

    dt = 0.05

    kf = UKF(3, 1, dt, fx=fx, hx=hx, kappa=1.)

    kf.Q *= 0.01
    kf.R = 10
    kf.x = np.array([0., 90., 1100.])
    kf.P *= 100.
    radar = RadarSim(dt)

    t = np.arange(0,20+dt, dt)

    n = len(t)

    xs = np.zeros((n,3))

    random.seed(200)
    rs = []
    #xs = []
    for i in range(len(t)):
        r = radar.get_range()
        #r = GetRadar(dt)
        kf.predict()
        kf.update(z=[r])

        xs[i,:] = kf.x
        rs.append(r)


    kf.x = np.array([0., 90., 1100.])
    kf.P = np.eye(3)*100
    M, P = kf.batch_filter(rs)
    assert np.array_equal(M, xs), "Batch filter generated different output"

    Qs = [kf.Q]*len(t)
    M2, P2, K = kf.rts_smoother(Xs=M, Ps=P, Qs=Qs)


    if DO_PLOT:
        print(xs[:,0].shape)

        plt.figure()
        plt.subplot(311)
        plt.plot(t, xs[:,0])
        plt.plot(t, M2[:,0], c='g')
        plt.subplot(312)
        plt.plot(t, xs[:,1])
        plt.plot(t, M2[:,1], c='g')
        plt.subplot(313)

        plt.plot(t, xs[:,2])
        plt.plot(t, M2[:,2], c='g')
f.x = array([0, 90, 1005])
f.R = 0.1
f.Q *= 0.002




xs = []
track = []

for i in range(int(20/dt)):
    z = radar.get_range()
    track.append((radar.pos, radar.vel, radar.alt))

    f.predict()
    f.update(array([z]))

    xs.append(f.x)


xs = asarray(xs)
track = asarray(track)
time = np.arange(0,len(xs)*dt, dt)

plt.figure()
plt.subplot(311)
plt.plot(time, track[:,0])
plt.plot(time, xs[:,0])
plt.legend(loc=4)
plt.xlabel('time (sec)')
Ejemplo n.º 47
0
def test_fixed_lag():
    def fx(x, dt):
        A = np.eye(3) + dt * np.array ([[0, 1, 0],
                                        [0, 0, 0],
                                        [0, 0, 0]])
        f = np.dot(A, x)
        return f

    def hx(x):
        return np.sqrt (x[0]**2 + x[2]**2)

    dt = 0.05

    kf = UKF(3, 1, dt, fx=fx, hx=hx, kappa=0.)

    kf.Q *= 0.01
    kf.R = 10
    kf.x = np.array([0., 90., 1100.])
    kf.P *= 1.
    radar = RadarSim(dt)

    t = np.arange(0,20+dt, dt)

    n = len(t)

    xs = np.zeros((n,3))

    random.seed(200)
    rs = []
    #xs = []

    M = []
    P = []
    N =10
    flxs = []
    for i in range(len(t)):
        r = radar.get_range()
        #r = GetRadar(dt)
        kf.predict()
        kf.update(z=[r])

        xs[i,:] = kf.x
        flxs.append(kf.x)
        rs.append(r)
        M.append(kf.x)
        P.append(kf.P)
        print(i)
        #print(i, np.asarray(flxs)[:,0])
        if i == 20 and len(M) >= N:
            try:
                M2, P2, K = kf.rts_smoother(Xs=np.asarray(M)[-N:], Ps=np.asarray(P)[-N:])
                flxs[-N:] = M2
                #flxs[-N:] = [20]*N
            except:
                print('except', i)
            #P[-N:] = P2


    kf.x = np.array([0., 90., 1100.])
    kf.P = np.eye(3)*100
    M, P = kf.batch_filter(rs)

    Qs = [kf.Q]*len(t)
    M2, P2, K = kf.rts_smoother(Xs=M, Ps=P, Qs=Qs)


    flxs = np.asarray(flxs)
    print(xs[:,0].shape)

    plt.figure()
    plt.subplot(311)
    plt.plot(t, xs[:,0])
    plt.plot(t, flxs[:,0], c='r')
    plt.plot(t, M2[:,0], c='g')
    plt.subplot(312)
    plt.plot(t, xs[:,1])
    plt.plot(t, flxs[:,1], c='r')
    plt.plot(t, M2[:,1], c='g')

    plt.subplot(313)
    plt.plot(t, xs[:,2])
    plt.plot(t, flxs[:,2], c='r')
    plt.plot(t, M2[:,2], c='g')
Ejemplo n.º 48
0
T = np.array([16.878, -7.1368, 0])		#Translation vector joining two inertial frames
time = np.arange(START_TIME,END_TIME,dt)
print time.shape,time[0],time[-1]
d = np.linspace(20,40,time.shape[0])
zs = np.zeros((time.shape[0],15))
Rs = np.zeros((time.shape[0],15,15))

means = np.zeros((time.shape[0],12))
covs = np.zeros((time.shape[0],12,12))
cam_locs = np.zeros((time.shape[0],3))
ekf_locs = np.zeros((time.shape[0],3))

for i in range(1,time.shape[0]):
	t = time[i]
	
	ukf.predict(1.0/30)
	# Get camera location and covariance points in ball inertial frame
	cam_loc = track.get_mean(t,d[i]) + T
	cam_sigs = track.get_cov(t,d[i],10) + T[:,None]
	cam_points = np.vstack((cam_sigs.T, cam_loc)).T
	cam_cov = np.cov(cam_points)
	
	# Get kalman filter state estimate
	ekf_loc = left_reader.get_ekf_loc_1d(t)
	ekf_vel = left_reader.get_ekf_vel(t)
	ekf_att = np.deg2rad(left_reader.get_ekf_att(t))
	ekf_attdot = np.deg2rad(left_reader.get_gyr(t))
	
	ekf_locs[i,:] = ekf_loc
	cam_locs[i,:] = cam_loc
	
seed(12)
cmds = np.array(cmds)

cindex = 0
u = cmds[0]

track = []

std = 16
while cindex < len(cmds):
    u = cmds[cindex]
    xp = move(xp, u, dt, wheelbase) # simulate robot
    track.append(xp)

    ukf.predict(fx_args=u)

    if cindex % 20 == 0:
        plot_covariance_ellipse((ukf.x[0], ukf.x[1]), ukf.P[0:2, 0:2], std=std,
                                facecolor='b', alpha=0.58)

    #print(cindex, ukf.P.diagonal())
    #print(ukf.P.diagonal())
    z = []
    for lmark in m:
        d = sqrt((lmark[0] - xp[0])**2 + (lmark[1] - xp[1])**2) + randn()*sigma_r
        bearing = atan2(lmark[1] - xp[1], lmark[0] - xp[0])
        a = normalize_angle(bearing - xp[2] + randn()*sigma_h)
        z.extend([d, a])

        #if cindex % 20 == 0:
Ejemplo n.º 50
0
def test_circle():
    from filterpy.kalman import KalmanFilter
    from math import radians
    def hx(x):
        radius = x[0]
        angle = x[1]
        x = cos(radians(angle)) * radius
        y = sin(radians(angle)) * radius
        return np.array([x, y])

    def fx(x, dt):
        return np.array([x[0], x[1]+x[2], x[2]])

    std_noise = .1


    f = UKF(dim_x=3, dim_z=2, dt=.01, hx=hx, fx=fx, kappa=0)
    f.x = np.array([50., 90., 0])
    f.P *= 100
    f.R = np.eye(2)*(std_noise**2)
    f.Q = np.eye(3)*.001
    f.Q[0,0]=0
    f.Q[2,2]=0

    kf = KalmanFilter(dim_x=6, dim_z=2)
    kf.x = np.array([50., 0., 0, 0, .0, 0.])

    F = np.array([[1., 1., .5, 0., 0., 0.],
                  [0., 1., 1., 0., 0., 0.],
                  [0., 0., 1., 0., 0., 0.],
                  [0., 0., 0., 1., 1., .5],
                  [0., 0., 0., 0., 1., 1.],
                  [0., 0., 0., 0., 0., 1.]])

    kf.F = F
    kf.P*= 100
    kf.H = np.array([[1,0,0,0,0,0],
                     [0,0,0,1,0,0]])


    kf.R = f.R
    kf.Q[0:3, 0:3] = Q_discrete_white_noise(3, 1., .00001)
    kf.Q[3:6, 3:6] = Q_discrete_white_noise(3, 1., .00001)

    measurements = []
    results = []

    zs = []
    kfxs = []
    for t in range (0,12000):
        a = t / 30 + 90
        x = cos(radians(a)) * 50.+ randn() * std_noise
        y = sin(radians(a)) * 50. + randn() * std_noise
        # create measurement = t plus white noise
        z = np.array([x,y])
        zs.append(z)

        f.predict()
        f.update(z)

        kf.predict()
        kf.update(z)

        # save data
        results.append (hx(f.x))
        kfxs.append(kf.x)
        #print(f.x)

    results = np.asarray(results)
    zs = np.asarray(zs)
    kfxs = np.asarray(kfxs)

    print(results)
    if DO_PLOT:
        plt.plot(zs[:,0], zs[:,1], c='r', label='z')
        plt.plot(results[:,0], results[:,1], c='k', label='UKF')
        plt.plot(kfxs[:,0], kfxs[:,3], c='g', label='KF')
        plt.legend(loc='best')
        plt.axis('equal')
Ejemplo n.º 51
0
filter.R = np.diag([100,100,0.25])
robot = vehicle.Vehicle(1,50)           #create a robot
robot.setOdometry(True)                 #configure its odometer
robot.setOdometryVariance([0.2,1])
speed,angle = [],[]
for a in xrange(4):                     #create a retangular path
    for i in xrange(400):
        angle.append(0)
    for i in xrange(9):
        angle.append(10)

for i in xrange(len(angle)):        #set the speed to a constant along the path
    speed.append(1)

robot.sim_Path(speed,angle)             #run in a rectangular path
speed , angle =  robot.readOdometry()       #reads the sensors
cam = upper_cam.UpperCam([10,10,0.5],robot)
cam.readPath()
camPoses = cam.readPoses()
Uposes = [[],[]]
for i in range(len(speed)):
    x = filter.x
    #print x
    Uposes[0].append(x[0])
    Uposes[1].append(x[1])
    filter.predict(fx_args=[speed[i],angle[i]*0.01745])
    filter.update(z = [camPoses[0][i],camPoses[1][i],camPoses[2][i]*0.01745])
#robot.show("Real")
plt.plot(Uposes[0],Uposes[1],'y',label = "UKF")
plt.legend()
plt.show()
Ejemplo n.º 52
0

def hx(x):
    """ measurement function - convert position to bearing"""

    return math.atan2(platform_pos[1], x[0] - platform_pos[0])


xs_scaled = []
xs = []
for i in range(300):
    angle = hx([i + randn() * 0.1, 0]) + randn()
    sf.update(angle, hx, fx)
    xs_scaled.append(sf.x)

    f.predict(fx)
    f.update(angle, hx)
    xs.append(f.x)


xs_scaled = asarray(xs_scaled)
xs = asarray(xs)

plt.subplot(211)
plt.plot(xs_scaled[:, 0], label="scaled")
plt.plot(xs[:, 0], label="Julier")
plt.legend(loc=4)

plt.subplot(212)
plt.plot(xs_scaled[:, 1], label="scaled")
plt.plot(xs[:, 1], label="Julier")
Ejemplo n.º 53
0
class Follower(BehaviorBase):
    def __init__(self, g, zeta,
                 leader, trajectory_delay=2.0,
                 update_delta_t=0.01,
                 orig_leader=None, orig_leader_delay=None,
                 noise_sigma=0.0, log_file=None,
                 visibility_fov=config.FOV_ANGLE, visibility_radius=None,
                 id=None,
                 dt=0.02):

        """
        Construct a follower Behavior.

        leader is the Bot to be followed
        g > 0 is a tuning parameter
        zeta in (0, 1) is a damping coefficient
        trajectory_delay is the time interval between leader and follower
        """
        super(Follower, self).__init__()

        assert(isinstance(leader, Bot))
        assert(isinstance(orig_leader, Bot))

        self.radius = config.BOT_RADIUS
        self.leader = leader
        self.orig_leader = orig_leader
        self.trajectory_delay = trajectory_delay

        assert g > 0, "Follower: g parameter must be positive"
        self.g = g
        assert 0 < zeta < 1, "Follower: zeta parameter must be in (0, 1)"
        self.zeta = zeta

        # leader_positions stores config.POSITIONS_BUFFER_SIZE tuples;
        # tuple's first field is time, second is the
        # corresponding position of the leader
        self.leader_positions = RingBuffer(config.POSITIONS_BUFFER_SIZE)
        self.noisy_leader_positions = RingBuffer(config.POSITIONS_BUFFER_SIZE)

        self.leader_is_visible = False

        # precise_orig_leader_states stores the first leader's precise state;
        # used to calculate "real" errors (as opposed to calculations
        # w.r.t. the approximation curve)
        self.precise_orig_leader_states = []
        # precise_leader_states is used for the same purpose, but with the bot's own leader
        self.precise_leader_states = []

        self.update_delta_t = update_delta_t
        needed_buffer_size = config.SAMPLE_COUNT // 2 + self.trajectory_delay / self.update_delta_t
        if needed_buffer_size > config.POSITIONS_BUFFER_SIZE:
            sys.stderr.write("leader_positions buffer is too small for update_delta_t = {}".format(self.update_delta_t) +
                             " (current = {}, required = {})".format(config.POSITIONS_BUFFER_SIZE, needed_buffer_size))
            raise RuntimeError, "leader_positions buffer is too small"
        self.last_update_time = 0.0

        self.noise_sigma = noise_sigma

        self.log_file = log_file

        self.visibility_fov = visibility_fov
        if visibility_radius is None:
            visibility_radius = 2.0 * trajectory_delay * config.BOT_VEL_CAP
        self.visibility_radius = visibility_radius

        self.id = id;

        if orig_leader_delay is None:
            orig_leader_delay = trajectory_delay
        self.orig_leader_delay = orig_leader_delay


        if self.log_file is not None:
            log_dict = {"id": self.id,
                         "g": self.g,
                         "zeta": self.zeta,
                         "noise_sigma": self.noise_sigma,
                         "reference_points_cnt": config.SAMPLE_COUNT,
                         "trajectory_delay": trajectory_delay}
            print >> self.log_file, log_dict

        q = 0.01   # std of process
        r = 0.05   # std of measurement

        self.delta_time = dt
        if not config.DISABLE_UKF:
            points = MerweScaledSigmaPoints(n=6, alpha=.1, beta=2., kappa=-3)
            self.ukf = UKF(dim_x=6, dim_z=2, fx=f, hx=h, dt=dt, points=points)

            self.ukf_x_initialized = 0
            #self.ukf.x = np.array([0, 0, 1, pi/4, 0, 0])
            self.ukf.R = np.diag([r, r]);
            self.ukf.Q = np.diag([0, 0, 0, 0, q, q])


    def point_in_fov(self, p):
        if length(p - self.pos) > self.visibility_radius:
            return False
        d = p - self.pos
        ang = atan2(cross(self.real_dir, d), dot(self.real_dir, d))
        return -0.5 * self.visibility_fov < ang < 0.5 * self.visibility_fov


    def point_is_visible(self, p, obstacles):
        if not self.point_in_fov(p):
            return False
        try:
            ray = Ray(self.pos, p - self.pos)
        except NormalizationError:
            ray = Ray(self.pos, Vector(1.0, 0.0))
        i = first_intersection(ray, obstacles)
        return (i is None) or (length(i - self.pos) > length(p - self.pos))


    def store_leaders_state(self, engine, obstacles):
        if self.point_is_visible(self.leader.real.pos, obstacles):
            self.leader_is_visible = True

            noisy_pos = self.leader.real.pos
            noisy_pos += Vector(gauss(0.0, self.noise_sigma),
                                gauss(0.0, self.noise_sigma))
            if config.DISABLE_UKF:
                filtered_pos = noisy_pos
            else:
                if (self.ukf_x_initialized == 0):
                    self.ukf_x1 = noisy_pos
                    self.ukf_x_initialized += 1
                    filtered_pos = noisy_pos
                    self.ukf.x = np.array([noisy_pos.x, noisy_pos.y,
                                           0, pi/2, 0, 0])
                #elif (self.ukf_x_initialized == 1):
                #    self.ukf_x2 = noisy_pos
                #    self.ukf_x_initialized += 1
                #    self.ukf.x = np.array([noisy_pos.x, noisy_pos.y,
                #                           length((noisy_pos - self.ukf_x1) / self.delta_time),
                #                           atan2(noisy_pos.y - self.ukf_x1.y,
                #                                 noisy_pos.x - self.ukf_x1.x),
                #                           0, 0])
                #    filtered_pos = noisy_pos
                else: # UKF is initialized
                    self.ukf.predict()
                    self.ukf.update(np.array(noisy_pos))
                    filtered_pos = Point(self.ukf.x[0], self.ukf.x[1])
                                      
            self.leader_noisy_pos = noisy_pos
            self.noisy_leader_positions.append(TimedPosition(engine.time, noisy_pos))
            self.leader_positions.append(TimedPosition(engine.time, filtered_pos))
            self.last_update_time = engine.time
        else:
            self.leader_is_visible = False
            if not config.DISABLE_UKF:
                self.ukf.predict()
                #TODO: do magic with UKF?

        orig_leader_theta = atan2(self.orig_leader.real.dir.y,
                                  self.orig_leader.real.dir.x)
        self.precise_orig_leader_states.append(TimedState(time=engine.time,
                                                   pos=self.orig_leader.real.pos,
                                                   theta=orig_leader_theta))
        leader_theta = atan2(self.leader.real.dir.y,
                             self.leader.real.dir.x)
        self.precise_leader_states.append(TimedState(time=engine.time,
                                             pos=self.leader.real.pos,
                                             theta=leader_theta))


    def polyfit_trajectory(self, pos_data, t):
        x_pos = np.array([el.pos.x for el in pos_data])
        y_pos = np.array([el.pos.y for el in pos_data])
        times = np.array([el.time   for el in pos_data])

        # needed for trajectory rendering
        self.t_st = times[0]
        self.t_fn = max(times[-1], t)

        # calculate quadratic approximation of the reference trajectory
        x_poly = np.polyfit(times, x_pos, deg=2)
        y_poly = np.polyfit(times, y_pos, deg=2)
        known = Trajectory.from_poly(x_poly, y_poly)
        return known, x_pos[-1], y_pos[-1], times[-1]


    def extend_trajectory(self, known, last_x, last_y, last_t):
        # now adding a circle to the end of known trajectory
        # k is signed curvature of the trajectry at t_fn
        try:
            k = known.curvature(last_t)
        except (ValueError, ZeroDivisionError):
            k = config.MIN_CIRCLE_CURVATURE
        if abs(k) < config.MIN_CIRCLE_CURVATURE:
            k = copysign(config.MIN_CIRCLE_CURVATURE, k)

        if abs(k) > config.MAX_CURVATURE:
            k = copysign(config.MAX_CURVATURE, k)

        radius = abs(1.0/k)
        # trajectory direction at time t_fn
        try:
            d = normalize(Vector(known.dx(last_t), known.dy(last_t)))
        except NormalizationError:
            d = self.real_dir

        r = Vector(-d.y, d.x) / k
        center = Point(last_x, last_y) + r
        phase = atan2(-r.y, -r.x)
        #freq = known.dx(last_t) / r.y
        freq = k
        self.x_approx = lambda time: known.x(time) if time < last_t else \
                                     center.x + radius * cos(freq * (time - last_t) + phase)
        self.y_approx = lambda time: known.y(time) if time < last_t else \
                                     center.y + radius * sin(freq * (time - last_t) + phase)
        dx = lambda time: known.dx(time) if time < last_t else \
                          -radius * freq * sin(freq * (time - last_t) + phase)
        dy = lambda time: known.dy(time) if time < last_t else \
                          radius * freq * cos(freq * (time - last_t) + phase)
        ddx = lambda time: known.ddx(time) if time < last_t else \
                          -radius * freq * freq * cos(freq * (time - last_t) + phase)
        ddy = lambda time: known.ddy(time) if time < last_t else \
                          -radius * freq * freq * sin(freq * (time - last_t) + phase)
        # FIXME: don't use division by y if y == 0
        try:
            if isnan(self.x_approx(last_t + 1)):
                return known
        except Exception:
            return known
        return Trajectory(x=self.x_approx, y=self.y_approx,
                          dx=dx, dy=dy, ddx=ddx, ddy=ddy)



    def generate_trajectory(self, leader_positions, t):
        arr = get_interval(self.leader_positions, t, config.SAMPLE_COUNT)
        self.traj_interval = arr
        if len(arr) == 0:
            return None
        known, last_x, last_y, last_t = self.polyfit_trajectory(arr, t)
        if config.DISABLE_CIRCLES:
            return known
        else:
            return self.extend_trajectory(known, last_x, last_y, last_t)


    def calc_desired_velocity(self, bots, obstacles, targets, engine):
        # update trajectory
        if engine.time - self.last_update_time > self.update_delta_t:
            self.store_leaders_state(engine, obstacles)

        # reduce random movements at the start
        # TODO: this causes oscillations that smash bots into each other.
        # Change to something smoother. PID control?
        #if self.leader_is_visible and length(self.pos - self.leader_noisy_pos) < MIN_DISTANCE_TO_LEADER:
        #    return Instr(0.0, 0.0)

        t = engine.time - self.trajectory_delay
        self.trajectory = self.generate_trajectory(self.leader_positions, t)
        if self.trajectory is None:
            return Instr(0.0, 0.0)

        dx = self.trajectory.dx
        dy = self.trajectory.dy
        ddx = self.trajectory.ddx
        ddy = self.trajectory.ddy

        # calculate the feed-forward velocities
        v_fun = lambda time: sqrt(dx(time)**2 + dy(time)**2)
        #omega_fun = lambda time: (dx(time) * 2 * y_poly[0] - dy(time) * 2 * x_poly[0]) / (dx(time)**2 + dy(time)**2)
        omega_fun = lambda time: (dx(time) * ddy(time) - dy(time) * ddx(time)) / (dx(time)**2 + dy(time)**2)
        v_ff = v_fun(t)
        omega_ff = omega_fun(t)

        # x_r, y_r and theta_r denote the reference robot's state
        r = State(x=self.trajectory.x(t),
                  y=self.trajectory.y(t),
                  theta=atan2(self.trajectory.dy(t),
                              self.trajectory.dx(t)))
        self.target_point = Point(r.x, r.y)

        if isnan(v_ff):
            v_ff = 0.0
        if isnan(omega_ff):
            omega_ff = 0.0

        # cur is the current state
        cur = State(x=self.pos.x,
                    y=self.pos.y,
                    theta=atan2(self.real_dir.y, self.real_dir.x))

        # error in the global (fixed) reference frame
        delta = State(x=r.x - cur.x,
                      y=r.y - cur.y,
                      theta=normalize_angle(r.theta - cur.theta))

        # translate error into the follower's reference frame
        e = State(x= cos(cur.theta) * delta.x + sin(cur.theta) * delta.y,
                  y=-sin(cur.theta) * delta.x + cos(cur.theta) * delta.y,
                  theta=delta.theta)

        # calculate gains k_x, k_y, k_theta
        # these are just parameters, not a state in any sense!
        omega_n = sqrt(omega_ff**2 + self.g * v_ff**2)
        k_x = 2 * self.zeta * omega_n
        k_y = self.g
        k_theta = 2 * self.zeta * omega_n

        # calculate control velocities
        v = v_ff * cos(e.theta) + k_x * e.x
        se = sin(e.theta) / e.theta if e.theta != 0 else 1.0
        omega = omega_ff + k_y * v_ff * se * e.y + k_theta * e.theta

        if config.DISABLE_FEEDBACK:
            v = v_ff
            omega = omega_ff

        real_e = State(0.0, 0.0, 0.0)
        try:
            orig_t = engine.time - self.orig_leader_delay
            orig_leader_state = lerp_precise_states(orig_t, self.precise_orig_leader_states)
            real_e = State(x=orig_leader_state.x - cur.x,
                               y=orig_leader_state.y - cur.y,
                               theta=normalize_angle(orig_leader_state.theta - cur.theta))
        except LerpError:
            # not enough data is yet available to calculate error
            pass

        try:
            leader_t = engine.time - self.trajectory_delay
            leader_state = lerp_precise_states(leader_t, self.precise_leader_states)
            approx_e = State(x=leader_state.x - cur.x,
                             y=leader_state.y - cur.y,
                             theta=normalize_angle(leader_state.theta - cur.theta))
        except LerpError:
            # same as above
            pass

        if self.log_file is not None:
            log_dict = {"id": self.id,
                         "time": engine.time,
                         "delta_time": engine.time_since_last_bot_update,
                         "x": cur.x,
                         "y": cur.y,
                         "theta": cur.theta,
                         "v": v,
                         "omega": omega,
                         "v_ff": v_ff,
                         "omega_ff": omega_ff,
                         "e_x": e.x,
                         "e_y": e.y,
                         "e_theta": e.theta,
                         "real_e_x": real_e.x,
                         "real_e_y": real_e.y,
                         "real_e_theta": real_e.theta,
                         "approx_e_x": approx_e.x,
                         "approx_e_y": approx_e.y,
                         "approx_e_theta": approx_e.theta,
                         "leader_is_visible": self.leader_is_visible
                        }
            print >> self.log_file, log_dict

        return Instr(v,  omega)


    def draw(self, screen, field):
        if config.DISPLAYED_POINTS_COUNT > 0:
            k = config.POSITIONS_BUFFER_SIZE / config.DISPLAYED_POINTS_COUNT
            if k == 0:
                k = 1
            for index, (time, point) in enumerate(self.leader_positions):
                if index % k == 0:
                    draw_circle(screen, field, config.TRAJECTORY_POINTS_COLOR, point, 0.03, 1)
            for index, (time, point) in enumerate(self.noisy_leader_positions):
                if index % k == 0:
                    draw_circle(screen, field, config.NOISY_TRAJECTORY_POINTS_COLOR, point, 0.03, 1)

        if config.DISPLAYED_USED_POINTS_COUNT > 0:
            k = len(self.traj_interval) / config.DISPLAYED_USED_POINTS_COUNT
            if k == 0:
                k = 1
            for index, (time, point) in enumerate(self.traj_interval):
                if index % k == 0:
                    draw_circle(screen, field, config.USED_TRAJECTORY_POINTS_COLOR, point, 0.03, 1)

        if config.DRAW_DELAYED_LEADER_POS:
            try:
                orig_leader_dir = Vector(cos(self.orig_leader_theta),
                                         sin(self.orig_leader_theta))
                draw_directed_circle(screen, field, (0, 255, 0),
                                     self.orig_leader_pos, 0.2,
                                     orig_leader_dir, 1)
            except AttributeError:
                pass

        if config.DRAW_SENSOR_RANGE:
            ang = atan2(self.real_dir.y, self.real_dir.x)
            draw_arc(screen, field, config.SENSOR_COLOR, self.pos, self.visibility_radius,
                                    ang - 0.5 * self.visibility_fov,
                                    ang + 0.5 * self.visibility_fov,
                                    1)
            draw_line(screen, field, config.SENSOR_COLOR,
                      self.pos,
                      self.pos + rotate(self.real_dir * self.visibility_radius,
                                        0.5 * self.visibility_fov),
                      1)
            draw_line(screen, field, config.SENSOR_COLOR,
                      self.pos,
                      self.pos + rotate(self.real_dir * self.visibility_radius,
                                        -0.5 * self.visibility_fov),
                      1)

        try:
            if config.DRAW_VISIBILITY and self.leader_is_visible:
                draw_circle(screen, field, config.config.VISIBILITY_COLOR, self.leader.real.pos,
                            0.5 * config.BOT_RADIUS)
        except AttributeError:
            pass

        try:
            if config.DRAW_REFERENCE_POS:
                draw_circle(screen, field, config.TARGET_POINT_COLOR, self.target_point, 0.2)

            if config.DRAW_APPROX_TRAJECTORY and self.trajectory is not None:
                #if len(self.traj_interval) > 1:
                #    p2 = Point(self.traj_interval[0].pos.x,
                #               self.traj_interval[0].pos.y)
                #    for t, p in self.traj_interval:
                #        draw_line(screen, field, config.APPROX_TRAJECTORY_COLOR, p, p2)
                #        p2 = p

                step = (self.t_fn - self.t_st) / config.TRAJECTORY_SEGMENT_COUNT
                for t in (self.t_st + k * step for k in xrange(config.TRAJECTORY_SEGMENT_COUNT)):
                    p = Point(self.trajectory.x(t),
                              self.trajectory.y(t))
                    p2 = Point(self.trajectory.x(t + step),
                               self.trajectory.y(t + step))
                    draw_line(screen, field, config.APPROX_TRAJECTORY_COLOR, p, p2)

                p_st = Point(self.trajectory.x(self.t_st), self.trajectory.y(self.t_st))
                p_fn = Point(self.trajectory.x(self.t_fn), self.trajectory.y(self.t_fn))

                step = 0.5 / config.TRAJECTORY_SEGMENT_COUNT
                p = p_fn
                p2 = p
                t = self.t_fn
                it = 0
                while it < config.TRAJECTORY_SEGMENT_COUNT and min(dist(p, p_fn), dist(p, p_st)) < 1.0:
                    it += 1
                    t += step
                    p2 = p
                    p = Point(self.trajectory.x(t), self.trajectory.y(t))
                    draw_line(screen, field, config.APPROX_TRAJECTORY_COLOR, p, p2)

        except AttributeError as e: # approximation hasn't been calculated yet
            pass
Ejemplo n.º 54
0
    radarUKF = UKF(dim_x=3, dim_z=1, dt=dt, hx = hx, fx = fx, points = points);
    radarUKF.Q *= Q_discrete_white_noise(3, 1, .01)
    radarUKF.R *= 10
    radarUKF.x = np.array([0., 90., 1100.])
    radarUKF.P *= 100.

    t = np.arange(0, 20+dt, dt)
    n = len(t)
    xs = []
    rs = []
    for i in range(n):
        r = GetRadar(dt)
        rs.append(r)
        #rs = r;
        radarUKF.predict();
        radarUKF.update(r)

        xs.append(radarUKF.x)

    xs = np.asarray(xs)

    plt.subplot(411)
    plt.plot(t, xs[:, 0])
    plt.title('distance')

    plt.subplot(412)
    plt.plot(t, xs[:, 1])
    plt.title('velocity')

    plt.subplot(413)