예제 #1
0
def test_linear_2d_simplex():
    """ should work like a linear KF if problem is linear """
    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 = SimplexSigmaPoints(n=4)
    kf = UnscentedKalmanFilter(dim_x=4,
                               dim_z=2,
                               dt=dt,
                               fx=fx,
                               hx=hx,
                               points=points)

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

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

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

    x = kf.x
    zs = []

    for i in range(20):
        x = fx(x, dt)
        z = np.array([x[0] + randn() * 0.1, x[2] + randn() * 0.1])

        zs.append(z)

    Ms, Ps = kf.batch_filter(zs)
    smooth_x, _, _ = kf.rts_smoother(Ms, Ps, dts=dt)

    if DO_PLOT:
        zs = np.asarray(zs)
        plt.plot(Ms[:, 0])
        plt.plot(smooth_x[:, 0], smooth_x[:, 2])
        print(smooth_x)
예제 #2
0
    def __init__(self):
        self.cap = cv2.VideoCapture(CV2_CAPTURE_PATH, apiPreference=cv2.CAP_V4L2)
        self.cap.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc('M', 'J', 'P', 'G'))
        self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)
        self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 720)
        self.cap.set(cv2.CAP_PROP_FPS, 60)
        self.cap.set(cv2.CAP_PROP_AUTOFOCUS, 0)
        self.cap.set(cv2.CAP_PROP_AUTO_WB, 0)
        self.cap.set(cv2.CAP_PROP_AUTO_EXPOSURE, 0)
        self.cap.set(cv2.CAP_PROP_BUFFERSIZE, 1)
        with open('calibration/board_transform.npy', 'rb') as f:
            self.board_transform = np.load(f)
        with open('calibration/bot_transform.npy', 'rb') as f:
            self.bot_transform = np.load(f)

        self.bot_filter = UnscentedKalmanFilter(
                dim_x=6, dim_z=4,
                dt=None, fx=bot_filter_f, hx=bot_filter_h,
                points=MerweScaledSigmaPoints(6, alpha=.1, beta=2., kappa=-1))
        self.bot_filter.P = np.diag([5**2, 5**2, 0.1**2, 0.1**2, 1**2, 0.1**2])
        self.bot_filter.Q = np.array([
            [(5)**2, 0, 0, 0, 0, 0],
            [0, (5)**2, 0, 0, 0, 0],
            [0, 0, (0.1)**2, 0, 0, 0],
            [0, 0, 0, (0.1)**2, 0, 0],
            [0, 0, 0, 0, (200)**2, 0],
            [0, 0, 0, 0, 0, (1)**2]], dtype=np.float32)
        self.bot_filter.R = np.diag([5**2, 5**2, 0.1**2, 0.1**2])
        self.bot_filter_last_update = None

        self.dc = DataClient()
예제 #3
0
 def __init__(self, vehicle):
     super(LastVehicleUKF, self).__init__(vehicle)
     #noises2 = self.vehicle.observation_noises.sigma**2
     #for i in range(len(noises2)):
     #    if noises2[i] == 0.:
     #        noises2[i] = 1e-16
     points = MerweScaledSigmaPoints(n=6, alpha=.1, beta=2., kappa=0.1)
     self.kf = UnscentedKalmanFilter(6,
                                     39,
                                     self.delta_t,
                                     fx=self.fx,
                                     hx=self.hx,
                                     points=points)
     #self.Q_factor = 10
     #self.Q_factor_power = 1
     self.kf.Q = Q_discrete_white_noise(3,
                                        dt=self.delta_t,
                                        var=1e-2,
                                        block_size=2)
     #print(self.kf.R,'RRR')
     self.kf.R *= max(np.median(self.vehicle.observation_noises.sigma**2),
                      1e-16)
     self.kf.x = np.concatenate(
         (self.vehicle.ground_truth, self.vehicle.ground_truth))
     self.kf.x[0] += self.vehicle.safty_dist
     self.kf.P *= max(self.vehicle.actuator_noise.sigma**2, 1e-16)
예제 #4
0
def get_ukf(R_std, Q_std, dt):
    def f_(x, dt, v_angle):
        v = v_angle[0]
        rad = v_angle[1]
        x[2] += rad * dt
        x[2] %= 2 * np.pi
        dist = (v * dt)
        x[0] += np.cos(x[2]) * dist
        x[1] += np.sin(x[2]) * dist
        return x

    def h_(x):
        return x[:2]

    sigmas = MerweScaledSigmaPoints(3, alpha=.1, beta=2., kappa=0.)
    ukf = UnscentedKalmanFilter(dim_x=3,
                                dim_z=2,
                                fx=f_,
                                hx=h_,
                                dt=dt,
                                points=sigmas)
    ukf.x = np.array([0., 0., 0.])
    ukf.R *= R_std
    ukf.Q *= Q_std
    #ukf.Q = Q_discrete_white_noise(3, dt=dt, var=Q_std)

    return ukf
예제 #5
0
def test_batch_missing_data():
    """ batch filter should accept missing data with None in the measurements """
    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)

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

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

    zs[2] = None
    Rs = [1] * len(zs)
    Rs[2] = None
    Ms, Ps = kf.batch_filter(zs)
예제 #6
0
    def __init__(self, dt, state=np.array([0.0, 0.0, -2.0, 0.0, 0.0, 0.0])):
        M = len(state)
        points = JulierSigmaPoints(M)

        def project(state, world_positions):
            return project_plane_markers(world_positions,
                                         state.reshape(2, 3)).reshape(-1)

        self.kf = kf = UnscentedKalmanFilter(
            dt=dt,
            dim_x=M,
            dim_z=1,
            points=points,
            #fx=lambda X, dt: predict_state(X.reshape(4, -1), dt).reshape(-1),
            fx=lambda x, dt: x,
            hx=project,
        )
        z_dim = 2  # This changes according to the measurement
        kf.P = np.eye(M) * 0.3
        kf.x = state.reshape(-1).copy()  # Initial state guess
        self.z_var = 0.05**2
        #kf.R = z_var # Observation variance
        dpos_var = 0.01**2 * dt
        drot_var = np.radians(1.0)**2 * dt
        #kf.Q = np.diag([0]*3 + [0]*3 + [dpos_var]*3 + [drot_var]*3)
        kf.Q = np.diag([dpos_var] * 3 + [drot_var] * 3)
예제 #7
0
    def __init__(self):
        n_dim_state = 4  # x = (x, y, vx, vy)

        def fx(x, dt):
            # state transition function - predict next state based
            # on constant velocity model x = vt + x_0
            F = np.array(
                [[1, 0, dt, 0], [0, 1, 0, 0], [0, 0, 1, dt], [0, 0, 0, 1]],
                dtype=float)
            return np.dot(F, x)

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

        points = MerweScaledSigmaPoints(n_dim_state,
                                        alpha=.1,
                                        beta=2.,
                                        kappa=-1)
        self.kf = UnscentedKalmanFilter(n_dim_state, 2, step, hx, fx, points)
        self.kf.x = np.array([0.0, 0.0, 0.0, 0.0])
        self.kf.P *= 0.1
        self.kf.R = np.diag([0.01**2, 0.01**2])
        self.kf.Q = Q_discrete_white_noise(dim=2,
                                           dt=step,
                                           var=0.2**2,
                                           block_size=2)
예제 #8
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()
예제 #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 = UnscentedKalmanFilter(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')
예제 #10
0
 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_ukf(self):
        '''
        Initialize the parameters of the Unscented Kalman Filter (UKF) that is
        used to estimate the state of the drone.
        '''

        # Number of state variables being tracked
        self.state_vector_dim = 12
        # The state vector consists of the following column vector.
        # Note that FilterPy initializes the state vector with zeros.
        # [[x],
        #  [y],
        #  [z],
        #  [x_vel],
        #  [y_vel],
        #  [z_vel],
        #  [roll],
        #  [pitch],
        #  [yaw],
        #  [roll_vel],
        #  [pitch_vel],
        #  [yaw_vel]]

        # Number of measurement variables that the drone receives
        self.measurement_vector_dim = 7
        # The measurement variables consist of the following column vector:
        # [[x_vel],
        #  [y_vel],
        #  [yaw_vel],
        #  [slant_range],
        #  [roll],
        #  [pitch],
        #  [yaw]]

        # Function to generate sigma points for the UKF
        # TODO: Modify these sigma point parameters appropriately. Currently
        #       just guesses
        sigma_points = MerweScaledSigmaPoints(n=self.state_vector_dim,
                                              alpha=0.1,
                                              beta=2.0,
                                              kappa=(3.0 -
                                                     self.state_vector_dim))
        #kappa=0.0)
        # Create the UKF object
        # Note that dt will get updated dynamically as sensor data comes in,
        # as will the measurement function, since measurements come in at
        # distinct rates. Setting compute_log_likelihood=False saves some
        # computation.
        self.ukf = UnscentedKalmanFilter(dim_x=self.state_vector_dim,
                                         dim_z=self.measurement_vector_dim,
                                         dt=1.0,
                                         hx=self.measurement_function,
                                         fx=self.state_transition_function,
                                         points=sigma_points,
                                         compute_log_likelihood=False)
        #residual_x=self.residual_x_account_for_angles)
        self.initialize_ukf_matrices()
예제 #12
0
def filter_pose(ukf, z, R, dt, model):
    ukf = UnscentedKalmanFilter()
    ukf.predict(dt=dt)
    predicted_state = ukf.x

    positions_relative_to_drone = model.features_positions - np.tile(
        predicted_state[7:10], (model.number_of_features, 1))
    positions_in_drone_space = quaternion.rotate_vectors(
        predicted_state[0:4], positions_relative_to_drone)
예제 #13
0
    def __init__(self, OctorotorParams):
        super(OctorotorBaseEnv, self).__init__()
        # Octorotor Params
        self.octorotor = Octocopter(OctorotorParams)
        self.state = self.octorotor.get_state()
        self.xref = 5
        self.yref = 0
        self.xrefarr = pd.read_csv("./Paths/EpathX5.csv", header=None).iloc[:,
                                                                            1]
        self.yrefarr = pd.read_csv("./Paths/EpathY5.csv", header=None).iloc[:,
                                                                            1]
        self.allocation = ControlAllocation(OctorotorParams)
        self.resistance = np.full(8, OctorotorParams["resistance"])
        self.dt = OctorotorParams["dt"]
        self.motor = OctorotorParams["motor"]
        self.motorController = OctorotorParams["motorController"]
        self.posc = OctorotorParams["positionController"]
        self.attc = OctorotorParams["attitudeController"]
        self.altc = OctorotorParams["altitudeController"]
        self.OctorotorParams = OctorotorParams
        self.omega = np.zeros(8)
        self.step_count = 0
        self.total_step_count = OctorotorParams["total_step_count"]
        self.zref = 0
        self.psiref = np.zeros(3)
        self.reward_discount = OctorotorParams["reward_discount"]
        # OpenAI Gym Params
        # State vector
        # state[0:2] pos
        # state[3:5] vel
        # state[6:8] angle
        # state[9:11] angle vel

        # poserrs+eulererrs
        # above + state
        # state
        self.observation_space = spaces.Box(np.full(1,
                                                    -np.inf,
                                                    dtype="float32"),
                                            np.full(1, np.inf,
                                                    dtype="float32"),
                                            dtype="float32")
        #U = [T, tau]
        self.action_space = spaces.Box(np.array([0.1, 0.1, 0.1, 0.1]),
                                       np.array([1, 1, 1, 1]),
                                       dtype="float32")
        self.viewer = None
        # introduce filtering for parameter estimator
        points = MerweScaledSigmaPoints(6, alpha=.1, beta=2, kappa=0)
        self.kf = UnscentedKalmanFilter(dim_x=6,
                                        dim_z=6,
                                        dt=OctorotorParams["dt"],
                                        fx=self.fx,
                                        hx=hx,
                                        points=points)
        self.kf.x = np.zeros(6)
예제 #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.)
    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])
예제 #15
0
    def reset(self):
        """
        Reset our SIRD model.
        """

        # Reset β, γ and μ to the values mentioned on Wikipedia (see https://bit.ly/2VMvb6h).

        self.__beta = 0.4
        self.__gamma = 0.035
        self.__mu = 0.005

        # Reset I, R and D to the data at day 0 or the values mentioned on Wikipedia (see https://bit.ly/2VMvb6h).

        if self.__use_data:
            self.__x = np.array([self.__data_i(0), self.__data_r(0), self.__data_d(0)])
            self.__n = self.__population
        else:
            self.__x = np.array([3, 0, 0])
            self.__n = 1000

        # Reset our Unscented Kalman filter (if required). Note tat we use a dt value of 1 (day) and not the value of
        # Model.__DELTA_T.

        if self.__use_data:
            points = MerweScaledSigmaPoints(Model.__N_FILTERED,
                                            1e-3,  # Alpha value (usually a small positive value like 1e-3).
                                            2,  # Beta value (a value of 2 is optimal for a Gaussian distribution).
                                            0,  # Kappa value (usually, either 0 or 3-n).
                                            )

            self.__ukf = UnscentedKalmanFilter(Model.__N_FILTERED, Model.__N_MEASURED, 1, self.__h, Model.__f, points)

            self.__ukf.x = np.array([self.__data_i(0), self.__data_r(0), self.__data_d(0),
                                     self.__beta, self.__gamma, self.__mu, self.__n])

        # Reset our data (if requested).

        if self.__use_data:
            self.__data_s_values = np.array([self.__data_s(0)])
            self.__data_i_values = np.array([self.__data_i(0)])
            self.__data_r_values = np.array([self.__data_r(0)])
            self.__data_d_values = np.array([self.__data_d(0)])

        # Reset our predicted/estimated values.

        self.__s_values = np.array([self.__s_value()])
        self.__i_values = np.array([self.__i_value()])
        self.__r_values = np.array([self.__r_value()])
        self.__d_values = np.array([self.__d_value()])

        # Reset our estimated SIRD model parameters.

        self.__beta_values = np.array([self.__beta])
        self.__gamma_values = np.array([self.__gamma])
        self.__mu_values = np.array([self.__mu])
예제 #16
0
    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)
예제 #17
0
 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
예제 #18
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)
예제 #19
0
    def __init__(self, bbox):
        """
    Initialises a tracker using initial bounding box.
    """
        def fx(x, dt):
            # state transition function - predict next state based on constant velocity model x = x_0 + vt
            F = np.array([[1, 0, 0, 0, dt, 0, 0], [0, 1, 0, 0, 0, dt, 0],
                          [0, 0, 1, 0, 0, 0, dt], [0, 0, 0, 1, 0, 0, 0],
                          [0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 1, 0],
                          [0, 0, 0, 0, 0, 0, 1]],
                         dtype=float)

            return np.dot(F, x)

        def hx(x):
            # measurement function - convert state into a measurement where measurements are [u, v, s, r]
            return np.array([x[0], x[1], x[2], x[3]])

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

        #define constant velocity model
        self.kf = UnscentedKalmanFilter(dim_x=7,
                                        dim_z=4,
                                        dt=dt,
                                        fx=fx,
                                        hx=hx,
                                        points=points)

        # Assign the initial value of the state
        self.kf.x[:4] = convert_bbox_to_z(bbox)
        # Covariance matrix (dim_x, dim_x), default I
        self.kf.P[
            4:,
            4:] *= 1000.  # Give high uncertainty to the unobservable initial velocities
        self.kf.P *= 0.2
        # Measuerment uncertainty (dim_z, dim_z), default I
        self.kf.R *= 0.01
        # Process noise (dim_x, dim_x), default I
        self.kf.Q[-1, -1] *= 0.0001
        self.kf.Q[4:, 4:] *= 0.0001

        self.time_since_update = 0
        self.id = KalmanBoxTracker.count
        KalmanBoxTracker.count += 1
        self.history = []
        self.hits = 0
        self.hit_streak = 0
        self.age = 0
 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)
예제 #21
0
def Unscentedfilter(zs):  # Filter function
    points = MerweScaledSigmaPoints(2, alpha=.1, beta=2., kappa=1)
    ukf = UnscentedKalmanFilter(dim_x=2,
                                dim_z=1,
                                fx=fx,
                                hx=hx,
                                points=points,
                                dt=dt)
    ukf.Q = array(([50, 0], [0, 50]))
    ukf.R = 100
    ukf.P = eye(2) * 2
    mu, cov = ukf.batch_filter(zs)

    x, _, _ = ukf.rts_smoother(mu, cov)

    return x[:, 0]
    def initialize_ukf(self):
        """
        Initialize the parameters of the Unscented Kalman Filter (UKF) that is
        used to estimate the state of the drone.
        """

        # Number of state variables being tracked
        self.state_vector_dim = 7
        # The state vector consists of the following column vector.
        # Note that FilterPy initializes the state vector with zeros.
        # [[x],
        #  [y],
        #  [z],
        #  [x_vel],
        #  [y_vel],
        #  [z_vel],
        #  [yaw]]

        # Number of measurement variables that the drone receives
        self.measurement_vector_dim = 6
        # The measurement variables consist of the following vector:
        # [[slant_range],
        #  [x],
        #  [y],
        #  [x_vel],
        #  [y_vel],
        #  [yaw]]

        # Object to generate sigma points for the UKF
        sigma_points = MerweScaledSigmaPoints(n=self.state_vector_dim,
                                              alpha=0.1,
                                              beta=2.0,
                                              kappa=(3.0 -
                                                     self.state_vector_dim))
        # Create the UKF object
        # Note that dt will get updated dynamically as sensor data comes in,
        # as will the measurement function, since measurements come in at
        # distinct rates. Setting compute_log_likelihood=False saves some
        # computation.
        self.ukf = UnscentedKalmanFilter(dim_x=self.state_vector_dim,
                                         dim_z=self.measurement_vector_dim,
                                         dt=1.0,
                                         hx=self.measurement_function,
                                         fx=self.state_transition_function,
                                         points=sigma_points,
                                         compute_log_likelihood=False)
        self.initialize_ukf_matrices()
예제 #23
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 = 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.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()

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

    s.to_array()

    if DO_PLOT:
        plt.plot(s.x[:, 0], s.x[:, 2])
예제 #24
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'
예제 #25
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()
예제 #26
0
def smooth(data: ndarray, dt: float):
    points = MerweScaledSigmaPoints(3, alpha=1e-3, beta=2.0, kappa=0)
    noisy_kalman = UnscentedKalmanFilter(
        dim_x=3,
        dim_z=1,
        dt=dt,
        hx=state_to_measurement,
        fx=state_transition,
        points=points,
    )

    noisy_kalman.x = array([0, data[1], data[1] - data[0]], dtype="float32")
    noisy_kalman.R *= 20**2  # sensor variance
    noisy_kalman.P = diag([5**2, 5**2, 1**2])  # variance of the system
    noisy_kalman.Q = Q_discrete_white_noise(3, dt=dt, var=0.05)

    means, covariances = noisy_kalman.batch_filter(data)
    means[:, 1][means[:, 1] < 0] = 0  # clip velocity
    return means[:, 1]
예제 #27
0
    def __init__(self, g_params, dim_z=3):
        self.sigmas = MerweScaledSigmaPoints(n=2, alpha=.1, beta=10., kappa=0.)
        self.ukf = UnscentedKalmanFilter(dim_x=2,
                                         dim_z=dim_z,
                                         dt=1.,
                                         hx=self.hx,
                                         fx=self.fx,
                                         points=self.sigmas)

        self.s1params_a = g_params[0]
        self.s1params_b = g_params[1]
        self.s1params_c = g_params[2]

        self.s2params_a = g_params[3]
        self.s2params_b = g_params[4]
        self.s2params_c = g_params[5]

        self.s3params_a = g_params[6]
        self.s3params_b = g_params[7]
예제 #28
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()
예제 #29
0
def test_linear_2d_merwe():
    """ should work like a linear KF if problem is linear """
    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)

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

    # test __repr__ doesn't crash
    str(kf)

    zs = [[i + randn() * 0.1, i + randn() * 0.1] for i in range(20)]

    Ms, Ps = kf.batch_filter(zs)
    smooth_x, _, _ = kf.rts_smoother(Ms, Ps, dts=dt)

    if DO_PLOT:
        plt.figure()
        zs = np.asarray(zs)
        plt.plot(zs[:, 0], marker='+')
        plt.plot(Ms[:, 0], c='b')
        plt.plot(smooth_x[:, 0], smooth_x[:, 2], c='r')
        print(smooth_x)
예제 #30
0
    def create_ukf(
        self, dt: float, hx: callable, fx: callable
    ) -> UnscentedKalmanFilter:
        """Create an unscented Kalman filter with state transition functions
        `fx`, measurement function `hx` with timestep between measurements
        estimated as `dt`.

        Parameters
        ----------
        dt : float
            control timestep
        hx : callable
            function describing mapping between sensor inputs and measurements
        fx : callable
            function describing system. Can be non-linear.

        Returns
        -------
        UnscentedKalmanFilter
            UKF object with sensible defaults for sigma points.
        """
        n = 4
        points = sigma_points.MerweScaledSigmaPoints(
            n,
            alpha=1e-4,
            beta=2,
            kappa=3 - n,
        )

        kf = UnscentedKalmanFilter(
            dim_x=n,
            dim_z=n,
            dt=dt,
            hx=hx,
            fx=fx,
            points=points,
        )
        return kf