AHRS на MPU6050 + Python
Круглый авиагоризонт, 3D-визуализация, фильтры Madgwick / Mahony, загрузка OBJ/STL моделей
Что такое AHRS?
AHRS — Attitude and Heading Reference System (Система определения ориентации и курса).
Это комплексная система, которая определяет трёхмерную ориентацию объекта в пространстве: углы крена (Roll), тангажа (Pitch) и рыскания/курса (Yaw). В отличие от простых датчиков, AHRS обрабатывает данные с нескольких сенсоров (гироскоп, акселерометр, магнитометр) с помощью фильтров ориентации, объединяя их для получения стабильного и точного результата.
Как это работает?
Система AHRS решает ключевую проблему инерциальных датчиков:
- Гироскоп — измеряет угловую скорость, но со временем накапливает дрейф (ошибка интегрирования).
- Акселерометр — показывает направление гравитации (даёт абсолютный опорный вектор «вниз»), но чувствителен к ускорениям и вибрациям.
- Фильтр (Madgwick или Mahony) — объединяет эти данные, используя алгоритмы слияния с перекрёстной коррекцией ошибок, и выдаёт стабильный кватернион — математическое представление ориентации без «складок» и сингулярностей.
В нашем проекте: фильтр работает прямо на ESP32, передавая в Python уже готовые кватернионы и углы. Это разгружает компьютер и обеспечивает высокую частоту обновления (до 200 Гц).
- Авиация и БПЛА — стабилизация полёта, автопилоты, телеметрия.
- Робототехника — балансировка, SLAM-навигация, управление манипуляторами.
- Виртуальная реальность — трекинг головы и тела.
- Смартфоны и носимые устройства — распознавание движения, шагомеры.
- Научные приборы — измерение углов в эксперименте.
Описание интерфейса
Левая панель (управление)
Вкладка «Управление»:
- Подключение: выбор COM-порта, кнопка «Подключиться/Отключиться», индикатор статуса.
- Управление: кнопки «Сброс ориентации» и «Калибровка» (активируются после подключения).
- 3D Модель: загрузка OBJ/STL-файлов, сброс к кубу, слайдер прозрачности (0–100%).
- Цвет фона 3D сцены: выбор цвета с помощью диалогового окна.
- Настройки фильтра ориентации: выбор профиля (6 предустановок), тип фильтра (Madgwick/Mahony), ручная настройка параметров, кнопка «Применить».
- Настройки отображения: чекбоксы «Показать сетку», «Показать оси», «Показать векторы», «Автомасштаб графиков».
- Экспорт данных: кнопки «Экспорт CSV» и «Начать запись» (с индикацией количества записей).
Вкладка «Данные»
- Текущие значения: температура, гироскоп (X, Y, Z) в °/s, акселерометр (X, Y, Z) в g.
- Углы ориентации: Roll, Pitch, Yaw в градусах.
- Кватернион: (q0, q1, q2, q3) — представление ориентации.
- Уровень шума гироскопа: отображается после калибровки.
- Отладка: текстовое поле для сообщений системы (до 100 строк).
Вкладка «Настройки шрифтов»
- Настройка шрифтов для разных элементов интерфейса:
- Основные: общий шрифт, моноширинный шрифт.
- Заголовки: шрифт для заголовков групп.
- Углы: шрифт для отображения углов.
- Отладка: шрифт для окна отладки.
- Настройка цветов: текст, гироскоп (X, Y, Z), углы (Roll, Pitch, Yaw).
- Кнопки «Применить» и «Сбросить» для возврата к стандартным настройкам.
Вкладка «Темы»
Выбор готовых тем оформления:
- Dark — тёмная тема (по умолчанию).
- Light — светлая тема.
- Aviation — авиационная тема (сине-оранжевая гамма).
- Terminal — стиль терминала (чёрный фон, зелёный текст).
Правая панель (визуализация)
- Вкладка «3D Визуализация»:
- 3D-сцена с вращающейся моделью (куб или загруженная OBJ/STL-модель).
- Управление камерой: вращение, масштабирование, перемещение (мышь).
- Отображение осей координат (X — красный, Y — зелёный, Z — синий).
- Опциональное отображение векторов ускорения и гироскопа.
- Вкладка «Авиагоризонт»:
- Круглый авиагоризонт с отображением неба (голубой) и земли (коричневой).
- Линия горизонта с углом наклона, соответствующая Pitch.
- Шкала крена (дуга сверху) с указателем текущего Roll.
- Вертикальная шкала тангажа с метками ±30°.
- Цифровые значения углов внизу (Roll, Pitch, Yaw) с цветовой кодировкой.
Графики
- Данные гироскопа: три линии (Gyro X, Y, Z) — угловая скорость (°/s) от времени (с).
- Данные акселерометра: три линии (Accel X, Y, Z) — ускорение (g) от времени (с).
- Углы ориентации: три линии (Roll, Pitch, Yaw) — углы (°) от времени (с).
- Автомасштабирование осей (опционально, отключается чекбоксом).
Компоненты и стек
Железо
- ESP32-S3 (или любой Arduino с I²C)
- MPU6050 (GY-521)
- Провода, макетная плата
- Подключение по I²C:
SDA → GPIO8,SCL → GPIO9
Программное обеспечение
- Arduino IDE 2.x / PlatformIO
- Python 3.10+
- Библиотеки (см. ниже)
- Visual Studio Code (рекомендуется)
Библиотеки для Arduino IDE
В прошивке AHRS-avia.ino используются только встроенные библиотеки — дополнительная установка не требуется.
| Библиотека | Тип | Назначение |
|---|---|---|
Wire.h |
Встроенная | Работа по протоколу I²C (общение с MPU6050) |
math.h |
Встроенная | Математические функции (sqrt, atan2, sin, cos) |
Библиотеки для Python
Все зависимости перечислены в таблице ниже. Установка выполняется одной командой (см. раздел «Установка»).
| Библиотека | Версия (рекомендуемая) | Назначение |
|---|---|---|
vispy |
≥ 0.14.0 | 3D-движок (сцена, модель, камера) |
PyQt5 |
≥ 5.15.0 | Графический интерфейс, виджеты, события |
pyqtgraph |
≥ 0.13.0 | Графики в реальном времени (гироскоп, углы) |
pyserial |
≥ 3.5 | Работа с COM-портом (приём данных) |
numpy |
≥ 1.24.0 | Математические вычисления, матрицы, кватернионы |
trimesh |
≥ 4.0.0 | Загрузка 3D-моделей (OBJ, STL, PLY и др.) |
pywavefront |
≥ 1.3.0 | Альтернативный парсер OBJ-файлов |
trimesh и pywavefront используются только для загрузки пользовательских моделей. Если они не установлены, программа будет работать с кубом по умолчанию без ошибок.Установка и настройка
1️⃣ Прошивка ESP32 (Arduino)
- Откройте
AHRS-avia.inoв Arduino IDE. - Выберите плату ESP32S3 Dev Module (или вашу).
- Убедитесь, что пины I²C соответствуют:
#define I2C_SDA 8,#define I2C_SCL 9. - Загрузите прошивку. В мониторе порта появится
MPU6050_READY.
CALIBRATION_COMPLETE.2️⃣ Установка Python-библиотек
Способ 1 — через pip (рекомендуемый):
pip install vispy pyqt5 pyqtgraph pyserial numpy trimesh pywavefront
Способ 2 — через requirements.txt:
Создайте файл requirements.txt со следующим содержимым:
vispy>=0.14.0
PyQt5>=5.15.0
pyqtgraph>=0.13.0
pyserial>=3.5
numpy>=1.24.0
trimesh>=4.0.0
pywavefront>=1.3.0
Затем выполните:
pip install -r requirements.txt
pip3 вместо pip. В некоторых системах также нужны системные пакеты python3-pyqt5, python3-pyqt5.qtopengl.3️⃣ Проверка зависимостей
Запустите Python и выполните импорт всех библиотек:
python -c "import vispy, PyQt5, pyqtgraph, serial, numpy, trimesh, pywavefront; print('✅ Все библиотеки установлены')"
Если какая-то библиотека отсутствует, вы увидите сообщение ModuleNotFoundError — установите её отдельно.
Также можно использовать скрипт-проверку:
import importlib
libs = ['vispy', 'PyQt5', 'pyqtgraph', 'serial', 'numpy', 'trimesh', 'pywavefront']
for lib in libs:
try:
importlib.import_module(lib)
print(f'✅ {lib} — OK')
except ImportError:
print(f'❌ {lib} — НЕ УСТАНОВЛЕН')
4️⃣ Запуск Python-клиента
- Сохраните скрипт
AHRS-avia-round.pyв рабочую папку. - Убедитесь, что все зависимости установлены (см. п. 2–3).
- Запустите:
python AHRS-avia-round.py - В интерфейсе выберите COM-порт и нажмите «Подключиться».
После подключения вы увидите:
- 3D-сцена с вращающейся моделью (куб, самолёт или ваша модель).
- Круглый авиагоризонт с дугой крена и шкалой тангажа.
- Графики гироскопа, акселерометра и углов в реальном времени.
- Панель управления фильтрами, калибровкой, темой оформления.
Ключевые возможности
- Два фильтра ориентации: Madgwick (параметры Beta/Zeta) и Mahony (Kp/Ki). Переключение в реальном времени.
- Калибровка гироскопа с анализом сходимости — автоматическое определение смещений и уровня шума.
- Загрузка 3D-моделей через интерфейс (OBJ / STL). Прозрачность регулируется слайдером.
- Темы оформления: Dark, Light, Aviation, Terminal — меняются мгновенно.
- Экспорт данных в CSV с возможностью непрерывной записи.
- Горячие клавиши: Ctrl+W (подключение), Ctrl+K (калибровка), Ctrl+E (экспорт), F11 (полный экран).
Предустановленные профили фильтров
В программе доступно 6 предустановленных профилей для быстрой настройки фильтрации под разные сценарии использования. Каждый профиль оптимизирован для конкретных условий работы датчика.
Default (AHRS)
Назначение: Универсальный профиль для большинства применений. Обеспечивает хороший баланс между точностью и скоростью реакции.
Параметры (Mahony): Kp = 0.5, Ki = 0.001
Особенности: Минимальное запаздывание, умеренное подавление шума. Подходит для пилотирования, стабилизации, навигации.
High Accuracy
Назначение: Максимальная точность определения ориентации. Используется в стационарных или медленно движущихся системах.
Параметры (Madgwick): Beta = 0.05, Zeta = 0.001
Особенности: Низкий уровень шума, минимальный дрейф. Отличная фильтрация вибраций. Рекомендуется для научных измерений и систем позиционирования.
High Speed
Назначение: Быстрая реакция на резкие движения. Оптимален для динамичных систем (дроны, роботы, спортивные тренажёры).
Параметры (Mahony): Kp = 1.0, Ki = 0.01
Особенности: Минимальная задержка, высокая чувствительность. При быстрых вращениях может наблюдаться небольшой шум.
Low Noise
Назначение: Максимальное подавление шума и вибраций. Используется в условиях сильных помех.
Параметры (Madgwick): Beta = 0.2, Zeta = 0.0
Особенности: Очень плавные изменения углов. Не рекомендуется для быстрых манёвров — возможна заметная задержка.
Aggressive
Назначение: Экстремально быстрая реакция. Для систем с очень резкими движениями и мгновенной обратной связью.
Параметры (Mahony): Kp = 2.0, Ki = 0.0
Особенности: Максимальная чувствительность, минимальное сглаживание. Возможен повышенный уровень шума на неподвижном датчике.
Conservative
Назначение: Максимальная стабильность при минимальном движении. Для статических систем и долговременных наблюдений.
Параметры (Madgwick): Beta = 0.01, Zeta = 0.001
Особенности: Очень медленная реакция на изменения, но отличное подавление дрейфа. Идеален для мониторинга и систем с низкой динамикой.
- Для авиасимуляторов и игр — High Speed или Aggressive.
- Для стабилизации камеры — Low Noise или High Accuracy.
- Для робототехники — Default или High Speed.
- Для научных экспериментов — High Accuracy или Conservative.
Расширенная настройка
Изменение пинов I²C (ESP32)
В файле AHRS-avia.ino измените строки:
#define I2C_SDA 8
#define I2C_SCL 9
Настройка фильтров вручную
Помимо предустановленных профилей, вы можете задать индивидуальные параметры фильтрации через интерфейс:
- Madgwick: Beta (градиентный спуск, влияет на скорость сходимости) и Zeta (подавление дрейфа).
- Mahony: Kp (пропорциональный коэффициент, определяет скорость реакции) и Ki (интегральный коэффициент, влияет на подавление систематической ошибки).
Рекомендуемые диапазоны: Beta: 0.01–0.5, Kp: 0.1–3.0, Ki: 0.0–0.1.
Режимы производительности (на ESP32)
В прошивке доступны три режима, переключаемые по команде:
MODE_BALANCED # 100 Гц, DLPF 44 Гц (баланс скорости и качества)
MODE_HIGH_SPEED # 200 Гц, без DLPF (максимальная частота обновления)
MODE_HIGH_ACCURACY # 50 Гц, DLPF 5 Гц (минимальный шум)
Экспорт данных
Данные сохраняются в CSV с колонками: time, temp, gx, gy, gz, ax, ay, az, roll, pitch, yaw, q0, q1, q2, q3. Можно экспортировать текущий буфер или записывать непрерывно кнопкой «Начать запись».
Устранение неполадок
- Нет данных в Python: проверьте скорость порта (115200) и правильность пинов.
- Модель не загружается: установите
trimesh(pip install trimesh). - Авиагоризонт не обновляется: убедитесь, что подключение активно и приходят пакеты с углами.
- Сбой калибровки: положите датчик неподвижно и повторите.
Дальнейшее развитие
- Добавление поддержки магнитометра (HMC5883L) для абсолютного курса.
- Сохранение видео с 3D-сценой и авиагоризонтом.
- Поддержка нескольких датчиков (резервирование).
- Управление сервоприводами или дроном по данным AHRS.
Исходный код (фрагменты)
Arduino — обработка кватернионов (Mahony)
void MahonyFilter::update(float gx, float gy, float gz, float ax, float ay, float az, float dt) {
// ... нормализация акселерометра, вычисление ошибки,
// интегральная и пропорциональная составляющие,
// интегрирование кватерниона, нормализация
}
Python — круглый авиагоризонт (отрисовка)
def paintEvent(self, event):
painter = QPainter(self)
painter.setRenderHint(QPainter.Antialiasing)
# Создаём круглую область отсечения
path = QPainterPath()
path.addEllipse(center_x - radius, center_y - radius, size, size)
painter.setClipPath(path)
# Рисуем небо, землю, линию горизонта, шкалы, символ самолёта
...

