From 5ba19cde4674ed33ff989da199c78b3ba24eb303 Mon Sep 17 00:00:00 2001 From: Alexander Date: Mon, 22 Jun 2026 15:30:08 +0300 Subject: [PATCH] =?UTF-8?q?docs(domain=20K):=20v2=20=D0=BF=D0=BE=D1=81?= =?UTF-8?q?=D0=BB=D0=B5=20adversarial-=D1=80=D0=B5=D0=B2=D1=8C=D1=8E=20(18?= =?UTF-8?q?=20=D0=BD=D0=B0=D1=85=D0=BE=D0=B4=D0=BE=D0=BA)=20+=20=D0=BA?= =?UTF-8?q?=D1=80=D0=BE=D1=81=D1=81-=D0=B4=D0=BE=D0=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - GPS-скорость: zero-clamp <~2-3 км/ч (на стоянке Doppler-шум, не ноль) — distraction v1 получал бы ложный on; FixQuality многоуровневый (no_fix/2d/3d/augmented/dead_reckoning + HDOP/sats); dead_reckoning не валиден для distraction/Nav; валидность времени ≠ позиции - приватность локации: эфемерна (без трека в v1), audit-log, исключена из LLM-промпта, while-in-use грант, on-device - антенна (внешняя/активная), TTFF cold/warm-start, окно без GPS на старте поездки; питание GPS в sleep/battery-cutoff (обесточивание+cold-start по умолчанию) - резистивная ADC-лесенка руля: контракт window-table + кондиционирование + collision-drop + темп-дрейф; транспорт ввода = uinput/evdev (не Shell-D-Bus, иначе surface-апы не покрыты); гейтинг руль-действий в distraction - IMU опционален/не гарантирован → dashcam (J) = непрерывный ring-buffer, не на g-sensor - точность времени SHM (~десятки-сотни мс), PPS опц./hardware-gated; Nav «фаза 2»→v4 - кросс-док: a-base §7/§14 (SHM, split time-row + K-dep), hardware §4 (антенна/1PPS), domains/README (K-cell без TPMS/климата), ipc Location (enum), c-shell §7/§9/§11 (clamped speed, uinput-ввод, закрыт Location-вопрос) Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/contracts/hardware.md | 2 +- docs/contracts/ipc.md | 4 +- docs/domains/README.md | 2 +- docs/domains/a-base-system.md | 8 +- docs/domains/c-shell-ux.md | 11 +- docs/domains/k-sensors-peripherals.md | 161 ++++++++++++++++++++++++++ 6 files changed, 177 insertions(+), 11 deletions(-) create mode 100644 docs/domains/k-sensors-peripherals.md diff --git a/docs/contracts/hardware.md b/docs/contracts/hardware.md index 193bc19..cb3527d 100644 --- a/docs/contracts/hardware.md +++ b/docs/contracts/hardware.md @@ -81,7 +81,7 @@ fail-safe при отказе/зависании самого MCU** (незав |------|-------|--------------| | **Дисплей** | HDMI + USB-тачскрин | MIPI-DSI / LVDS панель | | **CAN/OBD** | ELM327 (USB/BT) | нативный CAN-трансивер → **SocketCAN** | -| **GPS** | USB/UART, NMEA | — | +| **GPS** | USB/UART, NMEA | **внешняя/активная антенна** (LNA); 1PPS — опц. (PPS-точность времени; на USB-донглах обычно нет) | | **Связь** | USB-модем (ModemManager) / Wi-Fi | — | | **Аудио** | I2S codec + усилитель | — | | **Микрофон** | USB **mic-массив** (wake-word, шумоподавление) | — | diff --git a/docs/contracts/ipc.md b/docs/contracts/ipc.md index 13eae67..129b700 100644 --- a/docs/contracts/ipc.md +++ b/docs/contracts/ipc.md @@ -83,9 +83,9 @@ - **Properties:** `Online` (bool — «сервис ещё не поднят» ≠ «offline»), `Type` (wifi/modem), `SignalStrength`. ### `ru.shturman.Location` — GPS/положение (владелец — домен K) -- **Properties:** `Latitude`, `Longitude`, `Heading`, `Speed` (GPS-скорость), `FixQuality`, `ts`. +- **Properties:** `Latitude`, `Longitude`, `Heading`, `Speed`, `FixQuality` (enum `no_fix`/`fix_2d`/`fix_3d`/`augmented`/`dead_reckoning`), `HDOP`, `satellites`, `ts`; per-property quality для `Speed`/`Heading` (зануление у нуля — domain K §2). - **Сигналы:** `LocationChanged(...)`, `FixChanged(quality)`. -- Источник — NMEA/gpsd (hardware §4); гейтится capability `location`. **GPS-скорость берётся ОТСЮДА** (не из VehicleData/E — E это CAN/OBD, появляется в v2). До домена K — мок-стаб (dev fake-GPS). +- Источник — NMEA/gpsd (hardware §4); гейтится capability `location`. **GPS-скорость — ОТСЮДА** (не из VehicleData/E). До домена K — мок-стаб (dev fake-GPS). --- diff --git a/docs/domains/README.md b/docs/domains/README.md index 2dce8c1..4067d10 100644 --- a/docs/domains/README.md +++ b/docs/domains/README.md @@ -27,7 +27,7 @@ | H | Медиа / аудио | `h-media-audio.md` | **вся стандартная мультимедиа**: локальное аудио, BT A2DP/AVRCP, радио, стриминг | | I | Навигация | `i-navigation.md` | офлайн-карты OSM, роутинг, POI, связка с ассистентом | | J | Камеры / видео | `j-cameras-video.md` | задняя камера, парктроник-оверлей, dashcam | -| K | Датчики / периферия | `k-sensors-peripherals.md` | GPS, IMU, кнопки руля (чтение), TPMS, климат-дисплей (чтение) | +| K | Датчики / периферия | `k-sensors-peripherals.md` | GPS/Location, IMU; кнопки руля — резистивная ADC-лесенка (CAN-кнопки/TPMS/климат/парктроник на CAN — у E); выделенные не-CAN датчики | | L | Облако / компаньон | `l-cloud-companion.md` | мобильное приложение, синхронизация, бэкап, OTA-канал, телеметрия (opt-in) | > Порядок наполнения определим в [roadmap.md](../roadmap.md); технически — после контрактов. diff --git a/docs/domains/a-base-system.md b/docs/domains/a-base-system.md index ff7acf7..d6ec62c 100644 --- a/docs/domains/a-base-system.md +++ b/docs/domains/a-base-system.md @@ -123,8 +123,9 @@ - Battery-RTC как требование reference-платы (hardware) — либо явный no-RTC план. - Онлайн-синк: `systemd-timesyncd` (легче) / chrony. -- **GPS как offline-first источник UTC** (NMEA `$GPRMC/$GPZDA` → gpsd → chrony SHM/PPS) — - основной фолбэк без сети (принцип #3). +- **GPS как offline-first источник UTC** (NMEA → gpsd → chrony **SHM**, ~десятки–сотни мс; PPS µs — + опц., hardware-зависим, см. k-sensors §2) — основной фолбэк без сети (#3). Время может быть валидно + без позиционного фикса (k-sensors §2). - **Персист last-known-time в `/data`** (`fake-hwclock`) — **периодически + на синке + на graceful shutdown** (владение → домен B §8), чтобы холодный boot/резкий обрыв не откатывали часы к 1970. - **Boot-политика:** до любого TLS-egress к LLM часы должны быть «вменяемыми» (gated). @@ -196,7 +197,8 @@ reference-таргет — first-party**, остальное — порты. | Быстрый boot (Stage 0/1/2, < 10 c) | **MVP** | architecture §6 | v0 | | Splash (Stage 0) | **MVP** | — | v0 | | First-boot provisioning (`/data` init, machine-id) | **MVP (день 1)** | — | v0 | -| **Время** (NTP + GPS-fallback + fake-hwclock) | **MVP** | hardware(GPS), B | v0/v1 | +| Время: NTP (timesyncd) + fake-hwclock персист | **MVP** | B | v0 | +| Время: GPS как offline-first UTC (NMEA→gpsd→chrony) | **MVP** | hardware(GPS), **K** | v1 | | **Память** (zram + OOM + cgroup-лимиты) | **MVP (день 1)** | — | v0 | | **Логирование** (journald volatile + критичное в `/data` + pstore) | **MVP (день 1)** | — | v0 | | eMMC write-minimization | **MVP (день 1)** | — | v0 | diff --git a/docs/domains/c-shell-ux.md b/docs/domains/c-shell-ux.md index e75f7bd..167365d 100644 --- a/docs/domains/c-shell-ux.md +++ b/docs/domains/c-shell-ux.md @@ -86,7 +86,8 @@ Shell** (его пробрасывает bubblewrap при `ui_*`, security-priv - Выше порога скорости → **упрощённый UI**, приоритет голосу, блокировка сложных взаимодействий. - **Источник скорости:** **GPS (домен K, `ru.shturman.Location`) уже в v1** (раньше OBD), - уточняется OBD-скоростью (E) в v2. + уточняется OBD-скоростью (E) в v2. C потребляет **занулённую/quality-флагнутую `Speed`** от K §2 + (не сырой Doppler-шум на стоянке) — это source-level фикс, ортогональный гистерезису ниже. - **Fail-safe при неизвестной/устаревшей скорости** (тоннель/нет фикса GPS, stale OBD — #3): гейт по умолчанию в **консервативное состояние** (к безопасности), таймаут staleness + видимая пометка «скорость неизвестна». @@ -101,8 +102,9 @@ Shell** (его пробрасывает bubblewrap при `ui_*`, security-priv ## 9. Ввод -- Тач + **мультируль** (кнопки руля, чтение из K/E) → навигация по UI без касания - (важно для distraction). +- Тач + **мультируль**: K нормализует кнопки (ADC-лесенка / проксированные CAN из E) в **uinput** → + композитор Shell маршрутизирует их фокусом (штатный Wayland-input), не «Shell сам потребляет». + Навигация по UI без касания; часть руль-действий сама гейтится distraction-режимом (K §3). ## 10. Зависимости @@ -119,7 +121,8 @@ Shell** (его пробрасывает bubblewrap при `ui_*`, security-priv - ◻️ **UI управления разрешениями** (review/revoke) — из security-privacy. → этот домен + Settings. - ◻️ **Источник день/ночь** (v0 время; **GPS-восход v1**; датчик освещённости / сигнал машины — later). → реализация + домен K. - ◻️ **Мультидисплей, профили** — later. -- ◻️ **Контракт Location/GPS (домен K)** — distraction v1 и день/ночь-восход гейтятся им; до K — мок-стаб (ipc `Location`). +- ✅ **Контракт Location/GPS** — в [k-sensors §2](k-sensors-peripherals.md) (QoS, FixQuality, zero-clamp скорости у нуля; C потребляет занулённую `Speed`). Арбитраж GPS-vs-OBD (v2) — открыт. +- ◻️ **Какие руль-действия гейтятся в distraction** — парный с K §10. - 🟡 **Slot-протокол поверхностей** (`ru.shturman.shell_slot`: surface→слот, slot-token, peer-creds) — спроектировать (§4). --- diff --git a/docs/domains/k-sensors-peripherals.md b/docs/domains/k-sensors-peripherals.md new file mode 100644 index 0000000..6f44dea --- /dev/null +++ b/docs/domains/k-sensors-peripherals.md @@ -0,0 +1,161 @@ +# Домен K — Датчики / периферия + +> Не-CAN сенсоры и периферия **самого устройства**: GPS (→ сервис `Location`), +> IMU, выделенные ADC/GPIO-входы (резистивный руль), USB-сенсоры. Содержит +> `ru.shturman.Location`, на который ссылаются C (distraction, день/ночь), D, a-base §7 (GPS-время). + +Статус: **v2 (на ревью).** v2 — после adversarial-ревью (18 находок). +Связано с: [hardware.md](../contracts/hardware.md) (§4 GPS/периферия) · [ipc.md](../contracts/ipc.md) (`Location`) · [security-privacy.md](../contracts/security-privacy.md) (`location`, приватность) · [a-base-system.md](a-base-system.md) (§7 GPS-время) · домены C (ввод/distraction/тема), D, E (CAN-граница), J (камеры) + +--- + +## 1. Назначение и границы + +- **Что делает:** интегрирует **не-vehicle-bus** сенсоры и периферию устройства: + **GPS** (→ `Location`), IMU/акселерометр, выделенные ADC/GPIO-входы, специфичные USB-сенсоры. +- **Граница с E (важно):** **K не трогает CAN** — единственный владелец CAN — E (red-line, #2). + Сигналы с шины авто (кнопки руля на CAN, парктроники, TPMS, климат) — **сигналы E/data-model**, не K. +- **Граница с A:** udev/USB-стек — база (A); K — прикладная интеграция конкретных сенсоров. + +## 2. `ru.shturman.Location` — GPS / положение (главный артефакт K) + +- **Источник:** GPS-приёмник (USB/UART, NMEA) → `gpsd` → сервис (hardware §4). +- **Публикует** (ipc §3): `Latitude`, `Longitude`, `Heading`, `Speed`, `FixQuality`, `HDOP`, + `satellites`, `ts`; сигналы `LocationChanged`, `FixChanged`. Гейтится capability `location`. + +**FixQuality — многоуровневый** (не бинарный): enum `{no_fix, fix_2d, fix_3d, augmented (DGPS/SBAS), +dead_reckoning}` + `HDOP`/`satellites` как метрики достоверности при валидном фиксе. Инварианты: +`dead_reckoning` НЕ считается валидным для distraction/Nav (экстраполяция); высокий HDOP = +большая ошибка. **Валидность времени отделена от валидности позиции** (RMC/ZDA UTC может быть +валиден без позиционного фикса — для a-base §7). Точный маппинг NMEA — сверяется при реализации. + +**Скорость/курс на малой скорости (контракт):** ниже порога уверенности (~2–3 км/ч, +BSP-tunable) Location **зануляет `Speed`** (не сырой Doppler-шум) и помечает `Heading` невалидным. +Это **source-level** фикс (ортогонален гистерезису distraction в C §7): убирает систематический +дрейф на стоянке, который иначе держал бы ложный distraction-on. C потребляет **занулённую/ +quality-флагнутую** `Speed`, не сырую. + +**QoS:** типовая частота NMEA ~1 Гц (выше — зависит от приёмника); латентный бюджет +fix→`LocationChanged`→потребитель. Ненадёжность у нуля и в urban-canyon — вход для гистерезиса/ +fail-safe C §7. До поднятия K — **мок-стаб** (dev fake-GPS). + +**Приём, старт, антенна:** +- **Внешняя/активная антенна** на reference-плате (встроенная в торпедо часто не видит небо) → hardware §4. +- **TTFF:** cold-start (потеря эфемерид) — десятки секунд; warm/hot — быстрее. После + `battery-cutoff` (B §7, долгая стоянка) поездка может стартовать с **окна без GPS** — потребители + деградируют штатно (C §7 консервативный distraction; a-base §7 нет GPS-времени до первого fix). +- **Питание в sleep/battery-cutoff:** по умолчанию GPS **обесточивается** (приоритет энергии на + запуск, #5; ценой cold-start на wake), keep-alive рейл — только если сценарий wake требует фикса + сразу. Селективный рейл — hardware §3; бюджет разряда — B §7/§12. +- **Boot:** Location/gpsd поднимаются в **Stage 2** (фоном, architecture §6); ранняя поездка до + фикса — деградированный режим. Подписки авто-снимаются по `NameOwnerChanged` (ipc §2). + +**Точность времени:** по NMEA-via-gpsd-SHM — **десятки–сотни мс** (достаточно для TLS-гейта +a-base §7 и упорядочивания логов). **PPS (µs)** — опционально, требует приёмник с 1PPS + линию на +GPIO/UART-DCD (hardware §4); на USB-донгле обычно нет. По умолчанию — SHM-класс. + +**Приватность локации:** по умолчанию **эфемерна** — live-позиция на шине, **без персистентного +трека** (в v1 нет фичи, требующей хранения; Nav — v4). Если позже понадобится (last-parked/ +trip-log) — только **fscrypt-поддерево** `/data` (a-base §3), с retention и factory-reset-wipe +(a-base §12). Доступ к локации — в **audit-log** (security-privacy ✅); точная локация **исключена +из онлайн-LLM-промпта** по умолчанию (только по отдельному гранту, security-privacy §7); +`location`-грант — **while-in-use** (revoke при уходе в фон). First-party-потребители (C, a-base) — +строго **on-device**, наружу не уходит. + +**Dev-симулятор Location** (#13): обязательные сценарии — реплей NMEA-трека, no-fix/тоннель/потеря, +дрейф, cold-start TTFF, время-без-позиции, низкоскоростной джиттер у нуля, расхождение GPS-vs-OBD +(для арбитража C §7 v2). Детали — dev-environment. + +## 3. Мультируль (кнопки руля) — двойной источник + +- **CAN-кнопки** (современные авто): читаются как **сигналы E** (через VehicleData), не K. +- **Резистивная ADC-лесенка** (старые авто): **K** оцифровывает → нормализует в события. + +**Контракт ADC-лесенки** (самая хрупкая часть — не одна строка): +- **Window-table, не точечные пороги:** BSP даёт на кнопку окно `[min,max]` + гистерезис (учитывая + резисторы авто И наш делитель/Vref/pull-up). Статические per-vehicle данные, аналог DBC (hardware §5). +- **Рантайм-кондиционирование:** debounce + median/avg-фильтр + отбрасывание транзиентных уровней + при нажатии/отпускании (release-through-adjacent не даёт фантомных нажатий); short/long/repeat. +- **Коллизии:** чтение вне всех окон → no-press (никогда не ложная кнопка); простая лесенка не + различает одновременные нажатия (паразитный уровень) — политика detect-and-drop. +- **Темп./aging-дрейф:** ширина окон/гистерезис под конверт −20…+70 °C (hardware §1a) + запас. + +**Транспорт ввода — `uinput`/evdev (не Shell-D-Bus):** K нормализует кнопки (ADC + опц. проксированные +CAN из E) в виртуальное **uinput-устройство** → libinput → smithay-композитор Shell → штатный +Wayland-input сфокусированному клиенту. Это покрывает и декларативные тайлы, и **surface-апы** +(нав/медиа), что вариант «только Shell-D-Bus» НЕ покрывает. Гейтинг «кому руль» — фокус +композитора (C §2), не отдельная D-Bus-capability. + +**Distraction-дисциплина:** в distraction-режиме (C §7, через `DistractionModeChanged`) часть +руль-действий **гейтится** — навигация по упрощённому UI и приоритет голосу OK; сложное листание/ +глубокие меню блокируются, чтобы руль не обходил #6. + +## 4. IMU / акселерометр + +- Ориентация устройства, детект движения; **опционально** g-sensor. +- I2C/SPI-сенсор на плате — **не обязателен, на большинстве сборок может отсутствовать**. Фаза — later. +- ⚠️ **Констрейнт для J:** g-sensor НЕ гарантирован. Dashcam (J) **не закладывается** на g-sensor: + дефолт — **непрерывная кольцевая запись** без триггера; event-маркировка опциональна (IMU **или** + резкое замедление по GPS-`Speed`). Деградирует видимо (пишет всегда), не тихо (#4). + +## 5. Прочие сенсоры (в основном — E) + +- **Парктроники, TPMS, климат (чтение):** в современных авто на CAN → **сигналы E/data-model** (K не дублирует). +- K подключает только **выделенные не-CAN** датчики (редко, ретрофит). Парктроник-дистанция → + оверлей поверх вида камеры (J) — данные из E или K по источнику. + +## 6. USB-периферия + +- Енумерация/интеграция специфичных **сенсоров** на USB. Базовый udev/USB-стек — A. +- (mic-массив — PipeWire/аудио; ELM327 — транспорт E; модем — Connectivity; не K.) + +## 7. IPC + +- `ru.shturman.Location` — см. §2 и [ipc.md](../contracts/ipc.md) §3 (`FixQuality`-enum + per-property quality для `Speed`/`Heading`). +- **Input руля** — через **uinput/evdev** (§3), не отдельный D-Bus-интерфейс. + +## 8. Функции + +| функция | MVP/later | зависит от | фаза | +|---------|-----------|------------|------| +| `ru.shturman.Location` (GPS → position/speed/heading + FixQuality/HDOP) | **MVP** | hardware(GPS), gpsd | v1 | +| Zero-clamp скорости / валидность курса у нуля | **MVP** | — | v1 | +| GPS-источник (NMEA/gpsd) для time-sync a-base §7 | **MVP** | hardware(GPS) | v1 | +| Приватность локации (эфемерна; audit; не в промпт) | **MVP** | security-privacy | v1 | +| Мультируль: ADC-лесенка (window-table) → uinput | later | hardware(ADC)/BSP | v1/v2 | +| Мультируль: CAN-кнопки (через E) | later | E | v2 | +| IMU/акселерометр (опц.) | later | hardware(IMU) | later | +| Выделенные не-CAN датчики | later | hardware | later | +| Nav-позиционирование (потребитель Location) | later | домен I | v4 | + +## 9. Зависимости + +- **Вниз:** hardware (§4 GPS/антенна/1PPS-опц., ADC-входы, IMU; §3 селективный рейл GPS). +- **Вбок:** E (CAN-граница); A (udev/USB-стек); **B** (питание GPS в sleep/battery-cutoff, бюджет разряда); + J (парктроник-оверлей; констрейнт — dashcam не на гарантированный g-sensor, §4). +- **Вверх/потребители:** C (GPS-скорость для distraction v1, GPS-восход для темы v1; input с руля + через uinput), D (геоконтекст), a-base §7 (GPS-время, v1), Nav (I, v4). + +## 10. Открытые вопросы + +- 🟡 **Маппинг кнопок руля → действия** + калибровка ADC-порогов на конкретном авто (BSP/HAL, hardware §5). +- ◻️ **Какие руль-действия гейтятся в distraction** (C §7) — парный вопрос с C §11. +- ◻️ **IMU на reference-плате** — нужен ли (ориентация? опц. g-sensor для dashcam-маркировки?); до + решения J = непрерывный ring-buffer (§4). + **dead-reckoning** (IMU+GPS) для тоннелей/удержания + distraction-скорости при потере GPS — нужен ли и где живёт (K-fusion/gpsd/Nav). +- ◻️ **Питание GPS в sleep/battery-cutoff** (keep-alive warm-start vs обесточивание+cold-start) — hardware §3 + B §7. +- ◻️ **Арбитраж GPS-vs-OBD-скорости** (C §7 v2) — кросс-проверка. + +--- + +## Журнал решений (домен K) + +| Решение | Выбор | Дата | +|---------|-------|------| +| Граница с E | K — не-CAN сенсоры/периферия; CAN-сигналы (кнопки/парктроник/TPMS/климат) — у E | 2026-06-16 | +| Location | `ru.shturman.Location` (GPS/gpsd) — владелец K; K поставляет фид, time-sync владеет a-base §7 | 2026-06-16 | +| Скорость GPS | zero-clamp <~2-3 км/ч; FixQuality многоуровневый; dead_reckoning не валиден для distraction | 2026-06-16 | +| Приватность | эфемерна (без трека в v1); audit-log; не в LLM-промпт; while-in-use грант; on-device | 2026-06-16 | +| Мультируль | window-table + кондиционирование + collision-drop; транспорт **uinput/evdev**; гейт фокусом C | 2026-06-16 | +| IMU/dashcam | IMU опц./не гарантирован; J = непрерывный ring-buffer, не на g-sensor | 2026-06-16 | +| Время | SHM-класс (десятки-сотни мс); PPS — опц., hardware-gated | 2026-06-16 |