docs(rover): record calibration control acceptance and operating boundaries

This commit is contained in:
DCCONSTRUCTIONS
2026-09-25 16:39:19 +03:00
parent bc55901d4d
commit 6bbbd5bf7d
12 changed files with 4603 additions and 0 deletions
File diff suppressed because it is too large Load Diff
+176
View File
@@ -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.
+99
View File
@@ -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.
+145
View File
@@ -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-*.
+95
View File
@@ -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).
+37
View File
@@ -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; переключатель не объявляется действующим до реализации и проверки
реального пути команд.
+595
View File
@@ -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`, раздел «Нейтраль после возврата питания».
Профиль одного стика и постоянный перехват этим чтением не приняты.
+247
View File
@@ -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`. Наблюдатель
завершился штатно; постоянный процесс опроса не оставлен.
@@ -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.