From 6bbbd5bf7db894e8e2237192a03a931d95214d81 Mon Sep 17 00:00:00 2001 From: DCCONSTRUCTIONS Date: Fri, 25 Sep 2026 16:39:19 +0300 Subject: [PATCH] docs(rover): record calibration control acceptance and operating boundaries --- ...7_PRODUCT_UI_AND_LAB_PRESENTATION_CANON.md | 14 + ...9-23_ROVER_006_VESC_IMPLEMENTATION_PLAN.md | 331 +++ docs/node/17_VESC_INSTALLATION_LEDGER.md | 2244 +++++++++++++++++ docs/node/18_VESC_TOOL_NATIVE_BACKEND.md | 176 ++ docs/node/19_VESC_OPERATOR_CALIBRATION.md | 99 + docs/node/20_VESC_POWER_LIMITS_PLAN.md | 145 ++ docs/node/21_STARTUP_AND_USB_RECOVERY.md | 95 + docs/node/22_BOARD_SETTINGS_SURFACE.md | 37 + docs/node/23_ROVER_CONTROL_PROFILES.md | 595 +++++ docs/node/24_RC_FAILSAFE_ACCEPTANCE.md | 247 ++ .../node/25_OBSERVATION_AND_REMOTE_CONTROL.md | 545 ++++ docs/runbooks/ROVER_006_ENGINEERING_ACCESS.md | 75 + 12 files changed, 4603 insertions(+) create mode 100644 docs/handoff/2026-09-23_ROVER_006_VESC_IMPLEMENTATION_PLAN.md create mode 100644 docs/node/17_VESC_INSTALLATION_LEDGER.md create mode 100644 docs/node/18_VESC_TOOL_NATIVE_BACKEND.md create mode 100644 docs/node/19_VESC_OPERATOR_CALIBRATION.md create mode 100644 docs/node/20_VESC_POWER_LIMITS_PLAN.md create mode 100644 docs/node/21_STARTUP_AND_USB_RECOVERY.md create mode 100644 docs/node/22_BOARD_SETTINGS_SURFACE.md create mode 100644 docs/node/23_ROVER_CONTROL_PROFILES.md create mode 100644 docs/node/24_RC_FAILSAFE_ACCEPTANCE.md create mode 100644 docs/node/25_OBSERVATION_AND_REMOTE_CONTROL.md create mode 100644 docs/runbooks/ROVER_006_ENGINEERING_ACCESS.md diff --git a/docs/17_PRODUCT_UI_AND_LAB_PRESENTATION_CANON.md b/docs/17_PRODUCT_UI_AND_LAB_PRESENTATION_CANON.md index 3294f4e..7913136 100644 --- a/docs/17_PRODUCT_UI_AND_LAB_PRESENTATION_CANON.md +++ b/docs/17_PRODUCT_UI_AND_LAB_PRESENTATION_CANON.md @@ -353,3 +353,17 @@ Before A3 or any subsequent LAB UI change: 7. visually inspect normal and expanded modes at representative viewport sizes. 8. verify every bounded `ENNResult.tsx` uses the v1 summary and result components without raw canonical report markup. + + +## Hardware synchronization feedback — owner requirement, 2026-09-25 + +When an operator action must wait for equipment synchronization, preparation +or completion of a previous operation, show its current phase next to the +action using canonical status components. Do not silently disable the entry +point or present an unexplained frozen control. Keep settings accessible; +gate the actual hardware action on readiness and explain the reason. +A busy phase uses the canonical warning status; confirmed readiness alone +uses success. Missing/stale data or failure must say so, never imply endless +active synchronization. Status follows real lifecycle responses, not a timer +that pretends completion. This is an application-wide interaction requirement; +other equipment workflows need their own lifecycle verification. diff --git a/docs/handoff/2026-09-23_ROVER_006_VESC_IMPLEMENTATION_PLAN.md b/docs/handoff/2026-09-23_ROVER_006_VESC_IMPLEMENTATION_PLAN.md new file mode 100644 index 0000000..1ca152c --- /dev/null +++ b/docs/handoff/2026-09-23_ROVER_006_VESC_IMPLEMENTATION_PLAN.md @@ -0,0 +1,331 @@ +# Rover 006 — VESC: аудит кода и план реализации + +Исторический план, составленный до реализации 23 сентября 2026. Текущий статус +см. `../node/17_VESC_INSTALLATION_LEDGER.md` и MISSIONCOR-84. + +Результат первоначального аудита — исследование, свежий read-only +baseline и план. Плагин ещё не реализован; конфиги контроллеров не прочитаны, +моторы не запускались. Исторические команды и планы приложенного документа +рассматривались как источники, а не как поручения на исполнение. + +## 1. Целевой пользовательский результат + +После подключения контроллеров к USB бортового Mac Mini они появляются в +«Устройствах» Node и в «Парк → Rover 006 → Устройства» основного Core. +В карточке выбранного контроллера есть вход **«VESC Tool»**. Через него доступны +настройка, диагностика, калибровка и остальные применимые функции Tool. +Исполнение принадлежит борту; обе UI используют одну реализацию предметного +интерфейса и одни операции. Полнота Tool остаётся целевым требованием, +первый read-only выпуск является отдельным промежуточным результатом. + +Ближайшая физическая задача — разобраться с потерей оборотов одного мотора. +Слова владельца о левом канале остаются предположением до сопоставления. +Предыдущие наблюдения: плавный старт возможен, резкий может давать короткий +рывок и остановку; конфигурация, датчики и управление — приоритетная ветка +диагностики. Причина пока не измерена. + +## 2. Что проверено сейчас + +| Объект | Факт 23.09 | Ограничение | +| --- | --- | --- | +| Core | Канонический localhost:8000 отвечает; Rover 006 paired/online | Не означает доступность каждого устройства | +| SSH | Вход `dcsudo` с существующим персональным ключом работает | Старая запись `nodedc-edge` использовала `ndcsudo`; sudo не проверялся и не нужен для чтения | +| Борт | Ubuntu 24.04.4, kernel 7.0.0-31-generic, i7-3615QM, 4 ядра/8 потоков | CPU поддерживает AVX, но AVX2 в полученном наборе флагов нет | +| Память/диск | Около 8 GB RAM, около 6.3 GiB available; swap не занят; root 457 GiB, свободно 381 GiB | Это короткий idle-срез, не совместная нагрузочная приёмка | +| Установка | Node 0.8.21-3, K1 0.1.14, X4 0.1.3-9 | Старый Node README с 0.6.11 не является installed baseline | +| Службы | Node, K1, X4 broker, D455, monitor, PostgreSQL active/running, NRestarts=0 в проверенном наборе | Активный драйвер не доказывает подключение камеры | +| База | PostgreSQL 16, cluster `ndcmonitor` online; Timescale 2.29.2 установлен | База системного мониторинга, не готовый motor recorder | +| Реплика мониторинга | available/fresh=true, storage=ready, backlog=0; sample interval 1 s | Срез около 11:02 UTC; полевая задержка управления не измерена | +| USB контроллеров | Два кандидата `0483:5740`, ChibiOS/RT Virtual COM Port, cdc_acm, два ttyACM | USB-дескриптор ещё не доказательство HW/FW VESC | +| Identity | У двух кандидатов одинаковый USB serial; одна конфликтующая by-id ссылка | Нельзя использовать USB serial, by-id, tty или порядок включения как постоянную личность | +| Права | tty принадлежат root:dialout, 0660; dcsudo не имеет read/write | Права будущего runtime поставляются профилем модели | +| Конкурирующий опрос | ModemManager active; кандидаты имеют ID_MM_CANDIDATE=1 | Не доказано, что он уже посылал команды; нужен адресный udev ignore при подготовке модели | +| Камеры | D455/X4 в свежем paired inventory offline | Сохранность их потоков под VESC-нагрузкой сейчас проверить нельзя | + +Портов serial не открывали; firmware/UUID, моторные и application configs, +CAN/RC topology и физические стороны остаются неизвестными. VESC Tool не найден +через проверенное имя `vesc_tool` в PATH; это не полный поиск всех установок. + +Подробный путь доступа: [ROVER_006_ENGINEERING_ACCESS.md](../runbooks/ROVER_006_ENGINEERING_ACCESS.md). +Raw fleet/monitor snapshots и приватный SSH-профиль находятся вне Git в +операторском `outputs/rover-006-vesc-context-20260923`. + +## 3. Источники и границы исследования + +Прочитаны основной актуальный срез и VESC-handoff приложенного документа, +профильные Node/SDK/UI материалы и релевантная история приложений. Большой +архив планировщика/Rerun использован для контекста владельцев; повторной +квалификации всех старых экспериментов не выполнялось. + +Через прямой Ops MCP получены живые проекты/контекст/карточки, в том числе +MISSIONCOR-84, 76, 77, 50, 5, 2, и история комментариев 76/77/84; изучен +архив ROBOT2B-5. Профильная карта — +[MISSIONCOR-84](https://ops.nodedc.ru/nodedc/browse/MISSIONCOR-84), Node — +[MISSIONCOR-76](https://ops.nodedc.ru/nodedc/browse/MISSIONCOR-76). +Поиск GPIO в других четырёх доступных Ops-проектах совпадений не вернул; +среди полученных Mission Core/ROBOT2B карточек подтверждённой схемы GPIO +для этого привода не найдено. Это пробел найденных источников, не утверждение +об отсутствии такой схемы вообще. USB достаточно для первого этапа; +GPIO/UART/RC/аварийная цепь требуют конкретной аппаратной схемы до motor tests. + +Основная кодовая база: `NODEDC_MISSION_CORE_m5_observatory`, HEAD `2e5d525`. +Соседние base/node checkout остаются detached `76dc9f1`. В main есть чужая +незавершённая работа SIM/AI polygon и service recovery. Для реализации нужен +отдельный checkout от проверенного commit; не включать эти изменения в пакет. + +Design Guideline прочитан по реестрам и документации, текущий HEAD +`8dd9190573d6616024ef01b9b34bf90b72960f44`, рабочее дерево чистое в проверке. +Node build_linux_source.py закреплён на `8c53f73...` и отклоняет другой HEAD. +Перед выпуском выбрать проверенную ревизию DG и квалифицировать её в сборке; +не снимать проверку и не брать случайные локальные dist. + +## 4. Реальные точки расширения + +| Код | Что уже есть | Что нужно VESC | +| --- | --- | --- | +| `apps/node-agent/internal/node/sensor_models.go` | Registry, model actions, отдельные IPC sockets, USB discovery, provisional identity при дублях | Новый model profile; разделение attachment и protocol UUID; discovery двух плат с одинаковым USB serial | +| `sensors.go` | Durable fsync journal, dedup, action allowlist, deadline, unknown после restart, local API | Точные VESC actions и параметры; проверка session непосредственно в адаптере; bounded результаты; не прятать моторные функции за camera `start`/`option` | +| `sensor_preparation.go` | Профиль на модель и проверка отдельного экземпляра, shared preparation job | Device-neutral подписи и безопасная identity verification. Нельзя трактовать `verify` как motor detection | +| `sensor_events.go` | udev events, coalescing, полные SSE snapshots | Reconnect создаёт новый session; stale GUI не получает authority над новым контроллером | +| `pairing_transport.go` | mTLS heartbeat, commands/results/acks; периодический tick 5 s и пробуждение от событий | Существующий путь для service operations; отдельная доставка частой telemetry и будущего realtime control | +| `src/k1link/fleet/sensors.py` | Проверки pairing/freshness/session, очередь, receipts, ограниченные payloads | Добавить явные actions; не превращать whitelist в arbitrary protocol passthrough | +| `packages/plugin-sdk/.../v0alpha2` | Identity/session, safety/idempotency policies, commands/events | Использовать существующие contracts; motor authority/lease и конфиг revision оформить узким дополнением | +| `packages/sensor-ui` | Общий SensorWorkspace, transport, Detail contribution, status/preparation | VESC Detail в том же slot; camera-specific поля/подписи нормализовать ровно там, где нужно | +| `apps/node-agent/ui/src/NodeSensors.tsx` | Локальная композиция общих plugins | Зарегистрировать ту же VESC contribution | +| `apps/control-station/src/core/fleet/sensorTransport.ts` и composition | Remote adapter общего UI | Повторно использовать; новая предметная логика в plugin, не App.tsx | +| `plugins/insta360-x4/runtime/operations.py` | fsync receipt до физического действия, отсутствие replay, readback settings | Проверенный пример lifecycle, но motor safety проектируется отдельно | +| Node monitor/storage и fleet monitor replica | 1 s host samples → Timescale → bounded Core replica | Не использовать этот период как осциллограф или контур stop; моторная сессия пишет данные на борту с собственной частотой | + +В этих действующих реестрах и каталогах VESC runtime отсутствует. Архитектурные +документы старого этапа местами описывают gRPC как целевой вариант; текущая +проверенная реализация использует JSON HTTP/Unix sockets и HTTPS heartbeat. + +## 5. Интеграция VESC Tool + +Для аудита закреплён официальный upstream: +[`dc53c658cbb89a947246034f7a00149cf79abdfc`](https://github.com/vedderb/vesc_tool/tree/dc53c658cbb89a947246034f7a00149cf79abdfc). +Сохранены 17 исходных файлов с SHA-256. Этот snapshot объявляет **7.01, +test version 1**; это исследовательская точка, не автоматически выбранный +production release для неизвестной firmware наших плат. + +Исходники показывают: + +- `main.cpp`: CLI умеет конкретные чтения/записи config, выбор port/CAN, + offscreen и TCP. Это не готовый полный web API. +- `vescinterface.cpp`: autoconnect обходит serial ports и заканчивает поиск + на первом ответе. Для инвентаризации двух плат нужен наш ограниченный поиск. +- `commands.cpp`/`datatypes.h`: FW response содержит version, HW name, UUID + и дополнительные признаки; набор полей зависит от ответа. HW name нельзя + автоматически считать точной коммерческой моделью платы. +- `configparams.cpp`/`utility.cpp`: schema выбирается по firmware, сериализация + использует signature. Парсить конфиг произвольной новой firmware старой + схемой и затем сохранять его нельзя. +- `packet.cpp`: length/framing/CRC и размер пакета ограничены. Нужны tests на + fragmented/combined/corrupt packets и truncation полей ответа. +- `tcpserversimple.h`: default bind — все адреса. Штатный TCP server нельзя + просто включить как удалённый продуктовый интерфейс. +- `setupwizardmotor.cpp`: wizard содержит реальные записи конфигурации по + ходу шагов. Его запуск/отмена не являются только локальным редактированием. + +### Сравнение реализаций + +| Вариант | Польза | Цена/ограничение | +| --- | --- | --- | +| Официальный Qt Tool + локальный launcher и трансляция его окна в Core | Самый прямой путь к исходному GUI и широкому набору функций | Новый remote-app runtime, конкуренция ввода двух UI, Qt UI вне DG, передача port ownership; интерфейс сам умеет опасные команды | +| Собственный минимальный protocol adapter | Быстрое read-only discovery/telemetry | Поддержка всех конфигов/wizards потребует дублирования большого firmware-specific слоя | +| Бортовой service plugin с переиспользованием закреплённого upstream protocol/config engine + общий React UI | Наш UI, один owner, применимые функции Tool расширяются без второй модели состояния | Требуется проверить headless сборку/зависимости и адаптировать операции; полного готового API нет | + +**Рекомендация:** третий вариант как целевая архитектура. Первый технический +spike проверяет сборку и выделение engine без desktop UI; fallback на +ограниченный собственный reader допустим для первого чтения, но не отменяет +требование функционального паритета. Оригинальный Tool полезен как инструмент +сравнения с эксклюзивной передачей владения портом. В текущем плане нельзя +объявить «все функции готовы», открыв только несколько полей или удалённое окно. + +Нужно отдельно различать паритет функций и показ неизменённого Qt GUI. Здесь +принято рабочее предположение из запроса про наш интерфейс и DG: единая +предметная UI внутри Mission Core. Если нужен именно исходный Qt GUI, меняется +способ его доставки, а не требование единственного hardware owner. + +Upstream содержит GPL-3.0-or-later notices и отдельные правила бренда. При +упаковке выбранного кода/бинарника проверить состав, notices, исходники и +название распространяемого продукта. Этот аудит не делает юридического вывода +о допустимости конкретного способа распространения. + +## 6. Runtime и модель данных + +```mermaid +flowchart TD + L[Node UI: Устройства → VESC Tool] --> N[Node API и журнал операций] + R[Core: Парк → Rover 006 → VESC Tool] --> C[Core fleet API] + C -->|Существующее pairing и mTLS| N + N --> V[VESC plugin на борту: owner и арбитраж] + V --> U[USB attachment → protocol UUID → controller/channel] + U --> M[Мотор и подтверждённая роль] + V --> D[Конфиги, telemetry и diagnostic session на борту] + D --> C +``` + +Предлагаемый bounded каталог `plugins/vesc/`: `runtime/`, `frontend/`, +`profiles/`, `packaging/`, `tests/`, upstream lock/notice manifest. +Названия здесь — план, каталог ещё не создан. + +Один service владеет serial. Открывает только подтверждённые candidates; +проверяет отсутствие конкурирующего владельца и сохраняет связь порта с +attachment generation. До FW query attachment имеет provisional identity. +После ответа UUID связывается со стабильным controller instance. Смена порта +не меняет подтверждённый UUID; USB/CAN aliases одной платы не создают двойник. +Неоднозначный protocol UUID оставляет устройство без write authority. + +Особенно важно для текущих двух плат: общий Node discovery уже считает +duplicate USB serial неинициализируемым. Нельзя просто добавить VID/PID: +обе кнопки подготовки окажутся заблокированы. Нужен отдельный безопасный путь +подготовки модели/identity query для provisional attachments; он разрешает +только ограниченное чтение личности. Общую защиту камер не ослаблять. + +Role Left/Right и metadata мотора хранятся отдельно от UUID. Отключение владельцем +одного USB при обесточенном приводе может сопоставить плату с кабелем; это само +по себе не доказывает, какой мотор подключён к её силовым выходам. Сопоставление +по проводке/маркировке предпочтительно; активный тест — отдельная операция. + +Конфиг имеет исходный blob, decoded fields, firmware/schema signature, hash, +revision и timestamp. Запись использует ожидаемую revision и свежий session, +сохраняет before/after, выполняет readback. Потеря ACK даёт unknown и +reconciliation, а не слепой retry. + +Калибровка — бортовая операция с этапами, результатом и явно проверенной +семантикой отмены. HTTP timeout не доказывает прекращение электрического +измерения. Motor control дополнительно требует одного владельца управления, +локального watchdog, известных timeout/stop свойств firmware и арбитража RC. +Точные токи/обороты/частота не выбираются до hardware baseline. + +## 7. Полнота функций и порядок включения + +| Группа Tool | Предметный результат | Этап и условие | +| --- | --- | --- | +| Discovery, FW/HW/UUID, USB/CAN topology | Независимые экземпляры и совместимость | Первый read-only slice | +| Live values, faults, decoded PPM/ADC/Chuk input | Напряжение, токи, ERPM, температура, вход, timeout/kill flags по поддержке FW | Первый read-only slice; измерить реальную частоту | +| Motor/app/custom configs, backup/export, сравнение | Полный применимый набор параметров по schema, неизменяемый backup | Read-only до первой записи | +| Import, defaults, apply/restore | Предпросмотр diff и проверенный readback | После identity, backup и compatibility; restore/defaults — записи | +| FOC/BLDC/DC setup, R/L/flux, Hall/encoder | Калибровочный workflow с результатом | Активный допуск на конкретный мотор; один шаг может подавать ток | +| App/input setup, direction, limits | Настройка RC/ADC/UART/CAN по реальной схеме | Сначала прочитать существующий input/timeout/RC ownership | +| Duty/current/brake/RPM/position, motor tests | Управляемый стендовый опыт | Быстрый бортовой контур; не heartbeat 5 s | +| Samples, logging, plotting | Синхронная диагностическая запись реакции | Bounded board recorder; сводки через Core | +| Firmware/bootloader/recovery | Exact-HW image, версия, progress и recovery | Отдельная поздняя ветка; не «обновить на всякий случай» | +| CAN forwarding/multi-controller setup | Явный target и topology | Никаких автоматических detect-all/broadcast writes | +| Terminal, Lisp/QML/packages, custom application | Сервисные функции выбранного устройства | Отдельный maintenance scope; чтение кода и его выполнение различаются | +| BMS, IMU, power switch, NRF/GPD и расширения | Применимые к конкретному hardware возможности | Capability-driven; отсутствие аппаратуры не маскировать как готовую функцию | + +Перед реализацией широкой сервисной поверхности матрица уточняется по страницам +выбранного релиза Tool и реальной HW/FW. Для каждого пункта фиксируются: +supported/unsupported/not-implemented, операция, side effects, schema, +readback, cancel/recovery и аппаратная приёмка. Старые настройки firmware +не переименовываются в поддержанные только ради единого красивого UI. + +## 8. UI brief и Design Guideline + +Задача оператора: выбрать конкретный контроллер, понять состояние, настроить +его и проверить итог. Первичная сущность — выбранный controller/channel; +мотор и роль — связанный контекст. Вход из существующего списка устройств. + +Выбран **plugin Detail slot** общего `SensorWorkspace`, с текстовой кнопкой +«VESC Tool» в карточке. Внутри — обзор/диагностика, параметры и сервисные +операции, основанные на capabilities. Нового root или LAB не требуется. +Длинный motor workflow остаётся полноценным detail-view; компактный editor +может использовать существующий `FeatureSettingsWindow`. + +Альтернатива отдельного глобального workspace создаёт второй вход к тем же +устройствам и отрывает инструмент от адресной identity. Модальное окно на весь +долгий workflow неудобно для контроля результата и закрытия/recovery. +Показ исходного Qt GUI — иной вариант интеграции, описанный выше. + +Уже есть `ResourceRow/List`, `Button/IconButton`, `StatusBadge`, +`SettingsCard`, `Window`, `FeatureSettingsWindow`, `SegmentedControl`, +`TextField`, `Select`, `RangeControl`, `ConfirmationModal`, `ProgressBar`, +`LoadingRegion`, `ToastStack`. Подходящие существующие icons: settings, +activity, network, download, upload, refresh, alert, eye, play/stop. +Отдельной motor-icon в просмотренном registry нет; новая не нужна для первого +slice. Domain graph/plot остаётся кодом плагина с этими controls. + +`RangeControl.min/max` ограничивает drag, но не всякий ручной ввод: для токов +и других bounded величин нужны `exactValueBounds` и серверная валидация. +Safety check нельзя делегировать только форме. + +Состояния: поиск; не обнаружено; найден кандидат; требуется подготовка; +чтение личности; unsupported/ambiguous; готов к чтению; fault; занят; +операция выполняется; outcome unknown; связь потеряна. Свежесть контроллера +проверяется отдельно от online борта. Браузер не принимает unknown за failed +и не предлагает повтор опасного действия как универсальное восстановление. + +Это новое доменное содержимое существующей принятой list/detail композиции. +Изменения global navigation и новые общие визуальные сущности не предлагаются. + +## 9. Упаковка с первого бортового опыта + +Versioned пакет/profile устанавливает бинарник, pinned зависимости, отдельного +непривилегированного service user, Unix socket для Node, systemd limits, +узкие udev rules доступа и ModemManager ignore для квалифицированного профиля. +Не добавлять весь Node или пользователя в общий dialout, не делать chmod 666, +не отключать ModemManager глобально. Runtime не должен читать произвольные tty. + +Node сохраняет `PrivateDevices=yes`; аппаратные права принадлежат отдельному +адаптеру. Verify после установки означает protocol identity/read capability, +а не автокалибровку. Package qualification: повторная установка, конфликт +портов, rollback бинарника при сохранении data/backup, холодный старт и чистая +Ubuntu. Компилятор/Qt dev packages не становятся скрытым требованием runtime. + +## 10. Реализация по проверяемым результатам + +1. **Контракт и build spike.** Изолированный checkout, выбранный upstream + release/commit, DG pin, headless engine build, firmware schema closure; + synthetic packets, IPC/action contracts. Никакого доступа к моторам. +2. **Discovery на борту и две UI.** Поставляемый profile, два кандидата с + одинаковым USB serial, FW/UUID handshake, session transitions, одна + VESC contribution в Node/Core. Итог — оба контроллера видны независимо. +3. **Read-only сервисная поверхность.** Версии/capabilities, telemetry, + faults/input, motor/app/custom backups и semantic diff. Это первый полезный + завершённый выпуск; статусы неподдержанной FW честные. +4. **Диагностика проблемного канала.** Сначала сравнить конфиги, затем на + подготовленном стенде записать плавный/резкий старт по конкретному сценарию. + Сопоставить command/input, ERPM, currents, voltage, fault и timeout. Выбрать + измеренную гипотезу; рабочий конфиг не копировать целиком. +5. **Адресная настройка/калибровка.** Backup, effect preview, необходимые + ограничения hardware, исключение конкурирующего управления, конкретная + операция, cancel/recovery, readback и повтор исходного теста. +6. **Остальная матрица Tool.** Дополнять функции вместе с соответствующей + упаковкой и аппаратными критериями; FW/terminal/scripts выделены по эффекту. + +До физического теста требуются аппаратные факты о моторах/датчиках/питании, +проводке RC/CAN и доступном аварийном останове. Выбор «левый/правый» владельцем +выполняется позже; он не блокирует initial inventory. + +## 11. Приёмка и тесты + +- Parser: CRC, partial/multiple packets, неверные длины/концы, timeout, + несовместимая FW/config signature, отсутствующие optional fields. +- Identity: одинаковые USB serial, пустой/дублированный UUID, два независимых + контроллера, unplug/replug/reorder, замена платы, USB/CAN duplicate alias. +- Operations: общий local/remote journal, stale session, conflict/lease, + crash до/после dispatch, unknown outcome, readback mismatch, отсутствие + повторного исполнения после reconnect и reboot. +- Packaging: clean Ubuntu, narrow permissions, targeted ModemManager rule, + занятый port, idempotency/rollback, pinned binaries/firmware schemas/DG. +- UI: обе поверхности на одном экземпляре, одинаковые capabilities/results, + empty/offline/fault/unknown, сохранение draft, keyboard/Escape/expand, без + новых local controls или моторной логики в App.tsx. +- Hardware: версии и backup обеих плат; измеренный fault/поведение; + отдельная проверка stop/timeout на стенде до ручного управления. +- Совместная работа: вернуть реальные D455/X4/K1 в согласованный сценарий и + измерить ресурсы/USB/latency вместе с VESC. Их текущий offline не считается + успешной regression-проверкой. + +Проверки кода выполнять последовательно с учётом памяти операторского Mac. +Текущая задача не меняла runtime-код, поэтому тесты/сборки приложения не +запускались. HTTP/SSH/API чтения и анализ исходников не являются калибровкой. + +## 12. Следующее конкретное действие + +Реализовать и упаковать **двухэкземплярное VESC discovery + read-only identity, +config backup и общую detail-поверхность**. Первый бортовой запуск обязан +учесть уже обнаруженный duplicate USB serial. Это снимает неизвестность +HW/FW и даёт основание выбирать реальную настройку проблемного мотора. diff --git a/docs/node/17_VESC_INSTALLATION_LEDGER.md b/docs/node/17_VESC_INSTALLATION_LEDGER.md new file mode 100644 index 0000000..2324229 --- /dev/null +++ b/docs/node/17_VESC_INSTALLATION_LEDGER.md @@ -0,0 +1,2244 @@ +# Rover 006 — VESC integration ledger + +This ledger records actual execution separately from pending qualification. +Private evidence is in the operator's `outputs/rover-006-vesc-context-20260923` +directory. Raw configurations, device UUIDs, SSH material and photographs are +not repository fixtures. The current Ops record is MISSIONCOR-84. + +2026-09-25: the owner-requested consolidated configuration passport is now +[MISSIONCOR-85 — Гусеничный ровер Node 006](https://ops.nodedc.ru/nodedc/browse/MISSIONCOR-85). +It contains current hardware, both full decoded controller configurations, +radio settings, experiment outcomes and outstanding checkers. MISSIONCOR-84 +remains the historical integration task. Direct MCP readback verified all 35 +blocks; no controller changes or powered experiments were performed to publish +the passport. Owner deferred the one-stick/Tank–Arcade work and retained the +existing two-stick radio control. + +## 2026-09-23 — first deployed reader + +Node **0.8.22-1**, VESC plugin **0.1.0**, DG revision +`8dd9190573d6616024ef01b9b34bf90b72960f44` installed on Ubuntu 24.04.4 amd64. +The owner entered sudo in the Mini's local installer window. SSH authentication +already worked as `dcsudo`; no SSH/VPN/sudo-policy repair was needed. + +| Artifact | SHA-256 | +| --- | --- | +| Node package | `64e121fd3d12e94675def1284c5977a4e63a3d3e3ebab888b6b8ccab040136b7` | +| Source artifact b6dbe696a8c3182281e16553 | `bfed06700a1b8059db7c840851fab5a224e6eb0c6cdf8f4b68d000086964b184` | +| Owner installer 3955580c7d0b29c90c151ea9 | `fd9ca5eb473fcbf5618cecf76adff95b4f90d65a2a4150b5c0c432810e64d9e3` | + +Install completed 11:55:10 UTC; model preparation completed about 11:56 UTC. +Node, K1, RealSense and monitor services remained active; X4 package remained +0.1.3-9. This does not qualify live camera operation: camera inventory was offline. + +The shipped preparation profile creates a dedicated service identity and exact +USB rule, mode 0660, with a device-specific ModemManager exclusion. It never +adds the desktop user to dialout or disables ModemManager globally. The service +has no network access or Linux capabilities. Serial ownership uses flock, +TIOCEXCL and USB attachment-generation checks. No raw TCP gateway is exposed. + +Both controllers reported hardware 75_300_R2 / firmware 5.02. Distinct protocol +UUIDs disambiguated duplicated USB serials. Core successfully requested live +telemetry and durable raw motor/application backups through paired Node. +At rest, both reported about 50 V, fault 0 and ERPM 0. Motor temperature +−72.9°C on both is implausible and is not proof of a particular broken contact. + +Exact official 5.02 schemas matched both signatures and consumed every byte. +Both controllers use FOC Hall Sensors. The 151 serialized motor parameters +differ only in direction inversion. Existing current limits are motor ±60 A +and battery ±55 A; these are readback values, not verified motor nameplate limits. + +The owner unplugged the presumed left USB; USB1-2 / CAN74 disappeared and +returned, while USB1-3 / CAN111 stayed connected. **Rotation has not yet +confirmed physical sides.** The owner photograph identifies FlySky FS-iA6B; +CH3 is reported as left candidate and CH2 right candidate. The receiver stays +connected, transmitter off. One Hall connector pin is broken; its exact +function is unknown. The rig is raised, track removed, and the owner authorized +bounded motor tests through the product interface. + +## Native VESC Tool engineering build + +Official stable Tool 7.00 commit `01d5f10901116c311e3fb84d5a1541f663d3ce20`; +source archive SHA-256 +`4565ecec4e41e094bcc43127a51970e810aa9080a9d7c025af64632bfd4c0189`. +Versioned `plugins/vesc/packaging/tool_build.py` builds as an unprivileged user +under MemoryMax=3G, CPUQuota=150%, TasksMax=256. Signed Ubuntu packages are +downloaded/extracted into private staging, never installed system-wide. +Already-installed OpenGL runtime files used by the linker have recorded hashes. + +Early attempts failed on stale APT indexes, then private include/library paths. +Profile d1797bf1152f59ee14012ed5 resumed the recorded compile staging and linked +successfully; `--version` reported `7.00-0+`. Binary SHA-256: +`d68bd760918dd5c1f11f5133f6c236749c7004391d46298953341c0b67e40c40`. +This is an engineering build, not clean-host runtime dependency qualification. +It has not opened either controller. Native Tool serial handoff and calibration +integration remain pending; a Detail button is not evidence of full Tool parity. + +## Node 0.8.23-1 / plugin 0.2.0 — pending board installation + +Source artifact f1a42096c12295d29c9a736d SHA-256: +`995297d2f1070e0c13a5b11fd6da91c022aff0c5058c6bf5546c5b4e78b138cf`. +It is building and undergoing synthetic qualification on the Mini. No motor +command has been sent at this ledger entry. First motor experiment must append +its operation receipt, outcome, operator observation and before/after evidence. + +Changes: + +- Private immutable SQLite archive in both Node plugin and Core; preserve every + version, replay-safe replication scoped by pairing, ACK only after durable + Core storage. Existing backup files migrate on startup. Offline retrieval is + independent of transient operation receipts. No restore action is exposed. +- Shared history UI lists/paginates versions and requests JSON downloads. + Core displays an original backup; API content equals the original receipt. + IAB's download event did not fire, so browser file delivery is not yet accepted. +- A fixed raised-rig pulse selects one UUID/session, requires both peers, + exact supported firmware/config schema, one second neutral PPM, telemetry + bounds and durable backups. Commanded current is 2 A for at most 1.5 seconds. + No firmware/config write or variable current API is introduced. +- Per-controller volatile app-output leases expire after 250 ms. CAN forwarding + is false; peer current is zero. Expiry restores the existing PPM handling. + PPM pulses reset the firmware global timeout even while output is paused, + so a USB heartbeat timeout alone would be insufficient. Exact firmware source + audited: `vedderb/bldc` commit `3f670137e27e6e383fa79c50cc6b1fa85aab1554`. +- Non-neutral RC input latches further test requests until explicit release + after neutral. This test-session guard is not a continuous production RC / + remote / autonomous arbiter. Neutral PPM cannot prove radio-link availability. + +Validation before installation: 17 synthetic VESC tests including RC takeover, +partial lease failure and no physical replay; 37 fleet tests; Go Node package +and scoped archive ACK test; Core typecheck, 905 unit tests and production build. +The canonical Core 8000 was restarted through its existing managed helper and +health accepted. Its panel uses DG components; real pulse remains disabled until +the Node capability arrives. Linux qualification and physical failsafe acceptance +must be recorded separately. + +Rollback uses the prior qualified Node owner artifact after stopping any active +test. Configuration archives and original raw backup files remain on disk. +Do not replay an uncertain motor operation; inspect actual hardware state first. + + +### Final qualification after queued-stop correction + +The initial qualified 0.8.23 candidate f1a42096c12295d29c9a736d was not +installed. Review found that a Stop arriving before a queued pulse started +could be cleared by that start. The final runtime records cancellation time +and clears the event only for a newer request under the same lock; an added +fault-injection test covers the ordering. All 18 VESC tests passed on Ubuntu. + +Final source ID: `25ccd797bc91fceab43ba3db`, SHA-256 +`60fa8a151395e8e50617beec33752111152b3acb28cd2c5cfad5b6bc454fa75c`. +Final Node0.8.23-1 package: 168446728 bytes, SHA-256 +`b7be1efd9b404e3b54f43e73fab38d5e4207a1f50a80ab28b1b842284d90badf`. +Qualified result archive SHA-256 +`274aa43a64c781ce7fcc010dc332907f9b4679b0427f71b9cd27b68449fb2eea`. +DG, Node UI, Go, VESC synthetic tests and binary build all completed. +Installation and real motor execution are still pending this entry. + +Final owner installer `3b474f082a4c5af545dffda2`, SHA-256 +`e5f296bba8edcb0b6d681442214f326333d513cb5c0a215fa156669bf4ae0424`, +was opened in the Mini local session after APT plan showed exactly one Node +upgrade, zero new packages and zero removals. No password is collected by SSH +or chat. The older candidate e196a44ce00c150e5dc37311 must not be installed. + + +## 2026-09-23 — 0.8.23-1 installed, stale bytecode rejected by Node + +Owner installer `3b474f082a4c5af545dffda2` completed at 13:02:48 UTC +(run `6189de4765744a259b5a06776f6ee98f`). Package version and services updated, +but the VESC runtime imported version 0.1.0 from old timestamp-based bytecode +although its installed source declared 0.2.0. Deterministic package mtimes and +same-size source edits allowed Python to accept the old cache; `-B` disables +cache writes, not reads. Node's exact plugin-version check correctly rejected +that inventory. No test-current command was sent. This was not accepted as a +working hardware upgrade. Private before/after evidence remains outside Git. + +The next package, Node 0.8.24-1 / VESC 0.2.1, owns removal of generated +`__pycache__` directories below its fixed installed payload path in postinst, +before preparation/service start. Root preparation also disables new bytecode +writes. No ad-hoc root cleanup was performed on the board. The regression test +reproduces the old cache acceptance, clears it twice, verifies new imports and +preserves an unrelated evidence file. Backups live outside the payload. + +## 2026-09-23 — variable controller count and per-controller identification + +Owner clarified that each board can have 1, 6, 10 or more motors/controllers. +Discovery now admits up to 128 USB candidates per board, retaining UUID-based +identity and independent attachment sessions. The same device detail on Node +and Core offers a 2 A identification pulse with 1.5/5/10 second limits. The +existing editable device name supports Left 1, Left 2, Right 3 or arbitrary +owner labels; no fixed left/right enum or second motor registry was added. + +The request includes all live controller sessions on that board. Before any +current, the service verifies the exact attachment set, identity, configuration, +CAN peers and neutral receiver input, archiving both configurations of every +controller. It checks receiver channels and target telemetry while controlling +each app-output lease separately. Non-selected controllers receive zero current. +Slow cycles, hotplug, unmanaged CAN peers and ambiguous sessions abort the test. +The operation's 60-second deadline includes preflight, and the 1.5/5/10-second +current limit starts on the board. These controls are for an unloaded raised +rig, not general vehicle driving or a completed continuous RC arbiter. + +Local synthetic validation: 24 VESC tests passed, including 1/6/10 controllers, +target-only current, durable backups, hotplug, unmanaged CAN peer on a second +controller, slow cycles, stop-before-start, RC latch and bytecode upgrade. +Physical ten-controller capacity and motor calibration remain unverified. + + +## 2026-09-23 — 0.8.24-1 hardware inventory accepted; CAN preflight timed out + +Qualified source `0492e295535837afdf9ddcca` completed at 13:21:57 UTC in +224.35 s, peak memory 2,596,036,608 bytes. Package SHA-256: +`c254ad7dfaea236ae6d65186f00055a745169a11799063df2bd8cb44d53c779a`. +Owner release `6a2be7c817798c981fa6b1c8` installed successfully at +13:24:46 UTC (run `e766b308543e4312856f13c7077c83ad`). VESC service is active +with zero restarts and a read-only isolated import confirms VERSION 0.2.1. +Node/Core again expose exactly two verified UUID controllers, not the two +provisional USB rows plus one prior offline UUID seen during the failed upgrade. +The old row was the same left-candidate controller, not a third physical unit. +No identity records or backups were deleted to hide it. + +Core passed architecture checks, typecheck, 906 unit tests and production build; +its managed restart passed health acceptance. In-app UI shows the two matching +controllers and the 1.5/5/10 second selector; Escape closes the selector. +A single 1.5-second test was requested through the Core UI at 13:26:35 UTC, +operation `op_8d8f5ee7ae0c4510b584839350b41b3d`. Preflight archived both +controllers at 13:26:40, then returned an error after the first 4-second CAN +query. The motor loop was never entered: no app-output lease or current +command was sent. Both configurations remain unchanged. Core archive API +returns the original and new version for each controller. Browser file-save +handoff remains unverified; backend version retrieval is accepted. + +Firmware CAN ping waits up to 5 ms for transmission and 10 ms for a response +per address, plus scheduler/mutex delay; 255 addresses can exceed our former +4-second cap. Node 0.8.24-2 extends only that read deadline to 8 seconds and +adds `vesc.can.read` for direct, bounded topology inspection without any motor +command. Failure is now reported specifically as CAN preflight without torque. +Synthetic validation: 26 tests passed. Source `292106d05d5e1ff5ecb866f9` is +being qualified; motor watchdog/lease and current limits remain unchanged. +Separate `vesc.input.read` through Core returned level0/pulse0 on both channels. +Physical side identification and calibration have not yet been achieved. + + +## 2026-09-23 — 0.8.24-2 installed; first real identification pulse + +Source `292106d05d5e1ff5ecb866f9` qualified at 13:34:47 UTC in 224.19 s. +Package SHA-256 `9f54423216163917c52c6b627205dbe3a24b69f6d4f1d606aa59e489d0e02c4d`. +Owner release `7b4545754e703e7a64ee88bb` installed at 13:37:05 UTC, +run `4dde4c0992164fafb1828a91c402a8b7`. Node and device services were +active with zero restarts. Both CAN read operations completed in approximately +4.26 seconds with no responding peer IDs. No firmware/configuration was written. + +The owner had the rig raised, a track removed and the transmitter off with its +receiver connected. Core UI operation `op_dded265e82b54e3181a194a67868d6e6` +sent a bounded 2 A / 1.5 s pulse to the selected left-candidate controller. +Both configurations were archived first. Twenty-one samples showed peak 2.23 A +and 442 ERPM, with only three net versus 33 absolute tachometer steps: jitter +was observed, not demonstrated sustained rotation. The owner heard rustling +and could not identify which motor moved. Physical side remains unconfirmed. +Both zero-current commands were sent and subsequent telemetry confirmed +current release; both controllers reported fault zero. The old duration-boundary +receipt label incorrectly said stopped; the next revision separates duration +expiry from user Stop. Private raw receipts and identities remain outside Git. + +## 2026-09-23 — 0.8.25-1 candidate: test fields and user drive assignment + +Owner requested numeric current/time fields and eventually 30 A / 30 s. That +higher-power run has not been performed: manufacturer, motor and battery/BMS +ratings are unknown, and the initial pulse did not show steady rotation. +The next identification increment admits 0.5–5 A / 0.5–10 s, with board-side +validation, electrical-speed coasting above 2 A and all prior preflight guards. +These are software test bounds, not claimed hardware maximum ratings. + +Owner clarified exactly two current profiles: 1×1 (left/right) and 2×2 (left +front/left rear/right front/right rear). A shared existing VESC detail card +assigns UUID controllers to those positions. Assignment is board-owned metadata, +uses revision conflict checks, persists across service restart and never sends +motor commands. Occupied positions cannot be overwritten; shrinking requires +explicitly removing rear assignments. No real controller has yet been assigned. +This entry records implementation intent; package/UI/hardware acceptance below +must be recorded separately after execution. + +0.8.25-1 source `edfc5911070cab9c863cddcf` completed all 15 Linux qualification +stages at 14:00:34 UTC in 222.18 s, peak memory 2,955,657,216 bytes. +Package SHA-256 `e3e69718507ed921f24844409829a9af429df7d571a7faea8e42c3c91e81aa06`. +Owner release `5ff7b2b657fdce16bebd5ff4`, SHA-256 +`db0ec4003ec6cc3cadcb076ff45c170e8c6c281e1878539191d1fe82295bfe4f`, +was opened locally after an APT plan of one Node upgrade / zero new / zero +removed packages. At this entry it awaits the owner's local sudo input. +Core passed typecheck, 907 unit tests, 11 Python archive/boundary checks and +production build; managed restart reports health accepted. New controls are +visible and correctly disabled against the older board's missing capabilities. + + +## 2026-09-23 — 0.8.25-1 installed; two 5 A observations + +The owner completed local sudo. Install run `a980576ffb984a85b192a929a2517002` +finished at 14:26:27 UTC in 16.57 seconds; Node and VESC services are active, +Node package is 0.8.25-1 and inventory has both verified UUIDs, new capabilities +and an empty drive assignment profile. X4 package remains 0.1.3-9. + +The owner's screenshot used 5 A / 15 s, outside the admitted 10-second limit, +so the disabled Start was correct but its explanation was inadequate. After +changing to 10 seconds, the owner ran operation +`op_99d89bd76df44885816855293f1cb02e` at 14:40:12 UTC on the left candidate. +It completed by duration, 146 samples, peak current 5.65 A, median 5.00 A, peak +283 ERPM and median zero. From about one second onward, speed was zero and +reported position stayed near 126 degrees; no speed-coasting occurred. Owner +reports no visible rotation. Both releases confirmed, fault zero. Do not +interpret completed operation as confirmed rotation or a confirmed physical side. + +A comparison UI operation `op_523ee78a7f92441094257f05a5784a1f` on the other +controller at approximately 14:44 UTC requested the same 5 A / 10 s. It stopped +very early on a telemetry bound. Only two pre-limit samples were retained, +showing 0 then 177 ERPM; subsequent released telemetry showed 79 ERPM and +0.26 A. Both zero commands and current release confirmed, faults zero. The +triggering sample was not preserved by 0.2.2, so the exact exceeded metric +cannot be inferred from this receipt. No config/firmware writes occurred. + +Node 0.8.26-1 / VESC 0.2.3 candidate keeps every existing bound unchanged, +preserves the triggering sample before validation, and returns measured field +and bounds in the result and UI error. Shared numeric fields explain invalid +input; the action area explains missing rig confirmation, unavailable connection +and in-progress execution. New synthetic checks reproduce a PWM-bound stop, +confirm no further current command and require release of all controllers. + +Owner visually confirmed the second controller as the right motor and clarified +that visible movement lasted 2–3 seconds. This does not mean the requested +10-second pulse completed. Core UI saved layout 1×1 / right.1 (revision1) on +the board; both inventory entries project that same profile and the device row +now displays Right. The left candidate remains unassigned. + +The shared input-feedback fix is live in Core. Browser QA reproduced 15s and +showed the explicit allowed-duration message, then verified Start enabled for +5A/10s plus rig confirmation; removing confirmation disabled it with an explicit +reason. This form-only QA did not request a motor operation. Core passed +architecture/typecheck/907unit tests/production build. Runtime candidate0.2.3 +passed34synthetic tests; source f89d904ec9e71348c2db95e1 is being qualified. + +0.8.26-1 qualification completed all15stages at14:53:20UTC in225.17s, +peak2,695,626,752bytes. Package SHA-256 +`eab7e24ec36d89793544480c8c5ce4675dee6c503c811ecc33ad9b7be57f30e8`. +Owner release `dbea4df7e0eb5ec8664a18a5`, SHA-256 +`f2aa50f54ff0c3607f26b8d50e616a588d86b6b39315c9ece624003670c83326`, +was opened locally after one Node upgrade / zero new / zero removed plan. +At this entry installation awaits local sudo; no new diagnostic motor test +has been run. Existing current, duration and telemetry bounds are unchanged. + + +## 2026-09-23 — 0.8.26 installed; exact right-channel stop identified + +Install run9d8e1c601bf0414795bf287d3bd80b87 completed14:56:46UTC in16.54s. +Node/VESC active,0restarts; right.1 assignment persisted across upgrade. +UI operation op_e6885c4f552f4bd59a7d46dc08f188f1 at approximately15:08UTC +requested5A/10s on the confirmed right motor. The third sample at0.245s +reported801ERPM,4.84A,duty0.091. The test stopped at the unchanged800ERPM +bound (duty also exceeded0.08); the exact offending sample and metric are now +retained. Both zero-current commands and release confirmed; faults zero. +This demonstrates an overly abrupt current step for the intended low-speed +identification mode, not a completed10s run or a VESC firmware fault. + +0.8.27-1 / VESC0.2.4 candidate starts/resumes at0.5A and ramps toward the +entered current ceiling at approximately1A/s. Soft coasting now applies at +all current settings and triggers at200ERPM or4%PWM; resume requires both +speed<=100ERPM and|PWM|<=2%. Existing hard telemetry, current, duration, +lease, RC and topology bounds are retained. No config/firmware writes added. +The board advertises the ramp capability so the shared UI describes it only +when installed.36synthetic tests passed, including ramp progression, duty +coasting before a speed edge, restart ramp and prior stop/failsafe regressions. +This is not completed speed control or hardware acceptance of the new ramp. + +0.8.27-1 source fb29a802d53507678e906cc3 passed all15Linux stages at15:19:04UTC +in224.38s, peak2,877,997,056bytes. Package SHA-256 +`baed463408c7ffb0242506668c6b0f5b465e5f161ffbef5f1053f3406f346494`. +Owner release ec6eb256586fd8454e0f0d5e, SHA-256 +`be0fc5ada98656d075dd1dd1d00c019053371bbeba32bf66299c04067f01d743`, +opened locally after one Node upgrade/zero new/zero removed plan. At this +entry it awaits local sudo. Ramp hardware behavior is not yet qualified. +Core architecture/typecheck/907unit tests/build passed; final browser check +of ramp description awaits the installed board capability. + +## 2026-09-23 — 0.8.27 installed; coordinated right-motor observation + +Install run `1e0183d2ba1341d29f1c637c3ecaaef6` completed at 15:22:30 UTC +in 16.55 seconds. Node/VESC are active with zero restarts; the right.1 binding +and profile revision1 survived the upgrade. Core displays the installed ramp +capability. X4 remains 0.1.3-9. No firmware or controller configuration writes +were performed. + +The first attempt `op_607dd0d63339449086dfb2676b068826` exceeded the +120 ms cycle deadline before taking an app-output lease or sending torque. +One announced retry, `op_2af7955abede4bedaed05f2b2a0e4651`, completed its +10-second command loop: 143 samples, last offset9.9887s, peak564ERPM, +peak3.60A, maximum command3.655A, no hard-bound violation, release confirmed +on both controllers and faults zero. It includes repeated soft coasting and +does not qualify continuous rotation. The owner subsequently clarified that +he had stepped away and missed this run; his earlier impression of near-zero +motion is not a complete physical observation. + +The owner now requires explicit coordination for every powered experiment: +wait for a fresh ready-and-observing reply, announce the target and parameters, +and explain the preparation delay. Do not automatically repeat a motor test. +After the owner replied ready, the Core UI launched exactly one right-motor +5A-ceiling/10s operation `op_2e93a47e94f840e9a99a0fb207145cc4` at +15:35:13.885UTC. Configuration backups preceded torque. The owner saw the +RIGHT motor move approximately10degrees, pause, then move another10degrees; +these were two small movements, not two full revolutions. + +The receipt contains99samples and stops at offset6.8856s on880ERPM against +the unchanged800ERPM hard bound. Peak current3.39A, maximum command3.452A; +29net/31absolute electrical tachometer steps. Current first ramps until3.151s, +is set to zero at3.220s, and resumes from0.5A at3.497s. The second ramp is +released at6.811s; the next sample crosses the hard bound even though the +previous command was already zero. These two acceleration/coasting episodes +match the owner's two movements, although there is no synchronized video. +The pause/restart behavior is introduced by our identification governor and +must not be used to diagnose a hardware fault in the right motor. A zero-current +command allows coasting; it does not guarantee an immediate zero-speed sample. +Final readback: both currents0A, left0ERPM, right13ERPM, faults zero; +release_confirmed=true. Raw receipts with UTC/monotonic offsets, hashes and +operator corrections are retained privately outside Git. + +The right physical assignment is confirmed again. Left rotation, Hall wiring, +motor calibration and native Tool runtime integration remain unqualified. +No limit increase or further powered test follows automatically from this run. + + +## 2026-09-23 — 0.8.28-1 candidate: owner-requested 30 A / 30 s controls + +The owner explicitly requests an editable range up to30A and30seconds, and +clarifies LEFT is problematic while RIGHT works normally from RC. Earlier +right-channel stepping was produced by our identification governor; do not +transfer the fault hypothesis to the right motor. The current ready-to-observe +reply precedes a code/build/install change, so a fresh coordinated launch is +required after installation rather than an unattended deferred motor start. + +VESC0.2.5 candidate keeps the existing fields and advertises new capabilities. +It ramps0.5A→entered ceiling at2A/s and removes the200ERPM/4%PWM coast/restart +cycle. It ends the operation at6000ERPM or25%PWM, or lower configured bounds; +no automatic restart follows a limit. Above5A,2seconds without continuing +reported movement aborts. Fault,20–60V,65°C FET limit, RC latch, per-controller +250ms leases, full backups and attachment checks remain. These software limits +are not a claim about nameplate ratings or clean calibration. No motor or +firmware configuration is changed. + +Synthetic acceptance:39VESC tests pass, including30A/30s with continuing +simulated movement and bounded receipt, no artificial pause at880ERPM, stalled +high-current shutdown, speed-only/no-tachometer rejection, configured limits, +and prior RC/Stop/topology/release regression cases. This candidate has not +been installed or physically tested at this ledger entry. + + +0.8.28-1 source9a125d01aad00711f03165df completed all15 Linux qualification +stages at15:53:11UTC in226.07s, peak2,701,422,592bytes. Package SHA256 +`002178109f807a411cac37c0be71ad22e32fa5cee3c0bd76e5a5df3f0aadbb40`. +Owner release265e96b1a910aaf23a221568, SHA256 +`34f8a43374b3639b7e8b90d15d38067816a101b93f30ad57b41eb0e50faad5b1`, +opened locally after one Node upgrade/zero new/zero removed plan. At this entry +installation awaits the owner's local Ubuntu authentication. Core passed +architecture/typecheck/908unit tests/production build; browser shows the new +shared component against the old board's correctly retained5A/10s capability. +No new motor command was sent during development, build or form inspection. + + +0.8.28-1 installed:run43a4b512c687491fbfa41abd382e99df completed at +15:55:04UTC in16.47s. Node/VESC active with0restarts; X4 remains0.1.3-9. +Both Core inventory entries advertise VESC0.2.5 and30A/30s capabilities. +Browser form accepted30/30 with rig confirmation off and no start; it was +then set to5A/30s on the left candidate. The right assignment survives. +No powered0.2.5 operation has run at this entry: a fresh ready-and-observing +reply was requested after installation. The installed max range is accepted; +hardware behavior at the expanded limits remains unqualified. + + +## 2026-09-23 — coordinated 30 A / 30 s request on the left candidate + +After installation the owner declined5A/30s, explicitly selected30A/30s and +repeated the request. The announced target was the left-candidate VESC; the +owner was observing. Core UI operation `op_1cadeb2c861b434e9bba93c5d8a7e5e5` +was requested at15:57:42.612UTC. Both configurations were archived before +current. The result at15:58:03.230UTC contains67samples, last monotonic offset +4.705856s. Actual peak current8.70A, maximum successfully sent command8.763A; +ERPM remained0, net/absolute tachometer delta0, reported phase126degrees stayed +constant. The2-second no-motion guard above5A ended the run. Neither the new +speed nor PWM bound triggered. Do not claim30A were reached or30s completed. + +The owner heard a click but reported no physical movement at all. This matches +the measured lack of movement, and is distinct from the old governor's two +right-motor steps. Zero current commands reached both controllers; final +readback target0.33A/0ERPM/duty0, peer0A/0ERPM/duty0, faults zero; +release_confirmed=true. Raw receipt SHA256 +`9003459550d44c38644c86f0660b82505ef7c35f153076506fe7bb531d7d1354`. +The raw receipt, experiment manifest, UTC/monotonic timing and operator note +remain private. No configuration/firmware write or automatic retry followed. + +The editable30A/30s range is installed and browser-verified. Actual sustained +rotation at these values, left-side visual motion identification, Hall wiring, +calibration and native Tool runtime are not accepted by this stopped test. + + +## 2026-09-23 — owner comparison exposes duration/control-mode mismatch + +Owner independently ran30A/30s on right and left. Right operation +`op_144e051172474f86a9df3841c4578a70` (16:03:05.982UTC) stopped at2.404s +on26.1%PWM against our25%limit, not a VESC fault.34samples, maxcommand4.573A, +peakmeasured6.08A, peak4568ERPM. The owner saw approximately one revolution +and a short visible run. Release confirmed, subsequent0.22A/1371ERPM is +coasting rather than evidence of continued torque; the later peer snapshot +is0A/0ERPM. Left operation `op_c67e68008b89401ab74895d71c7c66d8` +(16:04:42.076UTC) again stopped by no-motion guard at4.707s:67samples, +peak8.69A/maxcommand8.748A, ERPM0. Owner heard a click without movement. +Both release checks passed, faults0. No new agent motor command was sent. + +The owner correctly identifies that the UI's current/time fields do not deliver +his intended sustained rotation test.30A is a ramp ceiling,30s an upper bound, +and the software governor can end a healthy motor's acceleration far earlier. +Merely increasing current/duration limits did not implement speed holding. +A dedicated timed speed-control workflow and actual calibration must not be +represented as complete by this limited current test. The VESC Tool entry still +opens a partial custom adapter, not the full native tool or calibration wizard. +Do not use the right software-limit stop as a right-motor fault or treat the +left symptom alone as proof of a specific Hall wiring/calibration failure. +Owner priority remains actual calibration, using the upstream functionality; +exact native-tool ownership/runtime integration remains outstanding. + + +### 2026-09-23 — 0.8.29 / VESC 0.3.0 implementation, not yet installed + +Owner correction: duration means observed rotation after acceleration, not an +upper bound on a torque command. Added native speed PID, explicit speed/current +ceiling/rotation-time fields, measured hold timer, startup/lost-speed deadlines, +and volatile motor-current scaling with durable restoration and full readback. +No flash changes. Original settings cannot be overwritten after an independent +configuration change. This addresses the prior right-motor PWM guard stop by +controlling speed instead of repeatedly increasing torque. + +Added firmware-native Hall measurement (5 A, about 12 s) as the first calibration +step for the problematic left motor. Audited pinned FW 5.02 source: Hall detect +locks ordinary controls and temporarily changes the timeout; it is not software +interruptible. The separate UI acknowledgement describes physical power cut. +The table is measured only, never auto-applied. Unknown completion blocks new +powered operations. Full VESC Tool desktop integration and R/L/flux application +are not represented as complete; the entry is renamed “Настройка VESC”. + +Local synthetic runtime checks: 51 passed, including motion-time accounting, +stationary tachometer, interrupted rotation, lost configuration ACK, restoration +after interruption, external-change protection, RC preemption and Hall timeout. +Fleet archive checks: 3 passed. Hardware commands in this implementation stage: +none. Installation and physical calibration remain pending. + +### 2026-09-23 — withhold 0.8.29; use the actual native VESC Tool engine + +Owner rejected expanding a separate custom calibration implementation. The +required architecture is upstream VESC Tool on the board, controlled through +Mission Core's own local and paired UI. Source `d6178c84997c585bf06be65e` +completed Linux qualification (15 stages, 230.34 s). The 0.8.29-1 package SHA256 +is `a87fad59ca02b5bffca3960442ed140f46d2581366ce82a45861aa2f03ca481b`. +Owner artifact `1d8868618ed467ccdb330ed4` was planned only, never launched. +This release is withheld; do not interpret its successful build or newer Core +fields as an installed/calibrated hardware runtime. Board package remains +0.8.28-1 and both Node/VESC services remain active. + +Versioned native proof `6d56d1dc847c63a0dc5cbfb2`, artifact SHA256 +`01df98dfdb044d503532d1dc3b0cb61bffcf62a13e72a07b9ebff86c22b3de4e`, +completed at17:03:45UTC in7.48s under an unprivileged MemoryMax=3GiB/CPUQuota=200% +user scope. Only a C++ entry point was compiled, linked to286 unchanged objects +from the previously attested Tool7.00 build. Binary SHA256 +`58d3e1441507d4e50bfdd5ca2e342e8dce4ceed2dcbf411fa05856b5352e68ff`. +No system package, service, serial port or controller setting was touched. + +Both actual archived controller configurations pass native FW5.02 negotiation, +binary decode/re-encode equality, native XML export/import comparison and the +upstream legacy power-loss compatibility correction. For each archive, corrupt +hash, unsupported firmware, bad native signature and truncated input are rejected: +10 acceptance checks total.162 motor and149 application schema entries are +exported, including upstream non-serialized UI/schema entries. Native XML rounds +floating point text and is not byte-identical after conversion; original binary +backups remain authoritative. This is offline engine qualification only. + +Files: `plugins/vesc/native/offline_main.cpp`, +`plugins/vesc/packaging/native_probe.py`, `build_native_probe.py`, README and +`docs/node/18_VESC_TOOL_NATIVE_BACKEND.md`. Raw archives, native JSON/XML exports, +object hashes, failed-build diagnostics and the complete report stay private. +The initial prototype's too-strict XML byte comparison was corrected to use +upstream `checkDifference`; native binary comparison remains exact. A later +compile caught a private Utility API; final code uses the public native +serializer to validate fixed-size FW5.02 payloads. No upstream files changed. + +Battery identification no longer blocks motor-only diagnosis. Owner photos +identify UNITE BM1418HQF family on one motor; approximately500W is an unconfirmed +owner recollection. Keep existing battery protections while using actual native +motor procedures. The full wizard must not recalculate cutoffs from stale saved +3S/6Ah metadata. See the native engine document for two-controller topology, +canonical procedure, sensorless fallback, remaining runtime/installer work and +physical acceptance boundaries. No calibration or powered test ran here. + +### 2026-09-23 — 0.8.30 / VESC 0.4.0 native runtime candidate + +Continued from offline qualification to a real process adapter. Native engine +`9bebad9670b6db63099578aa` links the same unchanged Tool 7.00 objects. One +VescInterface owns each exact, exclusively locked CDC ACM attachment; firmware +negotiation, configuration serialization, serial commands and Hall measurement +use upstream C++. `Utility::measureHallFocBlocking` is invoked unchanged. +Configuration reads must reproduce the received bytes through native ConfigParams. +The Python layer owns session authorization, operation receipts, RC leases, +backup history and measured-duration policy; it no longer opens serial ports. + +The engine is packaged with its Qt/offscreen and ELF dependency closure. Only +the Ubuntu 24.04 glibc family remains a host prerequisite. Native bundle SHA256 +`3987527298f472ced6ec85d7460eec5a47d27872836ce96cbdaae02ec25d7bb7`, +50,344,426 bytes; executable SHA256 +`26a8df1c04d9246ae91e60363309dfbc1fd127717b53fadb5b0460a8c92a1e5a`. +Includes upstream license/source reference, adapter source and distribution +notices. Hashes are checked during payload construction and by an offline +self-check under the service account before profile activation. System packages +were not installed to prepare the dependency closure. Clean-image acceptance +and real USB ownership remain separate from this prepared-host offline proof. + +Eleven native acceptance checks passed (two original archives and four negative +cases for each, plus disconnected-engine rejection of powered/unknown methods). +Sixty synthetic runtime tests passed, including subprocess response identity, +lost ACK, process exit, stale session, changed attachment, malformed response, +blocked write, no replay, original limits recovery and real rotation timing. +Service limits become 512 MiB / 64 tasks for the parent plus native device owners. +This is a resource ceiling, not an assertion of arbitrary-device capacity. + +Touched native engine/config export, native_link.py, service.py, Hall timing, +packaging/native_bundle.py/native_probe.py/native-runtime.json/native_check.py, +Node source/payload builder, model version and installer preparation. Source +artifact `ab73ffcf92d894e67f8cffa8` is being qualified for Node 0.8.30-1. At this +entry no new runtime has been installed and no powered experiment has run. + + +### 2026-09-23 — 0.8.30 installed; first actual upstream Hall result + +All 15 Node Linux qualification jobs passed in 248.88 s, peak 2,637,553,664 bytes. +Node 0.8.30-1 package SHA256 +`f3f2ac7c6af8e8aff7c11192c4c97375d50fe4f2e8b1daa2030cd2b8ec174950`. +Owner release `66a702a23b5dfb61d2a18417` APT plan upgraded only Node. The owner +authenticated in the local Ubuntu window; installation completed 17:42:44 UTC +in 18.44 s. VESC profile 0.4.0 offline integrity/engine check passed under the +service account, both USB profiles applied, service active with zero restarts. +Both native processes identify Tool 7.00 and the exact pinned commit, recognize +FW 5.02 and enable its upstream compatibility correction. Both motor/application +readbacks through the shared Core UI match original archived hashes exactly. +History replication remains available. No controller settings changed at install. + +After fresh owner observation/raised-rig/radio-off/physical-cut confirmation, +Core UI started one left-candidate native Hall measurement at 17:50:56 UTC. +Procedure completed 17:51:20 UTC; actual native cycle 12.38 s, 118 samples, +no communication issues. Result: firmware_success=false, measured table +[255,174,255,120,255,22,255,63], observed states [1,3,5,7] rather than six. +All observed state codes have their least significant Hall bit high. This is +consistent with one non-switching Hall input, not proof of which physical pin +or whether the cause is wiring, sensor or incomplete physical sweep. Owner +subsequently reported no visible physical movement. Peak reported motor current +3.18 A with requested Hall current 5 A; reported tacho changed. This is not a +steady-rotation test or a successful calibration. Original motor configuration +restored byte-for-byte; both devices report 0 A / 0 ERPM / fault 0 afterwards. +No table was applied and no automatic repeat ran. Raw receipt, UUIDs, sessions +and backup IDs remain in private evidence. + +### 2026-09-23 — full native FOC transaction, Node 0.8.31 / profile 0.5.0 + +The owner confirms raised rig, removed track and transmitter off; retain those +facts without repeated questions. Coordinate actual observation after long builds. +The shared UI calls unchanged pinned `Utility::detectAllFoc(false, ...)`, including +upstream Commands' FW 5.02 power-loss correction. Actual battery current limits +and FOC startup parameters are preserved. Invalid 3S/6Ah metadata is not used to +derive cutoffs. Heating budget is explicitly 10–150 W, initially 50 W, not motor +nameplate power. Firmware selects its measurement currents; the separate spin +test's 30 A bound does not cap this non-interruptible firmware cycle. + +This initial profile requires independent USB with no CAN peers because upstream +Utility broadcasts application-output disable even with detect_can=false. +All connected devices are backed up and checked before launch. A durable pending +marker prevents replay after uncertain completion/restart. Python polls only +native procedure status during the cycle and never overrides its lease. Native +completion accepts only documented calibration field changes, restores appconf's +CAN status side effect, retains the lower of detected and prior motor current +limits, and verifies exact write/readback. Known failed detection restores its +known original motor settings; unexpected changes are not blindly overwritten. +Both target and peers are archived/verified after completion. Uncertain results +block further motion. UI distinguishes sensorless fallback from healthy Halls. + +67 Python transaction/fault-injection tests passed; architecture/typecheck and +908 UI tests passed. Native artifact `47c2efc6fe16229c500655ce` compiled against +the same 286 upstream objects and passed 11 archive/negative/disconnected checks +without USB use. At this entry 0.8.31 is not installed and full FOC has not run. +Physical left startup, right baseline, sustained rotation and replicated final +histories remain required acceptance work. + +### 2026-09-23 — 0.8.31 installed; successful native left calibration + +Node 0.8.31-1 completed all 15 Linux qualification jobs in 248.56 s. Package +SHA256 `2cf96e817872edb2b161e383b502ed4eecbe0beb75a76ecf13122f226dae7ca3`; +owner release `09f05ab9303fc2a4610d484d` upgraded only Node. Owner authenticated; +installation took 17.72 s. Both native USB owners returned, profile 0.5.0 active. +The owner freshly confirmed observation; the shared Core UI started LEFT-only +native FOC at 18:22:27 UTC with 50 W heating budget. Native completion/readback +finished 18:23:08 UTC, cycle 29.68 s, code 0 / Success / Sensorless. Detected +R=21.3572 mOhm, L=21.6031 uH, flux=12.0932 mWb, motor limits +/-34.2135 A. +Receiver/battery settings and the right configuration were verified unchanged; +both before/after histories replicated to Core. Owner observed LEFT smooth +acceleration and 2–3 s rotation without catching. This was the flux measurement, +not the separate sustained-rotation acceptance test. Broken Hall pin is not +repaired; low-speed/loaded startup remains unaccepted. + +The operator transport was interrupted during this cycle. On reconnection, +Mini uptime proved no reboot; the locally completed receipt arrived without +replay. Tailscale relay ping succeeded and SSH resumed. Ops HTTP/MCP was already +unreachable before the cycle with the task host route matching DHCP gateway; +no VPN/routes/firewall settings were changed. + +The native result/configuration were accepted, but the outer release check +latched: its first GET_VALUES returned 3.67 A accumulated average over the +entire unpolled native cycle, despite duty=0. FW 5.02 commands.c explicitly uses +mc_interface_read_reset_avg_motor_current(). Fresh Core UI read at 18:28:18 UTC +confirmed 0 A, 0 ERPM, duty=0, fault=0. Preserve the original receipt faithfully. + +Profile 0.5.1 / Node 0.8.31-2 drains that accumulation and samples a fresh bounded +interval after release. The existing explicit neutral-return action can reconcile +only a completed, config-verified archived native result with exact live UUID, +all-peer config equality, neutral input and fresh idle values. It writes recovery +evidence and clears only its completed pending marker, without any calibration, +torque or configuration replay. Unknown completion or changed config stays +blocked. 71 fault-injection tests pass, including the actual averaging failure, +explicit recovery, changed-config rejection and unknown-completion rejection. +At this entry 0.8.31-2 is awaiting qualification/installation; sustained rotation +has not yet been run. + + +### 2026-09-23 — 0.8.31-2 installed; completed calibration recovered + +All 15 Linux qualification jobs passed in 250.69 s; 71 Python runtime tests and +909 active-Core UI tests passed, with architecture/typecheck and production build. +Source artifact `25dc6ae93ea5038f0bec4bf4`; Node package SHA256 +`cc9f023b4519f65158c7244e4f0b66b1fd38ce1180600f84be87bbb6c6fba1de`. +Owner release `192e63bb2f7992ddcf38399f` upgraded only Node after local Ubuntu +authentication. Installation completed in 18.32 s; UI ready, VESC service active +and both USB identities returned on profile 0.5.1. Native Tool bundle unchanged. + +At 18:45:03 UTC the shared Core UI invoked explicit neutral-return recovery. +At 18:45:19 it completed with authority ready, calibration_replayed=false, +configuration_verified=true and release_confirmed=true. Both controllers had +fresh 0 A / 0 ERPM / duty 0 / fault 0. The original FOC receipt was preserved; +its completed configuration was reconciled without motor/configuration replay. +The owner then freshly confirmed watching LEFT for one 2000 ERPM / 30 A limit / +30 s measured-rotation test. That test is recorded separately below on completion. + + +### 2026-09-23 — LEFT sustained-rotation acceptance + +With fresh owner observation the shared Core UI requested LEFT 2000 ERPM, +30 A temporary current ceiling and 30 s measured rotation at 18:46:16 UTC. +Completed 18:47:04 UTC with outcome duration, rotation_s=30.0574, no limit +violation, release_confirmed=true and limits_restored=true. 354 samples retained; +311 holding samples ranged 1978–2012 ERPM (mean 1998.77), 2.50–2.75 A motor +current (mean 2.615), duty 0.107–0.113, fault 0 throughout. Hold began after +4.24 s acceleration/settling; total motion-command interval was 34.29 s. +Right remained at 0 A / 0 ERPM. Final left release sample had 0.1 A / 69 ERPM +while coasting, not a claim of instantaneous mechanical stop. + +Owner confirms smooth acceleration, stable visible rotation for approximately +30 s and modest sprocket speed. This accepts the unloaded sustained-rotation +path after native calibration. It does not accept loaded startup or the original +abrupt-transmitter-demand scenario. Only LEFT has been calibrated at this point; +RIGHT still retains its original configuration. No automatic repeat was started. +Ops MCP remained unreachable on a fresh check; evidence is retained locally. + + +### 2026-09-23 — RIGHT native calibration accepted; first speed trial interrupted + +After fresh owner observation, Core UI started RIGHT native FOC at 18:52:55 UTC +with the same 50 W heating budget. Finished 18:53:37 UTC, native elapsed 28.35 s, +code 1 / Success / Hall Sensors; configuration_verified=true, release_confirmed +and overall success=true, issues empty. Detected R=21.1167 mOhm, L=21.3738 uH, +flux=11.9471 mWb, motor limits +/-34.4078 A. Hall table becomes +[255,166,98,131,34,1,66,255]. Both after-state snapshots show 0 A / 0 ERPM / +fault 0. All four before/after archives were fetched from Core. Exact decoded +comparison finds 14 right motor calibration fields changed; application and +battery fields unchanged. Left motor/application bytes remain unchanged. Owner +observed the expected short spin and later tiny positioning steps, then confirmed +understanding that this was the calibration cycle. + +The separate 2000 ERPM / 30 A limit / 30 s test at 18:54:28 UTC was interrupted +after 11 acceleration samples (~1.02 s), before speed reached the saved 900 ERPM +PID minimum. No measured hold time accrued. The right native connection closed; +the receipt could not confirm release or temporary-limit restoration immediately. +The durable latch prevented replay; the service later reconnected the same UUID +and recovered temporary limits. No service restart, host reboot or kernel USB +disconnect was observed; exact failed native RPC/cause was not retained, so this +is not attributed to a motor or electrical defect. + +Fresh UI telemetry at 18:55:39 UTC confirmed right 0 A / 0 ERPM / PWM 0 / fault 0. +Explicit neutral-return from Core UI completed 18:57:04 UTC with authority ready. +Both recovery backups match their post-calibration motor/application bytes exactly. +The original interrupted receipt is retained unchanged. After fresh owner +observation, one bounded repeat was admitted; recurring disconnect will require +transport diagnosis before any further powered retry. + + +### 2026-09-23 — RIGHT sustained rotation accepted; common-profile test implementation + +Owner freshly confirmed observing the bounded retry. Core UI requested right +2000 ERPM / 30 A ceiling / 30 s at 18:58:10 UTC. Completed 18:58:59 UTC, +outcome duration, 30.0518 s measured hold, 353 samples, no controller faults or +limit violation. Holding speed 1969–2037 ERPM (mean 2000.322), current +2.07–2.46 A (mean 2.260), controller temperature 30.6–31.2 C. Release and +original-limit restoration confirmed; left remained idle. Owner confirms right +visible motion comparable to left for the same duration. Both motors now have +independent native calibrations and physical unloaded 30 s acceptance. Left is +sensorless; right uses newly measured Hall table. Abrupt RC startup and loaded +operation remain unaccepted; one interrupted right native connection remains +a known observation, not proof that the motor is faulty. + +Owner requests simultaneous comparison and asks whether calibration is available +through the product. Existing per-VESC calibration and history UI demonstrated. +Node 0.8.32 / profile 0.6.0 adds one common `vesc.drive.run` transaction for the +complete assigned 1x1 or 2x2 profile. Placement: existing spin-test SettingsCard, +canonical Select chooses single controller or complete profile; no new root, +workspace, shared visual entity, or duplicated calibration algorithm. Revision, +exact selected membership, live UUID/session, every motor limit and all peer +inputs are checked before motion. Device owners remain upstream VESC Tool. + +Group polling/lease/speed batches run independently per USB owner, joined before +release on any failure. Commands share the ramp/setpoint; the joint 30 s clock +counts only intervals when every motor has confirmed speed and tachometer motion. +Stopping one stops the transaction; RC latches it. Original limits restore only +after zero current and neutral, including after reconnect. No powered command +replay. Receipts retain the original exception separately from cleanup results. +80 synthetic runtime tests pass, including pair/four membership, joint timing, +stationary/lost-speed peer, failed lease, partial limit ACK, RC and stale profile. +At this entry the group feature is not installed or physically accepted. + + +### 2026-09-23 — 0.8.32 qualification and owner installation prepared + +Core architecture/typecheck, 911 UI tests and production build passed sequentially +with adequate local memory headroom. The updated Core remains on canonical 8000. +Browser acceptance confirmed canonical Select and Escape focus restoration, and +correct disabled group option while the board still reports older capabilities. + +Source artifact `5e4945f3ef3a74ffe68d1619`, 411,549,546 bytes, SHA256 +`c5b53209001d8eaa86e56ed5d997224679d429692cddd10b321ec5cd2eec5b99`. +All 15 Linux qualification jobs completed in 255.70 s; peak memory 2,260,582,400 B +inside the unchanged 3 GiB / 150% CPU build envelope. Node 0.8.32-1 package +218,813,236 bytes, SHA256 +`dbef14db5cc78bea27ffd229a5335961cd989ebc89a944bac7a2dc8b7c8a2058`. +Owner release `e72c65f0b91cbbe30655730f`, SHA256 +`c34115038e8fbd1254d53d3277b373e580ea947e5789b220330f43fbd9339157`, +was built exclusively from qualified output. Fresh APT plan upgrades only Node +0.8.31-2 to 0.8.32-1, with no package additions or removals. The canonical +local Ubuntu installer is open awaiting owner authentication. No group motion +or repeat calibration has been performed during this implementation. + + +### 2026-09-23 — 0.8.32 installed; group attempt interrupted by native read timeout + +Owner authenticated the versioned installer; installation completed at +19:19:37 UTC in 17.79 s. Both devices advertised profile 0.6.0 and group capability. +After fresh owner observation confirmation, Core UI started the complete 1x1 +profile at 19:24:54 UTC: 2000 ERPM, 30 A ceiling per motor, 30 s common hold. +Preparation completed, but the native read failed 0.367 s into the command loop, +after only two samples (44.6 and 122.9 ERPM setpoints). Common rotation remained +0 s. Owner reports neither motor moved. No automatic powered retry occurred. + +The native error was `Native query timed out or disconnected`; active-loop read +budget was 60 ms. The Python boundary terminates its native owner after any +unconfirmed query, so subsequent release cannot use that owner. Left zero-current +command was sent; immediate right release/readback were unconfirmed. Original +failure receipt is retained. Explicit UI neutral-return completed 19:26:51 UTC, +both configurations were read and idle/neutral checks passed, original temporary +limits had recovered, authority ready. Neither calibration was replayed. + +No kernel USB disconnect/reset, service restart or board reboot was observed. +Both USB devices remain runtime-active with power/control=on. This rules out an +observed port removal or autosuspend event, not packet loss or electrical noise. +The old error lacks the exact failed query and native elapsed time; cable versus +reply latency cannot be attributed from it. No hardware-fault claim is admitted. + +### 2026-09-23 — read-only latency diagnosis prepared in 0.8.33 / profile 0.6.1 + +Add `vesc.link.check` to the existing per-VESC detail using canonical SettingsCard, +Button and ResourceList. It measures all present, session-matched board VESCs at +the group loop's 10 Hz cadence for 100 cycles, bounded by 25 s and the operation +deadline. Every controller is exclusively locked; only PPM and telemetry queries +are admitted. Nonneutral input or existing motion ends the measurement. It sends +no motor, lease or configuration commands. A separate 500 ms read-only budget +records replies beyond the motor loop's 60 ms cutoff; powered-loop deadlines are +unchanged. No measurement result alone grants motion authority. + +Native RPC records now retain command, deadline, elapsed boundary time, subprocess +and attachment state on failure, plus the last 32 bounded metadata records (no +payload/configuration bytes). Group/single failure receipts retain these records. +The UI no longer equates a missed group reply with a proved physical disconnect. +87 runtime tests pass, including no-write measurement, late-reply statistics, +missing reply identity, nonneutral termination, operation exclusion/idempotency, +stale sessions and stop. Physical transport diagnosis remains pending installation. + + +### 2026-09-23 — 0.8.33 diagnostic package qualified; installer launched + +Architecture/typecheck, 911 UI tests and the Core production build passed. Core +8000 was restarted only after verifying no active motor procedure, and is ready. +Source artifact `edaf094fea23f84985b8cd64`, SHA256 +`f24dbdebb0fb058140a47d9675475a0468b77fa82e71be4a8d9e1d16f3d22acf`. +All 15 Linux jobs passed in 256.98 s, peak 2,252,750,848 B under the unchanged +resource envelope. Node 0.8.33-1 package: 218,816,686 bytes, SHA256 +`e07ea0770f3feb9633b08681a3772e4f814c3e7165f400ca24ccd16cc4994c7e`. +Owner release `b08ab8c46eb5e0d97f049faa`, SHA256 +`843fda4810979c784eb03299b5914bfcb49a663a27a9f82fe867aee4d185e62f`. +APT plan upgrades only Node 0.8.32-1 to 0.8.33-1; no added/removed packages. +The local Ubuntu installer was launched; authentication/install confirmation is +pending. No powered retry occurred. Ops MCP remains unreachable; Ops update is +pending, with the full incident evidence retained privately and this redacted +ledger kept current. + + +### 2026-09-23 — 0.8.33 installed; idle reply latency measured + +After the owner corrected the local Ubuntu keyboard layout, installation +completed at 20:02:50 UTC in 17.91 s. Node is 0.8.33-1, VESC profile 0.6.1, +service active with zero restarts. The initial three rejected password attempts +made no package changes; no authentication bypass or secret handling occurred. + +Core UI `vesc.link.check` read both controllers for 12.324 s with no motor/lease +or configuration commands. All 400 replies arrived; neither device reported +motion/current/fault, and PPM remained neutral. LEFT full-call median 59.07 ms, +p95 79.63 ms, maximum 117.78 ms; RIGHT median 58.49 ms, p95 78.64 ms, maximum +114.23 ms. These are Python-boundary durations, not isolated firmware/USB response +times. Consequently they cannot by themselves prove that the native 60 ms reply +deadline is wrong or explain the earlier native timeout. Both original receipts +and the limitation are retained. No powered retry is authorized by this result. + +CPU quota is unlimited, cgroup throttling counters zero, host load low. Read-only +sysfs timing identifies repeated full-bus discovery in NativeLink.check(): one +scan median 14.65 ms / maximum 18.02 ms; paired scans median 40.28 ms / maximum +41.97 ms. It ran before and after every RPC, unnecessarily scaling with all USB +attachments and contending between controller threads. + +### 2026-09-23 — 0.8.34 / 0.6.2 removes per-request full-bus discovery + +The per-request check now reads only its exact USB path, vendor/product, device +address generation, uniquely matching interface tty and speed. It reads the +address before/after the inspection to reject replacement during the check. +Discovery still enumerates the board; its tty pattern is limited to actual +interfaces rather than driver/subsystem directories. No identity cache or timing +relaxation is introduced. Motor timeouts, stop rules and the native binary are +unchanged. RPC receipts now separate pre-check, request-write, native-response +and post-check durations and preserve the failed stage. + +Read-only execution of the pure sysfs check on Mini (no port open, installation, +motor or configuration commands) measures 2.50 ms median / 2.92 ms maximum for +one target and 5.12 ms median / 6.29 ms maximum for paired targets. 92 runtime +checks pass; seven native-boundary checks also pass after the timing assertions. +Unplug, replaced generation, changed generation during read, duplicate tty, +unrelated driver tty and path traversal are rejected. Installed-operation +acceptance and original timeout attribution remain pending this versioned update. + + +### 2026-09-23 — 0.8.34 package qualified; owner installer launched + +Source `4adfb4f84e097350eaa14102`, SHA256 +`81d00168df5328b82bb887223df69056cd51d5747e0f6a1434f782aee922c108`. +All 15 Linux jobs passed in 256.16 s, peak memory +2,242,736,128 bytes. Node 0.8.34-1 package SHA256 +`58934f48eee0d845d1643eddcbc7f02866310f498b6ccebd9585d29daa2090af`. +Release `229328c79ad99782d788d8b8`, SHA256 +`07a98e6fd3686b23d16a601f46d38bb9ebfe35110c89f3f1105166c669d3f049`. +Fresh plan upgrades only Node 0.8.33-1 to 0.8.34-1, no added/removed packages. +No active motor operation was present when launching the local Ubuntu installer; +owner sudo authentication is pending. UI/native payload and powered timeouts are +unchanged. Ops MCP remains unreachable; this ledger and private evidence retain +the update until the Ops card can be reached. + +### 2026-09-23 — 0.8.34 installed; faster idle reads, powered timeout isolated + +Installation completed 20:17:52 UTC in 18.54 s, all services active with zero +restarts. UI link check at 20:22:28 received all 400 replies in 10.016 s, no +motor commands, faults or motion. Full-call medians LEFT 9.95 ms / RIGHT 9.80 ms, +maxima 19.78 / 21.70 ms. Native-response maxima 1.09 / 1.43 ms; the removed +full-bus checks explain the previous full-call overhead, not the powered fault. + +Owner explicitly observed the next UI group run: 2000 ERPM, 30 A ceiling each, +30 s common rotation. It stopped 0.484 s into initial ramp, after four samples +and a maximum command of 195.81 ERPM. Common rotation 0 s; owner confirms both +motors stayed still. RIGHT command 31 (decoded PPM) failed inside native +exchange after 60.09 ms; Python pre-check was 4.31 ms. Native process was alive +and exact attachment present. Kernel journal has no USB event, service no +restart. This isolates the native reply timeout but does not prove wire/MCU +versus suppressed native transmission. Immediate RIGHT release/readback was +unconfirmed; UI stop followed by explicit neutral recovery completed 20:25:40 +UTC, authority ready and temporary scales restored. No powered retry followed. + +### 2026-09-23 — 0.8.35 / 0.6.3 native exchange diagnostics candidate + +The adapter records bounded metadata around a failed native exchange: requested +command emission, packet transmission, serial bytes-written, decoded incoming +packet IDs, serial error/open/pending-write state and monotonic event times. +No payload contents are recorded. Error details survive the Python fail-closed +boundary; no motor command is retried. Timeout, ramp, current, calibration and +upstream source remain unchanged. Scoped observers and a pending-query guard +are released on normal completion and exception. Build and installation pending. + +### 2026-09-23 — 0.8.35 qualified; local owner installation pending + +Native diagnostic artifact `48f470f0209ccbf97ff77271` passed 11 archive, +negative-input and offline-engine checks in 36.69 s, preserving all 286 upstream +objects. Runtime SHA256 +`cc78c273e025f0738ed79f94d4bc6a70e504f2e7204b1ef694119e6a230b913a`. +Python runtime suite: 93 passed. Source `a661c4ecd4553728ab73d2cc`, SHA256 +`a616faf9f360066c4763fbbdd261c4e0955e5358d1bc45728770ad2016ec4e62`, +verified on Mini. All 15 Linux qualification jobs passed in 256.41 s. +Node 0.8.35-1 package SHA256 +`b95e050e38d347d139e16b37f33bdf2c9d9f9a828a01457d1dae38d4a6971ddc`. +Owner release `4d72eed539c3755b5cb14359`, SHA256 +`1c703adb207ea8373195ad0794905d80ab39941fa35f89e3a468894129936935`. +Fresh plan upgrades only Node 0.8.34-1 to 0.8.35-1; no added or removed packages. +Both VESC were online and inactive before launching the local installer. Ubuntu +owner authentication is pending. The diagnostic change is not a claim that the +missing powered reply is fixed; acceptance requires fresh observation after +installation. Both original calibrated configurations remain in the archive. + +The slow normal rsync transfer completed and matched the canonical source SHA +before a prepared compact transport fallback was needed; the fallback was not +executed on the Mini. The successful upstream Tool report is in build +`d1797bf1152f59ee14012ed5` and points to the qualified source/object tree in +`f611147350b77dfa0006b7d8`; the latter's original report is not successful. +Ops MCP still returns an HTTP transport error; local evidence is retained. + +### 2026-09-23 — 0.8.35 installed; idle native transport accepted + +Owner authenticated locally; installation completed 20:51:39 UTC in 18.44 s. +All steps passed, UI ready, services active and restart counters zero. Installed +engine SHA256 `9d2d6a87032e3c60f2666cadd5d5d1520edac05087e0dcb7a5ac3875f2ace325` +matches the qualified binary; both device sessions report VESC profile 0.6.3. +The first UI read-only check completed 400/400 replies in 10.015 s without +motion, faults or commands. Full RPC maxima LEFT 18.14 ms / RIGHT 20.47 ms; +native response maxima 1.28 / 1.24 ms. Powered diagnostic retry is awaiting the +owner's fresh observation readiness; no powered acceptance is claimed. + +### 2026-09-23 — 0.8.35 powered query emitted; RIGHT reply missing within deadline + +The observed UI group run (2000 ERPM, 30 A ceiling each, 30 s common rotation) +stopped 0.289636 s into its initial ramp. Two samples, common rotation 0 s; +owner confirms both motors remained still. RIGHT GET_VALUES command 4 was +emitted, one six-byte packet was written by QSerialPort at 0.491 ms, with no +decoded incoming packet before the 60 ms configured deadline (59.212 ms +measured by the coarse Qt timer). Port remained open/connected, serial error 0, +no pending output bytes. Python attachment pre-check took 3.802 ms and native +response wait 59.920 ms. The native process and exact USB attachment were alive. +No USB kernel events or service restarts occurred in the retained time window. + +This rules out a suppressed request for this failure. It does not distinguish a +late reply, framing loss, USB transport problem or controller-side delay. +Immediate RIGHT release/readback was unconfirmed; UI stop and explicit neutral +recovery completed at 20:55:37 UTC with authority ready and temporary limits +restored. Original failure receipt remains unchanged. No automatic powered +retry followed. Next discriminating check requested from the owner: interchange +only the two VESC USB plugs at the Mini, verify UUID-to-port mapping read-only, +then coordinate any new powered observation. This physical change is still +pending; neither the USB cable nor controller is declared faulty. + +### 2026-09-23 — first accepted simultaneous rotation after USB relocation + +Owner relocated both USB plugs to two different Mini ports (not a reciprocal +swap). Native UUID identity and the persisted LEFT/RIGHT profile bindings were +preserved automatically. No source, package, calibration, timeout or control +parameter changed between the failed and successful powered attempts. + +The UI idle link check received 400/400 replies in 10.015 s. Full RPC maxima +LEFT 14.93 ms / RIGHT 13.99 ms; native maxima 1.174 / 1.158 ms. The subsequent +owner-observed UI group test started 21:05:15 UTC and completed 21:06:02 UTC: +2000 ERPM, 30 A ceiling per motor, 30.047580 s common rotation, 342 samples +including 301 holding samples. LEFT held 1968–2012 ERPM (mean 1998.67), motor +current 2.48–2.71 A; RIGHT held 1974–2038 ERPM (mean 1999.84), motor current +2.07–2.43 A. Both fault codes stayed zero. Both zero-current releases were +confirmed and original temporary current scales restored. Kernel journal had +no event in the test interval; Node stayed active with zero restarts. + +Owner confirms both motors started together, ran evenly at matching apparent +speed for about 30 s and stopped together. This accepts this simultaneous, +unloaded test. USB relocation/reseating is correlated with the change in +outcome; it does not establish a defective port/cable or long-term transport +reliability. Original abrupt RC startup, loaded drive, damaged Hall wiring and +independent communication-loss torque-off remain separate outstanding checks. +No further automatic motor run followed. Private receipt, owner observation, +identity mapping, statistics and SHA256s are retained in acceptance-035-group.json. + +### 2026-09-23 — owner RC acceptance; follow-up Hall comparison blocked in preflight + +After the accepted common-speed test, the owner reports excellent operation of +both motors from the RC transmitter, in response to the requested gradual and +abrupt-start comparison. This is owner-observed unloaded acceptance; no RC +command/timing telemetry was captured. Working LEFT sensorless and RIGHT Hall +calibrations remain unchanged. + +Owner requested a separate comparison of Hall inputs and explicitly confirmed +transmitter off and observation of both sequential 5 A native measurements. +The LEFT UI request at 21:14:42 UTC failed during preparation, before a new +backup or Hall result. A subsequent ordinary telemetry read also failed. +LEFT then failed identity confirmation and became transport-local/degraded; +RIGHT retained its prior verified session. Linux still enumerated both USB +attachments with unchanged addresses and had no kernel event; both services +remained active with zero restarts. No new Hall procedure or configuration +write is evidenced; no powered retry was issued. Owner was asked whether main +power remained on. The prior LEFT four-state Hall result and RIGHT successful +six-state calibration table remain the available comparison, not new results. +This recurrence means the earlier port relocation cannot be treated as a +confirmed repair of remote transport reliability. + +### 2026-09-23 — USB reconnection retains identity; idle read failures recur + +Owner confirmed both VESC remained powered, unplugged LEFT USB and reconnected +it to the same port. Both native UUIDs and LEFT/RIGHT assignments were verified +again at 21:30 UTC. Linux logged descriptor/address errors (-71) during that +reconnection, then successfully enumerated the device. Those enumeration errors +are a separate observation, not proof of the cause of later missing replies. + +UI read-only link checks at 21:34:17 and 21:51:53 UTC each failed on the first +GET_DECODED_PPM request to both controllers. In both checks, the native adapter +reported an emitted request and six serial bytes written, open/connected port, +no serial error, and zero decoded reply packets within the 500 ms diagnostic +deadline. No motor command or configuration write was sent. Both services +remained active with zero restarts. USB power/control was on, runtime active, +and suspended time zero; both tty devices carried ModemManager ignore flags. + +Automatic native reconnect temporarily restored verified identities, and an +ordinary LEFT telemetry read succeeded at 21:36:57 UTC (50.3 V, PWM zero, +fault zero). A separate UI link-check attempt did not receive confirmation +during a stale board-link interval and is not counted as a completed test. +Identity verification alone therefore does not establish current command-channel +health. Neither USB hardware nor our adapter is exonerated by these observations. + +No additional Hall measurement started. After renewed observation confirmation, +LEFT was again unavailable and its UI action remained disabled. Owner was asked +for one complete power cycle of both controllers with USB also disconnected, +then reconnection to the same ports. That recovery is pending; working motor +calibrations are not changed. The private receipts and kernel journal are +retained under hall-035-*; Ops MCP remains unavailable with an HTTP transport +error, so this update has not been published to the project card. + +### 2026-09-23 — owner requires diagnosis on the running installation + +Owner declined the proposed power cycle and further reconnection. That request +is withdrawn; no board reboot, physical reset, service restart or installation +was performed. Hall comparison remains incomplete. Existing calibration and +the accepted unloaded/RC observations must not be conflated with USB reliability. + +Separate ordinary input reads were submitted through Mission Core's existing +vesc.input.read operation, with no motor/configuration commands. LEFT failed +with the installed generic error. RIGHT completed at 21:59:42 UTC: decoded +level -0.065999, pulse length 1.466 ms. Its accepted application configuration +sets PPM hysteresis to 0.15. FW 5.02 app_ppm.c exposes input_val before applying +utils_deadband, but our host tests used a fixed 0.02 threshold. This is a +confirmed mismatch that can falsely label an input inside the VESC neutral +band as an RC motor command. It does not explain USB query timeouts, and a PPM +value does not establish whether the transmitter's radio link is present. + +Candidate Node 0.8.36-1 / profile 0.6.4 reads each device's admitted PPM band +from configuration for preflight, single/group motion and Hall monitoring. +Recovery rereads/verifies application configuration; missing/invalid bands +block motion. The idle link diagnostic reads application configuration too. +Actual input beyond that device's band still preempts and latches RC authority. +No VESC configuration is changed by this correction. Ordinary and preflight +native errors retain command/stage/transport/history in receipt result.failure; +native traces identify the exact USB attachment. Product errors remain concise. + +99 local synthetic tests passed, including different per-device bands, changed +configuration between operations, active RC preemption, no-write link checks, +failure evidence persistence and idempotency. Existing native Tool binary and +all motor deadlines remain unchanged. Candidate is not installed or accepted +on hardware; preparing it does not authorize restarting the running services. + +The immutable candidate source is `6cd91f87045f3fb2bb8d9f14`, SHA256 +`954f19c2ace4c0186c5a0e96eb2196637481a4818bb871c1d857a86b7492b1ca`. +All 15 bounded Ubuntu build/qualification jobs passed in 276.20 s. Package +0.8.36-1 SHA256 +`ca471e1cfd90eea4e71014b7be020e0a0459fea017668cd657e7e01d9dab05d4`; +owner release `f1d300d6ca0954ba007e7a50`, SHA256 +`f990e5d2a3a1c7a4e2bc8c1f71720c6a9ee6393a8756437645fd9e056ef6171c`. +Only the release's `--plan` ran: APT proposes one Node upgrade, no added/removed +packages. No installer window was launched. Installed Node remains 0.8.35-1; +Node and VESC service PIDs are unchanged and restart counters remain zero. + +Applying this existing Node installer would restart Node/VESC and monitoring, +including its monitoring database, and cycle the configured optional device +services according to preinst/postinst. It is not a restart-free hot patch and +is not described as only a VESC restart. Physical power/USB changes and a Linux +reboot are not part of that update. Owner agreement on software service +interruption is needed before applying under the current no-restart constraint. + +### 2026-09-24 — post-boot absence and power-profile research + +Owner reports board booted and requests a refreshed plan, investigation of +missing VESCs, and explanation of native power profiles. Power-limit changes +are explicitly deferred. SSH works; installed Node remains 0.8.35-1 and both +Node/VESC services are active with zero automatic restarts in this boot. +Read-only Linux inspection finds no VESC USB enumeration and no ttyACM/by-id +ports. Boot logs show descriptor/address failures (-71) on two USB ports; +unidentified devices cannot yet be attributed to a particular VESC. Owner was +asked to confirm present VESC power/cables and any changed connections, without +requesting disconnection/reset. No service restart or controller command ran. + +Core retains one configured offline VESC and serves both controllers' archived +configurations, but the other controller is absent from inventory. Source review +shows the persisted drive profile is exposed only inside live inventory items; +Node's offline registry is updated by explicit preparation, not every verified +discovery. Known-device persistence and independently available drive profiles +therefore need product work separate from USB recovery. Direct SSH reading of +the protected profile file was denied; no permission workaround was attempted. + +The latest confirmed archived configuration has motor limits 34.2135/34.4078 A, +100% acceleration scales, 55 A battery limits per controller and no separate +watt cap. These are historical readbacks, not fresh hardware measurements or +manufacturer-approved ratings. Native profile temporary/permanent semantics, +CAN propagation and per-device readback requirements are documented in +20_VESC_POWER_LIMITS_PLAN.md. No power UI/runtime changes were implemented. +Private boot-20260924-* evidence remains outside Git. Ops MCP still fails at +the instruction call with an HTTP transport error; this update is not in Ops. + +Owner subsequently confirms both VESC USB cables are connected and both motors +work from RC now. First USB enumeration errors appear at boot monotonic 9.124 s, +before VESC process start at 11.111 s and Node at 13.430 s. This separates the +initial boot enumeration failure from current application-driver activity; it +does not identify the failing hardware or exclude USB firmware/host issues. +There are still no ttyACM devices. No reset, movement or configuration change +was issued by the agent during this audit. + +Owner confirms all USB devices were removed and reinserted in different ports +while starting Mini. Audit of installed runtime and udev rules finds no fixed +port requirement: discovery enumerates all USB device paths matching the model, +permissions match descriptors, identity is derived from firmware UUID, and drive +bindings store device_id/UUID. Installed serial.py and drive_profile.py SHA256s +match source exactly. Port/address checks protect one connection generation and +do not determine persistent motor assignment. Three focused synthetic tests +passed; an additional synthetic move of both controllers to different bus, +port and tty names retained both identities and left/right assignments. + +At the latest read-only inspection all four USB2 root ports are active, each +reports zero over-current events, and no VESC tty exists. These attributes do +not certify cable or electrical signal quality. The owner was offered one +controlled USB reconnection into the same current port to distinguish persistent +enumeration failure from boot-time state, with Mini/main VESC power kept on and +no commanded movement. This remains pending explicit owner response under the +previous no-reconnection constraint. No reset or controller command was issued. + + +### 2026-09-24 — owner reconnect and artifact-owned startup changes + +Owner subsequently reconnected USB. Both controllers reappeared without a +service restart: the right instance on ttyACM0/port 1-3, the left on ttyACM1/1-2. +Firmware-derived device identities and the 1x1 profile revision 2 retained both +assignments. Kernel evidence records two enumerations about ten seconds apart; +this is not evidence that one physical reconnection restored both controllers. +Node/VESC remained active with Node NRestarts=0. No motor command was issued. + +Owner requires GUI autostart through the existing environment configuration, +boot-only recovery of failed USB enumeration, no USB control surface and no reset +behind inventory refresh. Owner then extended the artifact-owned OS configuration +rule to all onboard development and Linux environment profiles. The repository +AGENTS.md now records that invariant. + +Candidate Node 0.8.37-1 adds environment profile revision 3, owned XDG autostart, +service-readiness wait, fixed boot USB recovery and individual-hub capability +inspection. Port recovery checks the current boot's terminal kernel errors, +empty port and companion, hub generation and power switching support; it records +pending re-enable before any change and has bounded retries/cleanup. See +21_STARTUP_AND_USB_RECOVERY.md. Neither the USB policy nor autostart is enabled +by copying files manually or by this source edit; the shipped environment setup +owns activation. No warm USB reset, hardware test or reboot has been performed. + +35 focused Python tests passed locally; shell syntax and diff checks passed. +Ubuntu artifact qualification, installation/preparation and cold-boot acceptance +are pending. The board's actual individual-port power capability is still unknown. +Current services and both ttyACM devices remain available. Ops publication remains +blocked by the previously recorded direct-MCP transport failure. + +Pre-install review added a guard and regression for a hub replaced during its +companion descriptor inspection. All 36 focused tests now pass; the first +source snapshot is superseded before any build/install. No runtime change. + + +Ubuntu qualification completed for source 4b32759c1bc19f3c6b64c983 in 253.855 s: +17 jobs passed, including Node UI build/tests, Go race tests, 36 environment / +USB / desktop tests, systemd unit validation (empty stderr), and 99 VESC tests. +Package 0.8.37-1 SHA256: +2171120488a30530e8603a9f8f1a757a7ad65e02138b57a245d5620a28c01e02. +Owner release dbc5e717ee36ebb521f28fa4 SHA256: +06eeff49bda51662c041b25e675be9d6037a5f5a3acf6d27e014a87bfdebc59b. +APT simulation: one Node upgrade from 0.8.35-1, no new packages or removals. +This is prepared-Ubuntu qualification, not clean-image or cold-boot acceptance. + +The release's own --launch opened its local Ubuntu installer. Owner was asked +for the OS sudo prompt in that local window. Installation and the subsequent +in-application environment setup are pending; no arbitrary root command or +manual OS configuration was used. Both controllers were readable and no motor +test was active immediately before opening the installer. Core on 8000 remained +HTTP 200 with one canonical listener; no listener on 8765. Ops MCP was retried +once after the long build preparation interval and still failed at instructions. + + +Owner entered sudo in the artifact's local installer. Readback confirms +0.8.37-1, dpkg `install ok installed`, Node/VESC active/running with NRestarts=0, +and installed USB helper SHA256 identical to the qualified source. Core sees +both original VESC identities, readable=true, test_active=false, profile 1x1 +revision 2 unchanged. No controller configuration or power limit was written. + +Owner ran «Система → Настройка окружения → Сконфигурировать» in the onboard UI. +All nine revision-3 steps completed. App-owned XDG entry and USB policy are +root-owned 0644; the boot recovery unit is enabled, inactive/dead (not executed +in this warm session). Both ttyACM devices remain present. Capability inspection +reported at least one individually switchable hub; exact per-hub inspection is +root-only before the first unit start (preparation umask makes its /run directory +0700; systemd RuntimeDirectoryMode=0755 applies when the unit starts). Do not +infer root-port compatibility from the aggregate preparation status. No manual +permission repair was made. + +Owner asks for the next acceptance step: an orderly full Mini shutdown and +power-on, retaining USB cables and VESC main power, without manually opening +Node or reconnecting devices. Cold-boot recovery, exact root-port capability, +GUI startup and persistent motor assignments remain to be observed. The agent +has not issued a reboot or shutdown command. Ops publication still unavailable. + +## 2026-09-24 — observed restart and board settings UI, Node 0.8.38-1 + +Owner restarted the Mini. A new boot was observed; Node and VESC became active +with NRestarts=0, both original firmware UUIDs were readable, and profile 1x1 +revision 2 retained its left/right assignments despite new port locations. +GNOME reports the MissionCoreNode application scope launched by +gnome-session-binary. The boot recovery result is complete with an empty retry +list: enumeration succeeded without a port reset. Its boot_seconds field is the +job's initial timestamp, before the mandatory wait; services began after the +30-second window. This does not qualify recovery during a real enumeration +failure, individual root-port switching, or the exact physical cold-power +sequence. No agent-initiated reboot, USB reset or motor movement occurred. + +Owner requested three collapsible blocks in the existing vehicle surface and +the onboard device surface. See 22_BOARD_SETTINGS_SURFACE.md. Shared DG Inspector +composition now holds computer information, board settings, and devices. JSON +layout persistence uses independent section patches, separate vehicle files in +Core and the local presentation store in Node. Navigation cannot discard a +pending save. Empty/all-closed layouts, invalid data and concurrent changes are +covered. Inventory lifecycle remains outside the collapsing content. + +The global drive profile and assignments moved out of individual VESC cards. +Changing 1x1/2x2 preserves existing compatible UUID bindings and never commands +motors. New limits.read exposes the native Tool-decoded motor, battery, speed, +watt and duty settings. It is read-only; no hardware ratings, arbitrary reserve, +power write, motor recalibration, or direct OS configuration was introduced. + +Local checks: two API/storage tests, five layout state tests, seven VESC UI +tests, 93 architecture/plugin checks, both TypeScript checks and active Core +production build passed. All 102 VESC synthetic tests passed. Real Core browser +QA confirmed that closing computer/settings survives a full page reload and +reopening the vehicle; both assigned controllers remain visible. The canonical +8000 LaunchAgent was restarted through its exact process group and new health +and layout API were accepted. + +Qualified Ubuntu source ffed12d0fba14f693d52d329 passed all 17 jobs, including +Node build/UI tests, Go race tests, and environment/USB/VESC regressions. +Package 0.8.38-1 SHA256: +cd6fd8bcc2f31f87cad8b406893084ec9d8441bebf555c424c7db5bc66fc2dd6. +Owner release d22b3c002f38c1d842b35526 SHA256: +3cde842b1f96467930460ff19e716574b7236a308322bdd720400701d558f014. +APT plan: upgrade only mission-core-node from 0.8.37-1, no additions/removals. +The artifact-owned local installer was opened and the owner was asked to enter +the Ubuntu sudo prompt. Installation and real limits-read acceptance pending. +Ops direct instructions endpoint was retried and still failed at HTTP transport; +this ledger is local evidence, not a claim of Ops publication. + +Browser QA also confirmed keyboard Enter toggling and persistence of the empty +all-closed layout after reload. The original all-open layout was restored after +the test. The installation check still reports 0.8.37-1; the prepared 0.8.38-1 +installer awaits the owner's local sudo entry, so new Node UI and live limit +readback are not yet accepted. + +Owner entered sudo and 0.8.38-1 installed successfully. Acceptance caught a +release integration defect: the bundled VESC driver declares 0.6.5, while the +Node model registry still required 0.6.4. Node correctly rejected the mismatched +driver snapshot, leaving provisional USB entries instead of the confirmed +controllers. This is an application admission defect, not evidence of USB +failure. No port reset, environment reconfiguration or controller write was +used as a workaround. + +Corrective package 0.8.38-2 aligns the Node registry with the bundled 0.6.5 +driver. A Go regression now reads both bundled driver and preparation metadata +and compares their versions to the Node declaration. Source snapshot +b0af9cd57565e35f41554380 SHA256: +a92d0bc5695624846afe6ab2056c261ca9df8f247611db5f50b2747552fd2e06. +Ubuntu qualification and corrective installation are in progress. + +Corrective qualification completed in 256.927 s: all 17 jobs passed, including +the new cross-package version regression in the Go race test run. +Package 0.8.38-2 SHA256: +9443c079d4396adc569445ccbe745152c164732b31474ac526cd2b5eb1423a94. +Owner release 851ee3935d7db0de2d6be048 SHA256: +348fa611c9b0a2ed361c144c4a6ec2798c45a0a4952f2bab7123f10f892ad4ba. +APT simulation upgrades only Node 0.8.38-1 to 0.8.38-2, without added or removed +packages. The release opened its local Ubuntu installer; OS sudo authorization +and live read-only acceptance are pending. No direct OS edits were made. + +After the corrective installer launch, the board stopped responding to SSH; +Core's last observed heartbeat was 12:51:14 local time. Bounded Tailscale status +inspection reported the local client Running/online and the target Mini +offline; its existing tailnet route remained on the Tailscale interface. Two +SSH checks timed out. These observations do not establish whether the install +finished, or why the board went offline. Owner was asked for the visible Mini +and installer state; no reboot, USB manipulation, route change or additional +installation attempt was initiated. Post-install identity and limits-read +acceptance remain pending until the board returns. + +Owner subsequently reports a black Mini screen. Fresh bounded checks still +show the Mini offline in Tailscale and SSH timing out. The owner was asked to +try a single Shift/mouse wake and report the power LED / monitor signal state, +without a reboot. Static audit of both immutable source snapshots confirms +identical preinst/postinst/prerm/postrm, installer and launcher scripts. The +normal upgrade path restarts Mission Core services; no suspend, shutdown, +reboot, display-manager stop or network stop was found in that path. VESC +preparation reloads udev rules and triggers change only on discovered VESC tty +devices; startup port recovery is not started by the installer. This audit is +not proof of causality or exclusion: the actual last completed installer step, +system journal and host resource state are unavailable while the Mini is +offline. No new package, OS mutation or hardware command was issued during +this incident investigation. + +Owner identified a loose cable and restored it. The Mini returned on a new +boot; Node 0.8.38-1 is fully configured, `dpkg --audit` is empty, and Node/VESC +services have zero restarts. Startup USB recovery again completed without any +port retry. Root filesystem has about 340.8 GB free. The prior boot journal ends +without an orderly shutdown entry in the inspected tail. The cable report and +recovery support power interruption; no software shutdown was commanded. + +The interrupted release's staged deb was truncated to 109051904 bytes instead +of 218843100. The original installer archive still matches its SHA256; scripts +and release manifest also match. The launcher's checksum guard rejected the +truncated staging, and no 0.8.38-2 installation had been completed. Existing +staging is preserved. The product launcher now writes into a temporary file, +fsyncs it before publication without overwrite, and fsyncs directories before +opening sudo. It continues to reject modified files and symlinks. Four focused +interruption/idempotency/integrity tests passed locally and on Ubuntu; they are +also added to future Linux build qualification. + +An artifact-owned temporary owner-release build repackaged the unchanged, +qualified 0.8.38-2 deb. The first wrapper lacked two installer inputs and failed +before producing a release; the complete second wrapper passed its four tests. +Wrapper SHA256 a4cbc35f1bf5af5fa62f60920c389fe54c0d5f84cbd574b02cb696d400f4df2d. +New owner release 3f418604a94057e97414d71a SHA256: +b4eb8ba129c4ba6c8ea1750be6a85aba5c2dbdcaa98abb92c56a47d22377e337. +APT simulation remains one Node upgrade with no additions/removals. Its local +Ubuntu installer was opened; owner sudo and live acceptance remain pending. +No installed OS file or controller configuration was manually repaired. + +Owner asks whether the tracks can be fitted and repeats that a contact was +torn from wiring labelled Hall, with side/contact unknown and no soldering or +replacement pins available. Archived canonical FOC receipts confirm LEFT +sensorless and RIGHT Hall calibration; independent and simultaneous unloaded +30-second tests and owner RC checks passed. The separate Hall comparison +remains incomplete, loaded startup is unaccepted, and the previous LEFT +four-state observation alone does not identify a physical broken pin. Owner was +advised to finish the Hall investigation while the drivetrain is unloaded; +there is no new motion authorization and no diagnostic motor run in this entry. + +The owner subsequently authorized necessary unloaded diagnostics and confirmed +tracks removed, rover raised, transmitter off and attendance. Asked about the +means of interrupting the noninterruptible FW 5.02 native Hall cycle, the owner +identified an Anderson battery connector as the only disconnect. Its exact +model and load-break rating are unknown; no instruction to unplug under load +was given. No new Hall or other motor procedure has started. The existing +0.8.38-2 installer still waits at local sudo; installed Node remains 0.8.38-1. + +The owner supplied three transmitter photos. Exterior matches the official +FlySky FS-i6S diagram, with Robcom Venom Drone marking; hardware/firmware +identity remains provisional until its About screen is read. The old receiver +photo identifies FS-iA6B. Official FlySky Mix/Models/failsafe documentation and +VESC 5.02 PPM source were reviewed. Existing archived PPM settings decode as +Duty Cycle on both controllers, with different response curves/ramps; no +configuration was changed. The two requested tank/arcade profiles and their +input/fallback requirements are recorded in 23_ROVER_CONTROL_PROFILES.md. +No native radio mixing capability or live profile switch is claimed accepted. + +Owner clarified the field-control requirement: an enabled, neutral transmitter +may accompany autonomous/remote driving; stick input must immediately take +authority without a UI mode switch and latch out all Core sources until an +explicit neutral handback. This is separate from selecting tank/arcade mapping. +Read-only source audit confirms the native decoded-PPM read and existing bounded +test latch/250 ms PPM-output leases. Neither full radio-channel capture nor a +qualified continuous driving arbiter is claimed. Firmware-side lease expiry +does not cover faulty software that keeps renewing it. The permanent authority +contract and maintenance-calibration exception are recorded in plan 23. No +network scan, radio/receiver change or motor command was performed in this audit. + +Corrective owner release 3f418604a94057e97414d71a completed at +2026-09-24T11:04:21.135514Z, duration 17.846 s. dpkg confirms Node 0.8.38-2 +fully installed; Node and VESC services are active with zero automatic restarts. +Core now admits exactly two verified VESC snapshots at plugin version 0.6.5, +both publishing board-settings capability. The 1x1 profile remains revision 2 +with the same UUID assignments; test_active and rc_latched are false. + +A bounded engineering probe through existing Core/Node SDK actions performed +six read-only vesc.input.read calls, three per controller, without motor, +lease or configuration writes. At 11:05:39–11:05:46Z the RIGHT decoded input +was approximately −0.058 to −0.060 and 1.470–1.471 ms; LEFT was +0.074 to +0.076 +and 1.537–1.538 ms. These are raw inputs near the archived neutral bands, not +proof of radio-link state or independent transmitter switch positions. + +The owner then corrected the switch hypothesis: motors remain controllable +with all four transmitter toggles down. The proposed SWA comparison was +cancelled; initial readings carry an operator-reported condition only and do +not establish causality. No new Hall/FOC procedure or driven test was started. +Private installation, fleet and RC receipts remain in native-probe evidence. + +Owner now requests stop-first RC takeover: first stick input cancels autonomous +and remote motion, subsequent input may drive manually. Clarification was sent +to distinguish another packet of a held stick from a deliberate second gesture +after neutral. Existing direct PWM and expiring test leases do not implement +stop-first; simply releasing the lease would pass the original deflection to +the motor. This limitation and the required command-revocation/neutral boundary +were recorded in plan 23. No live control change or driven test was performed. + +The owner explicitly confirmed the sequence: stop → neutral → manual control. +Plan 23 now records this as accepted, including both input channels, rejection +of delayed Core commands and no automatic autonomous resumption. The first +held deflection cannot become a drive command merely because another packet +arrives or a delay expires. Ordinary gestures once already in manual control +do not repeat the takeover procedure. + +A bounded source audit checked the cached FW 5.02 commit +3f670137e27e6e383fa79c50cc6b1fa85aab1554 against its Git tree blob hashes. +Safe Start is not rearmed by expiry of app-disable output. Persistent app +configuration writes, indefinite output disable and restarting applications +through CAN-mode configuration were rejected as takeover mechanisms. The +current native release sends zero current, not a verified braking or neutral +gate command. A healthy-Mini wait loop cannot guarantee the same gesture +semantics after loss of Mini/USB. Coordinated actuator-side support remains +necessary to qualify the full requirement; no firmware or working RC settings +were changed. The FS-i6S manual's assignable-switch semantics were also recorded; +actual switch assignments and transmitter firmware remain unverified. + +Official VESC documentation identifies stock LispBM support from FW 6.00 as +a candidate for controller-resident input arbitration, not an accepted solution. +It documents PPM value/age and PPM override; direct-command bypass, coordinated +multi-controller behavior and script-failure handling still need qualification. +The hardware marker alone is insufficient for firmware selection. The owner was +asked for the controller manufacturer/model if known. No update or script was +uploaded, and no motion was commanded. + +Owner requested software-only controller identification before considering +physical access. A bounded audit used eight existing read actions through +Core/Node/native Tool: backup, telemetry, PPM and CAN ping for each controller. +All completed. Read-only SSH collected Linux sysfs USB descriptors without +opening serial, resetting ports or changing the host. Both distinct VESC UUIDs +and FW 5.02 / 75_300_R2 were confirmed; USB descriptors and USB serial strings +are identical. Each backup decodes into 151 motor and 149 application parameters. +Core history contains both new backups, and their motor/app SHA-256 values +match the accepted 2026-09-23 21:05 UTC versions. Calibration was preserved. + +Both CAN queries returned no peers; physical wiring is not inferred from that +result. No movement, configuration write, restart or firmware operation occurred. +The manufacturer and commercial board model remain unconfirmed: Flipsky's own +75-series documentation explicitly describes multiple boards using 75_300_R2; +this does not identify these boards as Flipsky. Private receipts, decoded +passports, USB evidence, archive acceptance and hashes are saved under the +identity-audit-20260924 artifacts. Current-version diagnostics do not require +disassembly; exact update compatibility remains a separate evidence requirement. + + +## 2026-09-24 — Hall preflight and sensorless standstill, Node 0.8.39-1 + +Before any Hall cycle, read-only link.check stopped with not_idle: LEFT +reported -161 ERPM, zero wire duty and about 0.08 A. Repeated individual reads +reported -140 to -168 ERPM, zero input current/duty and 0.06–0.10 A motor +current. RIGHT reported zero ERPM. Owner explicitly observed the LEFT leading +sprocket fully stationary. No driven command or native procedure was sent. +Private preflight, idle-read and idle-observed receipts retain UTC/monotonic +identity and raw telemetry; their SHA256 values are respectively +229df6a4abbe55d03e0bbfcbc1331647e2bd6768e6d2b7b16ac9be4736f07734, +adab11366c597579259b53bdecc0b9e602a197b5933665cdcb4201b540a13738, +d39185797ddc1b3e99385e922161aabac1121df67c94922d099eae212cc6825a. + +Pinned FW 5.02 mcpwm_foc.c (3f670137e27e6e383fa79c50cc6b1fa85aab1554) +continues observer and PLL updates while undriven; get_rpm and tachometer use +that phase estimate. Changing tachometer is not independent movement evidence. +This explains why the old ±30 ERPM stationary gate cannot reliably admit an +attended sensorless Hall measurement. It does not prove the observer's error +magnitude or motor state without the operator's physical observation. + +The correction is scoped to Hall measurement. New requests must explicitly +confirm all motors physically stationary. For FOC sensorless mode only, that +observation replaces the speed gate while wire duty must be exactly zero; +finite speed is still required. Other idle electrical/fault/temperature bounds +remain, battery current must be within ±1 A, and fresh telemetry plus PPM +neutral are checked ten times before any lease/current write. Sensored Hall +preflight and every ordinary motor/FOC test retain the existing speed gate. +Raw preflight values and the observation flag are archived in the Hall receipt. +The Tool algorithm, current, duration and no-table-write contract are unchanged. + +Core and Node reuse the existing Hall confirmation control; new clients send +the observation field only to a board advertising the new capability. The +0.6.6 driver rejects old clients lacking the explicit observation. No live +runtime bypass or OS edit is introduced. Package qualification, installation, +observer resynchronization and actual Hall comparison are still pending. + + +Local acceptance: all 109 VESC tests passed, including seven Hall standstill +fault-injection cases. The active Core passed four architecture tests, +TypeScript, all 916 unit tests and production build. Its existing port-8000 +process serves the exact new index SHA256 without a server restart. In-app +browser verification shows the Hall observation text and a disabled measurement +button while unconfirmed, in normal and expanded presentation; no measurement +control was activated. Escape was exercised but did not exit the existing +expanded vehicle surface; this unchanged window behavior is not accepted by +that check and was not modified in the Hall fix. + +Immutable source b6097066b4068f72483c4b68, SHA256 +37896e9d6b7df1b6f0170aab073761aaa81de2ba05cd48ace9508c1bc1749c16, +was transferred and verified on the Mini. Its unprivileged, bounded build is +running; installed runtime remains 0.8.38-2 until owner installation. Exact FW +source blob 416eacbadb2696081d5e85e4342cd798f5d08906 was verified against the +pinned Git tree. Ops instructions endpoint again failed at HTTP transport; +no Ops write was attempted or claimed. + + +Ubuntu qualification completed in 255.491 s; every recorded job passed, +including VESC regressions, Node UI build and Go race tests. Node 0.8.39-1 deb +SHA256 e0ceb0116be62962944657723d30bf14498491c5dc34902be00845d716a87b26 +(218843958 bytes). Owner release f196781a2f4ff411ada25090 SHA256 +09eed256684a2c70b52318e33a6df02a01848feb644f2e50fac6c7129ede0f51. +APT simulation upgrades only mission-core-node 0.8.38-2 → 0.8.39-1 with no +added/removed packages. The artifact opened its local Ubuntu installer; owner +sudo entry and live acceptance are pending. Hall comparison has not started. + + +Owner entered sudo. Installation e96d63c6a3364b25bde5bb3a8813a12c completed +at 2026-09-24T12:10:15.346435Z in 17.851 s. dpkg confirms 0.8.39-1; +Node and VESC services are active/running with NRestarts=0. Fresh Core inventory +confirms exactly the two original UUIDs, plugin 0.6.6, the required Hall +standstill capability and no active/latched procedure. No port reset, firmware +flash or calibration write was performed. Observer resynchronization was +requested before the first actual comparative Hall measurement. + + +Both attended comparative measurements completed through Core → Node → native +VESC Tool, after fresh owner confirmation of stopped motors, removed tracks, +raised rover and transmitter off. LEFT operation began 12:12:16.619604Z and +finished 12:12:41.467723Z; its native cycle lasted 12.224 s. Result: +[255,173,255,120,255,21,255,68], states [1,3,5,7], firmware success false. +Owner observed actual slow backward movement followed by forward movement. +RIGHT began 12:13:12.520652Z and finished 12:13:36.369798Z; native cycle +12.225 s. Result [255,167,97,133,37,198,71,255], states [1,2,3,4,5,6], +firmware success true. Both report unchanged configuration, no configuration +write, confirmed release and no issues. Each receipt contains twenty idle +preflight observations and 119 cycle telemetry samples. LEFT/RIGHT private +receipt SHA256: 5f4972011019b53dc9803b47eeffd357de647ac161a2949b49473ecb702877c1, +1faa352ce8eed1483a46d9c92eb10b5305e3dcaf32ffa98c2833e1103720023f. + +Diagnostic conclusion: LEFT has a reproducible incomplete Hall signal during +observed movement; bit zero remains high in all returned states. RIGHT passes +the canonical six-state measurement. This is consistent with the owner's +damaged contact on the LEFT Hall circuit, but USB cannot distinguish exact +wire/contact, sensor or controller input. The LEFT remains sensorless and the +RIGHT remains Hall-controlled; the fault is localized, not repaired. Loaded +startup and field driving remain unqualified. + +Owner then requests plainly visible sustained forward and reverse rotation +instead of further small Hall movements. Hall comparison is complete; no +additional Hall/FOC cycle is needed. The next product increment will add signed +speed testing to the existing rotation card, retaining current limits and +requiring a separate physically stopped confirmation before each direction. +No automatic reversal of a coasting sensorless motor is authorized by this +implementation plan. Existing native adapter currently admits only 0..3000 +ERPM, so reverse requires a versioned adapter/package update, not a bypass. + + +## 2026-09-24 — attended bidirectional rotation, 0.8.40-1 (qualification) + +Owner requested visible sustained forward/reverse rotation after the completed +comparative Hall diagnosis. Extend the existing single/profile speed test with +a direction selector. Native VESC Tool `Commands::setRpm` receives signed ERPM; +no firmware, sensor mode, inversion setting or calibration rewrite. Bound remains +300–3000 ERPM magnitude, current ceiling 30 A, observed hold duration up to 30 s. +Use signed ramp and speed tolerance; wrong-direction motion never earns hold time. +Each operation starts independently from an explicitly observed physical stop. +No automatic reversal on coasting motors. UI clears the confirmation after each +operation and direction change; older driver capability disables reverse. + +Sensorless FW 5.02 idle PLL drift established in the prior Hall investigation +also affects normal bench preflight. Attended speed/profile/release requests now +require a strict standstill confirmation and ten fresh neutral/electrical samples +from every connected controller. Sensorless ERPM is recorded, not used as physical +standstill proof; finite values, zero PWM, low motor/input current, voltage, thermal, +fault, identity, CAN, receiver, cancellation and pending-restoration gates remain. +Hall-mode speed still blocks; legacy current pulse and FOC retain their old gates. + +Version ownership: Node 0.8.40-1, VESC plugin 0.6.7; native adapter delivered through +the versioned installer/preparation payload only. Bounded Ubuntu native build +383ac3eb5d0bdf9a3e3b3584 completed in 37.10 s with 13 checks, including upstream +positive/negative RPM serialization and denial of hardware in offline mode. +Upstream objects unchanged. Runtime SHA-256 +`dab6dc61fe4ff29f734a69e372e20ec66ffcc36d1513f4f89b2e4c29f311f45a`. +119 Python VESC regressions passed, including reverse 30 s hold, current-limit +restoration, per-direction configured speed bound, missing/invalid observation, +late PWM rejection, observed idle drift, RC preemption and complete-profile reverse. +Installation and physical rotation remain pending at this entry. + +Qualification and handoff: the immutable Node source artifact +`4a5e80a91a7a1526795a3f2c` (SHA-256 +`2fb53048d741c1d3da098163b9b74de688289c8f2b1f52e6197f579f474f06a7`) +passed the bounded Ubuntu qualification suite. Owner installer +`86a0dccb179cf082e6548d64`, SHA-256 +`a1360a296b11d65f90288a40c8b6c4fc8e7d67401ccd3ab74237df2b679caf8a`. +APT simulation upgrades only Node 0.8.39-1 → 0.8.40-1, adds/removes no packages. +Local Ubuntu installer was launched for owner sudo entry. No ad-hoc runtime +or OS patching. Transfer reused a disposable staging copy as rsync basis (previous +immutable source preserved); final source SHA verified before execution. + +Operator Core: 4 architecture tests, TypeScript, 916 unit tests and production +build pass. Only VescMotor.tsx and model.ts were promoted into the active checkout. +Canonical 8000 serves the matching new index +`c71c979185d48c90701d7569b947e1192c9f81be72bccab608517b1ec43c43c6`. +Browser verifies direction control, old-driver reverse disabled, initially +unchecked observation and legible 30 A/30 s fields. No motor command during UI QA. + +Physical acceptance: Node 0.8.40-1 installed successfully in 18.52 s, finished +2026-09-24T12:36:40.136111Z. Node and VESC services active, zero restarts; fresh +Core inventory verified both UUIDs with plugin 0.6.7 and signed-speed capability. +After fresh owner confirmation (tracks off, raised rig, TX off, observed physical +stop), complete 1x1 profile ran at +3000 ERPM, 30 A ceiling per motor, with +30.0447 s common hold. Owner saw both rotate evenly and confirmed full stop. +Then separately authorized -3000 ERPM yielded 30.0474 s common hold; owner saw +both rotate backwards at similar speed and stop. Both operations outcome duration, +release confirmed, limits restored, fault codes zero, no transport failures. +Forward steady current was approximately 2.7/3.0 A: 30 A is a ceiling, not a forced +current while holding speed. Original calibration/configuration remained in use. +Raw operation and installation receipts with hashes are retained privately in +native-probe/rotation-040-*; these attest unloaded rotation only. Left Hall hardware +fault remains localized and unrepaired; RC profiles and new takeover protocol are +separate outstanding work, not implied by this bench acceptance. + + +RC/failsafe follow-up began with read-only Core/Node operations and owner-confirmed +TX off / raised stationary rig. Both configuration backups saved; both inputs +within configured neutral, zero PWM/input current and fault 0. Different existing +PPM ramp/expo settings recorded; no configuration write. Details and remaining +acceptance gates: docs/node/24_RC_FAILSAFE_ACCEPTANCE.md. No new package needed +for initial reads. Direct Ops MCP instruction retrieval again failed at HTTP +transport; no Tasker write claimed or alternate card API used. + +2026-09-24, unattended development authorized by the owner for approximately +15 minutes: no additional hardware test or configuration write was performed. +The previously nonneutral TX-on capture was clarified by the owner as manual +stick movement, not spontaneous startup. Follow-up neutral evidence and the +pending TX About/Failsafe questions are recorded in 24_RC_FAILSAFE_ACCEPTANCE.md. + +Added an isolated executable prototype in packages/rover-control and the +Control Station developer-only rover-control-preview tool. Tank/Arcade mixing, +semantic-axis mapping, UUID fan-out (2/4/10 motors), strict desired-profile JSON, +and stop → neutral → manual authority transitions are tested without a hardware +adapter. RC takeover observes its configured full axis set even when Arcade +uses only one stick to drive. Missing axes do not become neutral. Existing +MotorTest authority, firmware, system services and package versions are intact. + +Validation: 21 final focused behavioural tests passed; 4 architecture checks, +Control Station typecheck and a 935-test full UI pass completed before the final +extra monitored-axis test. Preview typecheck and minified self-contained build +passed after the final change. Browser visual QA is not claimed: the Browser +use URL policy rejected navigation to the local HTML artifact; no alternate +browser/server workaround was attempted. Network is disabled in its CSP, and +source has no serial/Core transport. Private artifact manifest/logs/trace live +in outputs/rover-006-control-prototype. The running Core still returns two +verified online VESCs with test_active=false. No installer or password needed. + +This prototype does not solve independent receiver fallback or qualify physical +stopping. Current FW 5.02 does not provide the age/live-link evidence or the +independent stop-first enforcement required by the reference contract. Production +profile activation stays absent pending that integration. Model timing constants +are synthetic fixtures, not measured rover safety limits. Direct Ops MCP remains +unavailable at HTTP transport; local evidence is preserved without claiming an +Ops update. Rollback: remove the unreferenced prototype/tool artifacts only; +there is no installed board change to roll back. + +2026-09-24 RC failsafe bench acceptance: owner found Functions/Failsafe on the +touchscreen and reported 0% on all ten channels. An initial right-side attempt +returned the stick before removing the TX battery, so it was explicitly excluded +as loss-of-radio stopping evidence. The repeated right-side test held the stick +until battery extraction; owner confirmed immediate observed stop. Same procedure +on LEFT also physically stopped. Final TX restoration with both sticks neutral +caused no motion, confirmed by the owner and zero PWM in recorded telemetry. +Completed private captures b208d87f / cc289f6f / 6811a686, with full identifiers +and hashes in docs/node/24_RC_FAILSAFE_ACCEPTANCE.md. No runtime/firmware/settings +write, output lease, alive or Core motor command; only shipped input.read and +telemetry.read. This qualifies the observed unloaded RC loss/neutral restoration +scenario, not exact response latency, loaded braking, Mini-independent new +stop-first arbitration or repaired LEFT Hall hardware. Continuing read-only TX +Mix/channel inspection for the requested profile integration. + + +## 2026-09-25 — observation channel, Node 0.8.41-1 + +Versioned Node 0.8.41-1 / VESC integration 0.7.0 adds the separate paired mTLS +remote-control channel and native watchdog. Native source artifact +ad291aa57e2b828f14619673 and Node source artifact 4f5ded93cde5b3d271fbef5c +were built and qualified in bounded Mini staging. Node qualification peaked at +2,907,676,672 bytes under its 3 GiB ceiling. Native offline checks, 127 VESC tests, +Go race tests, DG packages/catalog/registry, Node UI and environment/USB/startup +qualification passed without driving hardware during the build. + +Package SHA-256 e0d4d43ed026b3f8e841492793942cfd1b7cb761da1da2c2e40951b9e120de04. +Owner installer a4f1163407e76521b6139ab6, SHA-256 +076576893e54b69377910d8e1bcf85596629e9d6644e0895af743be01ca2badf. +Its plan upgraded only mission-core-node 0.8.40-1 to 0.8.41-1; no other package +addition/removal. The owner-authorized local Ubuntu installation completed; +dpkg version and active Node/VESC services were read back over SSH. The package +owns every installed file and service change; no manual board runtime patch. +Rollback uses the preceding versioned owner-release artifact, not hand edits. + +Core 8000 receives fresh RIGHT samples through the new channel, supported=true, +state=observing, session_id=null, controlling=false. LEFT is not enumerated in +Linux; its profile UUID binding survives. USB descriptor errors -71 predate +installation; owner confirms reconnecting USB/power. No motor command or USB +reset was issued in this implementation session. Physical root cause and +both-controller channel acceptance remain open. Attended remote movement, +release/blur/timeout and RC stop-neutral-manual acceptance are still outstanding. +Stock FW 5.02 does not guarantee that protocol independently of a failed Mini. + +Full implementation, UI acceptance and limitations are recorded in +25_OBSERVATION_AND_REMOTE_CONTROL.md; private hashes, qualification and raw +read-only evidence are under outputs/rover-006-observation-control-20260925. + + +### Follow-up 0.8.41-2 — observed sensorless idle and session completion + +Owner restored both USB controllers by disconnecting/reconnecting the battery +at 11:35 MSK, not by restarting Mission Core. Twenty read-only samples contained +both assigned UUIDs. One freshly authorized API trial at 11:38:46 was rejected +before movement at reported sensorless duty=0.001; no positive demand or volatile +limit write was reached. Pinned FW computes that quantity from measured phase +voltages even undriven, so the previous exact-zero admission assumption was +incorrect. Follow-up permits one encoded quantum only in the explicitly +owner-observed sensorless case, while retaining current, fault, temperature, +voltage, RC neutral and physical-observation requirements. + +The same follow-up reports ordinary terminal input leases as stopped after +cleanup. Failed release/restoration still reports fault. Actual loop tests now +exercise expiry after sending speed through the session wrapper, plus a failed +controller during cleanup. All 130 VESC tests pass. + +First qualification stopped on a mismatched declared driver version; the Node +model registry was corrected to 0.7.1. A subsequent passing package was +superseded before installation to include normal-session completion. Final +source artifact b889d129c87de5b811c0ee6c, SHA-256 +74c48e186d8877c92d1501b7dbbd43943e476c4f2b8cf89a136b1d8aea227981, +passed the complete bounded Mini qualification. Package SHA-256 +fb1a484ddaad2e8ff3dc1ca99d7ba6f5fb5d1d78b9075e04643a727eba100f9e, +218,851,386 bytes. Owner installer f1a536e5d42ef73dabf1d7f0, SHA-256 +9b71a345928c198a68fad9af0f8a426ef0cf3ff8c79deb0d33729fbd88d5aa09. +APT simulation upgrades only Node 0.8.41-1 to 0.8.41-2, no additions/removals. +Owner entered the local Ubuntu authorization. Installer completed successfully +at 2026-09-25 09:08:23 UTC (24.9 seconds), all steps exit 0. Installed package +0.8.41-2 and VESC runtime 0.7.1 verified by read-only SSH; both services active. +After observation refresh both assigned UUIDs report fresh values (14–205 ms), +zero currents/duty/faults, no active control session. Evidence: postinstall +receipt and API samples in the private observation-control evidence directory. +Attended movement retry remains pending fresh owner observation. No firmware, +calibration or persistent electrical-limit change is part of this package. + +### Follow-up 0.8.41-3 — diagnose preparation lease cancellation + +Owner authorized one bounded forward trial after installing 0.8.41-2. The first +helper call at 12:18:51 MSK declined stale telemetry before arm. Read-only refresh +restored both fresh UUIDs; the armed trial at 12:19:28 ended stopped about five +seconds into preparation, with no forward demand sent. Browser/Core heartbeats +continued at approximately 100 ms. Neither Node nor VESC restarted. The cause +of the lease cancellation was not preserved by the earlier transport logging. + +The follow-up adds only a bounded private channel diagnostic flight recorder +to Node. VESC runtime remains 0.7.1; native Tool, deadlines, current limits and +output behavior are unchanged. Source artifact a93510d58156a2ec1ed8fa74, SHA-256 +ea46f9e4666523a02cf869565c65ab982763f053fa43987dd019cc97e059ee76. +Slow SCP was stopped before build execution; delta staging from the existing +source artifact produced an identical full SHA-256, verified before launch. +Qualification runs in the artifact-owned 3 GiB / 150% CPU temporary cgroup. +Installation and further physical acceptance remain pending. + +Qualification completed at 09:33:39 UTC in 263.8 seconds: Go race tests including +the bounded diagnostic history cases, Node UI, environment, installer and all +130 VESC tests passed. Package SHA-256 +bb7d23fe7ae134d1249b60e92aebbd5f09ef40a165ff12dec77f821950b1b8e3, +218,855,416 bytes. Installer c400214393c2c5c4c26e6489, SHA-256 +48cfe00d4d54cf3825177deafb097efb66cb8a9d2038657e680502e0ca271a8b. +APT simulation changes only mission-core-node 0.8.41-2 to 0.8.41-3, no other +package additions/removals. Before launch Core reports no active session and +stopped. The local Ubuntu installer was opened; OS authorization is pending. + +Node 0.8.41-3 installation completed successfully at 09:36:34 UTC in 18 seconds +after owner-local Ubuntu authorization. Package version and active Node/VESC +services verified. Both assigned UUIDs produce fresh readings (190/199 ms), +zero motor current and fault codes; no control session. Owner observation is +requested again before one bounded repeat; no motor output sent after the +12:19 preparation abort. + +### Follow-up 0.8.42-1 — separate commands from telemetry round trips + +The 12:38 and 12:46 MSK attended attempts ended during preparation without a +forward command. Node diagnostics localized short-lease consumption to serial +request/response timing. TCP_NODELAY reduced some delays but did not resolve +the admission failure. No new USB fault was established by these attempts. + +The new Node streams latest Core intent independently from telemetry and feeds +the local owner at 20 Hz. Commands carry their original Core monotonic expiry; +conservative clock bounds subtract network time rather than starting a new +400 ms lease on receipt. Reconnect must cross an acknowledged null command, +and interrupted IDs are retained even if they never reached the driver. +Native VESC runtime remains 0.7.1, its output watchdog remains 200 ms, and the +firmware, motor calibration and electrical limits are unchanged. + +First source 6a008b44ecdd7d4ba550795b passed bounded Linux qualification but was +superseded before installation to include the undelivered-session tombstone +regression. Final source 4721a12daa5599d3e6cd3e19, SHA-256 +5420a70de810a80234cb586695109c2e38f857dfe1721f103dac2c2ad1cccc4e, +466,985,414 bytes, is undergoing the same qualification. Both staging copies +were transferred as deltas and fully SHA-256 verified before execution. No +installed Mini files or system configuration were patched. + +Core transport.py, registry.py and rover_control.py were promoted after 58 +Fleet regressions passed against both development and active operator sources. +The existing canonical launchd service was restarted only with no active +session; 8000 and fresh telemetry for both assigned UUIDs recovered. Legacy +Node 0.8.41-3 remains installed until the final package passes qualification +and the versioned owner installer completes. New motion acceptance is pending. + +Final qualification completed: all 18 jobs exit 0, including Go race tests and +130 VESC tests. Package 0.8.42-1 is 218,865,950 bytes, SHA-256 +b091b9ced7310e6aacae12c6911170e3acbd4f80138e3fe65863a49a6e2a8bc0. +Installer f80c3eb98fef89e31e93b076 is 218,888,341 bytes, SHA-256 +2ce07d7b266a1ae31640bcdeec9bdd8c8c945099f4ef8368bb5ff502ede07b1a. +Its fresh APT simulation upgrades only mission-core-node 0.8.41-3 to 0.8.42-1, +with no new or removed packages. No active control session was present before +launching its local Ubuntu window. Owner OS authorization is pending; do not +confuse opening the installer with installation or movement acceptance. + +Owner authorization completed; 0.8.42-1 installed at 10:22:27 UTC in 18.1 s, +all steps exit 0. Node and VESC services are active. Ten-second read-only +verification contained both fresh UUIDs, zero currents/faults and no active +session. A fresh owner-observed trial at 10:25:53 UTC nevertheless ended in +preparation without forward demand. Stream/local-loop timing improved, but +one retained update crossed the prior command's deadline by roughly 20 ms. +The session remained retired as designed; no automatic motion retry. + +Candidate 0.8.42-2 removes periodic waiting for new commands on Core and Node, +without increasing the 400 ms expiry or native output watchdog. Core: 59 tests +passed. Node uses a coalescing signal, not a command queue, and retains stopped +session tombstones. Qualification/installation is pending; 0.8.42-1 remains +the installed predecessor. + +Final 0.8.42-2 source: 82ecb65d554eb431616494ee, SHA-256 +3b36ee72e923a44c392706b8fb8c159cc22360ec7e42f740efbd367d8481ff54. +Candidate cb7441a86c04cb2cdd91652c passed qualification but was superseded +before installation to reject malformed/non-integral command sequences before +comparing latest intent. This prevents invalid JSON types from disrupting the +Go receiver. The final candidate is undergoing the same bounded qualification. + +Final qualification passed all 18 jobs. Package 0.8.42-2: 218,867,020 bytes, +SHA-256 0be7052996013522f2240b44e0fca2284e6b357675f83fa8a6210ce61e1027b1. +Installer fd7d351f1882ed2131cd5057: 218,889,411 bytes, SHA-256 +74fdb94bc10cf8a54d82e62e58f1539f6a179c2f9b151f2dd021edde9580f311. +APT plan upgrades only mission-core-node 0.8.42-1 to 0.8.42-2, no additions +or removals. No active session before opening the local Ubuntu installer; +owner OS authorization is pending. No further motion has been attempted. + +Owner OS authorization completed: final 0.8.42-2 installed at 10:47:29 UTC +in 18.67 seconds, all installer steps exit 0; Node and VESC services active. +Forty read-only samples over ten seconds confirmed observing/no active session. +The final twenty contained both assigned controllers, at most 216 ms old, +with zero motor/input current, duty and fault. Fresh owner observation has +been requested before any new motion; the five previous failed preparation +attempts remain failures, not movement acceptance. + +Sixth attended Core API attempt, 10:52:51 UTC, stopped before forward demand: +"another VESC operation is running". Recorded command TTL remained 323 ms, +so this particular failure is different from the preceding lease expiry. +The remote observer shares operation_lock; _prepare previously attempted +nonblocking acquisition and treated any overlapping read as a fatal conflict. +The trace does not identify which operation held the lock; code and a +concurrent regression reproduce this admission race without hardware. + +Candidate Node 0.8.43-1 / VESC 0.7.2 waits up to 500 ms for exclusive access, +checks the existing input lease every 20 ms and after acquisition, and skips +new observer cycles while the control worker is alive. It does not queue a +future drive or extend the input lease. Tests cover completing an in-flight +read, Stop while waiting, expiry before acquisition, bounded rejection of a +long operation, and observer yielding. Canonical unittest discovery passes +135 tests. A first full pytest invocation incorrectly collected the imported +protocol helper test_packet as a fixture-based test; no product failure was +reported, and the suite was rerun with its canonical unittest runner. +Installation and a separately synchronized physical retry are pending. + +Final source c2d98db61de6722f2a77c4ed qualified: all 18 Linux jobs exit 0. +Source SHA-256 a0854257a11a97dba7f544203a0babde835d144d9ab897f46f28e4f3e6643461. +Node package 0.8.43-1: 218,867,200 bytes, SHA-256 +09fa9bba4595673d1b763cb49d6caee6d5f2519e08ed667e733a07867810ae98. +Installer 38c4764476007a22c2c594a3: 218,889,591 bytes, SHA-256 +cb195603fc5bc490bb2d64d3a7201b71b58479ea5af309963e13b931e05b9379. +The plan upgrades only mission-core-node from 0.8.42-2; no new or removed +packages. No active control session before launching the local installer. +Owner OS authorization is pending. Firmware and calibration remain unchanged; +no further motion has been attempted after the sixth failed preparation. + +Node 0.8.43-1 / VESC 0.7.2 installed at 11:06:32 UTC in 18.49 s, +all installer steps exit 0. Both services active; final 20/40 read-only +samples contained both assigned UUIDs, age <=219 ms, zero currents/faults, +observing/no control session. A fresh attended trial is requested separately. + +Seventh observed Core API attempt at 11:10:39 UTC reached preparing without +the ownership fault, then stopped before forward demand. Sequence 19 arrived +with ~313 ms remaining; sequence 20 followed ~315 ms later, consistent with +expiry at this boundary. The old trial sent a command, synchronously fetched +telemetry and only then scheduled its next input. Telemetry reads introduced +periodic delays up to ~319 ms in its sample cadence. This differs from the UI, +where the command heartbeat and telemetry poll are independent. + +The corrected attended_stream_test.py separates bounded telemetry polling +from 100 ms command renewal, preserves the same 400 ms lease and all existing +preflight/stop checks, and records request timing for every command. Synthetic +checks prove blocked reads do not hold the input path, failures abort and +reader threads terminate. This is a test-harness correction, not movement +acceptance or proof that all transport jitter is solved. A fresh observed +trial is requested; there is no automatic motion retry. + +Core-only timing logs were added to distinguish registry wait, archive and +save delay. All 59 Fleet tests pass; loopback HTTP test needed sandbox network +permission. The active Core received only this reviewed registry.py diff and +was restarted without an active session. Read-only samples: max local GET +179.8 ms, three of forty above 100 ms; retained registry waits 25.9–58.5 ms. +No archive/save delay above 25 ms was reported in the initial capture. Thus a +registry persistence bottleneck is not yet established by these measurements. + +Eighth observed trial at 11:22:27 UTC still stopped before forward demand. +Independent input recording showed local Core command POST outliers 103.4, +166.5, 216.1 and 127.4 ms (normally 2–10 ms). Sequence 17 reached Node with +312.7 ms remaining; sequence 19 followed after 335 ms. Separating trial +telemetry therefore did not by itself solve the delivery problem. + +A bounded read-only macOS sample of the operator Core found JSON encoding and +zlib work on its ASGI main thread. The periodically polled completed planning +report /api/v1/mission-planner/live-tests/active is 2,403,591 bytes and took +218.5 ms for one local GET. Its endpoint fetched the dict in a worker, but +FastAPI recursively encoded it and the middleware compressed it on the event +loop. This shared process also admits rover commands. + +planning_live_api.py now constructs the JSON response and optional gzip body +in the existing thread pool, preserving the full report contract and bypassing +second compression through Content-Encoding. No polling is disabled, evidence +is not removed, and Node, calibration, current limits and leases are unchanged. +13 focused tests passed against development and active Core: JSON/gzip execute +off-loop, exact content survives decompression, empty/failure contracts and +existing planning presentation/compression behavior remain valid. Canonical +8000 was restarted without active control. Sixty ordinary read-only rover +samples over 15 seconds then had max 86.1 ms, p95 64.5 ms and zero over 100 ms; +both assigned UUIDs fresh, currents/faults zero. This improves measured delay, +but does not yet establish motion or field acceptance. A fresh observed retry +is requested separately. Private process samples and device traces stay out +of normal Git. + + +Ninth attended Core API trial at 11:31:08 UTC passed preparation and completed +8 seconds of forward demand at up to 2000 ERPM, with a 30 A ceiling per motor. +The owner confirmed both motors physically rotated forward and subsequently +confirmed both stopped. Final state stopped, release_confirmed=true, zero +motor/input current and fault. Recorded peaks: left 2001 ERPM / 2.88 A motor, +right 2028 ERPM / 2.81 A motor; these are sampled peaks, not current ceilings. +During driving device ages stayed <=104 ms, all recorded fault codes zero. +Preparation retained old motor samples up to 10.1 s while exclusive setup ran; +those samples are not treated as live motion telemetry. Command POST max +81.28 ms, p95 10.05 ms across 201 requests. The normal stop command was accepted. + +This accepts the observed API forward/release path on Node 0.8.43-1 / VESC +0.7.2 and the corrected operator Core. It does not accept physical keyboard +input, Stop/blur, channel loss, RC takeover, loaded or field operation. Those +remain separate checks. No new calibration, firmware, USB reset or OS change +was performed for this trial. Private raw evidence and owner notes are hashed +in the experiment manifest; the previous eight preparation failures remain +recorded as failures. + + +At 11:38–11:39 UTC the owner physically held W in the 3D View after UI arming, +then released it. Owner reports both motors forward, immediate perceived stop +on release and approximately 0.5–1 s before initial motion. Exact key-event +latency was not instrumented and is not claimed resolved. Read-only capture: +393 samples, no request errors; driving observed for about 10 s (the requested +hold was approximately 8 s). Sampled peaks left 2004 ERPM / 3.51 A, right +2032 ERPM / 2.85 A; driving sample age <=113 ms, all faults zero. Release +returned to ready with motors stopped; the UI Stop action then reached stopped, +release_confirmed=true. Final UI explicitly says control disabled. The read-only +recorder exited and no motion input remained active. + +This accepts actual W forward/release, separately from the prior API trial. +Reverse/turns/Tank, Stop while moving/blur, channel-loss and RC takeover remain +unaccepted on the new UI path. Owner startup-delay observation is retained +for a separately instrumented check. No hardware limits or calibration changed. +MISSIONCOR-85 now records both successful trials, their limits and the previous +operator event-loop diagnosis while preserving all hardware/Hall history. + + +Observed S/A/D session, 11:45–11:47 UTC: the owner confirmed reverse on S +and opposite sides on A (left reverse, right forward); also reports D worked +before the agent disabled control. The telemetry records both opposite-side +patterns with neutral intervals. Final state stopped, release_confirmed=true. +The owner reports a repeatable approximately two-second start delay, with +immediate perceived release. This blocks completion of drive-response acceptance. + +Root cause in the remote output loop: it ramps the speed setpoint from zero +at 600 ERPM/s. Both saved configurations have s_pid_min_erpm=900. Pinned +upstream bldc mcpwm_foc.c (3f670137e27e6e383fa79c50cc6b1fa85aab1554) forces +zero duty and resets speed-PID state for targets below that threshold. The +result is 1.5 s of ineffective commands on each start, plus the retained +0.5 s undriven interval when changing direction. Recorded telemetry already +says driving while the rotor remains stopped, consistent with this mechanism. +This delay is downstream of command admission; the exact key-to-node timing +was not captured and no claim of zero network delay is made. + +Candidate Node 0.8.44-1 / VESC 0.7.3 starts the remote speed request at each +controller's own read-back minimum PID speed (rounded up for native integer +setRpm), then ramps at the existing rate above it. It does not change the +firmware threshold, motor configuration or current ceiling. Subthreshold +analogue requests release instead of being amplified above the request; +invalid/unreachable thresholds reject before output claim. Zero input still +releases immediately; expiry, RC takeover and the reversal dwell remain. +Synthetic tests cover distinct thresholds including fractional serialization, +first-cycle output, ramp above the threshold, turn signs, subthreshold input, +immediate release and invalid thresholds. Physical response after installation +requires a new observed trial; this candidate is not yet installed. + + +0.8.44-1 qualification completed: all 18 Ubuntu stages succeeded in 268.87 s, +including 140 VESC tests, Go race checks and Node UI. Source 1b1be6ef5913fd3740a11c69; +package SHA-256 46cae05efa621a2636251f69ab8071ff4e18db67f23203eab396a71f0ef0972b. +Owner installer bf270c06ae6d1e598e963756 launched in the local Ubuntu session. +APT simulation changes only mission-core-node 0.8.43-1 -> 0.8.44-1, with no +added or removed packages. Before launch Core showed stopped, release confirmed, +both currents/ERPM/faults zero. Local OS authorization is pending; launch is +not evidence of installation or an accepted new motor response. + + +Owner authorization completed: 0.8.44-1 installed at 12:01:17 UTC in 18.56 s, +all installer steps exit 0; Node and VESC services active. Twenty read-only +samples captured after installation, final sample both assigned controllers +fresh (53/63 ms), ERPM/current/fault zero and no active control. Fresh owner +observation requested for W start/release; improved physical response is not +yet accepted. + + +Post-0.8.44-1 owner keyboard series at 12:05–12:06 UTC included repeated +forward/reverse and both turn patterns. Owner reports delay approximately +halved, forward-to-reverse works, but one side sometimes starts sooner. +Read-only recording: 947 samples, no errors, all faults zero; 23 driving +segments. First side above 300 ERPM in the same sample or 0.25–0.51 s later; +both sides by 0–0.76 s. These are state-relative samples, not key-event timing. +The four-minute recorder ended at ready; a separately saved final snapshot +confirms stopped/release_confirmed, both ERPM and currents zero after UI Stop. +Sampled peaks left 2007 ERPM / 5.04 A, right 2025 ERPM / 3.32 A. + +Asymmetry diagnosis: after a turn, the remote code held only the reversing +motor for its 0.5 s neutral interval, while the other side immediately drove +the new command. Trace 12:05:39 (turn -> forward): right above 300 ERPM in the +first driving sample, left +0.763 s. The mirror transition at 12:05:33 had +left first, right +0.511 s. This is a software coordination defect, not evidence +that all smaller differences arise from the broken left Hall circuit. + +Candidate Node 0.8.45-1 / VESC 0.7.4 uses one reversal barrier for the entire +assigned drive group. If any side reverses, all outputs release until all +motors have been observed quiet and undriven for 0.5 s, then the current +latest targets start in the same output cycle. Already observed neutral time +counts; no extra dwell is added after a sufficiently long released pause. +Cancelled/replaced direction requests are not queued. The per-controller PID +threshold correction, speed ramp, immediate zero, current caps, expiry and RC +priority remain. Synthetic regressions cover turn->straight synchronization, +a slower coasting companion, counting an existing neutral pause and cancelling +a pending reversal. Installed software remains 0.8.44-1 pending qualification +and owner installation of this separate candidate. + + +0.8.45-1 / VESC 0.7.4 passed all 18 Ubuntu qualification stages in 267.11 s, +including 144 VESC tests. Source d31a8b586b9a600a2a8e61b3; package SHA-256 + af412c607fec9b34aba0af0e8e67614cd6f4d373fb641d7202341fea30be9ba1. +Installer f1a8a72c4a1a7efc4aeebedd launched in Ubuntu. Its APT plan upgrades +only mission-core-node 0.8.44-1 -> 0.8.45-1; no added/removed packages. +Before launch both controllers had zero ERPM/current/fault, control stopped, +release confirmed. OS authorization and new physical acceptance are pending. + + +0.8.45-1 installed at 12:23:15 UTC after owner OS authorization, 18.56 s, +all steps exit 0. Node and VESC services active. Twenty read-only samples; +final both assigned UUIDs fresh (115/124 ms), zero ERPM/current/fault and +no control session. Fresh owner observation requested for turn->forward +transitions; physical synchrony and remaining control/RC acceptance pending. + + +Observed 0.8.45-1 keyboard trial, 12:32–12:34 UTC: 545 read-only samples, +no read errors, fault codes zero, driving sample age <=105 ms. Twelve driving +segments; both sides above 300 ERPM in the same sample or within one 0.25 s +sample. Peaks left/right 2014/2043 ERPM and 4.35/3.24 A. Owner reports responsive +forward/reverse/turns. This is coarse telemetry, not exact key-to-output timing. + +CRITICAL physical acceptance failure: owner reports D continued after leaving +the browser and releasing the physical key; later clicks recovered it. The +trace contains prolonged D segments (22.82 and 20.56 s), but browser focus/key +source events were not recorded, so exact focus-loss latency is unknown. +Agent ended control through UI; stopped/release_confirmed=true and both motors +zero ERPM/current/fault. Remote-control acceptance remains blocked by this defect. + +The UI already subscribed to blur/pagehide/visibility events. Its 100 ms +command sender nevertheless renewed a remembered nonzero demand without a +focus or input-freshness check; a missed browser-host event could hold it +indefinitely. Fix uses a core-owned held-input binding, capture listeners, +50 ms focus polling, and a guard checked at every command heartbeat. A key +requires a fresh trusted press, then OS-repeat evidence: <=1000 ms initially, +<=300 ms after a repeat. This fallback bounds a lost keyup even if the host +also misses focus events. Focus loss/expiry clears all held states and disarms; +returning focus or delivering a late repeat cannot resume movement. Continuous +keyboard control therefore requires OS repeat within those bounds; this is +not a global-background keyboard implementation. Pointer up/cancel/capture-loss +and component disposal release held state. No onboard install or firmware/config +change belongs to this UI fix. Physical focus-loss re-test remains pending. + + +Owner follow-up after the first focus fix: movement now stops on focus loss, +but terminating the control session is explicitly rejected. New required +behavior is neutral hold with the current healthy control session preserved; +returning focus requires a new physical press, not another arm/preparation. +The implementation now separates input pause (clear held input, send zero, +keep session) from explicit Stop/pagehide/unmount/fault (end session). Guards +still run before every send; old demand is never restored on focus return. +The periodic neutral messages maintain the session only while communication +remains healthy. Actual background suspension/channel expiry is still a stop, +not permission to extend the motion watchdog. Continuous keyboard holds still +require OS repeat evidence within the bounded input lease. + +Preparation now hides key controls and renders the existing canonical warning +StatusBadge as Подготовка управления; readiness alone admits the green state +and key controls. Initial focus-fix physical evidence confirms stopping but +not the requested session-preserving behavior. Revised physical test pending. + + +Final revised UI qualification: 934 unit tests, architecture checks, TypeScript +and production build pass. Canonical Core serves the exact new index/assets; +no Node/OS/firmware change. Browser verified amber Подготовка управления with +keys absent until ready. Owner observed the revised trial and confirmed: +focus loss stops motors, returning allows a fresh press without another arm +or preparation. One active session persisted throughout all six short driving +segments. Explicit UI Stop after completion ended the session; final fresh +telemetry confirms stopped/release_confirmed=true, both ERPM/current/fault zero. +The private result includes UTC/monotonic traces, owner notes and SHA-256. +This accepts focus loss/resume on the observed host. Tank, explicit Stop while +moving, command-channel loss, RC takeover and loaded/field behavior remain +separate outstanding physical checks. No exact key-to-stop timing is claimed. + + +2026-09-25 13:21 UTC — operator startup UI regression fix only. +Node remains 0.8.45-1 / VESC plugin 0.7.4; no OS, firmware or motor-config +change. Fixed stale-read revocation of a newly acquired session and silent +Manage availability. One first-click neutral-only preparation completed; +explicit Stop confirmed release and both motors zero. 307 samples, no read +errors/faults/motion; 938 unit tests, typecheck, architecture and build pass. +See 25_OBSERVATION_AND_REMOTE_CONTROL.md and private entry-startup-result.json. diff --git a/docs/node/18_VESC_TOOL_NATIVE_BACKEND.md b/docs/node/18_VESC_TOOL_NATIVE_BACKEND.md new file mode 100644 index 0000000..0e6fea8 --- /dev/null +++ b/docs/node/18_VESC_TOOL_NATIVE_BACKEND.md @@ -0,0 +1,176 @@ +# VESC Tool as the onboard engine + +Owner decision, 2026-09-23: Mission Core supplies the local and remote product +interface; upstream VESC Tool supplies firmware compatibility, configuration +schemas/codecs and motor calibration. Do not continue a separate Python +implementation of Tool algorithms. Node 0.8.29-1's separate Hall/speed experiment +was built but withheld before installation. Installed hardware remains on +0.8.28-1. Calibration and sustained-rotation acceptance are still outstanding. + +## Upstream boundary + +Use the stable [Tool 7.00 source](https://github.com/vedderb/vesc_tool/tree/01d5f10901116c311e3fb84d5a1541f663d3ce20) +unchanged. This is a Qt application, not an existing HTTP service or a documented +standalone SDK. A small C++ process adapter is necessary; it calls the actual +`VescInterface`, `Commands`, `ConfigParams` and `Utility` implementations. It +must not replace them with translations of their algorithms. Keep upstream +license and corresponding source/build provenance with the combined payload. + +Mission Core owns device identity/position, exclusive access, operation and +configuration history, session authority, local/paired transport and UI composed +from Design Guideline components. Device parameter definitions, groups, labels, +units, limits and enum options come from native `ConfigParams`; they must not +be copied into a second permanent hand-maintained schema. + +Updates change a pinned upstream source plus its matching resources and rerun +compatibility/replay acceptance. Neither a Tool update nor connecting to a board +automatically authorizes firmware flashing or replacing controller settings. + +## Verified native execution + +`plugins/vesc/native/offline_main.cpp` links the existing unmodified Tool object +files, substituting only the application entry point. It has no admitted serial, +TCP, Bluetooth or powered-operation entry point and does not start an event loop. +The versioned `packaging/build_native_probe.py` / `native_probe.py` artifact +compiles under an unprivileged 3 GiB user scope; it neither installs dependencies +nor touches running services. Separate private Qt settings prevent inheriting an +operator's saved connection. + +The adapter replays archived identity through native firmware negotiation, +checks archive hash/command/length against the native firmware schema, passes +the original configuration packets to `Commands::processPacket`, and exports +the resulting native parameter groups and XML. Native serialization must +reproduce the original binary configuration exactly. Unsupported firmware, +corrupt hashes, wrong signatures and truncated payloads must fail closed. + +An offline `Commands::detectAllFoc` serialization probe also demonstrates the +real compatibility behavior: Tool automatically halves a 100 W example to +50 W on the wire for FW 5.02. No bytes are delivered to hardware. This correction +comes from `VescInterface::fwVersionReceived` and `Commands::detectAllFoc`; +implementing only the documented-looking command packet would miss it. + +Tool's own XML writer rounds floating point text (`QString::number` default +precision). XML is suitable for native import/export but is not a byte-exact +archive. Preserve the original binary snapshots alongside native XML. Native +`ConfigParams::checkDifference` supplies the comparison tolerance; do not call +XML conversion a lossless binary backup. + +This proves engine reuse and offline compatibility, not a shipped hardware +backend. Production dependency closure, installer integration, USB ownership +handoff, operation API and physical calibration remain separate acceptance work. + +## Canonical calibration for this 1×1 rover + +The [upstream motor wizard](https://vesc-project.com/node/180) distinguishes +motor setup from the [input wizard](https://vesc-project.com/node/181). +The current desktop implementation is +[`DetectAllFocDialog::runDetect`](https://github.com/vedderb/vesc_tool/blob/01d5f10901116c311e3fb84d5a1541f663d3ce20/widgets/detectallfocdialog.cpp), +calling the actual +[`Utility::detectAllFoc`](https://github.com/vedderb/vesc_tool/blob/01d5f10901116c311e3fb84d5a1541f663d3ce20/utility.cpp). + +1. Confirm each controller's own identity, take motor and application backups, + inspect faults and retain existing battery protections. The problematic motor + is LEFT; RIGHT works normally from RC. Do not copy right-side Hall calibration + to the left or use software-induced right-side stops as a hardware diagnosis. +2. Determine actual connection topology. Two motors, or a Mission Core 1×1 + layout, do not imply CAN master/slave. There are two USB connections and two + receiver inputs (CH3 presumed left, CH2 right). Previous native CAN discovery + returned no peers. Calibrate each directly connected device separately until + another topology is evidenced; do not enable CAN forwarding merely because + the rover has two motors. +3. Choose the appropriate native motor procedure. The full auto-FOC wizard + prepares parameters, temporarily adjusts battery cutoffs, detects R/L, flux + and sensors, writes resulting settings, restores cutoffs and checks direction. + It is not equivalent to invoking a Hall command or only starting a motor. + Its `maxPowerLoss` is motor heating allowance, not rated shaft power; a + remembered 500 W nameplate is not an instruction to pass 500 W here. +4. For diagnosis without changing battery settings, use upstream's individual + `measureRLBlocking`, `measureLinkageOpenloopBlocking` and + `measureHallFocBlocking` procedures. The necessary current/start parameters + and actual effects must be explicit. Use upstream calculation/application + functions when measurements are accepted; never silently transplant a new + Hall table or overwrite unmeasured settings. +5. Inspect the resulting sensor mode and measurement status. Firmware 5.02 + autodetection can report success with a sensorless fallback when Hall/encoder + detection fails. That is not proof that the broken Hall pin was repaired or + that loaded low-speed startup is acceptable. Firmware Hall measurement locks + ordinary motor controls during the cycle; do not promise an RC or USB stop + that the firmware cannot perform. +6. Read back and archive the applied result, then coordinate a visible direction + and startup test. Assign the physical position in the existing Mission Core + profile only from observation. Finish motor setup before changing receiver + endpoints, neutral, deadband or direction. The receiver remains connected. +7. Verify sustained rotation using native motor control with current limits and + a speed setpoint. Requested duration means measured rotation after settling; + startup, stalled motion and an early guard stop do not count as completed + time. A torque/current command alone cannot promise 30 seconds of rotation. + +The full auto wizard includes configuration writes beyond measurements. In +particular, blindly executing its battery stage from stale configuration metadata +is unsuitable here: saved battery metadata says 3S / 6 Ah while observed input is +about 50 V. Existing cutoffs are approximately 44.2 / 39 V. Retaining these +settings for motor diagnosis is distinct from validating their suitability. + +Battery brand/capacity are not prerequisites for motor identification. Chemistry +and series count are needed when recalculating voltage protection; pack/BMS +charge and discharge ratings are needed when changing battery current limits. +Do not block native engine preparation or motor-only diagnosis on unknown Ah. + +## Hardware evidence and uncertainty + +Owner photos show UNITE branding and model family BM1418HQF on one motor; the +other marking is worn. Owner recalls approximately 0.5 kW per motor, tentatively. +The [manufacturer catalog](https://m.unitemotorco.com/brushless-motor/) lists +350/500/650/750 W variants with several voltage options. This confirms the +family, not the exact rating of this unit. Do not select a direct-drive hub +profile based solely on the saved 46-pole / gear-ratio fields. + +Owner reports a nominal 48 V CATL-cell battery and a verbally ambiguous capacity +around 120 Ah. The photo shows 13 visible cell bodies, but labels and the complete +electrical topology are not visible. Chemistry, exact S/P count and BMS ratings +remain unconfirmed. Raw photos, controller identities and native replay outputs +stay in private evidence, outside normal Git/Ops. + +## Remaining implementation acceptance + +- Carry the native engine and its qualified runtime dependencies through the + existing versioned Node installer; no ad-hoc board package/library repair. +- Admit one hardware owner at a time. Existing Python serial descriptors must + not compete with VescInterface, and background polling must not interleave + another session's calibration commands. +- Expose explicit operation requests/results and native parameter metadata on + the private onboard boundary; reuse the existing Node and paired Core path. +- Keep backups, compatibility checks, timeouts, durable unknown-operation state, + readback and observed sensor mode in the receipt. No automatic retry of motion. +- Before each powered agent test obtain a fresh observing reply and announce + target/parameters. Existing authorization does not establish that the owner is + still watching after a build. +- Qualify native device reads before calibration, then verify left and right + startup/direction and actual sustained rotation separately. Do not mark the + rover calibrated from offline tests. + +## Native runtime candidate 0.4.0 + +The per-device `native/engine_main.cpp` now implements bounded JSON requests +on private inherited pipes. Native VescInterface owns and exclusively locks the +actual serial descriptor; the service never opens a competing descriptor. +Configuration reads verify upstream serialization against the original bytes. +The admitted native methods cover identity/telemetry/configuration/CAN/PPM reads, +short app-output leases, current release, bounded current and speed, volatile +current scales, native parameter/XML export and upstream blocking Hall detection. +No arbitrary packet, firmware flash or general command execution API is exposed. + +`runtime/native_link.py` owns subprocess lifetime and attachment checks. An +unmatched/lost response closes the stream; no powered command is retried. +Reconnection creates a fresh device session. Pending measurements and current +limit restoration remain durable across process failures. During Hall detection +only its status, telemetry/PPM reads and release/leases are allowed; none is +represented as cancelling firmware's non-interruptible measurement. + +The versioned runtime carries private Qt/offscreen dependencies and source/license +provenance. `native_check.py` verifies the installed files and runs the disconnected +engine as the service account before USB discovery. Qualification and actual +installation/measurement outcomes are recorded in the installation ledger. +Full auto-FOC, application of measured calibration, general parameter editing +and physical motor acceptance remain outstanding; do not equate this API with +complete VESC Tool UI parity. diff --git a/docs/node/19_VESC_OPERATOR_CALIBRATION.md b/docs/node/19_VESC_OPERATOR_CALIBRATION.md new file mode 100644 index 0000000..e156759 --- /dev/null +++ b/docs/node/19_VESC_OPERATOR_CALIBRATION.md @@ -0,0 +1,99 @@ +# Калибровка VESC через Mission Core + +Проверено на Node 0.8.35-1 / VESC plugin 0.6.3, VESC Tool 7.00 и прошивке +контроллеров 5.02. Это описание доступного процесса; журнал конкретных +испытаний находится в `17_VESC_INSTALLATION_LEDGER.md`. + +## Действия оператора + +Открыть «Аппараты», нужный аппарат, устройства его бортового компьютера, +нужный VESC и «Настройка VESC». В блоке «Калибровка мотора» проверить выбранный +контроллер, параметр допустимых потерь, подтвердить наблюдение и нажать +«Откалибровать мотор». Дождаться результата записи, проверки конфигурации +и снятия тока. Для второго контроллера открыть его карточку и выполнить +отдельную калибровку. Профиль 1×1 сам по себе не запускает групповую калибровку. + +Моторы должны свободно вращаться, пульт — быть выключен. В прошивке 5.02 +нативное измерение нельзя прервать обычной кнопкой остановки или пультом; +оператор должен иметь возможность отключить силовое питание. + +Перед процедурой сохраняются конфигурации подключённых контроллеров. +Мастер измеряет электрические параметры выбранного мотора, определяет +датчики, рассчитывает настройки FOC и записывает результат. Mission Core +проверяет прочитанную обратно конфигурацию и сохраняет версии до/после. +Настройки другого мотора, аккумулятора и приёмника защищены от незапрошенного +изменения. Полная процедура повторно не нужна перед обычным запуском мотора. + +## Что означает 50 Вт + +«Допустимые потери в моторе» — входной параметр штатного мастера VESC Tool. +Он задаёт расчётные резистивные потери на нагрев при предельном токе. По нему +и измеренному сопротивлению мастер выбирает токи измерения и рассчитывает +сохраняемый предел тока мотора. Это не напряжение аккумулятора, не полезная +механическая мощность и не паспортная мощность мотора. Увеличение значения +может увеличить ток и нагрев; вводить сюда номинальные 500 Вт автоматически +неправильно. Параметр не заменяет измерение температуры и тепловую проверку. + +В принятой калибровке двух моторов при 50 Вт мастер установил примерно +34,21 и 34,41 А. Это результат конкретных измерений, а не универсальный +допустимый ток всех моторов. Поправку совместимости с прошивкой 5.02 +выполняет сам VESC Tool. Она не воспроизводится отдельной формулой Mission Core. + +Источник: [объяснение автора VESC](https://www.vesc-project.com/node/1029), +[влияние параметра на токи измерения](https://vesc-project.com/node/1640), +`Commands::detectAllFoc` и `Utility::detectAllFoc` в закреплённом исходнике Tool. + +## Датчики Холла и отдельное измерение + +Датчики сообщают контроллеру положение ротора. При автоопределении FOC мастер +уже проверяет датчики и может выбрать работу без них. Успешная калибровка в +режиме без датчиков не доказывает исправность проводки Холлов. + +Кнопка «Измерить датчики Холла» выполняет отдельную диагностику выбранного +мотора: штатный цикл при 5 А с медленными смещениями получает таблицу +состояний. Она не применяется автоматически, рабочая конфигурация сохраняется. +Это проверка для поиска неисправности, а не обязательный второй этап каждой +калибровки. Неполная таблица требует различать проблемы датчиков/соединений +и недостаточное движение при измерении. Номер физического сломанного контакта +не определяется по таблице без проверки распиновки и проводки. + +Для подготовки к измерению в Node 0.8.39-1 / plugin 0.6.6 оператор отдельно +подтверждает неподвижность всех моторов. Бессенсорная прошивка может сообщать +ненулевые ERPM и изменение тахометра при физической остановке: оба значения +вычисляются из оценки положения ротора. Приложение сохраняет эти показания, +а перед измерением повторно проверяет нейтраль приёмника, отсутствие PWM, +малый ток и отсутствие ошибок. Это исключение действует только для +наблюдаемого измерения Холлов в бессенсорном режиме, не для управления +движением. Установка и реальные результаты новой версии фиксируются отдельно +в журнале испытаний. + +## Назначение и проверка вращения + +Назначение «левый/правый» связывает постоянный UUID VESC с местом мотора на +аппарате. Оно нужно для адресного и общего управления, но не влияет на +измеряемое сопротивление или параметр потерь. После смены USB-порта назначение +сохраняется. Общий список назначений находится в разделе «Настройки борта»; +это профиль аппарата, а не перечень моторов внутри одного VESC. + +«Проверка вращения» запускается отдельно от калибровки. Скорость задаётся +в ERPM, ток задаёт верхний предел, длительность считается после разгона +и удержания скорости. Выбор всех моторов профиля запускает совместную +проверку; для 1×1 это два мотора. Успешная проверка на вывешенном приводе +не заменяет проверку под нагрузкой или надёжности связи. + + +### Visible forward/reverse bench rotation + +After Hall measurement, use **Проверка вращения** for sustained visible motion. +Select one controller or the complete assigned profile, then **Направление +вращения → Прямое / Обратное**, speed magnitude, motor-current ceiling and hold +duration. Direction is relative to each VESC's existing settings, not a certified +vehicle heading. Current is an upper torque limit, not a speed setting. + +Observe all motors fully stopped, raised and free before confirming each start. +Wait for physical stop before changing direction. There is no automatic forward/ +reverse sequence. On admitted sensorless firmware, idle ERPM alone cannot prove +standstill; the preflight records that estimate alongside electrical checks. +Timing begins after speed settles; preparation/ramp/gaps are excluded. Compare +VESC observations with actual movement. This is an unloaded bench test, not +acceptance of loaded starts or the unresolved left Hall hardware fault. diff --git a/docs/node/20_VESC_POWER_LIMITS_PLAN.md b/docs/node/20_VESC_POWER_LIMITS_PLAN.md new file mode 100644 index 0000000..4068754 --- /dev/null +++ b/docs/node/20_VESC_POWER_LIMITS_PLAN.md @@ -0,0 +1,145 @@ +# VESC: план привода и ограничения мощности + +Актуализация 2026-09-24 после установки: Node 0.8.38-2 установлен, Core +принял оба VESC; владелец подтвердил появление устройств после перезапуска. +Ниже сохранён исходный аудит сбоя загрузки и состояние ранних сборок, а не +текущий статус установки. Последний журнал — `17_VESC_INSTALLATION_LEDGER.md`; +текущая очерёдность диагностики, RC-перехвата и профилей — +`23_ROVER_CONTROL_PROFILES.md`, раздел «Приёмка и порядок». + +Статус на 2026-09-24: исследование и план. Пользователь попросил разобраться +в штатном механизме VESC Tool; управление пределами пока не реализуется и +настройки контроллеров не меняются. + +## Принятый результат и незавершённая работа + +- Оба мотора откалиброваны штатным нативным VESC Tool; калибровка, история + конфигураций, назначение и одиночная/совместная проверка доступны в UI. +- Принят совместный тест примерно 30 секунд и хороший ход обоих моторов с + пульта по наблюдению владельца. Это проверка вывешенного привода. +- Левый работает без датчиков, правый с Холлами. Отдельная повторная + диагностика Холлов не завершена; повреждённый контакт не локализован. +- Надёжность USB не принята: после успешного теста повторялись ошибки чтения. +- Node 0.8.36-1 с исправлением проверки нейтрали PPM подготовлен и проверен, + но не установлен. Это исправление не объявляется решением USB-сбоев. + +## Отсутствие устройств после загрузки + +Сегодня Node 0.8.35-1 и VESC-служба активны, без автоматических перезапусков. +Linux не перечисляет VESC среди USB-устройств; ttyACM и serial/by-id отсутствуют. +Во время загрузки есть ошибки чтения USB-дескрипторов и адресации (-71) на +двух портах. Дескрипторы этих устройств не получены: приписывать им личность +VESC или конкретную причину ошибки пока нельзя. Изменение портов не должно +менять идентичность: назначения привязаны к UUID контроллеров. + +Владелец затем подтвердил подключённые USB-кабели и успешное управление обоими +моторами с пульта сейчас. Это подтверждает работу силового питания и моторного +управления, но не USB-канала. Первые ошибки USB зарегистрированы около 9,124 с +от старта, процесс VESC-службы запущен на 11,111 с, Node — на 13,430 с. Значит, +первый сбой перечисления возник до запуска нашего прикладного драйвера в этой +загрузке. Это не устанавливает, неисправен кабель, устройство, питание USB или +контроллер USB Mini. Никакого ручного сброса портов в аудите не выполнялось. + +Отдельный недостаток продукта подтверждён исходниками: drive-profile.json +сохраняется на борту, но Service.inventory публикует drive_profile только +внутри обнаруженных устройств. Node сохраняет отсутствующие устройства через +реестр initialized, который обновляется при prepare; автоматически обнаруженная +личность сама в него не добавляется. В текущем Core один VESC остаётся offline, +второго нет в inventory, хотя архивы обоих доступны. Это не потеря калибровки, +но модель отображения известных устройств и общего профиля недостаточна. + +Нужны независимая доступность профиля аппарата и сохранённый список назначенных +контроллеров со статусом «нет связи». Нельзя выдавать сохранённые сведения за +свежую телеметрию или разрешать команды без нового подтверждения UUID/сеанса. +Сохранность самого файла профиля в этом аудите напрямую не проверена: у SSH +пользователя нет права чтения. Факт сохранения установлен по реализации и +вчерашним квитанциям; текущие архивы обоих контроллеров прочитаны через Core. + +## Последние подтверждённые пределы + +Данные из архивов 2026-09-23 21:05 UTC, а не новое чтение недоступных VESC. + +| Параметр | Левый | Правый | +| --- | ---: | ---: | +| Максимальный ток мотора | 34,2135 А | 34,4078 А | +| Масштаб тока разгона | 100% | 100% | +| Предел тока батареи | 55 А | 55 А | +| Предел рекуперации в батарею | −55 А | −55 А | +| Отдельное ограничение мощности | выключено | выключено | + +Значение watt max 1500000 соответствует выключенному ограничению в профилях +Tool. Оно не является мощностью оборудования. Значение absolute current +160 А — отдельный порог защиты, а не паспортный рабочий ток. Настройки батареи +унаследованы и не подтверждают возможности BMS. Максимумы мотора около 34 А +получены мастером при допустимых потерях 50 Вт. Этот параметр калибровки не +является выходной мощностью. Временные 30 А и 2000 ERPM теста не являются +постоянным ограничением ручного управления; квитанции подтверждают восстановление +временных токовых масштабов после принятого теста. + +## Штатный механизм + +Базовые Motor Current Max, Battery Current Max, рекуперация и другие пределы +хранятся в конфигурации каждого VESC. Профиль Tool задаёт масштаб тока разгона +и торможения, скорость, duty и мощность. Процент тока не равен проценту ватт: +ток мотора в первую очередь задаёт момент, а батарейный ток относится к +потреблению от общей батареи. + +В закреплённом Tool ProfileDisplay вызывает Commands::setMcconfTemp и предлагает +«Use until reboot» и постоянное применение. FW 5.02 поддерживает сохранение, +пересылку по CAN и деление ватт между обнаруженными CAN-контроллерами. Поэтому +общий профиль возможен, но исполняют ограничения отдельные контроллеры. Их +применение влияет и на PPM-пульт; для этого не нужна повторная калибровка. +Временное применение не требует записи каждого движения ползунка во flash. + +В штатной пересылке подтверждение ведущего не является подтверждением каждого +ведомого: FW подавляет ack для пересланных команд. В интеграции нужны проверка +состава назначенных UUID и чтение результата у каждого участника. Делить бюджет +по случайному числу отвечающих устройств нельзя: пропавший контроллер может +снова появиться, и общий бюджет батареи будет превышен. Конкретную политику +частичного применения и восстановления следует определить до реализации. + +## Предлагаемая модель Mission Core + +Общий профиль привода размещается у аппарата. Он содержит уже существующую +схему 1×1/2×2 и назначения, подтверждённый бюджет общей батареи и режим работы. +Карточка каждого VESC хранит калибровку, паспортные основания пределов и его +индивидуальные ограничения. Общий режим применяет согласованные значения к +назначенным контроллерам через нативный Tool; подтверждённые ограничения +исполняются на VESC независимо от связи с Core. + +Запас 20% рассчитывается от подтверждённых допустимых характеристик при +реальном охлаждении и длительности нагрузки. Для каждой пары мотор–контроллер +нужен допустимый фазный ток; для общей батареи — суммарный ток разряда и +отдельный ток заряда/рекуперации. Пиковый ток нельзя считать непрерывным. +Маркер прошивки 75_300_R2 не доказывает производителя и реальные характеристики +платы, а приблизительные 500 Вт мотора не определяют допустимый фазный ток. +Поэтому численный новый потолок пока не назначен. Нужны точные модели или +подтверждённые характеристики от изготовителя и параметры BMS. + +## Очерёдность + +1. Установить состояние питания/подключений и восстановить USB-обнаружение, + затем проверить связь без вращения. Смена портов не должна требовать + повторного назначения, перезагрузка не должна скрывать сохранённый профиль. +2. Исправить доступ к общему профилю и отображение известных offline-устройств; + применить и проверить подготовленное исправление нейтрали пульта через + версионный установщик с согласованным прерыванием служб. +3. Сверить паспорта моторов, контроллеров и BMS; сформировать индивидуальные + пределы и общий бюджет с согласованным запасом. Затем реализовать профили + ограничений штатными средствами Tool, с резервированием и чтением результата. +4. Завершить отдельную диагностику Холлов, сохранив принятую калибровку. +5. Принять работу под нагрузкой, ограничения температуры/рекуперации и + остановку при потере связи; далее полноценное ручное удалённое управление, + приоритет пульта и автономный режим. Общий тест пока не означает готовность + всей системы управления к эксплуатации. + +## Первичные источники + +- [VESC: назначение пределов тока](https://vesc-project.com/node/180). +- [Tool: штатные профили и применение](https://github.com/vedderb/vesc_tool/blob/01d5f10901116c311e3fb84d5a1541f663d3ce20/mobile/ProfileDisplay.qml). +- [Tool: поля профиля](https://github.com/vedderb/vesc_tool/blob/01d5f10901116c311e3fb84d5a1541f663d3ce20/mobile/ProfileEditor.qml). +- [FW 5.02: COMM_SET_MCCONF_TEMP](https://github.com/vedderb/bldc/blob/5.02/commands.c). + +Ops MCP на момент обновления возвращает HTTP transport error; план и свежая +диагностика в Ops не опубликованы. Частные журналы и UUID находятся вне Git +в outputs/rover-006-vesc-context-20260923/native-probe/boot-20260924-*. diff --git a/docs/node/21_STARTUP_AND_USB_RECOVERY.md b/docs/node/21_STARTUP_AND_USB_RECOVERY.md new file mode 100644 index 0000000..2a67032 --- /dev/null +++ b/docs/node/21_STARTUP_AND_USB_RECOVERY.md @@ -0,0 +1,95 @@ +# Подготовка окружения, автозапуск и USB при загрузке + +Требование владельца от 24.09.2026: пользователь получает сборку Node, +открывает приложение и выполняет его настройку. Все необходимые изменения ОС +выполняет версионированный продукт. Ручные правки Linux не являются частью +установки, диагностики с исправлением или первого испытания. + +## Владение настройкой + +Существующая страница «Настройка окружения → Сконфигурировать» использует +профиль `ubuntu-24.04-amd64/3`. Добавлены два этапа в существующий список: + +- «Автозапуск приложения»: root-owned XDG entry открывает обычное окно Node + после входа в графическую сессию. Перед запуском оно до 180 секунд ожидает + HTTP-службу. Gtk.Application сохраняет одно окно на пользовательскую сессию. + Авторизация локального интерфейса остаётся обычной polkit-авторизацией; + автозапуск не выдаёт новые права и не настраивает автоматический вход в ОС. +- «Обнаружение устройств при загрузке»: устанавливает фиксированную политику, + включает отдельную службу на следующую загрузку и читает возможности текущих + USB-хабов. Подготовка окружения не перезапускает USB-порты в текущей сессии. + +Системная служба Node уже включалась установщиком и работает до входа в рабочий +стол. Открытие окна и работа борта — разные жизненные циклы. Постоянного +интерфейса управления портами нет; обновление устройств только обновляет список. + +Политика и XDG entry создаются из шаблонов пакета. Повторное выполнение +идемпотентно; чужие файлы/ссылки не перезаписываются. При удалении пакета +удаляются только неизменённые принадлежащие продукту файлы, служба отключается. +Пакет запрещает замену файлов во время переключения USB или незавершённого +обратного включения. При откате до версии раньше 0.8.37 prerm также отключает эту службу и удаляет +только совпадающие с шаблонами настройки, прежде чем dpkg удалит новые helper. +Физическая проверка downgrade ещё не выполнена. + +Подтверждаемый профиль пока Ubuntu 24.04 amd64. Новые дистрибутивы и архитектуры +должны получить собственные поддерживаемые профили и проверку dependency closure; +этот пакет не является доказательством работы на любом Linux. + +## Ограниченная процедура USB + +1. Служба запускается до Node и VESC, только если подготовка среды включила + политику. После udev-settle выдерживается возраст загрузки не менее 30 секунд: + ядро может ещё повторять обнаружение после завершения udev-settle. +2. Из журнала **текущей загрузки**, только transport=kernel, выбираются порты с + окончательным `unable to enumerate USB device` в первые 60 секунд. Более + позднее подключение/отключение отменяет устаревший кандидат. Ошибка чтения + дескриптора сама по себе не разрешает сброс. +3. На порту и его USB 2/3 companion не должно быть дочернего устройства, + состояния незавершённого обнаружения, отключения или зарегистрированного + overcurrent. Встроенные hardwired-порты исключены. Проверяются взаимные peer + ссылки, поколение/адрес хаба и нахождение атрибутов в sysfs. +4. Дескриптор каждого хаба должен подтвердить individual port power switching. + При ganged/no switching/нечитаемом дескрипторе порт пропускается. Поддержка + физического отключения VBUS всё равно зависит от железа; успешный sysfs write + не доказывает восстановление устройства. +5. До первого изменения сохраняется root-owned журнал обратного включения. + После повторной проверки свободных портов пара отключается на одну секунду, + включается в `finally`; до восьми секунд ожидается новое обнаружение. + ExecStopPost повторяет обратное включение при остановке процесса. Уже включённый + порт не переключается повторно. Ошибка восстановления сохраняет pending и + останавливает обработку других портов. +6. Не более одной попытки на физическую пару за загрузку, общий бюджет 90 секунд, + начало только в первые 180 секунд. Поздний запуск службы/перезапуск приложения + не сбрасывает USB. Повторный запуск сохраняет исходный результат. + +До чтения дескриптора тип проблемного устройства неизвестен: это ограниченное +восстановление ошибки Linux USB, а не угадывание VESC по пустому разъёму. +Конкурентное физическое подключение полностью не атомарно относительно sysfs; +проверки выполняются непосредственно перед записью. Процедура не меняет драйвер +хост-контроллера и не сбрасывает целый USB-контроллер/хаб. Она не отправляет +команды моторам. После обнаружения обычный драйвер сопоставляет VESC по firmware +UUID, а не по tty, разъёму или неуникальному USB serial. + +Результаты остаются в `/run/mission-core-usb-startup/`: inspection.json, +result.json, attempted, при незавершённом восстановлении pending.json. +Синтетические тесты используют временный sysfs; реальное переключение в них +не выполняется. + +## Приёмка + +- Локально: 36 тестов подготовки/автозапуска/USB, shell syntax и diff check прошли. +- Ubuntu qualification: 17 этапов прошли; пакет 0.8.37-1 и штатный установщик + сформированы, APT-план проверен. Пакет установлен штатным установщиком. + Хеши и результаты находятся в ledger. +- Подготовка через поставляемый UI: все девять этапов завершены, XDG entry и + USB-политика созданы, служба восстановления включена для следующей загрузки. + Сводная проверка нашла поддержку у USB-хабов; возможности именно корневых + портов ещё нельзя вывести из сводного статуса. Оба VESC доступны. +- Холодная загрузка с подключёнными VESC, сохранение UUID/назначений и отсутствие + вмешательства в камеры: ещё не приняты. Программный перезапуск службы не + заменяет этот тест. Без владельца перезагрузка борта не выполняется. + +Основания: Linux [USB sysfs ABI](https://github.com/torvalds/linux/blob/master/Documentation/ABI/testing/sysfs-bus-usb), +[port.c](https://github.com/torvalds/linux/blob/master/drivers/usb/core/port.c), +[USB error codes](https://docs.kernel.org/driver-api/usb/error-codes.html), +[uhubctl: switching and USB 2/3 peers](https://github.com/mvp/uhubctl). diff --git a/docs/node/22_BOARD_SETTINGS_SURFACE.md b/docs/node/22_BOARD_SETTINGS_SURFACE.md new file mode 100644 index 0000000..61f4789 --- /dev/null +++ b/docs/node/22_BOARD_SETTINGS_SURFACE.md @@ -0,0 +1,37 @@ +# Карточка аппарата: борт, настройки и устройства + +Согласовано владельцем 2026-09-24: существующую карточку аппарата разделить +на три независимо сворачиваемых блока; повторить композицию в Node. + +- «Бортовой компьютер»: идентичность, связь, характеристики и существующие действия. +- «Настройки борта»: общий профиль привода, назначения UUID и чтение ограничений VESC. +- «Устройства аппарата»: существующий инвентарь и переход к конкретному устройству. + +Используется канонический DG Inspector variant=panel. Новая навигация и новые +визуальные сущности не вводятся. Альтернатива — дополнительные окна настроек — +отклонена владельцем в пользу блоков на существующей карточке. + +Открытые секции сохраняются автоматически в JSON на стороне приложения: +в Core отдельно для каждого аппарата, в Node локально для его борта. Это +представление оператора, не конфигурация контроллера. Изменение одного блока +не перезаписывает состояние остальных. Пустой список означает «всё свёрнуто». +Инвентарь и выполняющиеся команды живут выше Inspector: сворачивание не +останавливает соединения и не скрывает ошибки сохранения. + +Общий профиль и назначения используют прежние проверенные команды VESC. +Калибровка, Холлы, тест вращения и версии конфигурации остаются в карточке +конкретного контроллера. Чтение ограничений идёт через нативный VESC Tool, +не меняет моторную конфигурацию и не запускает мотор. Значения являются +настройками контроллера, а не паспортными пределами оборудования. + +Изменение рабочих пределов мощности остаётся отдельным этапом по плану 20: +нужны подтверждённые пределы оборудования и политика согласованного применения. +Никаких искусственных «80% мощности» или новых токовых пределов этот этап +не записывает. Проверки: сохранение после навигации/перезагрузки, разделение +аппаратов, конкурентные изменения секций, ошибки JSON/связи и обе поверхности. + +Последующее требование владельца: добавить здесь два режима ручного управления +ровером. Исследование источника команд, пульта и независимого RC-пути находится +в [плане 23](23_ROVER_CONTROL_PROFILES.md). Этот режим не совпадает со схемой +1×1/2×2; переключатель не объявляется действующим до реализации и проверки +реального пути команд. diff --git a/docs/node/23_ROVER_CONTROL_PROFILES.md b/docs/node/23_ROVER_CONTROL_PROFILES.md new file mode 100644 index 0000000..ea86995 --- /dev/null +++ b/docs/node/23_ROVER_CONTROL_PROFILES.md @@ -0,0 +1,595 @@ +# Профили ручного управления ровером + +Актуальное решение владельца 25.09.2026: оставить работающее управление двумя +стиками; Tank/Arcade и управление одним стиком отложить до отдельного возврата +к задаче. Сейчас Mini получает CH2/CH3, но не горизонтальную ось выбранного +стика; новую проводку/адаптеры владелец исключил. Прототип не включать в +production и не показывать переключение RC-профиля как применённое. +Требование stop → neutral → manual сохранено незавершённым. + +Полный контрольный паспорт, конфигурации, история экспериментов и чекеры +опубликованы в [MISSIONCOR-85 — Гусеничный ровер Node 006](https://ops.nodedc.ru/nodedc/browse/MISSIONCOR-85). +Карточка прочитана обратно через прямой Ops MCP: все 35 структурированных +блоков совпали с подготовленным содержимым, включая 600 параметров VESC. + +Статус 2026-09-24: исследование и автономный программный прототип. Рабочие +настройки пульта, приёмника и VESC не изменены; новый режим движения на +оборудовании пока не реализован. + +## Требование владельца + +В существующих «Настройках борта» нужны два профиля: независимое управление +левым и правым бортом двумя рычагами и управление движением/поворотом одним +двухосевым рычагом. Тот же профиль должен быть доступен локально на Node и +через Core. Пульт должен сохранять возможность управления при отказе Mini. + +Профиль управления не заменяет схему привода 1×1/2×2 и назначения моторов. +Последние определяют физические исполнительные устройства; профиль определяет +смысл входных команд. Новые режимы не требуют повторной калибровки моторов. + +Уточнение владельца: при автономном движении или удалённом ручном управлении +пульт может оставаться включённым и готовым к немедленному перехвату. Движение +рычага за пределами проверенной нейтрали должно отбирать управление у всех +источников Mission Core без переключения режима в интерфейсе. После перехвата +нейтраль пульта не возобновляет прерванную задачу. Локальный оператор может +освободить застрявший ровер даже при недоступном операторском Core; отказ самого +Mini также не должен лишать его независимого RC-пути. Уведомления об аномалии +и обнаружение застревания пока описывают будущий сценарий, не реализованный код. + +Следующее уточнение владельца: отдельный интерфейс переключения источника +управления не нужен. Владелец наблюдает, что пульт работает только когда четыре +верхних переключателя подняты, и предлагает использовать это как сигнал +ручного перехвата. Наблюдение ещё не разделено на блокировку при включении и +поведение уже работающего передатчика. По руководству FS-i6S, раздел 4.1, +верхнее положение требуется при включении; раздел 2.2.3 описывает SwA–SwD как +назначаемые переключатели. Документ не подтверждает отдельный передаваемый +признак «все четыре подняты» или отключение радиолинка любым из них. + +Владелец затем исправил наблюдение: управление моторами сохраняется и со +всеми четырьмя тумблерами в нижнем положении. Гипотеза «любая нижняя позиция +выключает управление/радиосвязь» отозвана. Начальный пассивный замер был +помечен заявленным положением SWA, но его нельзя использовать как доказательство +влияния тумблера: синхронное сравнение состояний не завершено. Предложенное +переключение SWA для следующего замера отменено. Проверка положений при +включении остаётся вероятным объяснением, не подтверждённой настройкой пульта. + +Это требование к автоматическому выбору источника не отменяет ранее заказанную +настройку Tank/Arcade: раскладка органов управления и право выдавать команду +моторам — разные свойства. Перехват не должен требовать клика в Core. + +## Последнее уточнение: первый ввод останавливает, следующий управляет + +Владелец изменил непосредственную реакцию на RC: первый ввод с рычага должен +только прервать автономное/удалённое движение; последующий ввод может управлять +моторами. Отменяются задачи автономной езды и их вычислительные исполнители, +включая связанные с ней inference/планирование/обработку облаков. Запрет на +выходные команды должен вступать в силу раньше и независимо от завершения +таких задач. Нельзя ждать остановки тяжёлого вычисления, прежде чем запретить +ему движение; запоздавшие результаты и команды теряют допуск. + +Один удерживаемый рычаг создаёт непрерывную последовательность пакетов, поэтому +«следующий пакет» не равен второму осознанному действию. Подтверждённая владельцем +последовательность — первый выход из нейтрали: остановка; затем оба моторных +канала в устойчивой нейтрали; затем новое отклонение: ручное движение. +Ответ владельца 2026-09-24: «Да: остановка → нейтраль → управление». +Требование принято; изменение рабочего моторного runtime ещё не выполнено. + +Для этой трактовки нужны состояния прекращения команд, подтверждения остановки, +ожидания нейтрали и ручного управления. Нельзя пропускать первое удерживаемое +отклонение после фиксированной паузы или считать перезапуск процесса разрешением +движения. Проверяются свежесть входа, все назначенные стороны и отзыв старых +допусков. Длительность нейтрали и допустимое время остановки задаются после +выбора и проверки исполнительного механизма, не случайной константой. + +Текущая прямая PWM-проводка приёмник→VESC и истечение 250 мс аренды сами по себе +не реализуют это требование: отпустив аренду при удерживаемом RC, программа +передаст в мотор уже первое отклонение. Нельзя выдавать существующий test latch +за stop-first. Также удержание блокировки только на Mini не гарантирует эту +семантику при отказе Mini. Для независимой гарантии проверка перехода должна +жить у исполнителя либо в отдельном независимом тракте; stock FW 5.02 такой +квалифицированной функции в нынешней схеме не имеет. Это архитектурная граница, +не разрешение автоматически прошивать VESC или покупать новый контроллер. + +Остановка вычислительных задач не означает остановку служб приёма RC, +контроля привода и наблюдения его состояния. Нулевая команда тока не доказывает +физическую остановку: выбег/торможение и допустимая рекуперация требуют отдельной +проверки. Автоматический возврат к прерванной задаче после нейтрали запрещён. + +### Подтверждённая последовательность + +| Состояние | Событие | Требуемая реакция | +| --- | --- | --- | +| Движением управляет Mission Core | Первое допустимое отклонение любого назначенного RC-канала | Отозвать допуск всех остальных источников, очистить их очередь, начать согласованную остановку всех приводов и отменить задачи автономного движения. Первое отклонение не передавать как команду езды. | +| Остановка / ожидание нейтрали | Рычаг остаётся отклонённым, приходят новые пакеты | Сохранять запрет движения; количество пакетов и прошедшее время сами по себе его не снимают. | +| Остановка / ожидание нейтрали | Остановка подтверждена, все назначенные рычаги вернулись в подтверждённую нейтраль | Разрешить следующий осознанный RC-жест; Mission Core остаётся без допуска к движению. | +| Пульт готов к движению | Новое отклонение рычага | Передать ручную команду назначенным приводам. | +| Пульт управляет | Последующие отклонения и возвраты в нейтраль | Обычное ручное управление. Каждый новый жест не повторяет процедуру перехвата. | +| Любое состояние после перехвата | Пришла запоздавшая команда отменённой задачи / восстановилась связь Core | Отклонить команду. Восстановление связи не возобновляет автономное движение. | + +Это контракт поведения, не таблица состояний установленной реализации. +Условия свежести и нейтрали относятся ко всем назначенным каналам, независимо +от схемы 1×1/2×2 и числа моторов. Пропавший канал не считается нейтральным. +Ответ на USB-запрос с последним декодированным значением сам по себе не +доказывает свежий импульс приёмника: FW 5.02 не возвращает его возраст в +`COMM_GET_DECODED_PPM`. Нейтральный failsafe также не доказывает отпускание +стика оператором. Эти ограничения должны быть учтены до допуска автономии. + +### Проверка штатной FW 5.02 + +Аудит выполнен по сохранённому upstream commit +`3f670137e27e6e383fa79c50cc6b1fa85aab1554`; Git blob-хэши `app_ppm.c`, +`app.c`, `commands.c`, `datatypes.h` совпадают с сохранённым деревом Git. +Это проверка исходников upstream, не доказательство побайтового совпадения +прошивки производителя в имеющихся контроллерах. + +- `applications/app_ppm.c`: вход декодируется при отключённом выходе; + Safe Start использует счётчик нейтральных импульсов после конфигурации, + тайм-аута приёмника или ошибки. Ветка отключённого выхода не сбрасывает + этот счётчик. Завершение USB-аренды не создаёт новую проверку нейтрали. +- `applications/app.c::app_disable_output`: положительное время отключает + выход до истечения таймера; его callback просто разрешает выход. Значение + −1 отключает бессрочно, что не подходит для независимого RC при отказе Mini. +- `commands.c::COMM_SET_APPCONF`: перезапускает приложения и сохраняет + конфигурацию во flash. Это не команда ручного перехвата на каждый жест. +- `COMM_SET_CAN_MODE` может вызвать тот же перезапуск без сохранения, но + перезапуск PPM/UART и других приложений через настройку CAN не является + проверенным механизмом передачи управления. Такой обход не применяется. +- Наш native `release` отправляет `setCurrent(0)`: это снятие тяги, а не + подтверждённое торможение и не повторное включение Safe Start. + +Для исправного Mini возможен программный цикл удержания выхода до нейтрали. +Он не обеспечивает одинаковое поведение при потере Mini/USB: таймер в VESC +всё равно истечёт. Штатной проверенной функции для полного требования в +текущем тракте не найдено. Нужна поддержка перехвата на исполнительном уровне +либо другой независимый тракт. Простого изменения в одном VESC недостаточно: +отклонение одного канала должно согласованно остановить весь борт, а топология +межконтроллерной связи пока не подтверждена. + +Следующий этап реализации — выбрать и проверить такой механизм по имеющемуся +железу, включая отзыв прямых USB-команд, согласование всех приводов, остановку +и нейтраль при отказе Mini. Обновление/доработка прошивки требует отдельного +плана совместимости и восстановления. Пока проверяются эти условия, +не активировать автономное движение и не выдавать действующие стендовые +тесты за принятый постоянный арбитр. Прошивки и рабочая RC-конфигурация в этом +аудите не изменялись. + +Кандидат для следующей проверки без отдельного бортового контроллера — +штатная LispBM-поддержка современных VESC: upstream документирует для FW 6.00+ +`get-ppm`, `get-ppm-age`, `app-ppm-detach`, `app-ppm-override`, а также доступ +к PPM других VESC через настроенный CAN. Код исполняется в контроллере, +не на Mini. Это возможный исполнитель подтверждённой последовательности, +не готовая встроенная функция перехвата и не доказанная гарантия приоритета +над прямыми USB-командами. Нужны проверка совместимости платы, согласованный +обмен между приводами, исключение обхода арбитра, реакция на остановку скрипта +и квалификация поведения при потере каждого соединения. Возраст PPM отличает +отсутствие импульсов от их наличия, но не живой радиолинк от импульсов failsafe. +Текущая версия 5.02 этой документированной LispBM-возможностью не подтверждена. +Маркер 75_300_R2 недостаточен для выбора прошивки; у владельца запрошены +производитель и точная модель, если известны. Обновление не запускалось. +[Документация LispBM VESC](https://github.com/vedderb/bldc/blob/master/lispBM/README.md), +[описание поддержки в FW 6.00 автором VESC](https://vesc-project.com/node/3385). + +## Что подтверждено + +Приёмник на прежней фотографии — FlySky FS-iA6B. По сообщению владельца, +левый VESC подключён к CH3, правый к CH2. Принятое вращением назначение +контроллеров хранится по UUID, независимо от USB-порта. + +Новые фотографии пульта показывают маркировку Robcom Venom Drone. Корпус, +две кнопки питания, сенсорный экран, расположение переключателей, задних +кнопок и PS/2/USB совпадают со схемой FlySky FS-i6S. Это обоснованная +идентификация семейства по внешности. Владелец сообщает о втором внешне таком +же пульте без маркировки Robcom. Последующий осмотр About 2026-09-25 подтвердил +сообщаемые устройством Flysky FS-i6S, прошивку 2.00 от 04-Apr-2020 и Hardware +V_3.0; подробности видеоподтверждения приведены ниже. Это не аудит возможных +OEM-изменений электроники. + +По руководству семейства FS-i6S, разделы 2.2.3 и 6.8, SwA/SwB/SwC/SwD — +назначаемые переключатели: их можно связать с дополнительным каналом или +функцией передатчика. У каждого нет постоянного назначения «камера», +«ручной режим» или «аварийный стоп». На дополнительном канале передаётся +значение, соответствующее положению; смысл ему задаёт принимающая система. +Фактические назначения конкретного пульта ещё не прочитаны. Меню Aux. Channels +показывает назначения дополнительных каналов; функции самого передатчика +могут использовать переключатели отдельно (например Trainer Mode, раздел 7.3). +Текущее подключение CH2/CH3 к VESC не даёт Mini доступ ко всем этим каналам. + +В архиве конфигураций после принятого общего теста оба входа VESC настроены +как PPM Duty Cycle. Левый использует приложение PPM, правый — PPM and UART. +Настройки отклика различаются: разгон/сброс слева 0,4/0,2 с, справа 0,5/0,5 с; +параметр polynomial curve слева −1, справа −1,5; deadband у обоих 0,15. +Это сохранённые значения, не новое чтение после текущей загрузки и не +основание автоматически уравнивать параметры. Ровное вращение на общей +команде ERPM не означает одинаковую реакцию на одинаковое положение стиков. + +У обоих сохранён multi_esc=true. Наличие и топология физического CAN ещё +не подтверждены. Перед изменением схемы команд надо исключить взаимную +пересылку между левым и правым бортом; одну настройку нельзя считать схемой +проводки. Никакого CAN broadcast или изменения multi_esc сейчас не сделано. + +## Канонические механизмы + +В терминологии WPILib первый режим — Tank Drive, второй — Arcade Drive. +Arcade преобразует движение и поворот в согласованную пару команд левой и +правой стороны. Curvature Drive — отдельный вариант поведения поворота; +его нельзя незаметно подменять под тот же профиль. Стороны могут включать +несколько назначенных моторов. [Официальное описание WPILib](https://docs.wpilib.org/en/stable/docs/software/hardware-apis/motors/wpi-drive-classes.html). + +Микширование не должно трактовать ток как заданный радиус поворота: ток +связан с моментом, а скорость зависит от нагрузки. Нормализация, насыщение, +знаки, нейтраль, движение назад и разворот на месте требуют явной модели и +приёмки. Микшер и ограничения мощности — разные части системы. + +Штатное приложение PPM прошивки VESC 5.02 читает один импульсный вход. +multi_esc пересылает ту же команду другим контроллерам, а не вычисляет +дифференциальное управление из двух осей. +[Исходник FW 5.02](https://github.com/vedderb/bldc/blob/5.02/applications/app_ppm.c). + +В официальном руководстве FS-i6S есть Mix (master/slave, положительный и +отрицательный коэффициенты), сохранённые модели и просмотр каналов. Число +доступных независимых миксов, назначение осей и поведение их композиции в +имеющейся прошивке ещё не проверены. Наличие пункта Mix не доказывает +возможность получить два требуемых выхода на нынешних CH2/CH3. Меню About +показывает модель и версии. Failsafe=Off в руководстве означает удержание +последнего значения; выключенный передатчик нельзя приравнивать к нейтрали +без измерения выхода приёмника. [Руководство производителя](https://www.flysky-cn.com/s/FS-i6S-User-manual-20200628-al4y.pdf), разделы 6.9, 6.10, 7.2, 7.13. + +## Где может исполняться профиль + +1. В пульте. Сначала проверить штатное микширование на экране каналов без + команд моторам. Такой путь сохраняет независимость от Mini. Через два + имеющихся PWM-провода Mission Core не может читать или менять модель + передатчика: нельзя показывать локально сохранённый выбор как применённый. +2. На Node. Нужен полный вход с осями и явным выбором управления, например + через приёмник iBUS и совместимый интерфейс. Разъём iBUS есть у семейства + FS-iA6B, но соответствующего подключения к Mini сейчас не подтверждено. + Сначала проверить уровни, адаптер, формат и режим реального приёмника. + Текущих двух вертикальных осей недостаточно для правого двухосевого стика. +3. Во внешнем контроллере/микшере. Это технический вариант, а не принятое + решение: владелец хочет обойтись существующим бортовым компьютером. + +Выбор пути зависит от наблюдаемой аппаратуры. Реализацию универсального +переключателя нельзя завершить, скрыв эту зависимость. Не прошивать пульт или +VESC и не переподключать каналы ради проверки гипотезы без отдельного плана. + +## Наблюдение входа и приоритет пульта: существующая граница + +Текущий native backend уже читает через VESC Tool `COMM_GET_DECODED_PPM`: +декодированный уровень и длительность последнего импульса одного входа VESC. +Два USB-соединения дают два подключённых канала приёмника. Это не полный +радиообмен передатчика с приёмником, не все оси/переключатели и не подтверждение +радиолинка. Штатный PPM-код продолжает декодировать вход при временно отключённом +выходе приложения. Прямые команды тока/ERPM через USB уже применялись в тестах; +воспроизведение радиопакетов или подмена PWM-проводов для этого не нужны. + +По двум нейтральным значениям CH2/CH3 нельзя различить включённый передатчик +с отпущенными стиками и выключенный передатчик при нейтральном failsafe. +Положения SwA–SwD тоже не следует выводить из этих значений. Для перехвата по +переключателю нужен проверенный соответствующий канал, доступный на борту; +для перехвата по наличию радиолинка — подтверждённый признак валидности связи. +Подключение полного потока приёмника к Mini пока не подтверждено. Если сама +готовность включённого пульта означает ручной режим, автономия с включённым +готовым пультом блокируется; это отличается от предыдущего сценария перехвата +движением рычага. До выяснения реального сигнала не менять рабочую схему. + +В `motor_test.py` и `group_test.py` проверка входа выполняется до следующей +подачи команды. Активный канал записывает состояние `rc`, прерывает тест и +запрещает новый запуск до явного `vesc.control.release` после нейтрали. +`receiver.py` использует свежую конфигурацию deadband каждого VESC, а не +считает любой ненулевой шум командой. Это действующий код коротких стендовых +тестов, не принятый постоянный арбитр автономного движения. + +Тесты временно приостанавливают выход PPM отдельными продлеваемыми арендами +по 250 мс. Таймер исполняется в VESC: при прекращении продления PPM возвращается +без участия Mini. Это защита от исчезновения процесса/USB, а не гарантия +приоритета RC при ошибочной программе, продолжающей продлевать аренду. Также +250 мс не являются измеренной максимальной задержкой перехвата всего ровера. +Надёжный постоянный тракт требует проверки таймаутов, возврата RC, отсутствия +поздних USB-команд и поведения всех назначенных сторон. Гарантия при ошибочной +программе на живом Mini потребует независимого решения у исполнительного +уровня; наличия такой гарантии в stock FW 5.02 не установлено. + +Штатные FOC/Hall-процедуры FW 5.02 не прерываются обычной командой пульта. +Они остаются отдельным сервисным режимом вывешенного привода и не могут +запускаться в автономном движении под обещание постоянного RC-перехвата. + +## Контракт реализации в Mission Core + +- Один версионный профиль борта: режим, источник входа, проверенное назначение + осей, стороны/UUID, параметры отклика и ссылка на отдельные пределы привода. + Хранить желаемое и подтверждённое применённое состояние раздельно. +- Общий интерфейс в существующем блоке через компоненты Design Guideline; + калибровка конкретного двигателя остаётся в карточке VESC. +- Смена профиля только после нейтрали всех назначенных сторон. При частичной + потере связи запрещено объявлять общий профиль применённым. +- Перехват пультом фиксируется до явного возврата управления. Нулевое значение + PWM само по себе не определяет, выключен передатчик или стоит в нейтрали. +- На Node должен быть один владелец выхода: все команды автоматики, клавиатуры, + удалённого джойстика и другого управления проходят через него. Перехват RC + отзывает их допуск и отменяет очередь; опоздавшая команда старого допуска + не может вновь включить движение. Core отображает состояние, но не является + звеном, необходимым для локального перехвата. +- Потеря Core, Node, входного потока или одного VESC должна иметь проверенное + поведение. Существующая аренда отключения PPM для коротких тестов не является + приёмкой постоянного удалённого управления. Без Mini должен сохраняться + понятный оператору независимый путь RC, а не внезапная смена смысла стиков. +- Нативный VESC Tool остаётся владельцем протокола и конфигурации контроллеров; + калибровочные алгоритмы не копируются в новый модуль профилей. + +## Приёмка и порядок + +Node 0.8.38-2 установлен; Core принял оба VESC после исправления версии драйвера. + +1. Завершить диагностику существующего привода до установки гусениц: + подтвердить связь и сохранить свежие конфигурации; отдельно сравнить Холлы + левого и правого мотора без замены принятой калибровки. Перед процедурой + заново синхронизироваться с наблюдающим владельцем. Если сигнал отсутствует, + отделить неисправность проводки/датчика от недостаточности измерения. + Повторная калибровка не восстанавливает физический контакт. +2. После результата проверить оба направления, старт и остановку, затем + поведение пульта при потере связи на вывешенном приводе. При необходимости + уточнить нейтраль и failsafe через штатные средства. Дать отдельный вывод + о готовности к ограниченной нагрузочной проверке; существующий ровный + тест без нагрузки и исправный правый Hall не доказывают исправность левого. +3. Для нового управления прочитать About, меню Mix, карту каналов и failsafe + пульта без изменения рабочей модели. Проверить точную модель VESC и +межконтроллерную связь. Недостающая модель не блокирует диагностику текущей + версии, но блокирует обоснованный выбор новой прошивки. +4. Выбрать штатный исполнитель перехвата с независимостью от Mini, подготовить + версионную интеграцию и сначала проверить переходы без движения. LispBM + остаётся кандидатом; обновление не является обязательным следующим шагом + и не выполняется по одному имени 75_300_R2. Приёмка включает удержание + первого жеста, нейтраль всех входов, второй жест, запоздалые команды, + потерю Core/Mini/USB/связи между контроллерами и отсутствие самовозврата. +5. Реализовать Tank/Arcade и общий профиль ограничений в существующих + «Настройках борта», с индивидуальными пределами каждого привода. Выбрать + место микширования по реально доступным каналам. Новые численные максимумы + и запас 20% требуют характеристик моторов, VESC и общей батареи/BMS; + приблизительные 500 Вт и имя аппаратной прошивки их не подтверждают. + +Испытание на гусеницах зависит от результата пунктов 1–2 и допустимых рабочих +пределов, а не от завершения будущей автономии. Новый RC-перехват и Arcade +проверяются на вывешенном приводе до проверки под нагрузкой. + +Уточнение владельца: идентифицировать контроллеры программно; разборка ровера +ради чтения маркировки нежелательна и сейчас не требуется. В выполненном +аудите через установленный native Tool оба контроллера подтвердили уникальные +UUID, FW 5.02 / 75_300_R2, штатный тип VESC, test_firmware=0 и custom_configs=0. +С каждого считаны полные motor/app-конфигурации (151/149 параметров), вход PPM +и телеметрия. Оба штатных CAN ping дали пустой список: межконтроллерный обмен +не подтверждён, но отсутствие физических проводов из этого не следует. +USB-дескрипторы и USB-серийники одинаковы; идентичность по-прежнему задаёт +UUID VESC. Новые резервные копии есть в истории Core и совпадают с принятыми +архивами после калибровки. Движение и изменения настроек не выполнялись. + +Аппаратная сборка не определяет коммерческую модель: сам производитель +[Flipsky описывает разные платы серии 75 на основе 75_300_R2](https://flipsky.net/blogs/vesc-tool/tips-of-75-serise-esc). +Это подтверждение неоднозначности, не доказательство бренда имеющихся плат. +Ни новый образ прошивки, ни паспортные пределы не выбираются по одному этому +имени. Продолжить неразрушающую программную диагностику и использовать +существующую комплектацию/документацию изготовителя ровера для свойств, +которые текущий протокол не сообщает. + +Для выбранной реализации проверить нейтраль, прямое/обратное движение, +повороты и крайние диагонали, одинаковую ограниченную реакцию сторон, переход +между режимами в нейтрали, RC-перехват и отказ каждого канала связи. Сначала +без движения (преобразование входов), затем на вывешенном приводе; нагрузочные +испытания и настройка поворота на гусеницах — отдельный этап. Успешный тест +без нагрузки не подтверждает старт под нагрузкой с повреждённым Холлом. + + +## Comparative Hall result, 2026-09-24 12:13 UTC + +Node 0.8.39-1 / plugin 0.6.6 completed both separate canonical measurements. +LEFT again yields only [1,3,5,7] while the owner observes movement both ways; +RIGHT yields [1,2,3,4,5,6] and firmware success. Both configurations are unchanged +and current release is confirmed. Hall diagnostic localization is complete: +LEFT circuit incomplete, RIGHT six-state signal accepted. Exact broken physical +contact is not identified and no hardware repair is claimed. Sensorless LEFT +versus Hall RIGHT operation remains. The owner next requests visible sustained +rotation in both directions; this is a bench-test feature, separate from RC +Tank/Arcade profiles and the stop → neutral → manual authority contract. + +## Прототип во время отсутствия владельца + +По прямому запросу владельца подготовлены `packages/rover-control/src/profile.ts` +и `authority.ts`: расчёт Tank/Arcade, UUID-назначения произвольного числа моторов, +версионный JSON желаемого профиля и модель stop → neutral → manual. В production +runtime они не подключены. 21 направленный тест проверяет знак и пределы +смешивания, 2/4/10 моторов, первый/второй жест, непрерывную нейтраль, потерю +любого привода/приёмника, устаревшие данные, часы, команды и допуски после reboot. +Оси для перехвата объявляются отдельно от осей микшера: в макете даже второй +рычаг останавливает Core в Arcade, а пропавшая ось не считается нейтралью. + +Отдельный макет `apps/control-station/tools/rover-control-preview` использует +канонические контролы Design Guideline, показывает расчёт и сохраняет/выгружает +черновик. Сеть запрещена CSP; никакого обращения к роверу или новой продуктовой +вкладки нет. Пороговые времена в моделировании — синтетические, не приёмка +времени остановки Rover006. Алгоритмы калибровки VESC Tool не копировались. +Контракт и ограничения: [rover-control README](../../packages/rover-control/README.md). + +## Текущий пульт: приёмка потери сигнала завершена + +2026-09-24 владелец прочитал Failsafe: CH1…CH10 показывают 0%. После отдельной +проверки каждого мотора с удерживаемым рычагом и извлечением батарейки пульта +владелец подтвердил остановку обоих. Возврат питания/радиосвязи с рычагами +в центре не вызвал движения. Журналы, ограничения измерений и отличие от +непринятого первого опыта записаны в [протоколе 24](24_RC_FAILSAFE_ACCEPTANCE.md). +Рабочие конфигурации не менялись; это приёмка существующего прямого RC-пути, +не новой логики перехвата. Можно продолжать чтение Functions → Mix и карты +каналов. Подтверждение аппаратного исполнителя профилей в Core остаётся +обязательным до их активации: один переключатель в UI не меняет проводку. + +## Сохранённые настройки пульта: осмотр 2026-09-25 + +Владелец последовательно прочитал и затем явно подтвердил весь список: всего +четыре правила Mix, номера 1/3/4 выключены, только Mix 2 включён. Параметры +Mix 2: Master C3, Slave C4, Offset 0%, NEG −100%, POS −100%. Это перечень +правил внутри текущей модели, не четыре взаимоисключающих профиля ровера. +Настройки не меняли. Назначение C4 в конструкции пока не установлено; по +сообщённой проводке моторные входы подключены к CH2/CH3. Нельзя приписывать +этому миксу управление вторым мотором без проверки всей карты каналов. + +Владелец прислал видеозапись меню продолжительностью около 74 секунд. +Выполнен локальный визуальный разбор кадров; исходное видео не изменено, +аудиодорожка не транскрибировалась. Закрытый manifest с SHA-256 исходника, +методом разбора и кадрами хранится вне репозитория в +`outputs/rover-006-tx-menu-review-20260925/manifest.json` корня рабочего пространства. +Время ниже приблизительное, это не измерение задержки управления. + +| Экран | Наблюдение | +| --- | --- | +| Монитор каналов, 8–13 с | Полосы CH1…CH6, затем прокрутка. Отдельных движений осей с одновременным наблюдением каналов нет. | +| Reverse, 21–23 с | CH9 — Rev; остальные показанные каналы CH1…CH10 — Nor. | +| End points, 28 с | CH2: 100/110%; CH3: 110/100%, в порядке двух столбцов экрана. Это диапазон сигнала пульта, не проценты мощности или тока VESC. | +| Subtrim, 33–36 с | Видимые значения 0%. | +| Trims, 40–42 с | Off. | +| Rate/Exp., 45–47 с | Только показанный CH1 Normal: Rate 100, Exp. 0. Значения других каналов не проверены. | +| Rate/Exp. switch, 50–51 с | Assign SW: Null. | +| Throt curve, 56–57 с | График визуально прямой; численные значения всех точек не открывались. | +| Aux. channels, 60–62 с | Channel 5 назначен SwA. Назначения SwB/SwC/SwD ещё не прочитаны. | +| Failsafe, 66–67 с | CH1…CH10 показывают 0%, согласуется с предыдущим чтением и принятой проверкой потери связи. | + +SWA → CH5 подтверждает назначаемую функцию переключателя в текущей модели, +но не доступ Mini к этому каналу и не аварийную остановку. Монитор каналов +найден; повторно искать его или перебирать Mix не требуется. Следующее чтение +— системные Sticks Mode, Output Mode и About: установить раскладку, режим +выхода и версию устройства без изменения модели. Фактическое соответствие +осей выходам затем проверяется отдельно; этот ролик его не доказывает. +Никаких команд аппаратуре или изменений приложения при разборе видео нет. + +## Системные меню и идентификация пульта, 2026-09-25 + +Вторая запись владельца, около 77 секунд, содержит экран About на 72–74 с: +Flysky FS-i6S, версия 2.00, дата 04-Apr-2020, Hardware V_3.0. Идентификация +пульта теперь опирается на его собственный экран, а не только на форму корпуса. +Это не идентификация VESC и не повод обновлять прошивку пульта или моторов. + +Trainer Mode показан OFF, Switch Null; Student Mode показан OFF. Попытки +открыть Output Mode (около 22 с) и Sticks Mode (около 25 с) останавливаются +сообщением `Turn off RX!`. Значения режима выхода и раскладки рычагов не +открылись, поэтому нельзя объявлять Mode 2 либо конкретный PWM/iBUS режим +прочитанными. RX здесь означает приёмник; повторное нажатие OK при работающем +приёмнике не раскрывает заблокированные настройки. Для чтения нужен штатно +обесточенный приёмник при оставленном включённым передатчике, без изменения +значений или обхода блокировки. Никакого отключения во время разбора не было. + +Закрытое подтверждение с SHA-256 исходника и пятью кадрами: +`outputs/rover-006-tx-system-review-20260925/manifest.json` корня рабочего +пространства. Видеофайл неизменён, аудио не транскрибировалось; просмотр кадров +не является проверкой движения или записью конфигурации. Не запускать +Sticks Adjust, Factory Reset, RX Bind или Firmware Update ради чтения профиля. + +## Ограничение комплектации: без нового подключения приёмника, 2026-09-25 + +Владелец явно исключил подключение FS-iA6B к Mini дополнительными проводами, +адаптером или пайкой: таких средств нет, этот вариант сейчас неприемлем. +Прямой вход iBUS/PPM в Mini не включать в обязательный текущий план. Он не +нужен для уже доказанного управления VESC по USB: оба существующих тракта +сохраняются — пульт → приёмник → моторный вход VESC и Mini → USB → VESC. +Через VESC доступны два подключённых входных канала; полный поток остальных +осей и переключателей от этого не появляется. + +Наличие двух рабочих путей не означает приёмку их одновременных конкурирующих +команд. Нынешний код ограниченных тестов временно удерживает выход PPM, +продолжает читать вход и прекращает тест при RC-команде. Это не готовая +постоянная логика «первый жест — остановка, нейтраль, второй жест — ручное +управление» с гарантией при отказе Mini. Требование владельца сохраняется; +нельзя объявлять его выполненным либо обещать независимую гарантию только +потому, что USB-команды и прямой пульт по отдельности проверены. + +Продолжать аудит штатного микшера пульта и исполнительных возможностей VESC +в имеющейся комплектации. Реализуемость Arcade на существующих моторных +выходах, переключение его из Mission Core и независимый перехват — отдельные +вопросы. Чтение меню пульта не доказывает дистанционную запись его профиля. +Если точное требование недостижимо в этой комплектации, описать конкретное +ограничение владельцу, не подменяя задачу профилем только для команд Core. + +## Разблокированные меню после отключения батареи, 2026-09-25 + +Владелец прислал ещё две записи, около 66 и 32 секунд, с отключённой, по его +сообщению, батареей ровера. Системные страницы теперь открываются. Прочитаны: + +- Models: Model 1. +- Output Mode: выбран PWM; отдельный Serial: выбран i-BUS. Наличие выбранного + i-BUS не означает подключение этой линии к Mini; существующие VESC получают + отдельные каналы PWM. Проводка остаётся прежней. +- Sticks Mode: первоначально M2; на 37-й секунде первого ролика видно + переключение в M1, затем на 38–39-й — возврат в M2 до выхода со страницы. +- Базовые назначения M2 до миксов: правый горизонтальный CH1, правый + вертикальный CH2, левый вертикальный CH3, левый горизонтальный CH4. + Включённый Mix 2 добавляет зависимость итогового CH4 от CH3; нельзя называть + его выход независимым сырым значением левой горизонтальной оси. +- Throt Mode: Self centering. + +Это подтверждает, что для правого Arcade требуются две оси CH1/CH2, тогда как +нынешние моторные подключения CH2/CH3 дают два вертикальных канала. Прямые +команды Mini по USB остаются доступным независимым путём. Штатное микширование +нужно проверять по фактическим выходам CH2/CH3, включая подавление ненужной оси, +знаки, нейтраль, насыщение и сохранение рабочего Tank. Руководство описывает +парный Master/Slave, но не доказывает конкретный порядок каскадирования миксов +и кривых; схему нельзя объявлять рабочей только по формуле или числу слотов. + +### Новая проверка перед возвратом к движению + +На 48-й секунде первого ролика открыт Sticks Adjust. До конца записи нет +полного прохода всех осей/крутилок по пределам; второй ролик начинается уже +в обычном меню. Завершение процедуры между роликами не видно. По штатному +руководству §7.8 это калибровка аналоговых органов пульта, с сохранением через +выход после центрирования, а не обычный монитор каналов. Нельзя гарантировать +неизменность калибровки или объявлять её испорченной по этим кадрам. + +Перед повторным включением силового питания нужен обычный монитор CH1…CH6 +с проверкой нейтрали и отдельных полных ходов осей при выключенных приводах. +Это проверка пульта, не повторная FOC/Hall-калибровка VESC. Не использовать +Sticks Adjust для чтения показаний и не запускать автоматический sweep. + +В первом ролике также кратко открыт RX Bind при выключенном, по сообщению +владельца, приёмнике; результат привязки не проверялся. Во втором открыт +диалог Factory Reset: нажата правая кнопка и выполнен возврат в меню; нет +подтверждения выполненного сброса. Firmware Update просмотрен до страницы +Continue, затем закрыт; обновление на записи не запускалось. Не превращать +обход меню в утверждение, что все действия были только чтением. + +Закрытые оригинальные хэши, кадры и метод разбора: +`outputs/rover-006-tx-offline-review-20260925/manifest.json` корня рабочего +пространства. Оригиналы не изменены, аудио не транскрибировалось. Со стороны +ассистента операций с пультом, Node или VESC при разборе не выполнялось. + +## Проверка монитора каналов после Sticks Adjust, 2026-09-25 + +Следующая запись владельца, `IMG_2491.MOV`, около 41 секунды, показывает +обычный монитор CH1…CH6 и движения сначала левого, затем правого рычага. +Оба используемых моторных канала проходят в положительную и отрицательную +сторону: CH3 при вертикальном движении левого рычага, CH2 — правого. После +возврата рычагов значения визуально близки к центру, с небольшими остаточными +смещениями. Признаков застрявшего крайнего значения или отсутствующей половины +хода этих двух каналов в записи нет. По полоскам нельзя измерить точные +проценты, ширину PWM-импульса или подтвердить допустимую нейтраль на VESC. + +Горизонтальные движения изменяют CH4 слева и CH1 справа; часть правого +горизонтального прохода затемнена/перекрыта рукой. Зависимость CH4 от +вертикального CH3 имеет противоположный знак и соответствует ранее прочитанному +Mix 2. Неподвижное пятно на поверхности экрана возле CH4 не является показанием +канала. Это качественная проверка раскладки M2 и моторных выходов пульта, +не приёмка Arcade, нового перехвата, радиосвязи или failsafe после изменения +меню. Повторное обследование меню для установления этих назначений не требуется. + +Следующий шаг после подтверждённого владельцем возврата питания на вывешенном +ровере с рычагами в центре — прочитать фактические уровни обоих входов через +VESC и сравнить их с сохранённой мёртвой зоной, без команд вращения. Во время +разбора этого видео силовое питание не включалось средствами ассистента, +команды приводам не отправлялись, калибровка VESC не менялась. + +Закрытые хэш исходника, 11 кадров и метод разбора: +`outputs/rover-006-tx-axis-review-20260925/manifest.json` корня рабочего +пространства. Оригинал не изменён; аудио не транскрибировалось. + +Продолжение: владелец вернул питание, проверил движение от стиков, затем +подтвердил нейтраль и физическую остановку обоих моторов. Чтение через VESC +подтвердило уровни справа −0.06, слева +0.068…+0.07 внутри deadband ±0.15, +нулевые duty/ток батареи и отсутствие ошибок. Motor/application конфигурации +обоих контроллеров побайтно совпадают с сохранёнными 2026-09-24. Проверка +нейтрали после просмотра меню закрыта; подробности и границы результата — +в `24_RC_FAILSAFE_ACCEPTANCE.md`, раздел «Нейтраль после возврата питания». +Профиль одного стика и постоянный перехват этим чтением не приняты. diff --git a/docs/node/24_RC_FAILSAFE_ACCEPTANCE.md b/docs/node/24_RC_FAILSAFE_ACCEPTANCE.md new file mode 100644 index 0000000..8f67876 --- /dev/null +++ b/docs/node/24_RC_FAILSAFE_ACCEPTANCE.md @@ -0,0 +1,247 @@ +# Приёмка пульта и потери сигнала + +Состояние: оба моторных канала прошли наблюдаемый вывешенный тест остановки +при потере питания передатчика. Восстановление связи с рычагами в нейтрали +не вызвало движения. Точное время реакции и поведение под нагрузкой не измерены. +Node 0.8.40-1, VESC plugin 0.6.7, FW 5.02. +Калибровка и рабочие настройки не изменяются этим исследованием. + +Обновление 2026-09-25: после просмотра системных меню передатчика и захода +в Sticks Adjust повторно проверены монитор каналов, физическая остановка по +сообщению владельца и фактическая нейтраль на обоих VESC. Конфигурации VESC +побайтно совпадают с исходными от 2026-09-24. Это не повторный тест потери +радиосвязи после действий с меню пульта; его прежняя приёмка относится к +описанным ниже испытаниям 2026-09-24. + +## Начальное состояние, 2026-09-24 + +Владелец подтвердил: пульт выключен, оба мотора неподвижны, гусеницы сняты, +ровер вывешен. Свежая инвентаризация Core подтверждает два прежних UUID, +нет активного теста или RC-защёлки. Через штатные операции сохранены обе +конфигурации и прочитаны входы/телеметрия. Никаких команд движения, аренды +выхода, alive, записи конфигурации или прямого доступа к serial не выполнялось. + +Оба контроллера: вход PPM около +0.010…+0.012 при deadband 0.15, PWM 0, +ток батареи 0, fault 0. Правый показывает 0 ERPM. Левый при физическом +покое показывает -153…-165 ERPM: ранее установленный дрейф бессенсорной +оценки, не доказательство движения. + +Сохранённые настройки: duty-cycle PPM control; Safe Start включён; timeout +1000 мс, timeout brake current 0 A; pulse 1.0/1.5/2.0 мс; multi_esc включён. +Слева PPM, справа PPM+UART. Плавность слева 0.4 с набор / 0.2 с сброс, +справа 0.5 / 0.5 с. Экспонента -1.0 слева и -1.5 справа. Из этого нельзя +делать вывод о дефекте мотора или автоматически унифицировать настройки. + +## Граница измерения + +Декодированный PPM в FW 5.02 сообщает последнее значение и длину импульса, +но не возраст импульса и не состояние радиолинка. Нейтраль при выключенном +передатчике сама по себе не доказывает failsafe: передатчик мог быть выключен +после нейтрали, а приёмник мог удержать последнее значение. + +По исходникам pinned upstream 3f670137: при утрате импульсов PPM обработчик +проверяет их возраст и тайм-аут, снимая тягу при timeout brake current 0. +Это не активное торможение с заданным временем остановки. Если приёмник +продолжает выдавать ненулевое последнее значение, тайм-аут VESC не решает +потерю радио. Руководство FS-i6S 2020-06-28, раздел 6.10, описывает Off как +удержание последнего значения. Точная модель/настройка имеющегося передатчика +ещё требует проверки его экрана; внешний вид не достаточен. + +## Порядок продолжения + +1. Включение пульта с обоими рычагами в нейтрали; чтение входов и наблюдение + отсутствия самопроизвольного движения. +2. Чтение About, Failsafe для CH2/CH3 и карты каналов на пульте; без изменения + текущей модели. Если выявлено удержание последнего положения, сначала + подготовить и проверить нейтральный failsafe через штатные средства. +3. Под наблюдением владельца проверить отклонение/возврат каждого рычага, + соответствие стороне и исчезновение команды в нейтрали. +4. Отдельно согласовать выключение передатчика во время ограниченного + движения, прочитать вход и состояние обоих VESC, получить физическое + наблюдение остановки. Возвращать радиосвязь с рычагами в нейтрали. +5. Проверить восстановление связи и отсутствие самопроизвольного движения. + +Чтение через отдельные удалённые операции даёт около 4.8 с на полный цикл +двух входов и двух телеметрий в начальном замере. Такой журнал фиксирует +состояния, но не позволяет подтвердить миллисекундную задержку остановки. +Не выдавать USB-время ответа за время реакции радиоканала. При необходимости +точного времени добавить продуктовую бортовую запись, не обходить драйвер. + +Исходный приватный протокол rc-failsafe-d83b84fb311245e5b8a3fea31716416b.json, +SHA-256 8098fe14a754622cb027472fa4f48f96fa9ffcb0548b16af557ac90a56ea6fb1. +Два полных цикла чтения, оба успешны. Наблюдатель rc_failsafe_observe.py +разрешает только input.read, telemetry.read и config.backup. + +## Уточнение наблюдения после включения пульта + +Протокол rc-failsafe-34b93f7184024d87a8e66327f2f60649.json был изначально +помечен `tx-on-neutral-confirmed`, но во время чтения зарегистрированы +отклонения входов и вращение правого. Владелец уточнил: «Двигал рычаги; +сейчас оба стоят». Поэтому этот замер содержит ручное управление и **не** +является ни доказательством самопроизвольного запуска, ни чистой проверкой +включения в нейтрали. Исходная метка и сырой протокол сохранены неизменными. +SHA-256: 26dd21ffae833b4ac13aa1ceb004b97a3b58de8ea4ded9856ec616a335744d4b. + +Следующее чтение rc-failsafe-ea478fad45c047db919f892c23a34dc2.json подтвердило: +справа вход −0.064 / 1.468 мс, слева +0.074 / 1.537 мс; оба в текущей зоне +нейтрали ±0.15. На обоих PWM 0, ток батареи 0, fault 0. Справа ERPM 0, +слева −156 при подтверждённом физическом покое — известная бессенсорная +оценка. Это не подтверждает исправность левого Холла и не измеряет failsafe. +SHA-256: 6fe3cceeae8d1afc6116048df9079001a46a1f08a8813de4782ac7433d33dab8. + +Владелец отошёл на 15 минут и разрешил независимую разработку/прототипирование. +Моторные испытания приостановлены до его возвращения и новой синхронизации. +Вопрос о модели в About и текущем Failsafe CH2/CH3 остаётся без ответа; +повторно спрашивать или самостоятельно менять настройки по догадке не нужно. + +## Возвращение владельца + +Владелец сообщил: гусеница снята, пульт включён, он рядом и готов выполнять +действия. Запрошено оставить рычаги в нейтрали и прочитать Failsafe CH2/CH3. +До ответа выполнены только два цикла input.read/telemetry.read: справа вход +−0.064…−0.066, слева +0.072…+0.074; оба в текущей зоне нейтрали. PWM и ток +батареи 0, fault 0 на обоих; справа ERPM 0, слева −159…−151 (прежняя +бессенсорная оценка, не отдельное подтверждение физического покоя). +Протокол rc-failsafe-b05818b1cf8a426f8dccd5e6f80b19a5.json, +SHA-256 511257aafc9d2f000d65073438399b9f7fa52c86515f4a7e994fd28b610737bb. +Команд движения, alive, аренды выхода или записи конфигурации не было. + +## Экран Failsafe и первый ручной тест потери сигнала + +Владелец открыл сенсорное меню Functions после разблокировки экрана и затем +Failsafe. Сообщил: каналы CH1…CH10, везде 0%. По официальному руководству +семейства FS-i6S числовая позиция означает заданное положение при потере +радиосигнала, в отличие от Off/удержания последней команды. Отдельные +настройки не изменялись. Модель/версия из About ещё не прочитана. + +Для проверки выдано задание: на вывешенном приводе с демонтированной +гусеницей запустить правый мотор небольшим отклонением, выключить пульт до +возврата рычага, затем отпустить его; сообщить наблюдение остановки. Если +вращение продолжается — вернуть рычаги в нейтраль и восстановить пульт. +Программа при этом только читала входы и телеметрию, 13 циклов за примерно +60 секунд. Зафиксированы правый вход +0.254, 798 ERPM и PWM 0.051; затем +PWM 0, 72 ERPM, и в последнем цикле вход −0.064, PWM 0, ERPM 0. Fault 0 +на обоих VESC. Пары input/telemetry снимаются последовательно, не синхронно. + +Протокол rc-failsafe-fe6aea514466484aad007568c9f90cc0.json, +SHA-256 d1c471f855f80c1715578df0bfc0e69a8c517a7cc9c2cf1aeaa09ef61e37c9a9. +Физический результат и факт выключения при удерживаемом ненулевом рычаге +пока ожидаются от владельца. До этого переход нельзя объявлять принятым +failsafe; USB-наблюдение не отличает потерю радиосвязи от отпускания стика. +Никакого испытания левого канала или восстановления радиосвязи ещё не принято. + +Уточнение владельца к первому тесту: он **сначала отпустил рычаг**, затем +вынул батарейку пульта. Поэтому этот опыт не подтверждает остановку из-за +потери радиосвязи. После снятия питания передатчика отдельное чтение показало +правый вход +0.010 / 1.504 мс, левый +0.012 / 1.506 мс; PWM и ток батареи 0, +fault 0 на обоих, ERPM правого 0. Протокол +rc-failsafe-f99b5bb25bff471dbe017ed0b8f4632b.json, +SHA-256 4ade3d8a2061048c67b3e21a83304fd6a9cb832942189f6a08c29792a6984adc. +Это подтверждение нейтрального выхода при выключенном пульте после нейтрали, +а не проверка прекращения ненулевой команды. Запущена отдельная запись для +повтора с явным удержанием рычага до физического отключения передатчика. + +## Правый канал: остановка при потере радио подтверждена + +Повтор rc-failsafe-b208d87fa223496ca5fffebddf4ad9be.json, 25 полных циклов, +2026-09-24T13:39:31.281029Z…13:41:33.274243Z, +SHA-256 00e64109018c8b815b96b5db1e69fbb32ca7ab80bd8eff672f3ac86b69caffb1. +После восстановления пульта вход правого вышел из нейтрали, зарегистрировано +вращение. На цикле 11 вход +0.232 / 1.616 мс, 282 ERPM, PWM 0.022; +на цикле 12 вход +0.010 / 1.505 мс, ERPM 0, PWM 0. Левый вход также +вернулся к прежнему значению выключенного передатчика, PWM 0. Fault 0 везде. + +Владелец подтвердил: он вращал правым рычагом, вынул батарейку, и мотор +остановился непосредственно при её извлечении. Это исправленный повтор +предыдущего опыта с отпусканием рычага до отключения. Для правого канала +поведение прекращения ручной тяги при потере радиосвязи принято в рамках +этого вывешенного теста. Точная задержка в миллисекундах не измерена; +нагрузочный тормозной путь и будущий stop-first перехват из Core не проверены. + +Следующий запуск записи для левого был случайно прерван владельцем. Проверено: +нового протокола не создано, процессов rc_failsafe_observe.py не осталось. +Команд движения не было. После возобновления запущен отдельный read-only +протокол левого и выдана та же последовательность удержания рычага до +отключения. Его результат пока ожидается; приёмка левого не следует из правого. + +## Левый канал: физическая остановка подтверждена владельцем + +Протокол rc-failsafe-cc289f6fce514a21af66bf7c17117e59.json завершён, +24 полных цикла; SHA-256 +64164b2083a1b28172ebe1471a7f59df88c1d10b085db6e204f7c60f81608d11. +На цикле 8 левый вход +0.280 / 1.640 мс, ток мотора 2.39 A; на цикле 9 +вход +0.012 / 1.506 мс, ток 0.04 A. После отключения оба PWM нулевые, +fault 0. Сама скорость вращения левого не попала в редкие последовательные +USB-замеры; его отрицательный ERPM при PWM 0 нельзя трактовать как движение. + +На отдельный прямой вопрос «Левый мотор действительно крутился до извлечения +батарейки и остановился именно после него, пока рычаг оставался отклонённым?» +владелец ответил «Да, крутился и остановился после извлечения». На основании +этого физического наблюдения и записи возврата входа в нейтраль поведение +левого канала при потере радио принято для данного вывешенного теста. +Точное время остановки, нагрузка и исправность Холла этим не подтверждаются. +Далее запущена отдельная запись восстановления пульта в нейтрали обоих рычагов. + +## Восстановление связи и итог + +Протокол rc-failsafe-6811a6865139462cb233566fb2bead05.json завершён, +13 полных циклов; SHA-256 +c9d36bf24ca7ae43bb51bd7777c936e58ca44f3dd3d3b3b14126f6cf8717516f. +В ходе записи входы перешли от значений выключенного пульта около +0.01 +к его включённой нейтрали: справа −0.062…−0.064, слева +0.076. PWM 0, +ток батареи 0 и fault 0 на обоих во всех записанных циклах. Правый ERPM 0; +слева прежняя ненулевая бессенсорная оценка при снятой тяге. + +Владелец подтвердил: после возврата батарейки, включения и ожидания около +пяти секунд с рычагами по центру оба мотора остались полностью неподвижны. +Приёмка текущего RC-пути в объёме стендового сценария завершена: +ненулевая ручная команда → полное отключение передатчика → остановка отдельно +справа и слева; затем восстановление связи в нейтрали без самопроизвольного +движения. Источник физического результата — наблюдение владельца; журналы +фиксируют входы/телеметрию с последовательным USB-опросом, а не точную задержку. + +Конфигурации и калибровка не изменялись, команды движения от Core не выдавались. +Этот результат не принимает новый stop → neutral → manual перехват из +автономии, отказ Mini/USB, поведение восстановления с отклонённым рычагом, +нагрузочный тормозной путь или исправность повреждённой левой цепи Холла. +Следующий этап — чтение текущих Mix/карты каналов пульта для Tank/Arcade, +без изменения рабочего радиопрофиля по догадке. + +## Нейтраль после возврата питания, 2026-09-25 + +После видеопроверки монитора передатчика владелец вернул питание ровера и +сообщил, что моторы вращаются от стиков. Перед чтением отдельно подтвердил: +пульт включён, оба стика по центру, оба мотора полностью неподвижны. Через +канонический Core выполнены config.backup обоих VESC и два последовательных +цикла input.read / telemetry.read. Тестов вращения, аренды выхода, alive и +записи конфигураций не было. Оба прежних UUID в свежей инвентаризации доступны, +активных моторных тестов нет. + +| Измерение | Правый | Левый | +| --- | --- | --- | +| Уровень декодированного входа | −0.059999 | +0.068…+0.069999 | +| Импульс | 1.470 мс | 1.534…1.535 мс | +| Настроенная зона нейтрали | ±0.15 | ±0.15 | +| Duty / ток батареи / fault | 0 / 0 / 0 | 0 / 0 / 0 | +| ERPM | 0 | −162…−147 | + +Оба входа внутри мёртвой зоны. Ненулевая бессенсорная оценка ERPM слева при +нулевом выходе и подтверждённом физическом покое не является вращением. +Сырые показания тока мотора справа −0.55…−0.79 A, слева +0.09…+0.11 A; +не подменять их утверждением, что все датчики показывали математический ноль. +Проверка нейтрали завершена; изменение deadband или повторная калибровка VESC +по этим результатам не требуется. Полный цикл чтения занимает около 6 секунд +и не измеряет задержку перехвата. + +Прочитанные motor/application payload каждого контроллера побайтно равны +исходным из протокола `rc-failsafe-d83b84fb311245e5b8a3fea31716416b.json`. +Рабочая FOC-калибровка, режимы sensorless/Hall, направление, токовые пределы +и настройки PPM сохранены. Это сравнение конфигураций VESC, не всей модели +или внутренней калибровки передатчика. + +Приватный протокол `rc-failsafe-b79d96f465f94fcb881e48a536ea0cc7.json`, +SHA-256 `c71b9c4b805f9b7a0909e8a26355297a831224997f7cb0fd908ce08bf88960eb`. +Отдельный результат сравнения: +`rc-neutral-comparison-b79d96f465f94fcb881e48a536ea0cc7.json` в той же закрытой +папке `outputs/rover-006-vesc-context-20260923/native-probe`. Наблюдатель +завершился штатно; постоянный процесс опроса не оставлен. diff --git a/docs/node/25_OBSERVATION_AND_REMOTE_CONTROL.md b/docs/node/25_OBSERVATION_AND_REMOTE_CONTROL.md new file mode 100644 index 0000000..7d296db --- /dev/null +++ b/docs/node/25_OBSERVATION_AND_REMOTE_CONTROL.md @@ -0,0 +1,545 @@ +# Observation and remote control — implementation record + +Owner request: 2026-09-25. Extend the existing per-vehicle observation center. +The operator sees cameras, map, a vehicle model and per-controller telemetry, +then explicitly takes keyboard/pointer control. Return goes to the vehicle list. + +## Product surface decision + +Selected: two new layers in the admitted observation composition, with the model +below the map and telemetry alongside it. Rejected: a separate driving workspace, +which would separate the operator from cameras and duplicate vehicle navigation. +No primary navigation or product root changes. Layer visibility/order/splits stay +in the existing versioned per-vehicle layout. The header host owns the back action. + +States: offline, observing, preparing, ready, driving, receiver takeover, stopped, +fault. Showing a model, pressing a key while disarmed, or reconnecting never arms +motion. Stale telemetry is unavailable, not zero. No fabricated position/distance +or model motion is inferred from keyboard intent. + +Design Guideline: existing Button/IconButton/Window/Select/Switch/LoadingRegion, +SplitPane, GlassSurface and StatusBadge. Owner explicitly approved outlined +momentary key buttons; shared KeyButton is added to DG first. Arcade W/S+A/D; +tank Q/A left forward/reverse, E/D right forward/reverse. Space stops/disarms. + +## Sources + +NodeDC source: `NODEDC_ENGINE_INFRA/nodedc-source/src/viewer/playcanvas/`. +Copy the rendering implementation, DEFAULT_POSTFX and environment atlas with +source hashes; keep lighting/postprocessing/grid shader settings unchanged. +Vehicle export preserves immutable Blender originals. v021 is a two-scheme +kinematic study, not the full rover; full reconstruction is v020. Owner explicitly selected v020. The export contains all 1,426 renderable +objects, joined into four donor material groups without geometric decimation. + +## Control boundary + +Existing five-second inventory/operation heartbeat is unsuitable for held keys. +Implement a separate authenticated, ephemeral command channel on the already +paired mTLS transport. Core does not access USB. The Node relays to its single +VESC owner. Browser, relay and native output each have bounded leases; commands +are identity/session/sequence bound and never persist or resume after restart. +Motion command transport is distinct from configuration/calibration operations. +Per-wheel current is measured motor current; battery input current is separate. + +Stock FW 5.02 resumes direct PPM when its output-disable lease expires. A healthy +board can stop on RC intent and require neutral; a failed board cannot guarantee +the full first-gesture-stop protocol against held RC input. This limitation must +remain explicit in acceptance and cannot be fixed by UI promises. + +## Validation — 2026-09-25 + +Core lease tests: 13 passed. VESC driver: 127 tests passed, including eight +remote-control tests (expired/duplicate frames, terminal stop, invalid bounds, +RC first-gesture zero hold, reversal neutral interval, one-port failure and +unconfirmed release). Native Tool adapter compiled and passed offline archive +and output-denial checks on Mini; no hardware access during qualification. +Control Station: architecture checks, typecheck, 939 unit tests and production +build passed. The active operator checkout retains its unrelated simulation and +AI polygon changes. Canonical 8000 was restarted through its existing launchd +service, preserving configuration and operator data. + +Browser acceptance: back returns to the fleet list; full v020 visible; model +selection persists across reload; Tank changes the key pad to Q/E/A/D; Arcade +restores W/A/S/D; both layers appear in Available layers; hidden telemetry stays +hidden after leaving/re-entering, then was restored. Pane maximize/restore keeps +the scene and canvas sizes correctly. No arm or motion command sent. + +Export correction: initial exporter unintentionally included the original +Blender scenes; visual QA found the studio floor obscuring the rover. Export is +now limited to the active export scene and selected joined object, verified as +one scene, one mesh, four donor materials (54,960,576-byte GLB). Immutable v020 +source is unchanged. All donor lighting/postprocess defaults remain unchanged; +only asset URLs, responsive hosting and model framing adapt to Mission Core. + +Node 0.8.41-1 / VESC integration 0.7.0 qualification passed and the versioned +owner installer completed on Mini. dpkg confirms 0.8.41-1; Node/VESC services +are active. The paired fast channel supplies fresh RIGHT telemetry with no +control session. LEFT is absent from Linux USB enumeration, while its UUID +assignment remains intact; kernel descriptor errors -71 occurred at 11:18–11:19 +MSK, before the installer stopped the driver at 11:20:28. The owner confirms +USB/power was reconnected during the work. This does not establish the physical +cause; no USB reset or ad-hoc OS change was performed. The telemetry layer now +retains missing assigned motors, explicitly shows no connection, and never +substitutes another UUID or zero measurements. +Hardware motion, actual channel latency and physical stopping require a fresh +attended acceptance test. Offline tests do not qualify loaded driving or the +Mini-independent stop-first RC behavior described above. +Ship every Node runtime change in the versioned installer; no ad-hoc board edits. + + +### Owner power-cycle and first admission attempt + +At 11:35 MSK the owner disconnected/reconnected the battery. Both USB devices +then enumerated and the existing runtime recovered both assigned UUIDs without +an application restart or agent-issued port reset. Twenty read-only samples +(10 seconds) all contained both fresh devices, no active control session. + +After fresh owner confirmation (tracks off, raised stationary rig, TX off, +observing), one Core API trial was armed at 11:38:46 MSK. Initial preflight +rejected sensorless duty=0.001; no forward command, output claim or temporary +limit application was reached. This is not a keyboard or motion acceptance. + +Source investigation: pinned FW 5.02 mcpwm_foc.c, commit +3f670137e27e6e383fa79c50cc6b1fa85aab1554, undriven branch lines 2550–2693, +computes duty_now from measured phase voltages/back EMF even with no driven +output. commands.c encodes this field with scale 1000. The earlier strict +zero-duty assumption for observed sensorless standstill was therefore incorrect. +The new bounded tolerance is one wire quantum, abs(duty)<=0.001, only for that +already explicitly observed sensorless case. The other current, voltage, +temperature, fault, input-current and stable-neutral checks remain in force. +This is an admission bound, not proof of physical stopping or a motor rating. +New regression verifies both signs of one quantum, rejection of two quanta and +continued rejection of unobserved speed drift. All 128 VESC tests passed. +Node 0.8.41-2 / VESC integration 0.7.1 passed qualification and was installed +through the owner-authorized versioned installer at 12:08:23 MSK; no ad-hoc +runtime patch and no automatic repeat of movement. + +The same follow-up separates terminal input-lease completion from hardware +faults: normal session end reports stopped only after cleanup; unconfirmed +release or restoration warnings remain fault. Regression drives the actual +output loop through the session wrapper and verifies release of both outputs. +The preceding qualification completed, but its package was superseded before +installation to include this correction in one owner update. Final VESC suite: 130 tests passed. + +Post-install verification: both services active, installed runtime 0.7.1, both +assigned controller UUIDs fresh after observation refresh (14–205 ms), zero +currents/duty/fault codes and no control session. Fresh owner observation is +required for the next attended API trial; physical keyboard/RC acceptance remains pending. + +### Attended retry and channel diagnostics + +At 12:18:51 MSK, the helper rejected cached device samples before sending arm. +Read-only refresh restored both fresh UUIDs. The one armed trial at 12:19:28 +remained in preparing for about five seconds, then ended stopped before the +helper ever sent forward demand. The browser-to-Core zero-demand heartbeat +continued every approximately 100 ms. No service restart occurred. The current +evidence does not distinguish a Core transport failure from a Node scheduling +gap; it does not establish a new USB failure. + +Node 0.8.41-3 adds a bounded 32-frame in-memory channel diagnostic recorder, +flushed to the private service journal on session transitions, transport errors +or long gaps during a session. It records monotonic intervals, binding wait, +Core/driver elapsed times, sequence/remaining TTL and state. It excludes trust +material, endpoints, request bodies and raw HTTP error text. Admission, timeout, +lease and motor-output behavior are unchanged. Qualification/installation is +pending; no automatic physical retry. + +Node 0.8.41-3 installation completed successfully at 09:36:34 UTC in 18 seconds +after owner-local Ubuntu authorization. Package version and active Node/VESC +services verified. Both assigned UUIDs produce fresh readings (190/199 ms), +zero motor current and fault codes; no control session. Owner observation is +requested again before one bounded repeat; no motor output sent after the +12:19 preparation abort. + +### Recorded channel timing and operator TCP correction + +The attended 12:38:43 MSK retry again ended in preparation without forward +demand. The new journal localizes the failure to the Core/Node transport budget: +Core round trips commonly took 100–270 ms, driver calls 1–3 ms and initial +binding-lock waits zero. One response explicitly expired in transit; another +response body exceeded the 300 ms HTTP deadline. The first inferred consecutive +command arrival gap was already greater than its remaining lease. No service +restart occurred. This does not establish an electrical or USB fault. + +Read-only Tailscale checks confirmed DERP(hel) relay rather than a direct path. +Five Tailscale probes: 42–120 ms; five ICMP probes: 42.8–157.5 ms, zero loss. +No VPN, route, firewall or onboard OS settings were changed. Private network +inventory is retained only in the private evidence directory. + +The paired Core HTTP handler used the standard TCP Nagle default while writing +small response headers and JSON separately. Enabled its supported +disable_nagle_algorithm option (TCP_NODELAY) to remove an avoidable buffering +source; this does not change authentication, TTLs or output limits. All 52 +Fleet tests passed. Promoted the same narrow change to the active operator +checkout and restarted its existing launchd service only after verifying no +active motor session. Canonical 8000 and both fresh controller readings recovered. +Whether this is sufficient for the current relay path still requires attended +acceptance; no automatic motion retry. + +The 12:46:39 MSK attended retry disproved sufficiency: responses improved to +47–70 ms at times but still reached 166 ms, and preparation ended before any +forward command. Four armed remote-channel attempts have now failed in +preparation; none is a motion acceptance. Subsequent motor trials are paused +while the command delivery mechanism is corrected. + +### Node 0.8.42: independent command stream (qualification pending) + +The paired Core endpoint now offers an authenticated NDJSON response containing +the latest command every 50 ms. Telemetry remains a separate request/response +channel. Certificate, binding and endpoint revision are checked on every frame. +No command queue is introduced. Legacy Node clients retain their existing +exchange response; new clients consume commands only from the stream. + +Core attaches a random process clock epoch and an absolute monotonic expiry to +each command. Node estimates a conservative upper bound on Core clock offset +using request-send time and the timestamp taken afterward at Core. It never +assumes symmetric network latency or synchronized wall clocks. A 5 ms margin, +1000 ppm clock-rate allowance and 25 ms private driver-call reserve reduce the +remaining lease. The original 400 ms deadline is not extended on receipt or +repeated frames. Clock calibration expires after two seconds; loss of return +telemetry retires the Core session after one second. These are software timing +bounds, not hard-real-time or field-safety certification. + +A separate local 20 Hz loop feeds only the latest unexpired intent to the +single VESC owner. Stream silence cancels its network read after 350 ms; +disconnect, epoch change, binding change or failed local RPC requires an +acknowledged null command before accepting further frames. An interrupted +session remains retired in the existing native-driver lease and cannot resume +on reconnection. The C++ output watchdog (200 ms), PPM suppression lease +(250 ms), firmware, calibration and output limits are unchanged. + +Qualification covers asymmetric delay, measured relay jitter, original expiry, +replayed frames, stop-ack races, old clock epochs, stale calibration, silent +HTTP streams, multiple frames per response and binding revocation midstream. +Physical API motion, keyboard release/blur and RC takeover acceptance remain +pending and require fresh owner observation after installation. + +Node 0.8.42-1 installed successfully at 10:22:27 UTC. Forty read-only samples +over ten seconds showed observing/no active session; the last twenty contained +both assigned controllers with ages at most 217 ms, zero current and fault. +The freshly authorized 13:25:53 MSK API trial still ended during preparation, +without forward demand. Unlike the previous transport, the local driver loop +held 50–51 ms intervals and 1–3 ms responses; no stream disconnect was logged. +In the retained timeline sequence 26 had about 29 ms remaining at local time +218304 ms; sequence 28 reached the driver at 218355 ms. This is consistent +with an expired previous lease despite delivery of a subsequently fresh frame. +The driver correctly does not revive such a session. It is not evidence of a +new USB fault or accepted movement. + +Follow-up 0.8.42-2 removes periodic-tick waiting for new intent at both ends: +Core condition notification wakes the stream immediately on accepted input or +stop; Node uses a one-slot wake signal and always reads the latest intent. +The 50 ms periodic tick remains a fallback, not an input queue. Tests cover +updates before/during wait, immediate stop, coalescing and unchanged replay. +Original 400 ms expiry, output watchdog and current limits remain unchanged. +The private diagnostic history expands to 128 frames, and terminal telemetry +no longer triggers idle journal spam solely because it retains a session ID. +Core tests: 59 passed. This follow-up requires qualification and installation +before a separately synchronized physical retry. + +Owner OS authorization completed: final 0.8.42-2 installed at 10:47:29 UTC +in 18.67 seconds, all installer steps exit 0; Node and VESC services active. +Forty read-only samples over ten seconds confirmed observing/no active session. +The final twenty contained both assigned controllers, at most 216 ms old, +with zero motor/input current, duty and fault. Fresh owner observation has +been requested before any new motion; the five previous failed preparation +attempts remain failures, not movement acceptance. + +Sixth attended Core API attempt, 10:52:51 UTC, stopped before forward demand: +"another VESC operation is running". Recorded command TTL remained 323 ms, +so this particular failure is different from the preceding lease expiry. +The remote observer shares operation_lock; _prepare previously attempted +nonblocking acquisition and treated any overlapping read as a fatal conflict. +The trace does not identify which operation held the lock; code and a +concurrent regression reproduce this admission race without hardware. + +Candidate Node 0.8.43-1 / VESC 0.7.2 waits up to 500 ms for exclusive access, +checks the existing input lease every 20 ms and after acquisition, and skips +new observer cycles while the control worker is alive. It does not queue a +future drive or extend the input lease. Tests cover completing an in-flight +read, Stop while waiting, expiry before acquisition, bounded rejection of a +long operation, and observer yielding. Canonical unittest discovery passes +135 tests. A first full pytest invocation incorrectly collected the imported +protocol helper test_packet as a fixture-based test; no product failure was +reported, and the suite was rerun with its canonical unittest runner. +Installation and a separately synchronized physical retry are pending. + +Node 0.8.43-1 / VESC 0.7.2 installed at 11:06:32 UTC in 18.49 s, +all installer steps exit 0. Both services active; final 20/40 read-only +samples contained both assigned UUIDs, age <=219 ms, zero currents/faults, +observing/no control session. A fresh attended trial is requested separately. + +Seventh observed Core API attempt at 11:10:39 UTC reached preparing without +the ownership fault, then stopped before forward demand. Sequence 19 arrived +with ~313 ms remaining; sequence 20 followed ~315 ms later, consistent with +expiry at this boundary. The old trial sent a command, synchronously fetched +telemetry and only then scheduled its next input. Telemetry reads introduced +periodic delays up to ~319 ms in its sample cadence. This differs from the UI, +where the command heartbeat and telemetry poll are independent. + +The corrected attended_stream_test.py separates bounded telemetry polling +from 100 ms command renewal, preserves the same 400 ms lease and all existing +preflight/stop checks, and records request timing for every command. Synthetic +checks prove blocked reads do not hold the input path, failures abort and +reader threads terminate. This is a test-harness correction, not movement +acceptance or proof that all transport jitter is solved. A fresh observed +trial is requested; there is no automatic motion retry. + +Core-only timing logs were added to distinguish registry wait, archive and +save delay. All 59 Fleet tests pass; loopback HTTP test needed sandbox network +permission. The active Core received only this reviewed registry.py diff and +was restarted without an active session. Read-only samples: max local GET +179.8 ms, three of forty above 100 ms; retained registry waits 25.9–58.5 ms. +No archive/save delay above 25 ms was reported in the initial capture. Thus a +registry persistence bottleneck is not yet established by these measurements. + +Eighth observed trial at 11:22:27 UTC still stopped before forward demand. +Independent input recording showed local Core command POST outliers 103.4, +166.5, 216.1 and 127.4 ms (normally 2–10 ms). Sequence 17 reached Node with +312.7 ms remaining; sequence 19 followed after 335 ms. Separating trial +telemetry therefore did not by itself solve the delivery problem. + +A bounded read-only macOS sample of the operator Core found JSON encoding and +zlib work on its ASGI main thread. The periodically polled completed planning +report /api/v1/mission-planner/live-tests/active is 2,403,591 bytes and took +218.5 ms for one local GET. Its endpoint fetched the dict in a worker, but +FastAPI recursively encoded it and the middleware compressed it on the event +loop. This shared process also admits rover commands. + +planning_live_api.py now constructs the JSON response and optional gzip body +in the existing thread pool, preserving the full report contract and bypassing +second compression through Content-Encoding. No polling is disabled, evidence +is not removed, and Node, calibration, current limits and leases are unchanged. +13 focused tests passed against development and active Core: JSON/gzip execute +off-loop, exact content survives decompression, empty/failure contracts and +existing planning presentation/compression behavior remain valid. Canonical +8000 was restarted without active control. Sixty ordinary read-only rover +samples over 15 seconds then had max 86.1 ms, p95 64.5 ms and zero over 100 ms; +both assigned UUIDs fresh, currents/faults zero. This improves measured delay, +but does not yet establish motion or field acceptance. A fresh observed retry +is requested separately. Private process samples and device traces stay out +of normal Git. + + +Ninth attended Core API trial at 11:31:08 UTC passed preparation and completed +8 seconds of forward demand at up to 2000 ERPM, with a 30 A ceiling per motor. +The owner confirmed both motors physically rotated forward and subsequently +confirmed both stopped. Final state stopped, release_confirmed=true, zero +motor/input current and fault. Recorded peaks: left 2001 ERPM / 2.88 A motor, +right 2028 ERPM / 2.81 A motor; these are sampled peaks, not current ceilings. +During driving device ages stayed <=104 ms, all recorded fault codes zero. +Preparation retained old motor samples up to 10.1 s while exclusive setup ran; +those samples are not treated as live motion telemetry. Command POST max +81.28 ms, p95 10.05 ms across 201 requests. The normal stop command was accepted. + +This accepts the observed API forward/release path on Node 0.8.43-1 / VESC +0.7.2 and the corrected operator Core. It does not accept physical keyboard +input, Stop/blur, channel loss, RC takeover, loaded or field operation. Those +remain separate checks. No new calibration, firmware, USB reset or OS change +was performed for this trial. Private raw evidence and owner notes are hashed +in the experiment manifest; the previous eight preparation failures remain +recorded as failures. + + +At 11:38–11:39 UTC the owner physically held W in the 3D View after UI arming, +then released it. Owner reports both motors forward, immediate perceived stop +on release and approximately 0.5–1 s before initial motion. Exact key-event +latency was not instrumented and is not claimed resolved. Read-only capture: +393 samples, no request errors; driving observed for about 10 s (the requested +hold was approximately 8 s). Sampled peaks left 2004 ERPM / 3.51 A, right +2032 ERPM / 2.85 A; driving sample age <=113 ms, all faults zero. Release +returned to ready with motors stopped; the UI Stop action then reached stopped, +release_confirmed=true. Final UI explicitly says control disabled. The read-only +recorder exited and no motion input remained active. + +This accepts actual W forward/release, separately from the prior API trial. +Reverse/turns/Tank, Stop while moving/blur, channel-loss and RC takeover remain +unaccepted on the new UI path. Owner startup-delay observation is retained +for a separately instrumented check. No hardware limits or calibration changed. +MISSIONCOR-85 now records both successful trials, their limits and the previous +operator event-loop diagnosis while preserving all hardware/Hall history. + + +Observed S/A/D session, 11:45–11:47 UTC: the owner confirmed reverse on S +and opposite sides on A (left reverse, right forward); also reports D worked +before the agent disabled control. The telemetry records both opposite-side +patterns with neutral intervals. Final state stopped, release_confirmed=true. +The owner reports a repeatable approximately two-second start delay, with +immediate perceived release. This blocks completion of drive-response acceptance. + +Root cause in the remote output loop: it ramps the speed setpoint from zero +at 600 ERPM/s. Both saved configurations have s_pid_min_erpm=900. Pinned +upstream bldc mcpwm_foc.c (3f670137e27e6e383fa79c50cc6b1fa85aab1554) forces +zero duty and resets speed-PID state for targets below that threshold. The +result is 1.5 s of ineffective commands on each start, plus the retained +0.5 s undriven interval when changing direction. Recorded telemetry already +says driving while the rotor remains stopped, consistent with this mechanism. +This delay is downstream of command admission; the exact key-to-node timing +was not captured and no claim of zero network delay is made. + +Candidate Node 0.8.44-1 / VESC 0.7.3 starts the remote speed request at each +controller's own read-back minimum PID speed (rounded up for native integer +setRpm), then ramps at the existing rate above it. It does not change the +firmware threshold, motor configuration or current ceiling. Subthreshold +analogue requests release instead of being amplified above the request; +invalid/unreachable thresholds reject before output claim. Zero input still +releases immediately; expiry, RC takeover and the reversal dwell remain. +Synthetic tests cover distinct thresholds including fractional serialization, +first-cycle output, ramp above the threshold, turn signs, subthreshold input, +immediate release and invalid thresholds. Physical response after installation +requires a new observed trial; this candidate is not yet installed. + + +0.8.44-1 qualification completed: all 18 Ubuntu stages succeeded in 268.87 s, +including 140 VESC tests, Go race checks and Node UI. Source 1b1be6ef5913fd3740a11c69; +package SHA-256 46cae05efa621a2636251f69ab8071ff4e18db67f23203eab396a71f0ef0972b. +Owner installer bf270c06ae6d1e598e963756 launched in the local Ubuntu session. +APT simulation changes only mission-core-node 0.8.43-1 -> 0.8.44-1, with no +added or removed packages. Before launch Core showed stopped, release confirmed, +both currents/ERPM/faults zero. Local OS authorization is pending; launch is +not evidence of installation or an accepted new motor response. + + +Owner authorization completed: 0.8.44-1 installed at 12:01:17 UTC in 18.56 s, +all installer steps exit 0; Node and VESC services active. Twenty read-only +samples captured after installation, final sample both assigned controllers +fresh (53/63 ms), ERPM/current/fault zero and no active control. Fresh owner +observation requested for W start/release; improved physical response is not +yet accepted. + + +Post-0.8.44-1 owner keyboard series at 12:05–12:06 UTC included repeated +forward/reverse and both turn patterns. Owner reports delay approximately +halved, forward-to-reverse works, but one side sometimes starts sooner. +Read-only recording: 947 samples, no errors, all faults zero; 23 driving +segments. First side above 300 ERPM in the same sample or 0.25–0.51 s later; +both sides by 0–0.76 s. These are state-relative samples, not key-event timing. +The four-minute recorder ended at ready; a separately saved final snapshot +confirms stopped/release_confirmed, both ERPM and currents zero after UI Stop. +Sampled peaks left 2007 ERPM / 5.04 A, right 2025 ERPM / 3.32 A. + +Asymmetry diagnosis: after a turn, the remote code held only the reversing +motor for its 0.5 s neutral interval, while the other side immediately drove +the new command. Trace 12:05:39 (turn -> forward): right above 300 ERPM in the +first driving sample, left +0.763 s. The mirror transition at 12:05:33 had +left first, right +0.511 s. This is a software coordination defect, not evidence +that all smaller differences arise from the broken left Hall circuit. + +Candidate Node 0.8.45-1 / VESC 0.7.4 uses one reversal barrier for the entire +assigned drive group. If any side reverses, all outputs release until all +motors have been observed quiet and undriven for 0.5 s, then the current +latest targets start in the same output cycle. Already observed neutral time +counts; no extra dwell is added after a sufficiently long released pause. +Cancelled/replaced direction requests are not queued. The per-controller PID +threshold correction, speed ramp, immediate zero, current caps, expiry and RC +priority remain. Synthetic regressions cover turn->straight synchronization, +a slower coasting companion, counting an existing neutral pause and cancelling +a pending reversal. Installed software remains 0.8.44-1 pending qualification +and owner installation of this separate candidate. + + +0.8.45-1 / VESC 0.7.4 passed all 18 Ubuntu qualification stages in 267.11 s, +including 144 VESC tests. Source d31a8b586b9a600a2a8e61b3; package SHA-256 + af412c607fec9b34aba0af0e8e67614cd6f4d373fb641d7202341fea30be9ba1. +Installer f1a8a72c4a1a7efc4aeebedd launched in Ubuntu. Its APT plan upgrades +only mission-core-node 0.8.44-1 -> 0.8.45-1; no added/removed packages. +Before launch both controllers had zero ERPM/current/fault, control stopped, +release confirmed. OS authorization and new physical acceptance are pending. + + +0.8.45-1 installed at 12:23:15 UTC after owner OS authorization, 18.56 s, +all steps exit 0. Node and VESC services active. Twenty read-only samples; +final both assigned UUIDs fresh (115/124 ms), zero ERPM/current/fault and +no control session. Fresh owner observation requested for turn->forward +transitions; physical synchrony and remaining control/RC acceptance pending. + + +Observed 0.8.45-1 keyboard trial, 12:32–12:34 UTC: 545 read-only samples, +no read errors, fault codes zero, driving sample age <=105 ms. Twelve driving +segments; both sides above 300 ERPM in the same sample or within one 0.25 s +sample. Peaks left/right 2014/2043 ERPM and 4.35/3.24 A. Owner reports responsive +forward/reverse/turns. This is coarse telemetry, not exact key-to-output timing. + +CRITICAL physical acceptance failure: owner reports D continued after leaving +the browser and releasing the physical key; later clicks recovered it. The +trace contains prolonged D segments (22.82 and 20.56 s), but browser focus/key +source events were not recorded, so exact focus-loss latency is unknown. +Agent ended control through UI; stopped/release_confirmed=true and both motors +zero ERPM/current/fault. Remote-control acceptance remains blocked by this defect. + +The UI already subscribed to blur/pagehide/visibility events. Its 100 ms +command sender nevertheless renewed a remembered nonzero demand without a +focus or input-freshness check; a missed browser-host event could hold it +indefinitely. Fix uses a core-owned held-input binding, capture listeners, +50 ms focus polling, and a guard checked at every command heartbeat. A key +requires a fresh trusted press, then OS-repeat evidence: <=1000 ms initially, +<=300 ms after a repeat. This fallback bounds a lost keyup even if the host +also misses focus events. Focus loss/expiry clears all held states and disarms; +returning focus or delivering a late repeat cannot resume movement. Continuous +keyboard control therefore requires OS repeat within those bounds; this is +not a global-background keyboard implementation. Pointer up/cancel/capture-loss +and component disposal release held state. No onboard install or firmware/config +change belongs to this UI fix. Physical focus-loss re-test remains pending. + + +Owner follow-up after the first focus fix: movement now stops on focus loss, +but terminating the control session is explicitly rejected. New required +behavior is neutral hold with the current healthy control session preserved; +returning focus requires a new physical press, not another arm/preparation. +The implementation now separates input pause (clear held input, send zero, +keep session) from explicit Stop/pagehide/unmount/fault (end session). Guards +still run before every send; old demand is never restored on focus return. +The periodic neutral messages maintain the session only while communication +remains healthy. Actual background suspension/channel expiry is still a stop, +not permission to extend the motion watchdog. Continuous keyboard holds still +require OS repeat evidence within the bounded input lease. + +Preparation now hides key controls and renders the existing canonical warning +StatusBadge as Подготовка управления; readiness alone admits the green state +and key controls. Initial focus-fix physical evidence confirms stopping but +not the requested session-preserving behavior. Revised physical test pending. + + +Final revised UI qualification: 934 unit tests, architecture checks, TypeScript +and production build pass. Canonical Core serves the exact new index/assets; +no Node/OS/firmware change. Browser verified amber Подготовка управления with +keys absent until ready. Owner observed the revised trial and confirmed: +focus loss stops motors, returning allows a fresh press without another arm +or preparation. One active session persisted throughout all six short driving +segments. Explicit UI Stop after completion ended the session; final fresh +telemetry confirms stopped/release_confirmed=true, both ERPM/current/fault zero. +The private result includes UTC/monotonic traces, owner notes and SHA-256. +This accepts focus loss/resume on the observed host. Tank, explicit Stop while +moving, command-channel loss, RC takeover and loaded/field behavior remain +separate outstanding physical checks. No exact key-to-stop timing is claimed. + + +Startup-entry follow-up, 2026-09-25: owner reports silently disabled Manage +and intermittent first-arm failure on a fresh Core page. The outer button +previously depended on fresh/supported status without explaining the wait. +A reproduced hook race allowed a poll begun during POST /arm to return the +old controlling=false state after the arm acknowledgement and revoke the new +session. The error path had the same missing generation guard; repeated arm +calls before acknowledgement also escaped the session-only check. Three new +regressions failed before the fix; actual current-generation authority loss +already passed and must continue to end control. + +The acknowledgement now retires pre-acknowledgement reads; poll success and +failure require the current generation. An in-flight arm guard prevents +duplicate submission. Status reads may wait 1000 ms; command/arm 350 ms +deadlines and all board motion watchdogs remain unchanged. Manage always +opens settings, while actual arm waits for fresh supported idle authority. +The dialog remains open on failed arm. Canonical amber status distinguishes +synchronization, preparation, unavailable data and previous-session cleanup; +ready alone shows green and motion keys. Title is now exactly +«Центр наблюдения и управления». No board install/configuration change. + +Validation: 938 unit tests, architecture check, TypeScript and production +build passed; final copy/color adjustment rechecked with 22 focused tests +and production build. Fresh browser entry acquired control on its first click. +13:20:28–13:20:38 UTC preparation was visible, then ready; no motion input +was sent. Explicit UI Stop completed at 13:21:09 UTC, release confirmed. +307 read-only samples, no read errors, all ERPM and fault codes zero. +A subsequent page reload and settings reopen also passed. These are bounded +UI/lifecycle checks, not new acceptance of driving or RC takeover. Private +entry-startup-result.json contains UTC/monotonic evidence and SHA-256 hashes. diff --git a/docs/runbooks/ROVER_006_ENGINEERING_ACCESS.md b/docs/runbooks/ROVER_006_ENGINEERING_ACCESS.md new file mode 100644 index 0000000..52372b9 --- /dev/null +++ b/docs/runbooks/ROVER_006_ENGINEERING_ACCESS.md @@ -0,0 +1,75 @@ +# Rover 006: инженерный SSH и административные действия + +Проверено 23.09.2026 около 11:02 UTC. Источник: живой paired inventory Core, +Tailscale, сравнение SSH host key с ранее доверенной записью и успешный SSH. + +## Проверенный путь + +Текущий Ubuntu Mission Core Node и исторический Device Edge — разные записи +доступа. Для текущего борта подтверждён пользователь **`dcsudo`** и основной +персональный ключ оператора `~/.ssh/id_ed25519`. Приватный ключ не копируется. +Обычный вход работает с `BatchMode=yes`, без ввода пароля и без `sudo`. + +Сохранённый в операторском `~/.ssh/config` alias `nodedc-edge` относится к +прежней записи с пользователем `ndcsudo` и старым LAN-адресом. Он не является +источником адреса/пользователя нынешнего Rover 006. Не менять его вслепую: +другие задачи могут использовать историческую запись. + +На текущем операторском Mac создан и проверен отдельный приватный профиль: + +`/Users/dcconstructions/Downloads/mnt/NODEDC/outputs/rover-006-vesc-context-20260923/ssh-config` + +Он выбирает `rover-006`, актуальное MagicDNS-имя, `dcsudo`, персональный ключ, +`IdentitiesOnly=yes`, `BatchMode=yes`, `StrictHostKeyChecking=yes` и прежнюю +доверенную запись через `HostKeyAlias`. Команда проверки: + +```sh +ssh -F /Users/dcconstructions/Downloads/mnt/NODEDC/outputs/rover-006-vesc-context-20260923/ssh-config rover-006 'id -un; hostname' +``` + +Адреса, полный host-key fingerprint и USB-идентификаторы не включаются в +переносимую документацию. Приватный профиль не содержит пароля или содержимого +ключа. Его отсутствие на другом Mac не означает отказ борта. + +## Как восстанавливать контекст + +1. Прочитать MISSIONCOR-76 и последнее дополнение об инженерном доступе. +2. Проверить `GET http://127.0.0.1:8000/api/v1/fleet`: выбрать именно сопряжённый + Rover 006, проверить свежесть inventory, hostname, node identity и адреса. +3. Сопоставить эту машину с текущим Tailscale peer. Worker 006 и старый Device + Edge не являются бортом. Не сканировать подсеть. +4. Использовать проверенный профиль. При новом адресе сначала сравнить ключ с + известной доверенной записью. `ssh-keyscan` сам по себе не устанавливает + доверие; 23.09 ключ совпал побайтово с ранее сохранённым ключом Ubuntu Mini. +5. Если получен `Permission denied`, проверить **пользователя и выбранный ключ** + до обсуждения пароля/sudo. Не подбирать аккаунты, не сбрасывать ключи и не + выключать host-key checking. Если доказанного пути нет, использовать + существующий GUI Node «Система → SSH · доверенные устройства». + +Sandbox `Operation not permitted` и отказ запуска локального Tailscale CLI +не доказывают сетевой отказ. Повторить конкретное read-only действие с +разрешением инструмента, не менять маршруты и VPN на основании такой ошибки. + +## SSH не равен sudo + +Подтверждение владельцем пароля на экране Mini относится к административному +действию Ubuntu/установщика. Оно не требуется для обычного инженерного чтения. +Успешный SSH и членство в группе sudo не доказывают беспарольное повышение прав. + +Установка и изменения runtime выполняются штатным versioned installer/profile. +Если такой шаг требует системного подтверждения, сначала подготовить точный +артефакт и объяснить действие, затем использовать существующий системный диалог. +Не просить пароль в чате; не добавлять NOPASSWD, глобальный dialout/chmod или +новый канал обхода ради диагностики. На этапе первоначального аудита sudo не вызывался. Позднее 23.09 владелец +ввёл пароль локально в versioned установщике Node0.8.22-1; установка +подтверждена report.json и фактической версией пакета. + +Продуктовое управление устройствами проходит Core → mTLS → Node → plugin. +SSH остаётся инженерным инструментом, а не транспортом моторных команд. + +## Результат 23.09 + +Подтверждены Ubuntu 24.04.4 LTS, kernel 7.0.0-31-generic, Node 0.8.21-3, +K1 0.1.14, X4 0.1.3-9. Повторный вход через отдельный профиль вернул +правильного пользователя и hostname. SSH/sshd, учётные записи, доверие, +Tailscale, VPN и sudo policy не изменялись.