def _update_canvas(self):
        """
        Update the figure when the user changes and input value.
        :return:
        """
        # Get the parameters from the form
        time = self.time.text().split(',')
        start = float(time[0])
        end = float(time[1])
        step = float(time[2])
        number_of_updates = round((end - start) / step)
        t, dt = linspace(start, end, number_of_updates, retstep=True)

        # Adaptive parameters
        threshold = float(self.threshold.text())
        scale = float(self.scale.text())

        # Maneuver parameters
        maneuver_time = float(self.maneuver_time.text())
        vm_xyz = self.maneuver_velocity.text().split(',')
        vmx = float(vm_xyz[0])
        vmy = float(vm_xyz[1])
        vmz = float(vm_xyz[2])

        # Initial position
        p_xyz = self.initial_position.text().split(',')
        px = float(p_xyz[0])
        py = float(p_xyz[1])
        pz = float(p_xyz[2])

        # Initial velocity
        v_xyz = self.initial_velocity.text().split(',')
        vx = float(v_xyz[0])
        vy = float(v_xyz[1])
        vz = float(v_xyz[2])

        # Measurement and process noise variance
        measurement_noise_variance = float(self.measurement_noise_variance.text())
        process_noise_variance = float(self.process_noise_variance.text())

        # Create target trajectory
        x_true = zeros([6, number_of_updates])

        pre_index = [n for n, e in enumerate(t) if e < maneuver_time]
        post_index = [n for n, e in enumerate(t) if e >= maneuver_time]

        x = px + vx * t[pre_index]
        xm = x[-1] + vmx * (t[post_index] - maneuver_time)

        y = py + vy * t[pre_index]
        ym = y[-1] + vmy * (t[post_index] - maneuver_time)

        z = pz + vz * t[pre_index]
        zm = z[-1] + vmz * (t[post_index] - maneuver_time)

        x_true[0] = [*x, *xm]
        x_true[1] = [*(vx * ones_like(t[pre_index])), *(vmx * ones_like(t[post_index]))]
        x_true[2] = [*y, *ym]
        x_true[3] = [*(vy * ones_like(t[pre_index])), *(vmy * ones_like(t[post_index]))]
        x_true[4] = [*z, *zm]
        x_true[5] = [*(vz * ones_like(t[pre_index])), *(vmz * ones_like(t[post_index]))]

        # Measurement noise
        v = sqrt(measurement_noise_variance) * (random.rand(number_of_updates) - 0.5)

        # Initialize state and input control vector
        x = zeros(6)
        u = zeros_like(x)

        # Initialize the covariance and control matrix
        P = 1.0e3 * eye(6)
        B = zeros_like(P)

        # Initialize measurement and process noise variance
        R = measurement_noise_variance * eye(3)
        Q = process_noise_variance * eye(6)

        # State transition and measurement transition
        A = eye(6)
        A[0, 1] = dt
        A[2, 3] = dt
        A[4, 5] = dt

        # Measurement transition matrix
        H = zeros([3, 6])
        H[0, 0] = 1
        H[1, 2] = 1
        H[2, 4] = 1

        # Initialize the Kalman filter
        kf = kalman.Kalman(x, u, P, A, B, Q, H, R)

        # Generate the measurements
        z = [matmul(H, x_true[:, i]) + v[i] for i in range(number_of_updates)]

        # Update the filter for each measurement
        kf.filter_epsilon(z, threshold, scale)

        # Clear the axes for the updated plot
        self.axes1.clear()

        # Get the selected plot from the form
        plot_type = self.plot_type.currentText()

        # Display the results
        if plot_type == 'Position - X':
            self.axes1.plot(t, x_true[0, :], '', label='True')
            self.axes1.plot(t, [z[0] for z in z], ':', label='Measurement')
            self.axes1.plot(t, [x[0] for x in kf.state], '--', label='Filtered')
            self.axes1.set_ylabel('Position - X (m)', size=12)
            self.axes1.legend(loc='best', prop={'size': 10})
        elif plot_type == 'Position - Y':
            self.axes1.plot(t, x_true[2, :], '', label='True')
            self.axes1.plot(t, [z[1] for z in z], ':', label='Measurement')
            self.axes1.plot(t, [x[2] for x in kf.state], '--', label='Filtered')
            self.axes1.set_ylabel('Position - Y (m)', size=12)
            self.axes1.legend(loc='best', prop={'size': 10})
        elif plot_type == 'Position - Z':
            self.axes1.plot(t, x_true[4, :], '', label='True')
            self.axes1.plot(t, [z[2] for z in z], ':', label='Measurement')
            self.axes1.plot(t, [x[4] for x in kf.state], '--', label='Filtered')
            self.axes1.set_ylabel('Position - Z (m)', size=12)
            self.axes1.legend(loc='best', prop={'size': 10})
        elif plot_type == 'Velocity - X':
            self.axes1.plot(t, x_true[1, :], '', label='True')
            self.axes1.plot(t, [x[1] for x in kf.state], '--', label='Filtered')
            self.axes1.set_ylabel('Velocity - X (m/s)', size=12)
            self.axes1.legend(loc='best', prop={'size': 10})
        elif plot_type == 'Velocity - Y':
            self.axes1.plot(t, x_true[3, :], '', label='True')
            self.axes1.plot(t, [x[3] for x in kf.state], '--', label='Filtered')
            self.axes1.set_ylabel('Velocity - Y (m/s)', size=12)
            self.axes1.legend(loc='best', prop={'size': 10})
        elif plot_type == 'Velocity - Z':
            self.axes1.plot(t, x_true[5, :], '', label='True')
            self.axes1.plot(t, [x[5] for x in kf.state], '--', label='Filtered')
            self.axes1.set_ylabel('Velocity - Z (m/s)', size=12)
            self.axes1.legend(loc='best', prop={'size': 10})
        elif plot_type == 'Residual':
            self.axes1.plot(t, kf.residual, '')
            self.axes1.set_ylabel('Residual (m)', size=12)

        # Set the plot title and labels
        self.axes1.set_title('Adaptive Kalman Filter - $\epsilon_k$ Method', size=14)
        self.axes1.set_xlabel('Time (s)', size=12)

        # Set the tick label size
        self.axes1.tick_params(labelsize=12)

        # Turn on the grid
        self.axes1.grid(linestyle=':', linewidth=0.5)

        # Update the canvas
        self.my_canvas.draw()
示例#2
0
    def _update_canvas(self):
        """
        Update the figure when the user changes and input value.
        :return:
        """
        # Get the parameters from the form
        time = self.time.text().split(',')
        start = float(time[0])
        end = float(time[1])
        step = float(time[2])
        number_of_updates = round((end - start) / step)
        t, dt = linspace(start, end, number_of_updates, retstep=True)

        # Initial position
        p_xyz = self.initial_position.text().split(',')
        px = float(p_xyz[0])
        py = float(p_xyz[1])
        pz = float(p_xyz[2])

        # Initial velocity
        v_xyz = self.initial_velocity.text().split(',')
        vx = float(v_xyz[0])
        vy = float(v_xyz[1])
        vz = float(v_xyz[2])

        # Initial acceleration
        a_xyz = self.acceleration.text().split(',')
        ax = float(a_xyz[0])
        ay = float(a_xyz[1])
        az = float(a_xyz[2])

        # Measurement and process noise variance
        measurement_noise_variance = float(
            self.measurement_noise_variance.text())
        process_noise_variance = float(self.process_noise_variance.text())

        # Create target trajectory
        x_true = zeros([9, number_of_updates])

        x = px + vx * t + 0.5 * ax * t**2
        y = py + vy * t + 0.5 * ay * t**2
        z = pz + vz * t + 0.5 * az * t**2

        x_true[0] = x
        x_true[1] = vx + ax * t
        x_true[2] = ax
        x_true[3] = y
        x_true[4] = vy + ay * t
        x_true[5] = ay
        x_true[6] = z
        x_true[7] = vz + az * t
        x_true[8] = az

        # Measurement noise
        v = sqrt(measurement_noise_variance) * (
            random.rand(number_of_updates) - 0.5)

        # Initialize state and input control vector
        x = zeros(9)
        u = zeros_like(x)

        # Initialize the covariance and control matrix
        P = 1.0e3 * eye(9)
        B = zeros_like(P)

        # Initialize measurement and process noise variance
        R = measurement_noise_variance * eye(3)
        Q = process_noise_variance * eye(9)

        # State transition matrix
        A = eye(9)
        A[0, 1] = dt
        A[0, 2] = 0.5 * dt * dt
        A[1, 2] = dt

        A[3, 4] = dt
        A[3, 5] = 0.5 * dt * dt
        A[4, 5] = dt

        A[6, 7] = dt
        A[6, 8] = 0.5 * dt * dt
        A[7, 8] = dt

        # Measurement transition matrix
        H = zeros([3, 9])
        H[0, 0] = 1
        H[1, 3] = 1
        H[2, 6] = 1

        # Initialize the Kalman filter
        kf = kalman.Kalman(x, u, P, A, B, Q, H, R)

        # Generate the measurements
        z = [matmul(H, x_true[:, i]) + v[i] for i in range(number_of_updates)]

        # Update the filter for each measurement
        kf.filter(z)

        # Clear the axes for the updated plot
        self.axes1.clear()

        # Get the selected plot from the form
        plot_type = self.plot_type.currentText()

        # Display the results
        if plot_type == 'Position - X':
            self.axes1.plot(t, x_true[0, :], '', label='True')
            self.axes1.plot(t, [z[0] for z in z], ':', label='Measurement')
            self.axes1.plot(t, [x[0] for x in kf.state],
                            '--',
                            label='Filtered')
            self.axes1.set_ylabel('Position - X (m)', size=12)
            self.axes1.legend(loc='best', prop={'size': 10})
        elif plot_type == 'Position - Y':
            self.axes1.plot(t, x_true[3, :], '', label='True')
            self.axes1.plot(t, [z[1] for z in z], ':', label='Measurement')
            self.axes1.plot(t, [x[3] for x in kf.state],
                            '--',
                            label='Filtered')
            self.axes1.set_ylabel('Position - Y (m)', size=12)
            self.axes1.legend(loc='best', prop={'size': 10})
        elif plot_type == 'Position - Z':
            self.axes1.plot(t, x_true[6, :], '', label='True')
            self.axes1.plot(t, [z[2] for z in z], ':', label='Measurement')
            self.axes1.plot(t, [x[6] for x in kf.state],
                            '--',
                            label='Filtered')
            self.axes1.set_ylabel('Position - Z (m)', size=12)
            self.axes1.legend(loc='best', prop={'size': 10})
        elif plot_type == 'Velocity - X':
            self.axes1.plot(t, x_true[1, :], '', label='True')
            self.axes1.plot(t, [x[1] for x in kf.state],
                            '--',
                            label='Filtered')
            self.axes1.set_ylabel('Velocity - X (m/s)', size=12)
            self.axes1.legend(loc='best', prop={'size': 10})
        elif plot_type == 'Velocity - Y':
            self.axes1.plot(t, x_true[4, :], '', label='True')
            self.axes1.plot(t, [x[4] for x in kf.state],
                            '--',
                            label='Filtered')
            self.axes1.set_ylabel('Velocity - Y (m/s)', size=12)
            self.axes1.legend(loc='best', prop={'size': 10})
        elif plot_type == 'Velocity - Z':
            self.axes1.plot(t, x_true[7, :], '', label='True')
            self.axes1.plot(t, [x[7] for x in kf.state],
                            '--',
                            label='Filtered')
            self.axes1.set_ylabel('Velocity - Z (m/s)', size=12)
            self.axes1.legend(loc='best', prop={'size': 10})
        elif plot_type == 'Acceleration - X':
            self.axes1.plot(t, x_true[2, :], '', label='True')
            self.axes1.plot(t, [x[2] for x in kf.state],
                            '--',
                            label='Filtered')
            self.axes1.set_ylabel('Acceleration - X (m/s/s)', size=12)
            self.axes1.legend(loc='best', prop={'size': 10})
        elif plot_type == 'Acceleration - Y':
            self.axes1.plot(t, x_true[5, :], '', label='True')
            self.axes1.plot(t, [x[5] for x in kf.state],
                            '--',
                            label='Filtered')
            self.axes1.set_ylabel('Acceleration - Y (m/s/s)', size=12)
            self.axes1.legend(loc='best', prop={'size': 10})
        elif plot_type == 'Acceleration - Z':
            self.axes1.plot(t, x_true[8, :], '', label='True')
            self.axes1.plot(t, [x[8] for x in kf.state],
                            '--',
                            label='Filtered')
            self.axes1.set_ylabel('Acceleration - Z (m/s/s)', size=12)
            self.axes1.legend(loc='best', prop={'size': 10})
        elif plot_type == 'Residual':
            self.axes1.plot(t, kf.residual, '')
            self.axes1.set_ylabel('Residual (m)', size=12)

        # Set the plot title and labels
        self.axes1.set_title('Kalman Filter', size=14)
        self.axes1.set_xlabel('Time (s)', size=12)

        # Set the tick label size
        self.axes1.tick_params(labelsize=12)

        # Turn on the grid
        self.axes1.grid(linestyle=':', linewidth=0.5)

        # Update the canvas
        self.my_canvas.draw()