FTC++
  • Home
  • šŸ“·Vision
    • Introduction
    • AprilTags
    • Bitmaps
    • Custom Algorithms
  • šŸ”¢Data
    • Introduction
    • Moving Average Filter
    • Kalman Filter
    • Sensor Fusion
    • Multi-Variable Kalman Filter
  • šŸŽ®Control Theory
    • Introduction
    • State Space Control
    • Linear Quadratic Regulator
    • Model Predictive Control
    • Odometry
  • 🧊3D Modelling
    • Odometry pods
    • Sensors
    • Turrets
  • šŸ“šResources
    • Resources
Powered by GitBook
On this page
  1. Data

Moving Average Filter

for distance sensors

A Moving Average Filter is a digital signal processing technique used to smooth out noisy data from a sensor. In the context of FTC (FIRST Tech Challenge), this filter is commonly employed to improve the accuracy and stability of sensor readings. The basic idea behind the Moving Average Filter is to calculate the average of a fixed window of recent sensor values, effectively reducing random fluctuations and providing a more consistent output.

Mathematically, the Moving Average Filter can be described as follows:

Given a window size of N (usually an odd number for a centered filter), the filter calculates the smoothed output (y_t) at time t as the average of the most recent N sensor readings (x_t, x_(t-1), ..., x_(t-N+1)):

yt=(xt+x(tāˆ’1)+...+x(tāˆ’N+1))/Ny_t = (x_t + x_(t-1) + ... + x_(t-N+1)) / Nyt​=(xt​+x(​tāˆ’1)+...+x(​tāˆ’N+1))/N

In this equation:

  • y_t represents the smoothed output at time t.

  • x_t is the current sensor reading at time t.

  • x_(t-1), x_(t-2), ..., x_(t-N+1) are the previous N-1 sensor readings.

  • N is the window size, and it is typically chosen as an odd number to ensure that the central value is well-defined.

By maintaining a queue or circular buffer of the most recent N sensor readings, the Moving Average Filter continuously updates the smoothed output as new sensor data becomes available. As a result, rapid fluctuations or noise in the sensor readings are effectively averaged out, providing a more stable and accurate representation of the underlying signal.

The Moving Average Filter is relatively straightforward to implement and is useful in scenarios where a quick reduction of noise is desired. However, it does introduce a slight delay in the output response, which can be a consideration when dealing with rapidly changing signals.

It's important to note that while the Moving Average Filter is a simple and effective technique for noise reduction, it may not be suitable for all applications, particularly when dealing with complex or dynamic signals. In more advanced scenarios, other filtering methods such as Kalman filtering or exponential moving averages might be more appropriate. The choice of the filtering technique should be based on the specific characteristics and requirements of the sensor data and the FTC application at hand.

public class MovingAverageFilter {
    private Queue<Double> buffer;
    private int windowSize;
    private double sum;
    
    // Constructor and methods will be explained below...
}

We define a class called MovingAverageFilter, which will implement the filter's functionality. It contains three member variables:

  • buffer: A Queue (specifically, a LinkedList) to store the most recent sensor readings.

  • windowSize: An integer representing the number of recent sensor readings to consider in the average calculation. The window size also determines the "order" of the filter. For example, a window size of 5 means it is a 5th order filter. Higher-order filters provide more smoothing but introduce more delay.

  • sum: A variable to keep track of the sum of the sensor readings within the window.

public MovingAverageFilter(int windowSize) {
    this.buffer = new LinkedList<>();
    this.windowSize = windowSize;
    this.sum = 0.0;
}

The constructor MovingAverageFilter(int windowSize) is used to initialize the filter with the desired window size. It sets the windowSize value and initializes the buffer as an empty LinkedList, and the sum is set to 0.0.

public double filter(double newValue) {
    buffer.add(newValue);
    sum += newValue;

    if (buffer.size() > windowSize) {
        sum -= buffer.poll();
    }

    return sum / buffer.size();
}

The filter(double newValue) method is the core of the Moving Average Filter. It takes a new sensor reading as input (newValue) and returns the smoothed output, which is the moving average of the current window of data.

Here's a step-by-step explanation of the filter method:

  • buffer.add(newValue);: The new sensor reading is added to the buffer using the add method.

  • sum += newValue;: The value of the new sensor reading is added to the sum variable, which keeps track of the total sum of the sensor readings within the window.

  • if (buffer.size() > windowSize) { ... }: This conditional statement checks if the size of the buffer has exceeded the windowSize. If so, it means we have more sensor readings than we need for the average calculation.

  • sum -= buffer.poll();: If the buffer size is greater than the window size, the oldest reading is removed from the buffer using the poll method, and its value is subtracted from the sum. This ensures that the sum only considers the most recent windowSize readings.

  • return sum / buffer.size();: Finally, the method returns the calculated moving average, which is the sum divided by the current size of the buffer. The division by the buffer size ensures that we calculate the average of the sensor readings present in the buffer, which represents the current window of data.

The Moving Average Filter works by continuously updating the buffer with new sensor readings. As new readings are added, the filter maintains a fixed window of the most recent readings and calculates their average to produce a smoothed output. The effectiveness of the filter depends on the chosen window size, with larger window sizes providing more smoothing but introducing more delay in the output response.

The API is here with the functions shown above, it also has one extra clear(); funtion that just clears the data if you need it

double initvalue = 0;
double filteredvalue = 0;
MovingAverageFilter movingAverageFilter = new MovingAverageFilter(5);

here we create our variables and we parse in our window size/filtering size to our API

while(true) {
            initvalue = DISTANCESENSORVALUE; // dsensor values unit dose not matter
            filteredvalue = movingAverageFilter.filter(initvalue);
            telemetry.addData("initvalue: ",initvalue);
            telemetry.addData("filteredvalue: ",filteredvalue);
        }
PreviousIntroductionNextKalman Filter

Last updated 1 year ago

Remember to use FTC Dashboard to plot the telemetry into graphs

šŸ”¢
šŸ˜„
689B
MovingAverageFilter.java
Moving Average Filter API only for this usage