Добавить общие графики, декодер KONOR и порт STM32 bxCAN

This commit is contained in:
2026-09-04 12:22:17 +03:00
parent af82687e42
commit e163d9ba55
51 changed files with 5040 additions and 15 deletions

View File

@@ -0,0 +1,80 @@
# Общая работа с графиками Android и SETGUI
Численная логика находится в `include/set_plot.h` и `src/set_plot.c`.
Это модуль C99 без Qt, Android, транспорта, динамической памяти и глобального
состояния. Он собирается в существующую библиотеку SETProtocol; отдельная DLL
для графиков не требуется. Версия ABI графиков — `set_plot_abi_version() == 1`.
| Общее в templates | Адаптер приложения |
|---|---|
| Нормализованная область просмотра, масштаб 1…128, ограничение панорамирования | Размер поля и отступы в пикселях |
| Независимый масштаб X/Y с сохранением координаты под пальцами | События Compose или Qt, колесо, кнопки |
| Выбор преобладающей оси по изменению расстояния между пальцами | Накопление движения до порога; фиксация выбранной оси до конца жеста |
| Перевод значения в долю экрана и обратно, инверсия Y | Canvas/QPainter и оформление шкал |
| Перемещение маркера от начальной координаты, ограничение видимой областью | Захват линии пальцем/мышью, редактор положения |
| Разность BA, DC и множитель единиц, шаги шкалы 1/2/5 | Подписи, цвета, миллисекунды/герцы/единицы сигнала |
| Модели маркеров и их размещение в Kotlin/Python-портах | Жизненный цикл экрана, очистка и выбор источника |
Модель маркеров: A/B — координаты X и вертикальные линии во всю высоту поля;
C/D — координаты Y и горизонтальные линии. Они могут пересекаться: отрицательная
разность сохраняется. Начальные координаты — 1/3 и 2/3 диапазона. При изменении
масштаба уже установленные координаты сохраняются. «Маркеры в видимую область»
заново размещает их. Координаты и область просмотра времени/спектра независимы.
`set_plot_eval()` принимает операцию из `enum set_plot_operation`, точное число
входных `double` и буфер вывода. Контракт каждой операции указан в заголовке.
Возвращает число записанных элементов, 0 — неправильные аргументы. Некорректный
коэффициент масштабирования оставляет корректный viewport неизменным.
NaN/Inf и вырожденные диапазоны не передаются дальше в отрисовку.
FRACTION/VALUE не обрезают координаты: это позволяет правильно отсекать линии
по границе поля, а не создавать ложные горизонтальные участки на его краю.
DRAG, напротив, ограничивает положение маркера видимым диапазоном.
## Порты
- Android/JVM: `ports/android/kotlin/ru/setcorp/setprotocol/trends/NativePlot.kt`,
`PlotViewport.kt`, `TrendMarkers.kt`; тонкий JNI — `ports/android/set_plot_jni.c`.
Android использует `System.loadLibrary("setprotocol")`. Для JVM-тестов можно
передать абсолютный путь DLL/SO системным свойством `setplot.library`.
- Python: `python/protocan/plot.py`: `PlotMath(library)`, `Viewport`, `Bounds`,
`Markers`. Приложение передаёт уже загруженную SETProtocol `ctypes.CDLL`.
Зависимости — стандартная библиотека; Qt в этот модуль не импортируется.
Новые изменения не должны добавлять вторую реализацию численных операций
в Kotlin/Python или в приложение. Состояние и адаптация событий остаются в портах.
Добавление операции требует обновления C ABI, обоих портов и общих эталонов.
## Интеграция приложений
Android: `TrendGraph` использует общие viewport, bounds и маркеры, а Compose
рисует линии и панель. При измерениях время отображается в миллисекундах от
начала выбранного участка; сохранённые X-координаты включают абсолютное начало.
SETGUI: `ui/plot_interaction.py` адаптирует общий модуль к Qt. Его используют
`SignalPlot` (ТМС и датчики), `TrendPlot` (логи) и `SpectrumPlot`.
Колесо по вертикали масштабирует Y, Shift+колесо и горизонтальное колесо — X;
сенсорный pinch выбирает ось по движению. Временные графики хранят метку приёма
каждого отсчёта. Пропущенные значения не растягивают остальные серии:
все сигналы имеют единую шкалу времени. При повторном построении ТМС из журнала
используются исходные метки приёма. Дискретные дорожки имеют общую X-шкалу,
а маркеры уровня Y относятся к аналоговому полю.
Расчёт FFT не является частью этого модуля. Android вычисляет спектр через
`set_spectrum.c`; вкладка спектра SETGUI получает готовые уровни в дБмВ от
прибора. Общая интерактивная часть не меняет эти данные или единицы.
## Проверка и сборка
- CMake/CTest: `shared_plot` проверяет ABI, размеры буферов и координаты.
- `tests/fixtures/plot-v1.json` содержит общие численные эталоны. Их читают
`PlotContractTest` (фактический JNI) и `python/tests/test_plot.py` (ctypes).
- Host DLL/SO для Python: `python tools/build_host.py --output <путь>`.
- Для JVM: та же команда с `--java-home <JDK>` добавляет JNI-порт графиков.
Нужен C-компилятор (MSVC на Windows, cc/clang/gcc на Unix) и JDK с `jni.h`.
- Android-проект автоматически собирает host-библиотеку перед JVM-тестами;
интерпретатор Python можно задать свойством Gradle `setflash.python`.
- SETGUI проверяет события мыши, колеса и двух пальцев через QtTest без
физического прибора; численные тесты не требуют GUI.
Исходники должны приходить из одного коммита подмодуля `templates` в обоих
проектах. Локальная замена файлов без обновления gitlink не закрепляет версию.