WPILibC++ 2026.2.2
Loading...
Searching...
No Matches
MedianFilter.h
Go to the documentation of this file.
1// Copyright (c) FIRST and other WPILib contributors.
2// Open Source Software; you can modify and/or share it under the terms of
3// the WPILib BSD license file in the root directory of this project.
4
5#pragma once
6
7#include <algorithm>
8#include <vector>
9
10#include <wpi/Algorithm.h>
11#include <wpi/circular_buffer.h>
12
13namespace frc {
14/**
15 * A class that implements a moving-window median filter. Useful for reducing
16 * measurement noise, especially with processes that generate occasional,
17 * extreme outliers (such as values from vision processing, LIDAR, or ultrasonic
18 * sensors).
19 */
20template <class T>
22 public:
23 /**
24 * Creates a new MedianFilter.
25 *
26 * @param size The number of samples in the moving window.
27 */
28 constexpr explicit MedianFilter(size_t size)
29 : m_valueBuffer(size), m_size{size} {}
30
31 /**
32 * Calculates the moving-window median for the next value of the input stream.
33 *
34 * @param next The next input value.
35 * @return The median of the moving window, updated to include the next value.
36 */
37 constexpr T Calculate(T next) {
38 // Insert next value at proper point in sorted array
39 wpi::insert_sorted(m_orderedValues, next);
40
41 size_t curSize = m_orderedValues.size();
42
43 // If buffer is at max size, pop element off of end of circular buffer
44 // and remove from ordered list
45 if (curSize > m_size) {
46 m_orderedValues.erase(std::find(m_orderedValues.begin(),
47 m_orderedValues.end(),
48 m_valueBuffer.pop_back()));
49 --curSize;
50 }
51
52 // Add next value to circular buffer
53 m_valueBuffer.push_front(next);
54
55 if (curSize % 2 != 0) {
56 // If size is odd, return middle element of sorted list
57 return m_orderedValues[curSize / 2];
58 } else {
59 // If size is even, return average of middle elements
60 return (m_orderedValues[curSize / 2 - 1] + m_orderedValues[curSize / 2]) /
61 2.0;
62 }
63 }
64
65 /**
66 * Returns the last value calculated by the MedianFilter.
67 *
68 * @return The last value.
69 */
70 constexpr T LastValue() const { return m_valueBuffer.front(); }
71
72 /**
73 * Resets the filter, clearing the window of all elements.
74 */
75 constexpr void Reset() {
76 m_orderedValues.clear();
77 m_valueBuffer.reset();
78 }
79
80 private:
81 wpi::circular_buffer<T> m_valueBuffer;
82 std::vector<T> m_orderedValues;
83 size_t m_size;
84};
85} // namespace frc
A class that implements a moving-window median filter.
Definition MedianFilter.h:21
constexpr T Calculate(T next)
Calculates the moving-window median for the next value of the input stream.
Definition MedianFilter.h:37
constexpr void Reset()
Resets the filter, clearing the window of all elements.
Definition MedianFilter.h:75
constexpr MedianFilter(size_t size)
Creates a new MedianFilter.
Definition MedianFilter.h:28
constexpr T LastValue() const
Returns the last value calculated by the MedianFilter.
Definition MedianFilter.h:70
This is a simple circular buffer so we don't need to "bucket brigade" copy old values.
Definition circular_buffer.h:20
Definition CAN.h:11
std::vector< T >::iterator insert_sorted(std::vector< T > &vec, T const &item)
Definition Algorithm.h:16