Руководство · Начальный · 17 мин чтения

Шум, смещение и фильтрация датчиков в робототехнике

Шум, смещение и дрейф датчиков: как выбрать фильтр, сколько запаздывания он добавляет и когда помогает слияние данных.

Каждый робот действует по измерениям, содержащим шум, задержку и смещение, а иногда данные вовсе отсутствуют. Воспринимать исходное показание как истину — самый быстрый способ построить робота с непредсказуемым поведением. Это руководство описывает термины и компромиссы, которые необходимо понимать до доверия к датчику. Каждый эффект можно исследовать в Симуляторе датчиков робота.

Шум, смещение и дрейф — разные проблемы

  • Шум случайным образом меняется от отсчёта к отсчёту. Усреднение или фильтрация уменьшают его.
  • Смещение — постоянное отклонение от истинного значения. Фильтрация его не устранит: его необходимо измерить при калибровке и вычесть.
  • Дрейф — медленно изменяющееся со временем смещение, обычно связанное с температурой. Калибровка, полученная при запуске, постепенно перестаёт соответствовать действительности, поэтому при долгой работе необходима периодическая перекалибровка или эталон для коррекции.

Путаница между ними приводит к неверному исправлению: более сильная фильтрация никогда не устранит смещение.

Четыре графика построены для двадцати секунд времени относительно истинного значения, показанного горизонтальной пунктирной линией. Зашумлённый график сильно рассеивается выше и ниже истинного значения, но его среднее совпадает с ним. График смещения расположен выше истинного значения на постоянную величину с небольшим рассеиванием. График дрейфа начинается на истинном значении и непрерывно удаляется от него на протяжении всей записи.
Три неисправности, которые все выглядят как «плохое показание», но требуют трёх разных исправлений. Усреднение устраняет только первую. Скачать SVG

Выбор фильтра

Три распространённых фильтра покрывают большинство случаев:

  • Скользящее среднее и экспоненциальный фильтр низких частот сглаживают случайный шум, меняя быстродействие на плавность в зависимости от окна или постоянной времени.
  • Медианный фильтр лучше удаляет периодические выбросы и провалы, поскольку несколько плохих отсчётов не изменяют среднее по порядку.

Выбирайте самый простой фильтр, удовлетворяющий требованиям использующего измерение узла, а не тот, который строит наиболее гладкий график.

Фильтрация всегда добавляет запаздывание

Любой сглаживающий фильтр задерживает истинный сигнал, и более сильное сглаживание означает большую задержку. Фильтр низких частот с большой постоянной времени подавляет больше шума, но сильнее отстаёт при быстрых изменениях. Всегда строьте отфильтрованную оценку вместе с исходными отсчётами и истинным значением, чтобы задержка была видна до помещения фильтра в контур регулирования, где она может вызвать неустойчивость.

class LowPass:
    def __init__(self, alpha):
        self.alpha = alpha      # smaller alpha = smoother but more lag
        self.value = None
    def update(self, sample):
        if self.value is None:
            self.value = sample
        else:
            self.value += self.alpha * (sample - self.value)
        return self.value

Что может и чего не может слияние данных датчиков

Слияние объединяет несколько датчиков в одну оценку и помогает, только если они дают дополнительные друг к другу сведения, а их неопределённость представлена честно. Объединение двух измерений со смещением не создаёт истину. Например, комплементарный фильтр доверяет одному датчику на высоких частотах, а другому на низких; фильтр Калмана взвешивает каждый источник по его неопределённости. В обоих случаях начните с калибровки, меток времени и общих систем координат и только затем объединяйте данные.

Ставьте метки времени на всё

Отсчёты редко поступают через идеально постоянный интервал, а фильтрация и слияние предполагают, что известно время каждого измерения. Метки времени позволяют обнаруживать неравномерность интервалов, согласовывать данные разных датчиков и отбрасывать устаревшие показания. Записывайте исходные значения рядом с обработанными, чтобы такие отказы, как ограничение диапазона и провалы, можно было воспроизвести.

Сначала измерьте датчик, затем фильтруйте

Выбор фильтра до изучения характера шума — это догадка. Десять минут записи дадут ответ; для любого датчика процедура одинакова:

  1. Полностью неподвижно закрепите датчик на известном неизменном входном сигнале.
  2. Запишите несколько тысяч исходных отсчётов с метками времени.
  3. Вычислите среднее и стандартное отклонение.
  4. Постройте график отсчётов и гистограмму.

Эти четыре значения и два графика показывают, какая из трёх неисправностей присутствует:

Что наблюдается Что это Исправление
Среднее совпадает с истиной, значения симметрично рассеиваются Шум Отфильтруйте
Среднее смещено относительно истины, рассеивание невелико Смещение Измерьте и вычтите — фильтрация не поможет
Среднее постепенно удаляется в течение минут Дрейф Периодически калибруйте или корректируйте по эталону
Преимущественно плотное распределение с отдельными сильными значениями Выбросы Медиана, а не среднее
Значения располагаются на дискретных уровнях Квантование Ожидаемо; оно ограничивает разрешение

Гистограмма — часть, которую часто пропускают, хотя именно она наиболее информативна. Гауссов шум образует колокол, а выбросы — колокол с несколькими точками далеко в хвостах. Для них нужны разные фильтры, и никакое изучение графика временного ряда не различает их так чётко.

Выбор фильтра: количественная оценка

Фильтр Подавляет гауссов шум Подавляет выбросы Запаздывание Стоимость
Скользящее среднее, N отсчётов Да — в √N раз Нет — размазывает один выброс по N отсчётам (N−1)/2 отсчётов Буфер на N отсчётов
Экспоненциальный фильтр низких частот (EMA) Да Нет ≈ (1−α)/α отсчётов Одно число с плавающей точкой
Медиана N отсчётов Отчасти Полностью, до N/2 выбросов (N−1)/2 отсчётов Сортировка, пренебрежимо мало при малом N
Медиана, затем EMA Да Да Оба Оба

√N в первой строке — полезное значение: усреднение 4 отсчётов вдвое уменьшает шум, а усреднение 100 отсчётов уменьшает его в десять раз ценой 50 отсчётов запаздывания. Уменьшение шума быстро теряет эффективность, а запаздывание — нет, поэтому очень длинное усреднение почти всегда является неверным ответом.

Для EMA постоянная времени связана с α соотношением:

tau = dt x (1 - alpha) / alpha

При цикле 10 ms значение α = 0.1 даёт постоянную времени 90 ms. Выбор α на глаз приводит к фильтрам, которые значительно медленнее, чем предполагает разработчик: вычислите его один раз, и вы будете знать характеристику фильтра.

Запаздывание не бесплатно, и вот его цена

Любой сглаживающий фильтр задерживает сигнал, а внутри контура регулирования эта задержка неотличима от более медленного отклика объекта. Она напрямую уменьшает усиление, которое контур способен выдержать до возникновения колебаний.

Фильтр Запаздывание при цикле 10 ms Путь при 0.3 m/s
Медиана 3 10 ms 3 mm
Медиана 5 20 ms 6 mm
Скользящее среднее 10 45 ms 14 mm
EMA, α = 0.1 90 ms 27 mm
EMA, α = 0.02 490 ms 147 mm

Последняя строка заслуживает внимания. Значение α 0.02 даёт красивый плавный график и полсекунды запаздывания — робот управляет движением, ориентируясь на положение препятствия, устаревшее на 15 cm. Это самая распространённая причина, по которой продуманный фильтр ухудшает робота, и заметить её можно только при сравнении отфильтрованных данных с исходными при наличии истинного значения.

Выбирайте самый простой фильтр, удовлетворяющий требованиям, и всегда проверяйте цену запаздывания в единицах, важных для робота, — миллиметрах или градусах, а не в отсчётах.

Комплементарный фильтр и выбор его постоянной

Комплементарный фильтр — основной инструмент робототехники для любителей, поскольку он занимает три строки и решает реальную проблему: два датчика, отказавающихся противоположным образом.

// gyroRate in deg/s, accelAngle in degrees, dt in seconds.
angle = alpha * (angle + gyroRate * dt) + (1.0f - alpha) * accelAngle;

alpha задаёт частоту сопряжения: выше неё вы доверяете гироскопу, ниже — акселерометру:

tau = alpha x dt / (1 - alpha)          # the filter's time constant, seconds
f_crossover = 1 / (2 x pi x tau)        # Hz
α при dt = 5 ms Постоянная времени Частота сопряжения Поведение
0.90 45 ms 3.5 Hz Очень быстрый, заметный шум от акселерометра
0.98 245 ms 0.65 Hz Общее значение по умолчанию — хороший баланс
0.995 1.0 s 0.16 Hz Очень плавный, заметно дрейфует до коррекции
0.999 5.0 s 0.03 Hz Практически только гироскоп при любом коротком манёвре

Выбирайте по физике, а не на глаз: постоянная времени должна быть намного больше периодов возмущений, которые требуется подавить, и намного меньше скорости дрейфа гироскопа. Гироскоп со смещением 1 °/s набирает ошибку 1° за секунду, поэтому постоянная времени в несколько секунд позволяет реальной ошибке накопиться до того, как акселерометр восстановит оценку.

Также обратите внимание, что α зависит от dt. Копирование α из проекта с другой частотой цикла даёт другой фильтр — это распространённый и незаметный источник сообщений «эти коэффициенты у меня не работают».

Чего не может слияние данных

Слияние не является волшебством, и следует прямо указать три его предела:

Оно не устраняет общее смещение. Два акселерометра, оба показывающие на 2° больше, дадут объединённую оценку с отклонением на 2°. Слияние использует независимые ошибки; синфазная ошибка сохраняется без изменений.

Оно не создаёт отсутствующую информацию. Никакая фильтрация не даст шестиосевому IMU абсолютный курс. У рыскания нет гравитационного ориентира, поэтому оно дрейфует, и исправить это может только магнитометр или внешний эталон.

Оно не исправляет неверные метки времени. Для слияния поправки GPS 10 Hz с данными гироскопа 200 Hz необходимо знать, когда проведено каждое измерение, с точностью до доли более быстрого интервала. Поправка GPS, устаревшая на 100 ms, но обработанная как текущая, активно испортит оценку, которую гироскоп сам по себе вычислял верно.

Метки времени на практике

«Ставьте метки времени на всё» легко принять к сведению и легко пропустить. Практическая реализация:

struct Sample {
  float value;
  unsigned long micros;    // when it was MEASURED, not when it was read
};

// Reject anything too old to be useful, rather than fusing it.
bool isFresh(const Sample &s, unsigned long maxAgeUs) {
  return (micros() - s.micros) < maxAgeUs;
}

Получайте метку времени как можно ближе к моменту измерения — внутри прерывания, а не после разбора. Предложение GPS, разобранное через 80 ms после получения поправки и помеченное временем разбора, имеет ошибку 80 ms, которую ничто последующее не исправит.

Диагностика

Симптом Вероятная причина Исправление
Более сильная фильтрация не улучшает результат Это смещение, а не шум Измерьте отклонение в покое и вычтите
Оценка постепенно удаляется Дрейф Периодически калибруйте или используйте абсолютный эталон
Периодический выброс проходит через фильтр Используется среднее Медиана отбрасывает выбросы, а среднее размазывает
После добавления фильтра контур регулирования начинает колебаться Запаздывание уменьшило допустимое усиление Используйте более простой фильтр или повторите настройку
График плавный, робот реагирует с задержкой Постоянная времени намного больше ожидаемой Вычислите τ из α — не задавайте α на глаз
Объединённая оценка хуже оценки любого датчика Устаревшие метки времени или общее смещение Ставьте метку при измерении; проверьте смещения обоих датчиков
На стенде фильтр работает, на роботе — нет Вибрация является реальным сигналом, который нельзя автоматически считать шумом Установите датчик на мягкое крепление; фильтр не может их различить
Комплементарный фильтр ведёт себя иначе, чем в руководстве α зависит от dt Вычислите α для вашей частоты цикла

Попробуйте самостоятельно

В Симуляторе датчиков робота можно задать шум, смещение, дрейф и провалы, а затем сравнить исходные данные с оценками после фильтрации низких частот, скользящего среднего и медианы. Это самый быстрый способ почувствовать компромисс между шумом и запаздыванием — тот же компромисс, который определяет реакцию робота в Симуляторе обхода препятствий.

Исследуйте граф

Входит в эти сборки

Проекты и учебные пути, в которые входит это руководство.

Дополнительные материалы

Источники