13.4.1.6. Довідник API#

Публічна поверхня пакету openmv – це клас Camera для взаємодії з камерою та ієрархія OMVException для помилок протоколу. Обидва задокументовані на цій сторінці.

13.4.1.6.1. Клас Camera#

class openmv.Camera(port: str, *, baudrate: int = 921600, crc: bool = True, seq: bool = True, ack: bool = True, events: bool = True, timeout: float = 1.0, max_retry: int = 3, max_payload: int = 4096, drop_rate: float = 0.0)#

Проксі на стороні хоста для OpenMV камери, підключеної через USB serial.

Параметри:
  • port – Шлях до послідовного пристрою. На Linux: /dev/ttyACMx для USB CDC та /dev/ttyUSBx для USB-to-UART адаптера. На macOS: /dev/tty.usbmodem... або /dev/cu.usbmodem.... На Windows: COMx.

  • baudrate – Швидкість передачі (бод) послідовного порту. Через USB значення 921600 є магічним, яке перемикає камеру з MicroPython REPL на протокол OpenMV – будь-яке інше значення при USB-підключенні залишає камеру в режимі REPL, тому слід використовувати значення за замовчуванням. При підключенні через UART це фактична швидкість передачі (бод) лінії, яка може бути довільно встановлена з обох сторін.

  • crc – Увімкнути перевірку CRC для кожного пакету.

  • seq – Увімкнути порядкові номери для кожного пакету.

  • ack – Вимагати підтвердження отримання пакетів.

  • events – Увімкнути сповіщення про події від камери.

  • timeout – Тайм-аут на операцію у секундах.

  • max_retry – Кількість повторних спроб перед виникненням виключення при невдалій передачі пакету.

  • max_payload – Максимально узгоджений розмір корисного навантаження у байтах. Камера може зменшити це значення під час узгодження.

  • drop_rate – Лише для тестування – ймовірність відкидання пакету в діапазоні [0.0, 1.0]. Залишайте 0.0 у продакшні.

Клас підтримує протокол контекстного менеджера; with Camera(port) as cam: викликає connect() при вході та disconnect() при виході.

13.4.1.6.2. Підключення#

Camera.connect() None#

Відкрити послідовний порт та виконати рукостискання протоколу. Кешований стан (список каналів, системна інформація, інформація про версію) заповнюється як побічний ефект. Викликається автоматично контекстним менеджером.

Camera.disconnect() None#

Закрити послідовний порт та звільнити транспорт. Викликається автоматично при виході з контекстного менеджера.

Camera.is_connected() bool#
Повертає:

True, якщо послідовний порт відкритий.

Camera.reset() None#

Скинути камеру. З’єднання розривається, оскільки камера перезавантажується.

Camera.boot() None#

Перевести камеру в завантажувач. З’єднання розривається, оскільки камера перезавантажується.

Camera.update_capabilities() None#

Повторно узгодити можливості протоколу (CRC, перевірка послідовності, ACK, події, максимальне корисне навантаження) з камерою. Камера повідомляє про максимальне корисне навантаження, яке вона може обробити; запит хоста обрізається до цього значення, і узгоджені налаштування відправляються назад. Викликається автоматично connect() – немає причин викликати з коду користувача, якщо тільки флаги конструктора не потребують повторного узгодження на існуючому з’єднанні.

Camera.poll_events() None#

Запустити шлях отримання транспорту один раз для обробки будь-яких очікуючих подій від камери без надсилання команди. Корисно в довготривалих програмах, що працюють хвилинами без іншого I/O та хочуть своєчасно відображати події реєстрації каналів.

13.4.1.6.3. Виконання скриптів#

Camera.exec(script: str) None#

Завантажити script (рядок Python-коду) у буфер stdin камери та запустити його виконання.

Параметри:

script – Вихідний код MicroPython для виконання.

Camera.stop() None#

Перервати виконання поточного скрипту. Еквівалент кнопки Stop в IDE.

Camera.read_stdout() str | None#

Прочитати всі байти, що поточний скрипт записав до stdout з моменту останнього виклику.

Повертає:

Вивід у вигляді декодованого рядка, або None, якщо дані відсутні.

13.4.1.6.4. Потокова передача#

Camera.streaming(enable: bool, raw: bool = False, resolution: tuple[int, int] | None = None) None#

Увімкнути або вимкнути потік кадрів та вибрати формат передачі.

Параметри:
  • enableTrue вмикає потокову передачу, False вимикає.

  • raw – Якщо False (за замовчуванням), камера стискає кожен кадр у JPEG перед розміщенням у канал потоку, а read_frame() розпаковує його на хості. Якщо True, камера надсилає захоплений піксельний буфер без стиснення – правильний вибір для камер без апаратної підтримки JPEG, де програмне стиснення є найповільнішим кроком у циклі.

  • resolution(width, height) – цільовий розмір, до якого камера масштабує кожен необроблений кадр перед надсиланням, оскільки нестиснені кадри набагато більші за JPEG-стиснені. Обов’язково при raw=True; ігнорується в інших випадках.

Camera.read_frame() dict | None#

Прочитати останній кадр із каналу потоку.

Повертає:

None, якщо кадр відсутній, або словник з ключами width (int, пікселі), height (int, пікселі), format (int, ідентифікатор піксельного формату, оголошений камерою), depth (int, розмір стисненого зображення у байтах для кадрів JPEG / PNG; не використовується для нестиснених форматів), data (bytes, RGB888 довжиною width * height * 3) та raw_size (int, байти, які камера надіслала через USB до декодування).

13.4.1.6.5. Користувацькі канали#

Camera.has_channel(name: str) bool#
Повертає:

True, якщо канал, зареєстрований під іменем name, існує на камері.

Camera.channel_size(name: str) int#
Повертає:

Кількість байт, доступних у названому каналі, або 0, якщо канал порожній або не існує.

Camera.channel_read(name: str, size: int | None = None) bytes | None#

Зчитати з користувацького каналу.

Параметри:
  • name – Ім’я каналу, зареєстроване скриптом на стороні камери.

  • size – Кількість байт для зчитування, або None для зчитування всього доступного.

Повертає:

Байти або None, якщо канал не існує.

Camera.channel_write(name: str, data: bytes) bool#

Записати data до користувацького каналу. Записи, що перевищують розмір корисного навантаження, автоматично розбиваються на пакети.

Параметри:
  • name – Ім’я каналу, зареєстроване скриптом на стороні камери.

  • data – Байтоподібне корисне навантаження для надсилання.

Повертає:

True, якщо канал існує і запис був надісланий, False – в іншому разі.

Camera.read_status() dict[str, bool]#

Опитати всі зареєстровані канали.

Повертає:

Словник, що відображає ім’я каналу на булеве значення «дані готові до зчитування».

Camera.update_channels() None#

Оновити кешований список каналів з камери. Запускається автоматично наступного разу, коли виконується пошук каналу за іменем після надходження події реєстрації каналу; застосунок, що хоче дізнатися про щойно зареєстрований канал негайно, може викликати це напряму.

Camera.get_channel(name: str | None = None, channel_id: int | None = None) int | str | None#

Знайти канал за іменем (повертає його числовий ID) або за ID (повертає його ім’я). Оновлює кеш каналів через update_channels(), якщо є очікуючі події реєстрації каналів.

Параметри:
  • name – Ім’я каналу для перетворення на ID.

  • channel_id – ID каналу для перетворення на ім’я.

Повертає:

Відповідний ID або ім’я, або None, якщо канал не існує. Має бути вказано одне з name або channel_id.

13.4.1.6.6. Інтроспекція пристрою#

Camera.version() dict#

Повернути триплети версій протоколу, завантажувача та мікропрограми камери. Кешується після connect(). Кожен триплет – це кортеж (major, minor, patch) з int:

  • protocol_version – версія протоколу OpenMV, що реалізована в камері.

  • bootloader_version – образ завантажувача, що знаходиться у флеш-пам’яті.

  • firmware_version – мікропрограма MicroPython, що наразі виконується.

Camera.system_info() dict#

Повернути інформацію про апаратні можливості та пам’ять камери. Кешується після connect(). Ключі поверненого словника поділяються на чотири групи.

Ідентифікація

  • cpu_id – 32-бітний ідентифікатор CPU.

  • device_id – 3-елементний кортеж 32-бітних слів, унікальний серійний номер пристрою, вбудований у мікросхему.

  • chip_id – 3-елементний кортеж 32-бітних слів, по одному запису на кожен датчик зображення, підключений до камери.

  • usb_vid – USB vendor ID.

  • usb_pid – USB product ID.

Розміри пам’яті (усі в кілобайтах)

  • flash_size_kb – загальний обсяг внутрішньої флеш-пам’яті.

  • ram_size_kb – загальний обсяг RAM.

  • framebuffer_size_kb – RAM, зарезервований для захоплення зображень.

  • stream_buffer_size_kb – RAM, зарезервований для каналу потоку, що передає кадри на хост.

Прапори можливостей (по одному булевому значенню на ознаку, всі мають назву <feature>_present)

  • gpu_present – блок графічної обробки.

  • npu_present – блок нейронної обробки.

  • isp_present – процесор обробки сигналів зображення.

  • venc_present – відеокодер.

  • jpeg_present – апаратний кодер JPEG.

  • dram_present – зовнішня DRAM.

  • crc_present – прискорювач CRC.

  • pmu_present – блок моніторингу продуктивності.

  • wifi_present – радіомодуль Wi-Fi.

  • bt_present – радіомодуль Bluetooth.

  • sd_present – слот SD-карти.

  • eth_present – Ethernet PHY.

  • multicore_present – кілька ядер CPU.

Інше

  • usb_highspeed – булеве значення, True, коли USB перераховано в режимі високої швидкості (USB 2.0 HS, 480 Мбіт/с).

  • pmu_eventcnt – кількість доступних лічильників подій PMU; 0, якщо PMU відсутній.

Camera.print_system_info() None#

Вивести відформатований блок системної інформації в logging на рівні INFO. CLI використовує це при підключенні.

13.4.1.6.7. Діагностика#

Camera.host_stats() dict#
Повертає:

Лічильники транспортного рівня, що відстежуються на стороні хоста: sent, received, checksum, sequence.

Camera.device_stats() dict#
Повертає:

Лічильники транспортного рівня, що відстежуються на стороні камери: sent, received, checksum, sequence, retransmit, transport, sent_events, max_ack_queue_depth.

13.4.1.6.8. Профайлер#

Профайлер звітує про кількість викликів функцій та мінімальний / максимальний / загальний час виконання для інструментованих модулів мікропрограми – наразі image, ml та ulab. Входи та виходи функцій перехоплюються під час компіляції; під час виконання зчитується монотонний лічильник мікросекунд при кожному з них, результат накопичується для кожної функції та передається хосту через канал profile.

Профайлер вбудовується в мікропрограму лише тоді, коли при виклику make передається PROFILE_ENABLE=1. Стандартні образи мікропрограми не містять його – прапор -finstrument-functions, що додається збіркою до відстежуваних модулів, має відчутні витрати під час виконання, тому збірки з профілюванням виробляються з вихідного коду для конкретних сеансів налагодження, що їх потребують. Якщо мікропрограма не зібрана з цим прапором, канал profile не реєструється, і кожен метод профайлера на цій сторінці повертається мовчки, нічого не роблячи.

Arm Performance Monitoring Unit (PMU) – це блок апаратних лічильників Cortex-M55: невеликий набір налаштовуваних лічильників, що відстежують кількість тактів, попадання та промахи кешу, поведінку гілок та інші визначені архітектурою події без уповільнення вимірюваного коду. На камерах, що мають PMU – AE3 та N6, двох камерах в лінійці OpenMV, побудованих на M55 – профайлер зчитує ці лічильники разом із даними про час, і загальні значення подій з’являються в кожному записі функції. Камери без PMU все одно генерують записи часу; поля подій повертаються як нуль, а profiler_event() є no-op.

Camera.profiler_mode(exclusive: bool = False) None#

Перемикатися між включним та виключним режимами вимірювання часу. Включний режим зараховує час викликаних функцій до того, хто їх викликає; виключний режим – ні.

Параметри:

exclusiveTrue вибирає виключний режим, False – включний.

Camera.profiler_reset(config: list | None = None) None#

Очистити всі лічильники профілю. config=None також відновлює призначення подій PMU за замовчуванням.

Параметри:

config – Зарезервовано для майбутніх перевизначень конфігурації окремих лічильників. Передайте None, щоб зберегти значення за замовчуванням.

Camera.profiler_event(counter_num: int, event_id: int) None#

Прив’язати один зі слотів лічильника PMU до конкретної апаратної події.

Параметри:
  • counter_num – Індекс лічильника.

  • event_id – Ідентифікатор події, визначений архітектурою.

Camera.read_profile() list[dict] | None#

Повернути записи профілю для кожної функції, зібрані після останнього скидання. Кожен запис є словником з address, caller, call_count, min_ticks, max_ticks, total_ticks, total_cycles та кортежем events, розмір якого відповідає pmu_eventcnt камери.

Повертає:

Список словників записів або None, якщо канал профілю недоступний або дані не були зібрані.

13.4.1.6.9. Підкласи та внутрішні механізми каналів#

Методи, задокументовані вище, охоплюють кожне типове використання пакету. Деякі шаблони – обробка подій на стороні камери, на які хост хоче реагувати; блокування каналу для багатокрокового обміну; робота з каналами, що переносять структуровані дані замість потоків байт; або виклик команд керування, специфічних для каналу – потребують методів, які Camera зберігає з префіксом підкреслення. Ці імена є приватними за конвенцією (Python не змінює їх через name mangling), а застосунки, що їх потребують, можуть або успадкувати Camera, або викликати методи напряму.

Підклас для реакції на події. Кожна подія, що надходить від камери, проходить через Camera._handle_event(). Успадкування Camera та перевизначення цього методу – спосіб реакції застосунку на події, що генерує скрипт на стороні камери; сторінка Події описує повний шаблон.

Camera._handle_event(channel_id: int, event: int) None#

Обробити одну подію від камери. Викликається транспортним рівнем щоразу, коли надходить пакет події. Перевизначіть у підкласі для додавання специфічної для застосунку обробки; викличте super()._handle_event(...) для збереження стандартної поведінки (оновлення списку каналів при CHANNEL_REGISTERED, відстеження готовності кадру для каналу stream, логування запуску / зупинки каналу stdin).

Параметри:
  • channel_id0 для системних подій, інакше – зареєстрований ID каналу.

  • event – Ідентифікатор події; значення беруться з enum EventType для системних подій та з будь-якого значення, яке обрав бекенд каналу на стороні камери для подій каналу.

Підклас, що додає власні методи для роботи з протоколом, повинен декорувати їх retry_if_failed(), щоб вони успадкували таку саму поведінку повторної синхронізації та повтору, яку мають усі вбудовані методи на цій сторінці.

static Camera.retry_if_failed(func)#

Декоратор. Огортає метод екземпляра так, щоб він повторював спробу один раз при виникненні ResyncException у транспорті. Будь-який метод, що викликає _send_cmd_wait_resp() (безпосередньо або через один із обгорток _channel_*) повинен мати цей декоратор:

class MyCamera(Camera):
    @Camera.retry_if_failed
    def my_custom_command(self, payload):
        return self._send_cmd_wait_resp(Opcode.MY_CMD,
                                        0, payload)

Блокування каналу гарантує, що стан каналу не зміниться між двома пов’язаними операціями (наприклад, _channel_size(), за яким слідує _channel_read(), для каналу, до якого постійно додаються дані). read_frame() та read_profile() використовують це внутрішньо; застосунок, що керує користувацьким каналом із багатокроковим доступом, робить те саме.

Camera._channel_lock(channel_id: int) bool#

Отримати ексклюзивне блокування для каналу. Інші операції хоста з тим самим каналом блокуються до звільнення блокування.

Параметри:

channel_id – Числовий ID каналу, як правило, отриманий через get_channel().

Повертає:

True, якщо блокування було надано.

Camera._channel_unlock(channel_id: int) bool#

Зняти блокування, раніше встановлене _channel_lock(). Завжди парне з викликом блокування; використовуйте try / finally, щоб гарантувати зняття блокування навіть у разі виникнення виключення під час зчитування.

Параметри:

channel_id – Числовий ID каналу, як правило, отриманий через get_channel().

Структуровані канали передають упорядковані записи, а не простий потік байт. Канал профайлера є вбудованим прикладом: його форма – (record_count, record_size), і хост, що хоче знати, скільки записів очікує, зчитує форму, а не розмір у байтах.

Camera._channel_shape(channel_id: int) tuple[int, ...]#

Зчитати дескриптор форми каналу.

Параметри:

channel_id – Числовий ID каналу, як правило, отриманий через get_channel().

Повертає:

Кортеж беззнакових 32-бітних цілих чисел, що описують структуру каналу. Значення специфічне для каналу.

Команди керування, специфічні для каналу – запуск, зупинка, скидання, конфігурування – використовують один опкод (CHANNEL_IOCTL) з номером команди, специфічним для каналу, та необов’язковим навантаженням struct.pack. Вбудовані методи, такі як stop(), exec() та streaming(), є тонкими обгортками навколо викликів _channel_ioctl() для каналів stdin і stream; власний канал на стороні камери, що визначає своє меню ioctl, керується так само.

Camera._channel_ioctl(channel_id: int, cmd: int, fmt: str | None = None, *args) bytes | None#

Виконати ioctl-команду на каналі.

Параметри:
  • channel_id – Числовий ID каналу, як правило, отриманий через get_channel().

  • cmd – Номер команди, визначений бекендом каналу на стороні камери.

  • fmt – Необов’язковий рядок формату struct для кортежу аргументів. Передайте None для ioctl без аргументів.

  • args – Значення, що відповідають fmt.

Повертає:

Будь-яке корисне навантаження, повернуте каналом, або None.

Варіанти потоку байт за ID публічних методів каналу пропускають пошук імені-до-ID та приймають явне зміщення байт offset – корисно для зчитування фрагменту з середини великого буфера (наприклад, записів каналу profile).

Camera._channel_size(channel_id: int) int#
Параметри:

channel_id – Числовий ID каналу, як правило, отриманий через get_channel().

Повертає:

Байти, наразі доступні в каналі.

Camera._channel_read(channel_id: int, offset: int, length: int) bytes#

Зчитати length байт, починаючи з offset. Багатопакетні зчитування автоматично збираються.

Параметри:
  • channel_id – Числовий ID каналу, як правило, отриманий через get_channel().

  • offset – Байтове зміщення для початку зчитування.

  • length – Кількість байт для зчитування.

Camera._channel_write(channel_id: int, data: bytes, offset: int = 0) None#

Записати data за заданим offset. Багатопакетні записи автоматично розбиваються на пакети.

Параметри:
  • channel_id – Числовий ID каналу, як правило, отриманий через get_channel().

  • data – Байтоподібне корисне навантаження для запису.

  • offset – Байтове зміщення для початку запису.

Примітиви протоколу – це найнижчий рівень, який надає клас: відправка команди, отримання необробленого списку каналів та ручна повторна синхронізація, на яких врешті-решт побудовано все вище. Застосунок звертається до них при надсиланні опкоду, який клас ще не обгортає, або при реалізації власного відновлення у підкласі.

Camera._send_cmd_wait_resp(opcode: int, channel: int = 0, data: bytes = b'') bytes | None#

Надіслати команду протоколу та чекати на відповідь камери. Примітив, на якому побудований кожен інший метод у цьому розділі.

Параметри:
  • opcode – Номер команди. Вбудований enum Opcode перераховує коди, з якими постачається мікропрограма, але параметр є просто цілим числом – збірка власної мікропрограми може визначати та реагувати на власні коди.

  • channel – ID каналу або 0 для системних команд.

  • data – Корисне навантаження, специфічне для команди.

Повертає:

Корисне навантаження відповіді або None для команд на кшталт Opcode.SYS_RESET та Opcode.SYS_BOOT, що розривають з’єднання.

Camera._channel_list() dict#

Отримати поточний список каналів від камери, не торкаючись кешованих словників channels_by_id та channels_by_name, які заповнює update_channels(). Корисно для підкласу, що хоче безпосередньо перевірити стан каналів камери.

Повертає:

Словник, що відображає ID каналу на {'name': str, 'flags': int}.

Camera._resync() None#

Повторно виконати рукостискання протоколу з нуля. Викликається автоматично connect() при початковому підключенні та кожним публічним методом, що перехоплює OMVException від транспорту. Застосунок, що реалізує власний цикл відновлення у підкласі, може викликати це напряму після обробки базової помилки.

13.4.1.6.10. Виключення#

exception openmv.OMVException#

Базовий клас для кожної помилки рівня протоколу. Три підкласи нижче успадковують від нього, тому один except OMVException охоплює всю поверхню помилок.

exception openmv.TimeoutException#

Камера не відповіла протягом налаштованого тайм-ауту. Підклас OMVException.

exception openmv.ChecksumException#

CRC пакету не збігся. Виникає після того, як протокол вичерпав бюджет повторних спроб. Підклас OMVException.

exception openmv.SequenceException#

Пакет надійшов із неочікуваним порядковим номером після повторних спроб. Підклас OMVException.