Симуляция и валидация¶
Прошивка валидируется автоматизированной SITL-кампанией: 48 полётов на прогон (3 конфигурации × 16 сценариев), кампания прогнана дважды (96 полётов, 96/96 OK). Весь полёт — без GPS с момента включения борта, полный операторский флоу.
Методика¶
Взлёт от коррекции. GPS отсутствует с включения; каждый полёт начинается полным операторским флоу:
SET_GPS_GLOBAL_ORIGIN → DO_SET_HOME → наземные CMD 43003 (точность 4 м — точка старта) → загрузка миссии → force-arm (magic 21196) → AUTO. На наборе высоты — bootstrap-фиксы каждые ~8 с.
Условия. Ветер симуляции 10 м/с с 120°, без турбулентности. «Авто-ветер» = обучение только по коррекциям 43003; «ручной ветер» = CMD 43004 с истинным ветром после взлёта.
Метрика дрейфа — средняя по окнам: ошибка позиции (оценка борта против истины симулятора SIMSTATE) к моменту очередной коррекции, делённая на длину окна (м/с). Для коаста — ошибка на 300-й/конечной секунде.
Конфигурации¶
| id | Эстиматор | Параметры поверх базового GPS-denied набора |
|---|---|---|
| dcm0 | DCM чистый (полётный сет) | AHRS_EKF_TYPE 0, EK3_ENABLE 0, EK3_WIND_ADR 0, AHRS_WIND_MAX 18, FS_EKF_FWINT 1, FS_EKF_FWHGT 30, FS_EKF_FWANG 30, AHRS_OPTIONS 0, EK3_OPTIONS 0 |
| dcm1 | DCM + EKF3 фоном | AHRS_EKF_TYPE 0, EK3_ENABLE 1, AHRS_WIND_MAX 18 |
| ekf3 | EKF3 активный | AHRS_EKF_TYPE 3, EK3_ENABLE 1, AHRS_WIND_MAX 18 |
Сценарии¶
- A. Основная матрица — траектории {прямые, зигзаг, кружение, смешанные (наборы/снижения + loiter)} × ветер {авто, ручной}, коррекции через случайные 30–180 с, 360 с. Каждый полёт включает обесточивание в воздухе (disarm → свежий 43003 → re-arm → продолжение миссии). Координаты коррекций идеальные (точность 5 м).
- A2. Матрица с неидеальными координатами — та же матрица, но клики оператора по карте имеют разброс 1σ≈20 м и заявленную точность param3 = 30 м (реальный профиль вылета; точка старта остаётся точной ~4 м), каденс 40–180 с.
- B. Коаст 6 минут — ручной ветер, 360 с без единой коррекции в воздухе, все 4 траектории.
- C. Спам коррекциями — идеальные координаты каждые 2–24 с, 240 с.
- D. Точность авто-ветра — снимается с loiter-полётов секции A (auto).
- E. Реалистичные фиксы — первая точка 4 м (старт), дальше клики оператора: σ=15 м, заявленная точность param3 = 30 м.
- F. Переключение ветра в воздухе — t=120 с: 43004 с намеренно неверным ветром (15 м/с @ 210°); t=240 с: 43004 с истинным; коррекции 90 с всё время.
- Задержка фикса (опции драйвера): честный timestamp (
fix_latency_s— клик по точке N секунд назад, param1 честный) и слепой режим (fix_latency_blind_s— param1=0, компенсация только черезAHRS_DR_FIXLAG). - Дубль фикса (
dup_fix) — ретрансмит того жеcommand_intчерез 1 с; борт обязан его игнорировать без деградации дрейфа.
Валидированные характеристики¶
Числа прогона №1; воспроизводимость двух прогонов — в таблице агрегатов ниже.
A. Основная матрица (коррекции 30–180 с, идеальные координаты)¶
| Конфигурация / ветер | Прямые | Зигзаг | Кружение | Смешанные | Re-arm в воздухе |
|---|---|---|---|---|---|
| dcm0 — авто | 0.69 м/с | 0.64 м/с | 0.67 м/с | 1.10 м/с | 4/4 OK |
| dcm1 — авто | 0.61 м/с | 0.71 м/с | 0.77 м/с | 1.06 м/с | 4/4 OK |
| ekf3 — авто | 0.84 м/с | 1.23 м/с | 1.41 м/с | 0.81 м/с | 4/4 OK |
| dcm0 — ручной | 1.05 м/с | 1.32 м/с | 0.55 м/с | 1.25 м/с | 4/4 OK |
| dcm1 — ручной | 0.82 м/с | 1.53 м/с | 0.59 м/с | 0.99 м/с | 4/4 OK |
| ekf3 — ручной | 0.48 м/с | 0.79 м/с | 0.64 м/с | 0.75 м/с | 4/4 OK |
A2. Матрица с неидеальными координатами (клики 20–50 м)¶
Точка старта точна (~4 м), последующие коррекции — клики оператора с разбросом 1σ≈20 м и заявленной точностью 30 м (param3 → вес измерения R). Это рабочий профиль реального вылета.
| Конфигурация / ветер | Прямые | Зигзаг | Кружение | Смешанные | Re-arm в воздухе |
|---|---|---|---|---|---|
| dcm0 — авто | 1.19 м/с | 1.39 м/с | 0.96 м/с | 1.07 м/с | 4/4 OK |
| dcm1 — авто | 1.22 м/с | 1.38 м/с | 0.90 м/с | 0.99 м/с | 4/4 OK |
| ekf3 — авто | 0.90 м/с | 1.17 м/с | 1.59 м/с | 0.76 м/с | 4/4 OK |
| dcm0 — ручной | 1.42 м/с | 1.67 м/с | 0.94 м/с | 1.15 м/с | 4/4 OK |
| dcm1 — ручной | 1.78 м/с | 2.12 м/с | 1.01 м/с | 1.11 м/с | 4/4 OK |
| ekf3 — ручной | 0.51 м/с | 0.81 м/с | 1.17 м/с | 0.81 м/с | 4/4 OK |
B. Коаст 6 минут без коррекций (ручной ветер)¶
| Конфигурация | Прямые | Зигзаг | Кружение | Смешанные | Средняя |
|---|---|---|---|---|---|
| dcm0 | 0.40 м/с | 0.29 м/с | 0.24 м/с | 0.06 м/с | 0.25 м/с |
| dcm1 | 0.73 м/с | 0.29 м/с | 0.60 м/с | 0.12 м/с | 0.43 м/с |
| ekf3 | 0.59 м/с | 0.25 м/с | 1.04 м/с | 0.81 м/с | 0.67 м/с |
C. Спам коррекциями (2–24 с)¶
| Конфигурация | Дрейф | Стабильность |
|---|---|---|
| dcm0 | 0.68 м/с | сохраняет курс |
| dcm1 | 0.69 м/с | сохраняет курс |
| ekf3 | 1.09 м/с | сохраняет курс; 1 событие смены активного решения |
D. Точность авто-вычисления ветра (loiter, истина 10 м/с @ 120°)¶
Снято в конце полёта (после воздушного re-arm).
| Конфигурация | Скорость | Направление | Векторная ошибка |
|---|---|---|---|
| dcm0 | 9.77 м/с | 118° | 0.37 м/с |
| dcm1 | 9.71 м/с | 118° | 0.48 м/с |
| ekf3 | 9.40 м/с | 122° | 0.65 м/с |
E. Реалистичные фиксы (σ=15 м, param3=30 м)¶
| Конфигурация | Кружение | Зигзаг |
|---|---|---|
| dcm0 | 0.90 м/с | 1.46 м/с |
| dcm1 | 0.85 м/с | 1.34 м/с |
| ekf3 | 1.80 м/с | 0.78 м/с |
F. Переключение ветра в воздухе (авто → намеренно неверный 43004 → верный 43004)¶
| Конфигурация | Пик ошибки ветра после неверного 43004 | Финальная ошибка ветра | Статус |
|---|---|---|---|
| dcm0 | 18.03 м/с | 0.18 м/с | PASS |
| dcm1 | 18.03 м/с | 0.00 м/с | PASS |
| ekf3 | 18.03 м/с | 0.11 м/с | PASS |
Критерий секции: борт принимает ручной ветер в воздухе мгновенно (пик ошибки = величина введённой неверной инъекции) и после верного 43004 + авто-коррекций возвращается к малой ошибке. На участке заведомо неверного ветра гейт выбросов DCM штатно отклоняет противоречащие ему фиксы (фильтр доверяет операторскому ветру), не теряя позицию.
Повторяемость (агрегаты, прогон №1 / №2)¶
| Метрика | dcm0 | dcm1 | ekf3 |
|---|---|---|---|
| A авто, среднее по траекториям | 0.78 / 0.73 | 0.79 / 0.88 | 1.07 / 0.91 |
| A ручной, среднее | 1.04 / 1.17 | 0.98 / 0.99 | 0.67 / 0.73 |
| B коаст, среднее | 0.25 / 0.42 | 0.43 / 0.41 | 0.67 / 0.63 |
| C спам | 0.68 / 0.67 | 0.69 / 0.72 | 1.09 / 0.92 |
| D ошибка ветра | 0.37 / 0.36 | 0.48 / 0.29 | 0.65 / 0.62 |
| F финальная ошибка ветра | 0.18 / 0.16 | 0.00 / 0.00 | 0.11 / 0.14 |
| Re-arm в воздухе | 8/8 OK | 8/8 OK | 8/8 OK |
Агрегаты воспроизводятся в полосе ±0.05–0.2 м/с. Наибольший межпрогонный разброс — в клетках с малым числом окон на полёт (n=2–3): B-коаст dcm0 на прямых (0.40 / 0.88), E-зигзаг ekf3 (0.78 / 1.21).
Компенсация задержки фикса
При задержке доставки фикса 3 с (честный timestamp в param1 либо верный AHRS_DR_FIXLAG в слепом режиме) дрейф остаётся в полосе 0.44–1.05 м/с. Некомпенсированная задержка такого размера даёт систематическую ошибку ~75 м на фикс при 25 м/с.
Как запускать¶
Требования: собранный build/sitl/bin/arduplane и pymavlink. Скрипты самодостаточны (сами поднимают и гасят SITL).
# Полная кампания: 48 полётов, результаты в ins8plus_runs/, отчёт в ins8plus.md
python3 Tools/scripts/ins8plus_campaign.py [--workers N] [--only id-substr] [--dry-run]
# Один полёт по JSON-спеке (id, ahrs dcm|ekf, wind_mode, mtype, scenario, dur, workdir;
# опции fix_latency_s / fix_latency_blind_s / dup_fix)
python3 Tools/scripts/ins8_flight.py '<json-spec>'
# Быстрая проверка DCM-фильтра ветра/K_tas: R из param3, χ²-гейт (выброс +500 м),
# 43004 посреди окна, сходимость по коаст-окнам
python3 Tools/scripts/dcm_windkf_validate.py
--dry-runпечатает все 48 спецификаций и собирает отчёт из фиктивных результатов — без SITL.--onlyфильтрует полёты по подстроке id (например--only dcm0_B).fix_latency_s— операторская задержка с честным timestamp;fix_latency_blind_s— та же задержка, но param1=0 (компенсация только черезAHRS_DR_FIXLAG; само наличие ключа включает слепой режим);dup_fix— ретрансмит каждого фикса через 1 с.
Особенности SITL-тестирования¶
- Глушить GPS целиком:
SIM_GPS1_ENABLE=0(+GPS1_TYPE=0).SIM_GPS1_NUMSATS=3снижает только число спутников, но не снимает 3D-fix — DCM при живом фиксе продолжает якорить позицию GPS-ом, и счисление фактически не тестируется (фиктивно малый дрейф). - Некалиброванный компас в SITL не воспроизводится: SITL форсит
COMPASS_SCALE=1, поэтому путь посева деклинации из origin (have_scale_factor()==false) проверяется только на железе. - Задержку оператора моделировать опциями драйвера (
fix_latency_s/fix_latency_blind_s): драйвер ведёт историюSIMSTATEи шлёт позицию N-секундной давности — вручную честный сценарий задержки не воспроизвести. - SITL подтверждает логику и точность счисления против истины симулятора; калибровки датчиков и реальная атмосфера проверяются на борту.