Some sensors have a really fuzzy or jittery output (looking at you accels). Assuming this fuzz is an error, you can "filter" out the fuzz by using past readings to guess what the current reading should be.
One caution, a filter will also make your system respond slower. How much slower depends on the specifics of the filter.
If you're using a Kalman filter, it already assumes error in your sensor readings, but I've found it helps to have a specific filter on the accel to get rid of the worst jitters. Gyros seem to do okay without pre-filtering. You can use these filters on any data (accelerometer, magnetometer, gyroscope, pressure, etc.).
Here are I couple filters I use, if you have some better ones I'd def like to see them!
1) The Moving Average Filter
This takes the last n readings (including the current one) and averages them. Simple enough. A 5-point moving average filter returns the average of the last 5 readings:
- Code: Select all
//written for PIC18F4550
//sensorReading is an array length 5
sensorReading[4] = sensorReading[3]; //Move all the values over one place
sensorReading[3] = sensorReading[2];
sensorReading[2] = sensorReading[1];
sensorReading[1] = sensorReading[0];
ADCON0 = 0b00000011; //Read AN0
while(ADCON0bits.GO); //Wait for reading to complete
sensorReading[0] = ADRES;//Update the first value in the array with the new reading
//Average the five values in the array
movAvgFilt = (sensorReading[4] +sensorReading[3] +sensorReading[2] +sensorReading[1] +sensorReading[0]) / 5;
2)The Low Pass Filter (http://en.wikipedia.org/wiki/Low_pass_filter)
Low Pass means the filter allows low frequencies to "pass" through the filter. You set a cutoff frequency and all frequencies above this (i.e. jitters) get cutoff. I used 2Hz on one project, but it really depends on the project. Since this uses a second division in the calculation, it uses more CPU time than the moving average filter, but is a little more elegant.
Cutoff frequency is calculated by:
cutoff frequency = 1/ (2*pi*RC) --> RC is the constant you set in code to set the frequency.
- Code: Select all
filteredReading = currentReading*(dt/(RC+dt)) + oldFilteredReading*(RC/(RC+dt));
oldFilteredReading = filteredReading;
OK, that was a long post! Post some more filters, questions, comments. Thanks!