Kalman filter – simplified version
May 16, 2011 13 Comments
Finally… it’s been a while since I’ve started looking into filtering, and more precisely Kalman filters… since I started on my quadcopter project, to be more precise…
After reading the descriptions and formulas found here (highly recommend the short introductory pdf !) I decided I had to code my own simplified version.
The data I’m using for this post comes from a (very) noisy RC FM receiver that sits right next to an electric motor and that was causing troubles to the point that I couldn’t control the tank (even with a capacitor on the motor !).
So let’s start with simply filtering a scalar value…
Here’s the Java code :
package mykalman; public class MyKalman { private double Q = 0.00001; private double R = 0.01; private double P = 1, X = 0, K; private void measurementUpdate(){ K = (P + Q) / (P + Q + R); P = R * (P + Q) / (R + P + Q); } public double update(double measurement){ measurementUpdate(); double result = X + (measurement - X) * K; X = result; return result; } private static int[] DATA = new int[]{0,0,0,0,0,0,0,0,0,0,3,13,20,31,39,44,46,54,57,57,63,67,67,70,76,78,86,0,93,99,100,100,100,100,102,106,108,105,50,108,106,106,106,105,105,105,106,106,106,105,105,108,106,80,106,106,105,106,106,106,106,106,106,106,2,106,106,106,106,108,106,108,104,106,105,106,105,106,106,105,105,105,106,106,106,106,105,106,106,105,105,108,30,106,106,105,106,106,104,106,106,105,80,109,106,108,105,106,106,106,108,106,106,105,106,104,108,105,106,106,104,106,106,106,108,108,106,45,60,75,106,106,106,106,105,105,104,106,106,106,106,108,108,106,106,106,105,105,106,106,106,106,106,106,106,105,105,109,106,108,106,106,105,106,108,20,106,106,106,105,105,106,104,108,108,106,106,104,106,104,106,105,106,106,109,45,106,106,106,66,105,106,103,105,105,106,106,105,108,104,106,105,106,106,108,104,105,66,66,66,106,105,108,105,108,106,106,106,106,106,106,108,106,108,105,105,105,106,106,105,106,108,106,105,106,0,106,105,106,106,106,106,106,104,106,104,108,106,108,108,106}; public static void main(String[] args){ MyKalman filter = new MyKalman(); for(int d : DATA){ System.out.print(Math.round(filter.update(d)) + ","); } } }
Yep, that’s it…. no kidding… it’s obviously quite simple because :
- there is no control input
- we measure the state directly
- etc. …
But still does a quite impressive job !
Pingback: a drop in the digial ocean
Pingback: 【確率ロボティクス】カルマンフィルタの実装 | GUSUGUSU.NET
Pingback: kalman-filter-simplified-version | 不分享空間
Pingback: a drop in the digital ocean
Two questions:
1. Is it possible to replace second line in measurementUpdate method with
P = R * K; ( because (P + Q) / (R + P + Q) is already equal to K) ?
2. It seems K tends to 0.0311267292017… (after 100-th step) so do we need all that difficult calculations?
You are correct, after a while I did realise that this version of the filter was so “simplified” that it’s basically almost just a low pass filter… but never took the time to update this post.
Thank you for pointing it out.
Have a look at some of the comments below, especially the one with explaining that “K and P are actually independent “.
Dan
Hi,
for what does Q, R and P stand for? What I mean: Which of these Parameters I have to change, for example, to get a fast rise?
Q and R are used to estimate the noise in the measurements (http://en.wikipedia.org/wiki/Kalman_filter#Estimation_of_the_noise_covariances_Qk_and_Rk).
P is the predicted estimated covariance.
dan
Do you know of a reliable way to choose a decent process noise and measurement error covariance for use with your filter?
Thanks!
Hi Bob,
No, this is barely my first foray into filtering / machine learning, and to be honest I think the example in this post is sooo simplified, that it basically has the same effect as a low pass filter, which is much easier to write…
But please do let me know if you find a nice / simple process to choose the covariance matrix …!
Dan
Thanks, I’ll let you know if I find anything. I was hoping your solution would be a silver bullet but I think you are right, it might be a slightly better low-pass in its current state.
Pingback: Very Simple Kalman in C# « a drop in the digital ocean
thanks for you reference to my Java Kalman filter implementation.
Just beware that, because there is no control input K and P are actually independent of X (the process value) and will quickly tend to constant values… hence even that measurementUpdate() method becomes un-necessary and the whole filter will amount to doing a simple moving average over the measured values…