# ВП06 — «Шахта без спутников»: инерциальный датчик, вариация Аллана и счисление (этапы 1–4)

[План реализации ВП06](https://gitlab.astersky.ru/science/learncourses/-/blob/main/ИТЛН/План_реализации_ВП06.md) · [Описание в каталоге ВП](https://gitlab.astersky.ru/science/learncourses/-/blob/main/ИТЛН/Виртуальные_практические_занятия_ИТЛН.md#vp-06) · [Лекция Л4](https://gitlab.astersky.ru/science/learncourses/-/blob/main/ИТЛН/Лекции/Л4_Инерциальная_корреляционно-экстремальная_и_комплексированная_навигация/Лекция_Л4_Инерциальная_корреляционно-экстремальная_и_комплексированная_навигация.md)

**Статус (27.10.2026):** выполнены этап 1 плана — чистая модель без графики и тесты в Node.js, этап 2 — [стенд «Лаборатория и шахта»](stand.html) на общем ядре ([ниже](#stand)) и этап 3 — [игровая лабораторная для студента](index.html): пять миссий, расчёты с проверкой, Python, протокол и отчёт ([ниже](#lesson)). Этап 4 — прогон всех 15 вариантов с отчётами — выполнен 27.10.2026 ([ниже](#check-all)); Firefox и Safari по решению пользователя не проверяются, учебный компьютер кафедры не проверялся.

## Состав

| Файл | Что делает |
|---|---|
| [`../../engine/imu.js`](../../engine/imu.js) | Общий модуль ядра (нужен и ВП07). Генератор оси датчика по (1)–(2) плана: белый шум $N$, нестабильность смещения $B$ — сумма 11 гауссовских марковских процессов с временами корреляции от 0,1 до $10^4$ с, блуждание смещения $K$, постоянное смещение и масштаб. Точная теоретическая вариация Аллана генератора по (3) и модель (4.2) Л4. Пересчёт °/√ч, °/ч, °/ч$^{3/2}$ в СИ |
| [`lab/model.js`](lab/model.js) | Оценка вариации Аллана с перекрытием (4); подбор модели (4.2) взвешенным МНК с перевзвешиванием по модели; оценки по асимптоте и по минимуму; калибровка на поворотном столе (5); маршрут и истинное движение в шахте; показания ДУС, акселерометра и колёс; счисление «только ИНС» и «колёса + ДУС» по (4.4)–(4.5); детектор остановки (4.10) с проверкой по ДУС и ZUPT; 15 вариантов, контрольные ответы, допуски |
| [`lab/model.test.mjs`](lab/model.test.mjs) | 28 тестов |
| [`../../engine/worlds/lab.js`](../../engine/worlds/lab.js) | Мир ядра «Лаборатория калибровки»: зал, поворотный стол с лимбом, люлька с блоком датчиков в шести положениях (оси X, Y, Z — красная, зелёная, синяя стрелки), часы и окна для ускоренной «ночи» |
| [`stand.html`](stand.html), [`lab/stand.js`](lab/stand.js) → `stand.bundle.js` | Стенд этапа 2 для преподавателя и разработчика |
| [`index.html`](index.html), [`lab.css`](lab.css), [`lab/game.js`](lab/game.js) → `lab.bundle.js` | Учебная лабораторная этапа 3: загрузка, титул, кампания, ход миссии, приборы, журнал, справочник, итоги. Общий стиль — `../vp03/lab.css` |
| [`lab/missions.js`](lab/missions.js) | Пять миссий: брифинг, теория, расчёт и обработка с допусками, сценарий опыта, разбор, контрольный вопрос |
| [`lab/worker.js`](lab/worker.js) → `worker.bundle.js` | Фоновый поток: генерация многочасовой записи и её обработка; без сервера — запасной путь порциями в основном потоке |
| [`lab/charts.js`](lab/charts.js), [`lab/math.js`](lab/math.js), [`lab/py.js`](lab/py.js), [`lab/report.js`](lab/report.js) | График Аллана в двойном логарифмическом масштабе; формулы занятия (перевод LaTeX → MathML — общий с ВП03); Python через Pyodide; отчёт HTML |
| [`lab/mine_route.json`](lab/mine_route.json) | Маршрут мира «Шахта» для тестов Node.js — снят со сцены; при изменении `engine/worlds/cave.js` снять заново (`vp06stand.engine.world.route`) |

## Запуск тестов

```
npm test
VP06_FULL=1 npm test
```

Обычный прогон ВП06 — около 8 с: 2 записи по 8 ч на вариант. Полный — около 45 с: 8 записей на вариант, проверка средних. Записи для проверки восстановления $N$, $B$, $K$ генерируются при 20 Гц: кривая Аллана на $\tau \ge$ 1 с от частоты не зависит, а время прогона падает в 5–10 раз. Варианты в учебной работе — 100 и 200 Гц.

## Результаты проверки 26.10.2026

Node.js 22.23, Apple M1 Pro. `npm test`: 52 теста, все проходят (ВП03 — 21, ВП06 — 21, ВП02 — 10). `VP06_FULL=1` для ВП06: 21 из 21.

- **Генератор против Л4.** При $N$ = 0,3 °/√ч, $B$ = 10 °/ч, $K$ = 65 °/ч$^{3/2}$ теоретический минимум девиации — 8,2 °/ч при $\tau \approx$ 27 с, как на рис. 4.6. Вклад нестабильности смещения ровный ±3 % на 2–1000 с. Оценка по 2-часовой записи совпадает с теорией в пределах статистического разброса.
- **Оценка по минимуму** $\sigma_{\min}/0{,}664$ даёт 12,3 °/ч вместо 10 °/ч — то же число, что в лекции.
- **Восстановление по 8-часовой записи**, 15 вариантов × 8 записей: $N$ — отклонение не более 7 %, $B$ — не более 17 %; смещение $K$ по 120 записям −2,5 %, относительное СКО одной оценки $K$ — 16,7 %. Поэтому ответ студента сверяется с подбором программы **по той же записи** (допуски $N$ 5 %, $B$ 10 %, $K$ 15 %), а истинные параметры показываются на разборе.
- **Короткая запись:** разброс $K$ по 0,5 ч более чем вдвое больше, чем по 8 ч.
- **Счисление.** Без шумов ошибки совпадают с (4.6): боковая ошибка от смещения ДУС — в пределах 3 %, ошибка от смещения акселерометра — 2 %; с точными поправками ошибка исчезает. Пример Л4 (18 м, 6°, 3,1 м за минуту) воспроизводится.
- **Детектор остановки** при 100 и 200 Гц находит больше 90 % остановок, на шероховатом полу срабатывает менее чем в 1 % отсчётов, на гладком равномерном участке — больше чем в 50 %: это учебное ложное срабатывание.
- **Детектор по одному акселерометру** принимает начало поворота на месте за остановку и портит оценку смещения ДУС; проверка по ДУС уменьшает ошибку курса более чем в 10 раз. **ZUPT** убирает смещение, но не масштаб: после поправки масштаба ошибка курса падает больше чем в 5 раз во всех вариантах, без неё остаётся $s \cdot 3\pi/2$.
- **Скорость:** 8 ч при 100 Гц (2,88 млн отсчётов) — генерация и кривая из 48 точек за 2,0 с.

## Что изменено против плана

- Нестабильность смещения — 11 марковских процессов от 0,1 с вместо 9 от 1 с: при малом $N$ подбор занижал $N$ на 12 %.
- Подбор модели — с перевзвешиванием по подобранной кривой: веса по шумной оценке смещали $K$ вниз.
- Варианты пересчитаны: $\tau_K$ — пересечение асимптот нестабильности и блуждания — от 60 до 250 с, а не до 400 с.
- Детектор остановки дополнен проверкой по ДУС ($\omega_{\max}$).

Это проверка модели, а не учебной программы: сцена, интерфейс и миссии — этапы 2–3 плана.

<a id="stand"></a>
## Этап 2: стенд «Лаборатория и шахта» — 26.10.2026

[Открыть стенд](stand.html) (через веб-сервер: `npm run serve`). Модель считает с фиксированным шагом $1/f_s$, ускорение ×1–×10 меняет только число шагов за кадр.

- **Лаборатория.** Вращение стола $\pm\Omega$ (30, 45, 60 °/с), шесть положений люльки с плавной перестановкой; среднее за 1 с показаний гироскопа по оси $z$ и акселерометра по оси $x$ — отсчёты перестановки в среднее не идут. «Ночь на столе»: запись 0,5, 2 или 8 ч при 100 Гц порциями, в сцене темнеют окна и идут часы; затем кривая Аллана, подбор (4.2) и сравнение с истинными параметрами.
- **Шахта.** Мир «Шахта» без перепада высот и второго робота; движение по маршруту штрека с тремя остановками, разворотом на месте на 360° и гладким участком; три счисления одновременно — «только ИНС», «колёса + ДУС», «калибровка + ZUPT» — линиями цветов темы и таблицей ошибок. Флажки: проверка остановки по ДУС и по колёсам.

**Проверка в Chrome 26.10.2026** (встроенный браузер, M1 Pro; учебный компьютер не проверялся): ошибок в консоли нет; 60 кадров/с в обеих сценах при ×10; во время 8-часовой записи — 29 кадров/с, запись и кривая — 1,9 с, подбор варианта 1: $N$ = 0,099, $B$ = 6,95, $K$ = 44,3 при истинных 0,10, 7, 40. Показания стола сверены с моделью: при $+45$ °/с гироскоп даёт 45,52 °/с ($45 \cdot 1{,}01 + 0{,}08$), в положении «X вверх» акселерометр — 9,932 м/с². Шахта, вариант 1, 143 м за 260 с: «только ИНС» — 148 м и 22°, «колёса + ДУС» — 14,4 м и 22°, «калибровка + ZUPT» — 0,48 м и 0,55°. Светлая и тёмная темы, ширина 390 px без горизонтальной прокрутки.

**Найдено и исправлено на этапе 2:**

- Детектор остановки отстаёт от трогания на длину окна: первые отсчёты движения попадали в оценку смещения ДУС (после разворота смещение 0,14 °/с вместо 0,08). Теперь проверка по ДУС — по всему окну, а смещение усредняется по самому старому отсчёту окна.
- На гладком полу детектор по акселерометру принимает движение по изгибу штрека за остановку и портит смещение ДУС. Добавлена проверка по колёсам ($v_{\max}$) — учебный опыт миссии 5.
- Маршрут с одной остановкой зацикливался на ней; после остановки робот теперь отъезжает 0,5 м, прежде чем остановка может сработать снова.
- Запись в основном потоке страницы снижает частоту кадров до 29 во время генерации; фоновый поток (`worker.js` плана) — на этапе 3.

<a id="lesson"></a>
## Этап 3: учебная лабораторная — 26.10.2026

[Открыть лабораторную](index.html) (через веб-сервер). Устройство — как у ВП03: экран загрузки, титул (вариант 1–15, фамилия и группа), карта кампании, миссии по порядку, итоги и отчёт HTML и JSON. Этапы миссии: брифинг → теория → расчёт (до опыта) → опыт → обработка (по данным опыта) → код → разбор. Прогресс — в `localStorage` браузера. Настройки сервера — `window.VP06_CONFIG` в `index.html`: адрес Pyodide и адрес приёма отчёта.

| Миссия | Мир | Что делает студент | Проверка программой |
|---|---|---|---|
| 1. Ночь на столе | Лаборатория | Записывает неподвижный гироскоп 0,5, 2 или 8 ч; по точкам кривой Аллана находит $N$; рассчитывает СКО отсчёта и СКО среднего от белого шума; видит, что средние половин записи расходятся в сотни раз сильнее | $N$ — 5 % от подбора по той же записи; $\sigma_y$, $\sigma_{\bar y}$ — 6 %; звезда — запись не короче 2 ч |
| 2. Паспорт датчика | Лаборатория | Запись 8 ч; $N$, $B$, $K$ по асимптотам или своей моделью (4.2) ползунками; оценка $\sigma_{\min}/0{,}664$; функция `allan(omega, fs, m)` на Python | $N$, $B$, $K$ — 5, 10, 15 % от подбора по той же записи; функция — на скрытой записи 30 мин при 50 Гц, отличие не больше $10^{-6}$; на разборе — оценки по 0,5, 2 и 8 ч той же записи и истинные |
| 3. Поворотный стол | Лаборатория | По своему $N$ рассчитывает время в положении для 0,001 °/с; снимает средние при $+\Omega$, $-\Omega$, «X вверх», «X вниз»; находит $b_\omega$, $s_\omega$, $b_a$, $s_a$ по (5) | Поля — по показанным средним; поправки против истинных — в пределах 3σ достижимой точности (белый шум, среднее марковских процессов за окно, блуждание за опыт) |
| 4. Шахта без GPS | Шахта | По своим поправкам предсказывает через 60 с ошибку курса $b_\omega t + s_\omega\Delta\psi$, боковую ошибку и ошибку «только ИНС»; едет в трёх режимах | Прогноз — 3 % от расчёта по его данным; совпадение курса с опытом — 20 % (не меньше 0,3°) |
| 5. Остановки | Шахта | Рассчитывает $\sigma_a$ и порог $\gamma$; блок включён заново — смещение ДУС изменилось; едет круг без проверок и с проверками по ДУС и колёсам; размечает срабатывания детектора «стоял / двигался» | $\gamma$ — 5 %; разметка — против истинного движения в отсчётах, попавших в среднее; цель — возврат к лифту точнее 2 м с обеими проверками |

**Оценивание** — 4 балла, как в плане: расчёт и паспорт датчика (все поля и функция Python), протокол (все опыты), совпадение прогноза и опыта (миссии 3–5) ставит программа; выводы и защиту — преподаватель. Звёзды миссии: расчёт без лишних ошибок, цель опыта, контрольный вопрос; порядок ответов вопроса свой для каждого варианта.

**Что добавлено в модель** (`model.js`, раздел «Миссии учебной части»): обработка записи для интерфейса, чтение асимптот по точке, время в положении, поправки и допуски стола, опыт на столе без сцены, прогноз миссии 4 с членом масштаба, заезд миссий 4 и 5 по шагам, порог детектора, изменение смещения после повторного включения (`restartDegS`, 0,0125–0,0195 °/с), журнал срабатываний детектора.

**Тесты этапа 3** (4 новых, в `npm test`): $N$ по точке $\tau \approx$ 0,1 с — в 5 % от подбора во всех вариантах; поправки стола — в допуске не реже 97 % опытов (90 опытов); прогноз курса миссии 4 — в 20 % во всех вариантах на двух seed; миссия 5 — с обеими проверками возврат точнее 2 м и ни одного ложного срабатывания во всех вариантах, без любой из проверок цель не достигается не реже 90 % заездов, а ложное срабатывание нужного вида есть всегда.

**Проверка в Chrome 26.10.2026** (встроенный браузер, M1 Pro; учебный компьютер, Firefox и Safari не проверялись):

- Полный сценарий пройден на вариантах 1 и 15, на варианте 8 — по журналу браузера: все миссии, предварительная оценка 3 из 3. Ошибочные ответы отклоняются, после двух попыток появляется подсказка; неверный ответ на контрольный вопрос снимает звезду.
- Запись 8 ч при 100 Гц в фоновом потоке — 1,6 с при 58 кадрах/с; «ночь» в сцене длится не меньше 4 с. Функция Python: заготовка не проходит (отличие 1,0), верное решение срезами NumPy — отличие $3 \cdot 10^{-12}$ за 22 мс.
- Вариант 1: стол при $+30$ °/с — 30,3752 °/с ($30 \cdot 1{,}01 + 0{,}08$); поправки в допуске. Шахта за 60 с: прогноз курса 4,00°, опыт 4,10°; «только ИНС» — 17,2 м, «колёса + ДУС» с поправками — 0,10 м. Круг без проверки по ДУС: ложные срабатывания на развороте и на гладком участке, возврат 106 м; с обеими проверками — 0,38 м.
- Отчёт HTML: 53 формулы MathML, команд LaTeX и знаков `$` в тексте нет. Обход всех этапов и карточек теории — необработанной разметки на экране нет.
- 1440 и 390 px, светлая и тёмная темы; на 390 px без горизонтальной прокрутки и наложения панелей.

**Найдено и исправлено при проверке:** номер правильного ответа совпадал во всех вопросах — порядок теперь свой для варианта; «ночь» в сцене мелькала за 0,6 с — показ догоняет расчёт не быстрее 4 с; без повторного включения датчика ZUPT в миссии 5 почти не выигрывал у поправок со стола, отсюда изменение смещения после включения; детектор считал ложными остановки с медленным троганием — ложным считается только отсчёт движения, попавший в среднее смещения.

<a id="check-all"></a>
## Этап 4: прогон всех вариантов — 27.10.2026

Сценарий [`lab/autorun.js`](lab/autorun.js) подключается к открытой лабораторной и проходит кампанию так, как её прошёл бы студент по данным на экране. В каждое поле сначала вводит заведомо неверное значение и проверяет, что оно отклонено, затем — верное. Отвечает на контрольные вопросы, пишет функцию Python, выполняет все опыты, формирует отчёт. В учебную страницу сценарий не входит; для него в `window.vp06` добавлены `report()` и `resetProgress()`. Отчёты HTML и JSON всех вариантов и сводка — в [`docs/проверка_ВП06/`](../../../docs/проверка_ВП06/).

**Прогон 27.10.2026** — Chrome (встроенный браузер), M1 Pro, 15 вариантов подряд на одной странице, ускорение ×20:

| Вариант | Курс за 60 с, прогноз / опыт, ° | Возврат к лифту, м: без проверок / с обеими | Запись 8 ч, с | Прогон, с |
|---|---|---|---|---|
| 1 | 4,03 / 4,10 | 106 / 0,38 | 1,7 | 66 |
| 2 | 7,64 / 8,04 | 102 / 0,71 | 3,1 | 61 |
| 3 | −7,25 / −7,39 | 55 / 0,40 | 1,5 | 59 |
| 4 | 13,20 / 13,37 | 82 / 0,44 | 3,0 | 56 |
| 5 | −9,22 / −9,85 | 81 / 0,50 | 1,7 | 56 |
| 6 | 1,81 / 1,69 | 50 / 0,85 | 2,8 | 67 |
| 7 | −14,13 / −13,90 | 103 / 0,21 | 1,4 | 66 |
| 8 | 9,67 / 9,94 | 68 / 0,69 | 3,1 | 64 |
| 9 | −2,76 / −3,13 | 58 / 0,82 | 1,5 | 65 |
| 10 | 12,29 / 12,09 | 42 / 0,38 | 2,9 | 62 |
| 11 | −11,00 / −10,83 | 79 / 0,26 | 1,5 | 79 |
| 12 | 4,56 / 4,64 | 56 / 0,85 | 3,5 | 77 |
| 13 | −5,94 / −6,40 | 103 / 0,82 | 1,5 | 81 |
| 14 | 7,99 / 7,98 | 50 / 0,45 | 3,4 | 86 |
| 15 | −9,58 / −9,84 | 63 / 0,24 | 1,9 | 93 |

Во всех 15 вариантах: предварительная оценка программы 3 из 3; все 17 неверных значений отклонены, верные приняты; функция Python прошла проверку (отличие около $3 \cdot 10^{-12}$); курс миссии 4 совпал с опытом в пределах 20 % (наибольшее расхождение — вариант 9, 12 %); в миссии 5 найдены ложные срабатывания обоих видов — на развороте и на гладком участке; отчёт HTML — 53–55 формул MathML, команд LaTeX в тексте нет. Запись 8 ч: 1,4–1,9 с при 100 Гц и 2,8–3,5 с при 200 Гц.

**Найдено при прогоне:** ошибка самого сценария — прогресс прошлого прохода оставался в памяти страницы, и миссии открывались сразу на разборе; добавлен `resetProgress()`. Ошибок лабораторной не найдено.

**Не проверялось:** Firefox и Safari — по решению пользователя от 27.10.2026 проверка в них не проводится; учебный компьютер кафедры.
