v4.7.0

v4.7.0 — крупный функциональный выпуск. Главное в нём: новая плата OpenMV AE3 (Alif Ensemble, Cortex-M55 + NPU Ethos-U55) с двухъядерной моделью программирования openamp, файловая система только для чтения ROMFS (/rom) с включёнными моделями и каскадами, поддержка VL53L8CX 8x8 (время пролёта), новые постобработчики YOLOv8 / YOLO-LC и MicroPython 1.25. Также изменён способ загрузки встроенных моделей и каскадов Haar, поэтому ознакомьтесь с обратно несовместимыми изменениями ниже.

Основные моменты

  • Плата OpenMV AE3 — плата Alif Ensemble (Cortex-M55 + NPU Ethos-U55) с полным портом, загрузчиком и ROMFS.

  • Двухъядерный модуль openamp — перенос работы на второе ядро Alif через RPMsg (декоратор @async_remote, Endpoint/ EndpointIO).

  • ROMFS — файловая система /rom только для чтения со встроенными моделями TFLite и каскадами Haar, плюс новый хост-сборщик tools/mkromfs.py.

  • VL53L8CX — поддержка многозонного датчика времени пролёта 8x8.

  • Новые постобработчики MLyolo_v8_postprocess и yolo_lc_postprocess.

  • MicroPython обновлён до 1.25.0.

  • Обратно несовместимое изменение: встроенные модели и каскады Haar теперь загружаются из /rom по пути (см. изменение ml.Model и изменение каскада Haar).

Новые возможности

  • OpenMV AE3 — новая плата Alif Ensemble (прикладное ядро Cortex-M55 + NPU Ethos-U55) с портом, загрузчиком, конфигурацией платы, RGB-светодиодом и поддержкой ROMFS.

  • openamp — новый модуль для модели RPC двухъядерного Alif (Open-AMP / RPMsg): Endpoint, EndpointIO, new_service_callback и декоратор @async_remote для переноса маршалированных функций на второе ядро. Ядра HE/HP поставляются с заданным по умолчанию исполнителем задач _boot.py на базе asyncio.

  • audio — порт Alif добавляет аудиомодуль (PDM-микрофон) с потоковым API на основе функций обратного вызова (audio.init(channels=, frequency=, gain_db=, buffers=, samples=, overflow=, highpass=)) на AE3.

  • ROMFS — файловая система /rom только для чтения со встроенными ресурсами (модели TFLite, каскады Haar, …), упакованными для каждой платы, новый хост-инструмент tools/mkromfs.py (tflite, tflite+vela, каскад Haar, текст, двоичные данные) и вспомогательный модуль scripts/libraries/romfs.py, предоставляющий ls_romfs().

  • Постобработка ML — новые классы yolo_v8_postprocess (YOLOv8) и yolo_lc_postprocess (облегчённый вариант tiny-YOLOv2 с оптимизированными для встраиваемых систем якорями по умолчанию), каждый из которых принимает threshold, nms_threshold и nms_sigma.

  • Защита от мерцания GenX320 — новый ioctl IOCTL_GENX320_SET_AFK для включения и настройки фильтра защиты от мерцания событийного датчика (минимальная/максимальная частота мерцания в Гц), с примером genx320_grayscale_set_afk.py.

  • VL53L8CX — поддержка многозонного датчика времени пролёта 8x8 через модуль tof (автоматическое определение, 8x8 при 15 Гц).

Прочие изменения и улучшения

  • MicroPython обновлён до 1.25.0 (порты STM32 и i.MX RT), с добавлением вышестоящего порта Alif и удалением устаревших драйверов BT-HCI из портов STM32 / i.MX RT.

  • GenX320 — новая последовательность ISSD удваивает внутреннюю тактовую частоту пикселей (24 → 48 МГц) для более высокой частоты кадров.

  • STM32N6 / ST Edge AI — подготовка к развёртыванию моделей Neural-ART на STM32N6 (инструменты ST Edge AI и поддержка ROMFS).

  • PAG7936 — теперь устанавливается битрейт CSI PHY, что улучшает работу этого датчика.

Исправления ошибок

Камера и датчики:

  • Исправлен IMU через I2C — платы с подключением IMU LSM6DSx по I2C теперь корректно инициализируются и считывают данные (путь I2C ранее использовал неработающий путь чтения и неверные константы).

  • Инициализация FLIR Boson теперь повторяется до 10 раз для старых датчиков (< IDD 4.x), которым требуется ~10 с на запуск, и заводские настройки по умолчанию восстанавливаются при сбросе, чтобы загруженные извне настройки не могли нарушить видеовывод.

  • Исправлена запись неверного (нулевого) времени накопления в psee_ehc_activate_override для GenX320.

  • На платах STM32 без аппаратной поддержки FastMode+ запрос режима I2C fast mode теперь корректно защищён вместо незаметной неправильной настройки шины.

Машинное обучение:

  • Исправлены сбор ограничивающих рамок и обработка np.nonzero в постобработчиках YOLOv2 / YOLOv5, что повышает надёжность обнаружения.

Поддержка оборудования и плат

  • OpenMV AE3 — новая плата Alif Ensemble (Cortex-M55 + NPU Ethos-U55).

  • VL53L8CX — многозонный датчик времени пролёта 8x8; ToF-датчик на AE3 был переключён с VL53L5CX на VL53L8CX.

  • STM32N6 — подготовка к развёртыванию моделей ST Edge AI (Neural-ART).

Обратно несовместимые изменения API

Изменения API, видимые пользователю, между v4.6.20 и v4.7.0. Область: C-модули Python в modules/ и библиотеки Python в scripts/libraries/.

Каждое изменение помечено степенью влияния:

  • major — большинству скриптов, использовавших его, потребуются правки.

  • minor — узкий API; затрагивает только скрипты, использовавшие его.

  • behavior — тот же API, другие результаты; перепроверьте настроенные скрипты.

Изменения сгруппированы по влиянию в этом порядке. Если вам нужно только перенести свой код, перейдите к контрольному списку миграции в конце, где приведён сжатый перечень задач. Каждый хэш коммита ссылается на его diff на GitHub.

Встроенные модели загружаются по пути, а не по имени (major)

ml.Model больше не загружает встроенную модель из простой строки имени. Модели теперь загружаются из файловой системы / ROMFS по пути:

model = ml.Model("/rom/person_detect.tflite")   # was: ml.Model("person_detect")

Атрибут model.labels со стороны C был удалён; метки теперь загружаются обёрткой ml.Model на Python из сопроводительного файла <model>.txt (None при его отсутствии). Все прилагаемые примеры и ml/apps.py были обновлены на пути /rom/*.tflite.

Коммиты: 978fa436c, 3f55d956c, 416bc4613

Каскады Haar загружаются из ROMFS (minor)

image.HaarCascade() теперь загружает встроенные каскады через VFS / ROMFS. Файл фронтального каскада лица по умолчанию переименован из haarcascade_frontalface_default.xml в haarcascade_frontalface.xml, а сбой загрузки теперь вызывает RuntimeError («Failed to load Haar cascade») вместо OSError.

Коммит: 9de1220d8

Семантика tof.reset() / tof.deinit() (behavior)

В модуле tof reset() ранее был псевдонимом init(), а реальной функции deinit не было. tof.reset() теперь выполняет фактический сброс датчика, а tof.deinit() корректно выключает датчик (с поддержкой выключения VL53L5CX). Код, полагавшийся на повторную инициализацию датчика через reset(), следует перепроверить.

Коммиты: 20d6b53f8, c743cab6a

Ограничения тайминга и событийного режима GenX320 (behavior)

Новая последовательность ISSD для GenX320 меняет временную базу датчика: аргументы частоты кадров и экспозиции теперь выражаются в единицах 1 МГц вместо масштабирования по тактовой частоте, а гашение HSYNC динамически подстраивается под запрошенную частоту кадров. Скрипты с жёстко заданными значениями тайминга GenX320 необходимо перенастроить. Захват в событийном режиме теперь вызывает ошибку при включённом транспонировании изображения (оно не поддерживается в такой конфигурации).

Коммиты: 660a783d6, 7a718c6af

Контрольный список миграции

Для чистого переноса на v4.7.0 обычно требуется:

  1. Изменить загрузку встроенной модели со строки имени на путь /rom/<name>.tflite и предоставить метки через сопроводительный файл <name>.txt (изменение ml.Model).

  2. Обновить haarcascade_frontalface_default.xml на haarcascade_frontalface.xml и перехватывать RuntimeError (а не OSError) при сбое загрузки каскада (изменение каскада Haar).

  3. Удалить код, полагавшийся на повторную инициализацию датчика через tof.reset() (изменение tof).

  4. Перенастроить любые жёстко заданные значения частоты кадров / экспозиции GenX320 в единицы 1 МГц и не включать транспонирование в событийном режиме (изменение GenX320).