1
\$\begingroup\$

I have some accelerometer data that I need to filter and clean. However, based on the online examples that I see, the filter requires what's called a "Truth value". The code is based on this:

http://scottlobdell.me/2014/08/kalman-filtering-python-reading-sensor-input/

enter image description here

Now for the truth value for my accel data, I was wondering if I could generate it by applying a smoothing function to my dataset, then using that as the truth value. The image below shows my accel data, with the green part showing the smoothed data. It is using the "Blackman Tukey" smoothing algorithm. However, you can see that it is not good at processing high frequency signals. Nevertheless, i have a "rough truth" value.

enter image description here

My question is, can I use this smoothed value as my truth value in my kalman filter?

\$\endgroup\$
  • 1
    \$\begingroup\$ I don't see the truth value being use anywhere in the actual kalman filter in any of the examples you link. It's just there to show you what the ideal output should be. \$\endgroup\$ – Connor Wolf Sep 8 '14 at 8:49
  • \$\begingroup\$ You will occasionally see terms like "reference" in descriptions of an Indirect Kalman Filter, where the system mechanization (e.g. double integration of accelerometer data to get position) is run independently, and the IKF's state models the error in the "reference". \$\endgroup\$ – Ben Jackson Oct 19 '14 at 18:52
10
\$\begingroup\$

I'm not sure what you're looking at, but you need to understand the exmples you link.

None of them use the truth-value within the actual filtering. It's there so you have something to compare to with regard to the filter output.

Here is the simple script:

import random

# intial parameters
iteration_count = 500
actual_values = [-0.37727 + j * j * 0.00001 for j in xrange(iteration_count)]
noisy_measurement = [random.random() * 0.6 - 0.3 + actual_val for actual_val in actual_values]

process_variance = 1e-5  # process variance

estimated_measurement_variance = 0.1 ** 2  # estimate of measurement variance, change to see effect

# allocate space for arrays
posteri_estimate_for_graphing = []

# intial guesses
posteri_estimate = 0.0
posteri_error_estimate = 1.0

for iteration in range(1, iteration_count):
    # time update
    priori_estimate = posteri_estimate
    priori_error_estimate = posteri_error_estimate + process_variance

    # measurement update
    blending_factor = priori_error_estimate / (priori_error_estimate + estimated_measurement_variance)
    posteri_estimate = priori_estimate + blending_factor * (noisy_measurement[iteration] - priori_estimate)
    posteri_error_estimate = (1 - blending_factor) * priori_error_estimate
    posteri_estimate_for_graphing.append(posteri_estimate)

import pylab
pylab.figure()
pylab.plot(noisy_measurement, color='r', label='noisy measurements')
pylab.plot(posteri_estimate_for_graphing, 'b-', label='a posteri estimate')
pylab.plot(actual_values, color='g', label='truth value')
pylab.legend()
pylab.xlabel('Iteration')
pylab.ylabel('Voltage')
pylab.show()

Lets break it down:

First, build the input array, and then create the simulated "noisy" input by adding random values to each item in the input array.

import random

# intial parameters
iteration_count = 500
actual_values = [-0.37727 + j * j * 0.00001 for j in xrange(iteration_count)]
noisy_measurement = [random.random() * 0.6 - 0.3 + actual_val for actual_val in actual_values]

Next, several parameters are defined that describe the characteristics of the system variance. These will have to be derived from your signal source.

process_variance = 1e-5  # process variance    
estimated_measurement_variance = 0.1 ** 2  # estimate of measurement variance, change to see effect

# allocate space for arrays
posteri_estimate_for_graphing = []

# intial guesses
posteri_estimate = 0.0
posteri_error_estimate = 1.0

This is the actual filtering code:

for iteration in range(1, iteration_count):
    # time update
    priori_estimate = posteri_estimate
    priori_error_estimate = posteri_error_estimate + process_variance

    # measurement update
    blending_factor = priori_error_estimate / (priori_error_estimate + estimated_measurement_variance)
    posteri_estimate = priori_estimate + blending_factor * (noisy_measurement[iteration] - priori_estimate)
    posteri_error_estimate = (1 - blending_factor) * priori_error_estimate
    posteri_estimate_for_graphing.append(posteri_estimate)

Note: actual_values is not referenced anywhere in the above code. The Kalman filter operates entirely on just the data within the noisy_measurement array.

Finally, plot the various arrays.

import pylab
pylab.figure()
pylab.plot(noisy_measurement, color='r', label='noisy measurements')
pylab.plot(posteri_estimate_for_graphing, 'b-', label='a posteri estimate')
pylab.plot(actual_values, color='g', label='truth value')
pylab.legend()
pylab.xlabel('Iteration')
pylab.ylabel('Voltage')
pylab.show()

So basically, you don't need the truth value at all. You need to actually read your examples. It's graphed just so you can determine the efficacy of the Kalman filter.

Critically, particularly for testing purposes, you cannot characterize the error produced by a Kalman filter with contants of {n} without knowing the actual truth value. The filter will filter fine, but there is no way to determine if the output is accurate. Properly setting up the filter requires being able to measure just the noise within the system.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.