chore: rename repository to NODEDC MISSION CORE

This commit is contained in:
DCCONSTRUCTIONS
2026-07-16 12:10:05 +03:00
parent 8459bb03fb
commit 9225227421
50 changed files with 220 additions and 61 deletions
+256
View File
@@ -0,0 +1,256 @@
# NODEDC MISSION CORE · Control Station
Универсальный браузерный пункт управления Mission Core на React 19, TypeScript и
Vite. Приложение задаёт общую операторскую оболочку для аппаратов, сенсоров,
наблюдения, миссий и записей. XGRIDS/LixelKity K1 является первым реальным
device adapter, но структура интерфейса от него не зависит.
Внутри пространственной рабочей поверхности встроен открытый Rerun Web Viewer.
Это self-hosted frontend-компонент из npm-пакета `@rerun-io/web-viewer`, а не
переход во внешний облачный интерфейс. При запуске K1 live/replay backend сам
создаёт Rerun gRPC/proxy source; ручной адрес нужен только для другого Rerun
потока или совместимой RRD-записи.
## Текущее состояние
| Контур | Состояние | Что это означает |
| --- | --- | --- |
| Mission Core fixed shell | Реализован | Header, навигация по разделам, рабочая поверхность, окна и инспекторы работают в одном приложении. |
| Локальный control plane | Реализован | React получает состояние и выполняет операции через FastAPI REST и WebSocket на loopback. |
| K1 BLE → Wi-Fi | Реализован | Реальный BLE-поиск всех видимых устройств и одна подтверждённая provisioning-запись выбранному устройству. |
| K1 live/replay MQTT | Реализован | Read-only приём, raw-first сохранение, декодирование облака точек и позы, реальные метрики. |
| Автоматический MQTT → Rerun | Реализован | Первый live/replay поднимает process-wide `RecordingStream` и gRPC/proxy на TCP 9876; следующие сессии сбрасывают сцену и метрики и переиспользуют его. |
| Встроенный Rerun Viewer | Реализован | Self-hosted npm-компонент автоматически открывает текущий gRPC source внутри Control Station; внешний viewer не используется. |
| Контролы сцены → Rerun | Реализованы для текущей геометрии | Работают размер и видимость точек, атрибут цвета, палитра, окно накопления, траектория и сетка. Проекция, собственный timeline и сохранённые layout-профили ещё не подключены. |
| Legacy Foxglove module | Только regression | Модуль и тесты сохранены для сравнения декодирования. Текущий live/replay runtime не запускает Foxglove WebSocket и не использует TCP 8765. |
| Камеры, карты и миссии | Интерфейс готов | Серверная логика и реальные каналы для этих рабочих поверхностей ещё не подключены. |
Приложение не генерирует демонстрационное облако, траекторию, кадры или
метрики. Если реальных данных нет, область сцены остаётся пустой, а числовые поля
показывают `—`.
## Архитектура данных
```text
K1 MQTT :1883, read-only
└── raw .k1mqtt + metadata + SHA-256 сохраняются первыми
└── bounded latest-wins preview queue (32 сообщения)
└── проверенный protobuf/LZ4 decoder
└── Rerun Points3D + Transform3D + LineStrips3D
└── gRPC/proxy TCP 9876
└── rerun_grpc_url в REST/WebSocket state
└── встроенный @rerun-io/web-viewer
└── пространственная сцена Mission Core
Mission Core Control Station ←→ REST /api/* + WebSocket /api/events
FastAPI на 127.0.0.1:8000
CoreBluetooth + live/replay runtime
```
В момент готовности `RerunBridge` backend публикует адрес вида
`rerun+http://127.0.0.1:9876/proxy`. Frontend автоматически назначает его сцене,
если оператор не указал ручной source. После остановки приёма URL и встроенный
viewer остаются активны, а следующая сессия сбрасывает session-local геометрию,
траекторию и метрики и использует тот же listener. Он закрывается вместе с
процессом `k1link serve`.
Поля `foxglove_ws_url` и `foxglove_viewer_url` пока остаются в API как
совместимость со старым контрактом, но текущий runtime держит их пустыми.
## Фиксированная оболочка
Shell собран из локальных NODE.DC UI packages и сохраняет одну структуру для
всех функциональных модулей:
1. `AppHeader` — марка NODEDC MISSION CORE, выбор архитектурного раздела и состояние
локального backend.
2. `AdminNavigationPanel` — контекст аппарата и список рабочих поверхностей
выбранного раздела.
3. `LandingStage` — стартовая ситуационная поверхность и быстрые переходы.
4. `ApplicationPanel` — единый контейнер активной рабочей поверхности.
5. `Window` и `Inspector` — источник, отображение, слои и компоновка без
раскрытия внутренних панелей визуального движка.
Встроенный Rerun Viewer работает как canvas внутри этой оболочки. Его верхняя,
blueprint-, selection- и time-панели скрыты, чтобы продуктовые действия жили в
Control Station. Размер точек, способ окрашивания и палитра, 12-секундное по
умолчанию накопление, видимость облака и траектории и сетка связаны с backend и
Rerun Blueprint. Кнопки собственного timeline, смена 2D/3D/карты и сохранение
layout пока остаются интерфейсным контрактом.
## Архитектурные разделы
Навигация описана данными в `src/productModel.ts`, а не зашита в разметку каждой
страницы.
| Раздел | Назначение |
| --- | --- |
| Центр | Оперативный обзор, состояние контура и активность оператора. |
| Парк | Аппараты, текущее устройство, сенсоры и конфигурации борта. |
| Наблюдение | Пространственная сцена, камеры, карта, объекты, телеметрия и время. |
| Миссии | Планировщик, маршруты, сценарии и исполнение. Командный backend отключён. |
| Данные | Сессии, потоки, сущности, playback и экспорт доказательств. |
| Система | Модули, интеграции, сеть, аудит и настройки платформы. |
Карточки возможностей имеют четыре честных уровня: работает сейчас, готово к
источнику, интерфейсный контракт и последующий этап. Каталог не следует читать
как утверждение, что для каждой карточки уже существует backend.
## Установка, проверка, сборка и запуск
Требуются Node.js 20.19+ либо 22.12+, `uv` и соседний checkout
`NODEDC_DESIGN_GUIDELINE`: зависимости `@nodedc/*` подключены к нему через
локальные `file:` пути. Python устанавливается только в `.venv` репозитория.
Канонический путь от корня репозитория:
```bash
cd /Users/dcconstructions/Downloads/mnt/NODEDC/NODEDC_MISSION_CORE
uv sync --group dev
cd apps/control-station
npm install
npm run typecheck
npm run build
cd ../..
uv run k1link serve
```
Открыть `http://127.0.0.1:8000`. Команда `serve` отдаёт собранный `dist/` и
локальный API. Она намеренно привязана только к `127.0.0.1`; LAN bind не
предусмотрен, потому что endpoint подключения кратковременно принимает пароль
Wi-Fi.
Для разработки интерфейса после запуска backend:
```bash
cd apps/control-station
npm run dev
```
Vite слушает `http://127.0.0.1:5173` и проксирует `/api` и `/api/events` на
`http://127.0.0.1:8000`. Другой локальный backend можно указать переменной
`VITE_API_TARGET`. Preview production-сборки запускается командой
`npm run preview` на `http://127.0.0.1:4173`.
## Операторский путь для текущего K1 adapter
1. Запустить `uv run k1link serve` и открыть Mission Core Control Station.
2. Выбрать **Парк → Локальное устройство**.
3. Включить K1, дождаться стабильного индикатора и подтвердить это в форме.
4. Нажать **Показать все BLE-устройства**. Интерфейс показывает полный результат
шестисекундного поиска; метка совместимости является подсказкой, выбор делает
оператор.
5. Ввести SSID и пароль существующей сети и явно запустить подключение. Это одна
reviewed provisioning-запись без автоматических повторов.
6. Запустить live-приём по определённому адресу K1 либо replay локального
`.k1mqtt`/проверенного TSV. Физическое сканирование K1 запускается и
останавливается подтверждённым двойным нажатием кнопки устройства.
7. Backend автоматически поднимет Rerun gRPC на TCP 9876 и опубликует адрес в
state. Ручной source вводить не требуется.
8. Открыть **Наблюдение → Пространственная сцена**. Реальные облако и траектория,
частота, число точек, задержка и пропуски preview появятся после прихода
сообщений K1.
В проверочном live-сеансе через этот путь прошло 80 реальных MQTT-сообщений:
38 кадров `lio_pcl`, 42 кадра `lio_pose`, 2 775 точек в последнем облаке и
0 ошибок декодирования.
## Источники Rerun
Live/replay runtime автоматически назначает первый URL из примера. В
**Наблюдение → Пространственная сцена → Источник** можно оставить ручное поле
пустым либо указать другой адрес, который понимает `@rerun-io/web-viewer`
зафиксированной в `package.json` версии:
```text
rerun+http://127.0.0.1:9876/proxy
http://127.0.0.1:8080/recording.rrd
https://example.internal/recording.rrd
```
- `rerun+http://…/proxy` — живой Rerun gRPC source через доступный браузеру
proxy;
- `http(s)://…/recording.rrd` — RRD-запись по HTTP(S);
- версия RRD должна быть совместима с версией Web Viewer;
- ручной URL хранится только в состоянии текущей страницы и имеет приоритет над
автоматическим source;
- ошибка запуска показывается в viewport, без подстановки фиктивных данных.
После готовности Viewer выбор Rerun entity возвращает `entityPath` и имя view в
оболочку. Backend принимает и применяет к Rerun размер точки `0.5–12.0`, режимы
цвета `intensity`, `height`, `distance`, `rgb`, `class`, палитры Turbo, Viridis,
Plasma, grayscale и custom, накопление `0–120` секунд, а также видимость облака,
траектории и сетки. Значение по умолчанию — 12 секунд истории реальных кадров.
Для текущего firmware-3 `lio_pcl` доказана только интенсивность из младшего
байта `rgbi`; RGB используется лишь когда он действительно присутствует в
декодированном формате. Custom/class сейчас означает выбранный сплошной цвет,
а не готовую семантическую классификацию.
Custom timeline, переключатель 2D/3D/карты, семантические слои и сохранение RBL
пока не вызывают Blueprint/playback API. Черновик компоновки фиксируется только
в памяти текущей страницы и не записывается на диск.
## Контракт локального API
| Метод | Route | Тело / назначение |
| --- | --- | --- |
| `GET` | `/api/health` | Проверка локального сервиса. |
| `GET` | `/api/state` | Авторитетный snapshot состояния. |
| `POST` | `/api/ble/scan` | `{ "duration_seconds": 6 }`. |
| `POST` | `/api/connect` | `{ "device_id", "ssid", "password" }`. |
| `POST` | `/api/session/live` | Опционально `{ "host", "duration_seconds" }`. |
| `POST` | `/api/session/replay` | `{ "path", "speed", "loop" }`. |
| `POST` | `/api/session/stop` | Остановка активного источника. |
| `POST` | `/api/viewer/settings` | Размер/цвет точек, накопление, видимость облака, траектории и сетки. |
| `WS` | `/api/events` | Периодические snapshots для live UI. |
`/api/state` и изменяющие состояние ответы могут вернуть snapshot напрямую или
как `{ "state": { ... } }`. Текущие поля включают `phase`, `message`, `devices`,
`selected_device_id`, `k1_ip`, `source_mode`, `metrics`, `rerun_grpc_url` и
`viewer_settings`. Legacy-поля `foxglove_ws_url`/`foxglove_viewer_url` остаются
пустыми. OpenAPI доступен по `/api/docs`.
## Карта исходников frontend
| Файл | Ответственность |
| --- | --- |
| `src/App.tsx` | Fixed shell, выбор разделов и окна source/display/layers/layout. |
| `src/productModel.ts` | Архитектурные разделы, рабочие поверхности и уровни готовности. |
| `src/workspaces/DeviceWorkspace.tsx` | Реальный K1 BLE/Wi-Fi/live/replay adapter UI. |
| `src/workspaces/Workspaces.tsx` | Оперативный обзор, spatial viewport и остальные продуктовые поверхности. |
| `src/components/RerunViewport.tsx` | Жизненный цикл встроенного Rerun Web Viewer и selection events. |
| `src/api.ts` | REST/WebSocket контракт с FastAPI. |
| `src/useK1Console.ts` | Состояние backend, polling, события и действия оператора. |
| `src/sceneSettings.ts` | Типизированный UI-профиль пространственной сцены. |
| `src/presentation.ts` | Русские подписи фаз и форматирование реальных метрик. |
| `src/messages.ts` | Обезличивание и локализация технических сообщений в пользовательском интерфейсе. |
| `src/styles.css`, `src/styles/*` | Компоновка shell и рабочих поверхностей. |
## Safety и чувствительные данные
- Mission Core Control Station и credential endpoint доступны только на loopback.
- Исключение: Rerun gRPC/proxy на TCP 9876 сейчас слушает все сетевые интерфейсы,
хотя автоматически возвращаемый URL содержит `127.0.0.1`. На нём нет
connector-level authentication или TLS. Этот порт допустим только в доверенной
лабораторной LAN; его нельзя пробрасывать в публичный Интернет или cellular
WAN без аутентифицированного TLS reverse proxy. Listener намеренно остаётся
активным между сессиями; для его закрытия нужно остановить `k1link serve`.
- Пароль Wi-Fi находится только в React memory, передаётся в JSON POST body,
очищается после успешного ответа и не сохраняется в URL/local storage.
- BLE-подключение выполняет только отдельно рассмотренную provisioning-запись;
случайные GATT writes и автоматические повторы запрещены.
- MQTT live/replay не публикует команды устройству. Запуск и остановка
физического сканирования остаются за кнопкой K1.
- Live-сессии сначала сохраняют сырые сообщения, затем формируют preview. При
перегрузке preview может быть отброшен, raw evidence сохраняется.
- Timeline `capture_time` сохраняет Unix-время приёма сообщения Mac, а окно
накопления viewer использует session-local `stream_time`. `capture_time` — не
доказанный timestamp сенсора K1 и не photon-to-screen latency.
- Панорамный камерный поток в наблюдавшихся MQTT report topics отсутствует;
текущая Rerun-сцена содержит только облако точек и позу/траекторию, а
операционные метрики отображаются внешней оболочкой Mission Core.
- `sessions/` игнорируется Git и может содержать адреса, идентификаторы,
траекторию и карту помещения. В репозиторий попадают только redacted manifests
и безопасная документация.