13.3.1.6. API リファレンス

openmv パッケージの公開インターフェイスは、カメラと通信するための Camera クラスと、プロトコルエラーを扱う OMVException の階層です。どちらもこのページで解説します。

13.3.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)

USB シリアル経由で接続された OpenMV カメラに対するホスト側のプロキシです。

パラメータ:
  • port -- シリアルデバイスのパスです。Linux では、USB CDC の場合は /dev/ttyACMx、USB-UART ブリッジの場合は /dev/ttyUSBx です。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.3.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.3.1.6.3. スクリプトの実行

Camera.exec(script: str) None

script(Python ソースコードの文字列)をカメラの stdin バッファにアップロードし、実行を開始します。

パラメータ:

script -- 実行する MicroPython ソースコードです。

Camera.stop() None

実行中のスクリプトを中断します。IDE の Stop ボタンと同等です。

Camera.read_stdout() str | None

実行中のスクリプトが前回の呼び出し以降に stdout へ書き込んだバイト列をすべて読み取ります。

戻り値:

デコードされた文字列としての出力、または待機中のデータがない場合は None です。

13.3.1.6.4. ストリーミング

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

フレームストリームのオン・オフを切り替え、転送時のフォーマットを選択します。

パラメータ:
  • enable -- True でストリーミングを有効化し、False で無効化します。

  • raw -- False(デフォルト)の場合、カメラは各フレームをストリームチャネルに置く前に JPEG 圧縮し、read_frame() がホスト側で展開します。True の場合、カメラはキャプチャしたピクセルバッファを非圧縮で送信します。これは、ハードウェア JPEG をサポートしないカメラ(ソフトウェア圧縮がループ内で最も遅い処理となる)に適した選択肢です。

  • resolution -- 非圧縮フレームは JPEG 圧縮フレームよりもはるかに大きくなるため、送信前にカメラが各 raw フレームを縮小する対象となる (width, height) です。raw=True の場合は必須であり、それ以外の場合は無視されます。

Camera.read_frame() dict | None

ストリームチャネルから最新のフレームを読み取ります。

戻り値:

待機中のフレームがない場合は None、それ以外の場合は次のキーを持つ辞書です。widthint、ピクセル単位)、heightint、ピクセル単位)、formatint、カメラが宣言したピクセルフォーマット識別子)、depthint、JPEG / PNG フレームの圧縮画像サイズ(バイト単位)。非圧縮フォーマットでは未使用)、databytes、長さ width * height * 3 の RGB888)、raw_sizeint、デコード前にカメラが USB 経由で送信したバイト数)。

13.3.1.6.5. カスタムチャネル

Camera.has_channel(name: str) bool
戻り値:

name で登録されたチャネルがカメラ上に存在する場合は True です。

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.3.1.6.6. デバイスのイントロスペクション

Camera.version() dict

カメラのプロトコル、ブートローダー、ファームウェアのバージョンの3つ組を返します。connect() の後にキャッシュされます。各3つ組は int(major, minor, patch) タプルです。

  • protocol_version -- カメラが実装している OpenMV ワイヤプロトコルのバージョンです。

  • bootloader_version -- フラッシュに常駐するブートローダーイメージです。

  • firmware_version -- 現在実行中の MicroPython ファームウェアです。

Camera.system_info() dict

カメラのハードウェア機能とメモリ情報を返します。connect() の後にキャッシュされます。返される辞書のキーは4つのグループに分かれます。

識別情報

  • cpu_id -- 32ビットの CPU 識別子です。

  • device_id -- 32ビットワード3つのタプルで、シリコンに刻まれた一意のデバイスシリアルです。

  • chip_id -- 32ビットワード3つのタプルで、カメラに接続された各イメージセンサーにつき1エントリです。

  • usb_vid -- USB ベンダー ID です。

  • usb_pid -- USB プロダクト ID です。

メモリサイズ(すべてキロバイト単位)

  • flash_size_kb -- 内部フラッシュの総容量です。

  • ram_size_kb -- RAM の総容量です。

  • framebuffer_size_kb -- 画像キャプチャ用に予約された RAM です。

  • stream_buffer_size_kb -- フレームをホストへ転送するストリームチャネル用に予約された RAM です。

機能フラグ(機能ごとに1つのブール値で、すべて <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 -- イーサネット PHY です。

  • multicore_present -- 複数の CPU コアです。

その他

  • usb_highspeed -- ブール値で、USB がハイスピード(USB 2.0 HS、480 Mbps)モードで列挙された場合は True です。

  • pmu_eventcnt -- 利用可能な PMU イベントカウンタの数です。PMU がない場合は 0 です。

Camera.print_system_info() None

整形されたシステム情報ブロックを loggingINFO レベルで出力します。CLI は接続時にこれを使用します。

13.3.1.6.7. 診断

Camera.host_stats() dict
戻り値:

ホスト側で追跡されるトランスポート層のカウンタです。sentreceivedchecksumsequence

Camera.device_stats() dict
戻り値:

カメラ側で追跡されるトランスポート層のカウンタです。sentreceivedchecksumsequenceretransmittransportsent_eventsmax_ack_queue_depth

13.3.1.6.8. プロファイラ

プロファイラは、計測対象のファームウェアモジュール(現在は imagemlulab)について、関数ごとの呼び出し回数と最小 / 最大 / 合計の実行時間を報告します。関数の入口と出口はコンパイル時にインターセプトされ、ランタイムはそれぞれで単調増加するマイクロ秒カウンタをサンプリングし、関数ごとに結果を蓄積して、profile チャネルを介してそのテーブルをホストに公開します。

プロファイラは、makePROFILE_ENABLE=1 を渡した場合にのみファームウェアに組み込まれます。標準のファームウェアイメージには含まれていません。ビルドが計測対象モジュールに追加する -finstrument-functions フラグには無視できないランタイムオーバーヘッドがあるため、プロファイリング用ビルドは、それを必要とする特定のデバッグセッションのためにソースから生成されます。ファームウェアがこのフラグなしでビルドされた場合、profile チャネルは登録されず、このページのすべてのプロファイラメソッドは何もせずに静かに復帰します。

Arm の パフォーマンスモニタリングユニット(PMU)は、Cortex-M55 のハードウェアカウンタブロックです。これは、測定対象のコードを遅くすることなく、サイクル数、キャッシュのヒットとミス、分岐の挙動、その他アーキテクチャ定義のイベントを追跡する、構成可能なカウンタの小さなセットです。これを備えたカメラ(AE3 と N6 という、OpenMV ラインナップで M55 を中心に構築された2つのカメラ)では、プロファイラはタイミングデータと並行してこれらのカウンタをサンプリングし、イベント合計が関数ごとのレコードに現れます。PMU を持たないカメラでもタイミングレコードは生成されますが、イベントフィールドはゼロで返され、profiler_event() は何もしません。

Camera.profiler_mode(exclusive: bool = False) None

インクルーシブタイミングとエクスクルーシブタイミングを切り替えます。インクルーシブタイミングは呼び出された関数の時間を呼び出し元に計上し、エクスクルーシブタイミングは計上しません。

パラメータ:

exclusive -- True はエクスクルーシブタイミングを、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 カウンタスロットの1つを特定のハードウェアイベントにバインドします。

パラメータ:
  • counter_num -- カウンタのインデックスです。

  • event_id -- アーキテクチャ定義のイベント識別子です。

Camera.read_profile() list[dict] | None

前回のリセット以降に収集された関数ごとのプロファイルレコードを返します。各レコードは、addresscallercall_countmin_ticksmax_tickstotal_tickstotal_cycles、およびカメラの pmu_eventcnt に合わせたサイズの events タプルを持つ辞書です。

戻り値:

レコード辞書のリスト、またはプロファイルチャネルが利用できないかデータが収集されていない場合は None です。

13.3.1.6.9. サブクラス化とチャネルの内部構造

上記のメソッドは、このパッケージのあらゆる一般的な使用方法をカバーしています。いくつかのパターン(ホストが反応したいカメラ側イベントの処理、複数ステップのやり取りのためのチャネルのロック、バイトストリームの代わりに構造化データを運ぶチャネルとの通信、チャネル固有の制御コマンドの実行)では、Camera がアンダースコアを前置して保持するメソッドが必要です。これらの名前は 慣例として プライベートです(Python はそれらを名前マングルしません)。これらを必要とするアプリケーションは、Camera をサブクラス化するか、メソッドを直接呼び出すことが想定されています。

イベントに反応するためのサブクラス化。 カメラが発するすべてのイベントは Camera._handle_event() を通じて到着します。Camera をサブクラス化してこのメソッドをオーバーライドすることが、アプリケーションがカメラ側スクリプトの送出するイベントに反応する方法です。イベント ページでこのパターン全体を解説しています。

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

カメラからの1つのイベントをディスパッチします。イベントパケットが到着するたびにトランスポート層によって呼び出されます。サブクラスでオーバーライドしてアプリケーション固有の処理を追加してください。デフォルトの動作(CHANNEL_REGISTERED 時のチャネルリスト更新、stream チャネルでのフレーム準備完了追跡、stdin チャネルの開始 / 停止ログ記録)を維持するには super()._handle_event(...) を呼び出してください。

パラメータ:
  • channel_id -- システムイベントの場合は 0、それ以外の場合は登録されたチャネル ID です。

  • event -- イベント識別子です。システムイベントの値は EventType 列挙型に由来し、チャネルイベントの値はカメラ側チャネルバックエンドが選択したものに由来します。

独自のプロトコル通信メソッドを追加するサブクラスは、それらを retry_if_failed() でデコレートして、このページのすべての出荷メソッドと同じ再同期およびリトライの動作を継承させるべきです。

static Camera.retry_if_failed(func)

デコレータです。インスタンスメソッドをラップし、トランスポートが ResyncException を送出した際に一度リトライするようにします。_send_cmd_wait_resp() を(直接または _channel_* ラッパーの1つを介して)呼び出すメソッドは、このデコレータを付けるべきです:

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

チャネルのロック は、関連する2つの操作(たとえば、データを追加し続けるチャネルでの _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() といった出荷メソッドは、stdin および stream チャネルに対する _channel_ioctl() 呼び出しの薄いラッパーです。独自の 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 フォーマット文字列です。引数を取らない ioctl の場合は None を渡してください。

  • 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

offset から開始して length バイトを読み取ります。複数パケットの読み取りは自動的に再構成されます。

パラメータ:
  • channel_id -- 数値のチャネル ID で、通常は get_channel() で解決します。

  • offset -- 読み取りを開始するバイトオフセットです。

  • length -- 読み取るバイト数です。

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

指定した offsetdata を書き込みます。複数パケットの書き込みは自動的にパケットに分割されます。

パラメータ:
  • channel_id -- 数値のチャネル ID で、通常は get_channel() で解決します。

  • data -- 書き込むバイト列状のペイロードです。

  • offset -- 書き込みを開始するバイトオフセットです。

プロトコルプリミティブ は、このクラスが公開する最下層です。生のコマンド送信、生のチャネルリスト取得、手動再同期のエントリで、上記のすべてが最終的にこれらの上に構築されています。クラスがまだラップしていないオペコードを送信する場合や、サブクラスでカスタムリカバリを実装する場合に、アプリケーションはこれらを使用します。

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

プロトコルコマンドを送信し、カメラの応答を待ちます。このセクションの他のすべてのメソッドが構築されている基盤となるプリミティブです。

パラメータ:
  • opcode -- コマンド番号です。出荷されている Opcode 列挙型はファームウェアに同梱されているコードを列挙していますが、このパラメータは単なる整数です。カスタムファームウェアビルドは独自のコードを定義して応答できます。

  • channel -- チャネル ID、またはシステムコマンドの場合は 0 です。

  • data -- コマンド固有のペイロードです。

戻り値:

応答ペイロード、または接続を切断する Opcode.SYS_RESETOpcode.SYS_BOOT のようなコマンドの場合は None です。

Camera._channel_list() dict

update_channels() が設定するキャッシュ済みの channels_by_id および channels_by_name 辞書に触れずに、カメラから現在のチャネルリストを取得します。カメラのチャネル状態を直接調べたいサブクラスに便利です。

戻り値:

チャネル ID を {'name': str, 'flags': int} にマッピングした辞書です。

Camera._resync() None

プロトコルハンドシェイクを最初からやり直します。初回接続時に connect() によって、また、トランスポートからの OMVException をキャッチするすべての公開メソッドによって、自動的に呼び出されます。サブクラスで独自のリカバリループを実装するアプリケーションは、根本的なエラーを処理した後にこれを直接呼び出すことができます。

13.3.1.6.10. 例外

exception openmv.OMVException

すべてのプロトコルレベルエラーの基底クラスです。下記の3つのサブクラスはすべてこれを継承するため、単一の except OMVException でエラー全体をカバーできます。

exception openmv.TimeoutException

設定されたタイムアウト内にカメラが応答しませんでした。OMVException のサブクラスです。

exception openmv.ChecksumException

パケットの CRC が一致しませんでした。プロトコルがリトライ回数を使い果たした後に送出されます。OMVException のサブクラスです。

exception openmv.SequenceException

リトライ後、予期しないシーケンス番号を持つパケットが到着しました。OMVException のサブクラスです。