13.4.1.6. Referenční příručka API#

Veřejné rozhraní balíčku openmv tvoří třída Camera pro komunikaci s kamerou a hierarchie OMVException pro chyby protokolu. Obě jsou zdokumentovány na této stránce.

13.4.1.6.1. Třída 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)#

Hostitelská zástupná třída (proxy) pro OpenMV kameru dosažitelnou přes USB sériové připojení.

Parametry:
  • port – Cesta k sériovému zařízení. Na Linuxu /dev/ttyACMx pro USB CDC a /dev/ttyUSBx pro převodník USB-na-UART. Na macOS /dev/tty.usbmodem... nebo /dev/cu.usbmodem.... Na Windows COMx.

  • baudrate – Přenosová rychlost (baud rate) sériové linky. Přes USB je 921600 magická hodnota, která přepne kameru z MicroPython REPL do protokolu OpenMV – jakákoli jiná hodnota na USB lince ponechá kameru v režimu REPL, takže je nutné použít výchozí hodnotu. Přes UART linku je tato hodnota skutečnou přenosovou rychlostí linky a lze ji na obou stranách volně nastavit.

  • crc – Povolí ověřování CRC u každého paketu.

  • seq – Povolí pořadová čísla u jednotlivých paketů.

  • ack – Vyžaduje potvrzení paketů.

  • events – Povolí oznámení událostí z kamery.

  • timeout – Časový limit jedné operace v sekundách.

  • max_retry – Počet opakovaných pokusů před vyvoláním výjimky u neúspěšného paketu.

  • max_payload – Maximální vyjednaná velikost užitečného obsahu (payload) v bajtech. Kamera ji může při vyjednávání snížit.

  • drop_rate – Pravděpodobnost zahození paketu pouze pro testovací účely, v rozsahu [0.0, 1.0]. V produkci ponechte 0.0.

Třída podporuje protokol kontextového správce; with Camera(port) as cam: zavolá connect() při vstupu a disconnect() při výstupu.

13.4.1.6.2. Připojení#

Camera.connect() None#

Otevře sériový port a provede handshake protokolu. Mezipaměťový stav (seznam kanálů, informace o systému, informace o verzi) je naplněn jako vedlejší efekt. Voláno automaticky kontextovým správcem.

Camera.disconnect() None#

Zavře sériový port a uvolní transportní vrstvu. Voláno automaticky při ukončení kontextového správce.

Camera.is_connected() bool#
Vrací:

True, pokud je sériový port otevřený.

Camera.reset() None#

Resetuje kameru. Připojení se přeruší, protože se kamera restartuje.

Camera.boot() None#

Přepne kameru do jejího bootloaderu. Připojení se přeruší, protože se kamera restartuje.

Camera.update_capabilities() None#

Znovu vyjedná schopnosti protokolu (CRC, kontrola pořadí, ACK, události, maximální payload) s kamerou. Kamera oznámí maximální payload, který zvládne; požadavek hostitele se na tuto hodnotu ořízne a dohodnutá nastavení se odešlou zpět. Voláno automaticky metodou connect() – není důvod jej volat z uživatelského kódu, pokud není třeba znovu vyjednat příznaky konstruktoru na již existujícím připojení.

Camera.poll_events() None#

Jednou spustí přijímací cestu transportní vrstvy, aby zpracovala případné čekající události z kamery, aniž by odeslala příkaz. Užitečné v dlouho běžících programech, které mají minuty bez jiného I/O a chtějí pohotově zachytit události registrace kanálů.

13.4.1.6.3. Spuštění skriptu#

Camera.exec(script: str) None#

Nahraje script (řetězec se zdrojovým kódem v Pythonu) do vstupního (stdin) bufferu kamery a spustí jej.

Parametry:

script – Zdrojový kód MicroPython ke spuštění.

Camera.stop() None#

Přeruší běžící skript. Ekvivalent tlačítka Stop v IDE.

Camera.read_stdout() str | None#

Přečte všechny bajty, které běžící skript zapsal do stdout od posledního volání.

Vrací:

Výstup jako dekódovaný řetězec, nebo None, pokud žádná data nečekají.

13.4.1.6.4. Streamování#

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

Zapne nebo vypne stream snímků a zvolí formát přenosu.

Parametry:
  • enableTrue povolí streamování, False jej zakáže.

  • raw – Když je False (výchozí), kamera každý snímek zkomprimuje do JPEG před vložením do streamovacího kanálu a read_frame() jej na hostiteli dekomprimuje. Když je True, kamera odešle zachycený pixelový buffer nekomprimovaný – správná volba na kamerách bez hardwarové podpory JPEG, kde je softwarová komprese nejpomalejším krokem ve smyčce.

  • resolution(width, height) cílové rozlišení, na které kamera každý surový snímek zmenší před odesláním, protože nekomprimované snímky jsou mnohem větší než snímky komprimované do JPEG. Vyžadováno při raw=True; jinak ignorováno.

Camera.read_frame() dict | None#

Přečte nejnovější snímek ze streamovacího kanálu.

Vrací:

None, pokud žádný snímek nečeká, nebo slovník s klíči width (int, pixely), height (int, pixely), format (int, identifikátor pixelového formátu, který kamera deklarovala), depth (int, velikost komprimovaného obrazu v bajtech pro snímky JPEG / PNG; nepoužívá se pro nekomprimované formáty), data (bytes, RGB888 délky width * height * 3) a raw_size (int, počet bajtů, které kamera odeslala přes USB před dekódováním).

13.4.1.6.5. Vlastní kanály#

Camera.has_channel(name: str) bool#
Vrací:

True, pokud na kameře existuje kanál registrovaný pod jménem name.

Camera.channel_size(name: str) int#
Vrací:

Počet bajtů, které má pojmenovaný kanál aktuálně k dispozici, nebo 0, když je kanál prázdný nebo neexistuje.

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

Čtení z vlastního kanálu.

Parametry:
  • name – Jméno kanálu registrované skriptem na straně kamery.

  • size – Počet bajtů ke čtení, nebo None pro přečtení všeho, co je k dispozici.

Vrací:

Bajty, nebo None, pokud kanál neexistuje.

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

Zapíše data do vlastního kanálu. Zápisy větší než payload se automaticky rozdělí do více paketů.

Parametry:
  • name – Jméno kanálu registrované skriptem na straně kamery.

  • data – Payload typu bytes-like k odeslání.

Vrací:

True, pokud kanál existuje a zápis byl odeslán, jinak False.

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

Dotáže se na každý registrovaný kanál.

Vrací:

Slovník mapující jméno kanálu na booleovskou hodnotu „data jsou připravena ke čtení“.

Camera.update_channels() None#

Obnoví mezipaměťový seznam kanálů z kamery. Spustí se automaticky při příštím vyhledání kanálu podle jména poté, co dorazí událost registrace kanálu; aplikace, která chce zjistit nově registrovaný kanál okamžitě, může toto volat přímo.

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

Vyhledá kanál buď podle jména (vrátí jeho číselné ID) nebo podle ID (vrátí jeho jméno). Nejprve obnoví mezipaměť kanálů pomocí update_channels(), pokud čekají události registrace kanálů.

Parametry:
  • name – Jméno kanálu, které se má přeložit na ID.

  • channel_id – ID kanálu, které se má přeložit na jméno.

Vrací:

Odpovídající ID nebo jméno, nebo None, když kanál neexistuje. Musí být zadáno právě jedno z name nebo channel_id.

13.4.1.6.6. Introspekce zařízení#

Camera.version() dict#

Vrátí trojice verzí protokolu, bootloaderu a firmwaru kamery. Uloženo do mezipaměti po connect(). Každá trojice je n-tice (major, minor, patch) typu int:

  • protocol_version – verze drátového protokolu OpenMV, který kamera implementuje.

  • bootloader_version – obraz bootloaderu uložený ve flash paměti.

  • firmware_version – aktuálně běžící firmware MicroPython.

Camera.system_info() dict#

Vrátí informace o hardwarových schopnostech a paměti kamery. Uloženo do mezipaměti po connect(). Klíče vráceného slovníku spadají do čtyř skupin.

Identita

  • cpu_id – 32bitový identifikátor CPU.

  • device_id – trojice 32bitových slov, jedinečné sériové číslo zařízení vypálené do křemíku.

  • chip_id – trojice 32bitových slov, jedna položka pro každý obrazový senzor připojený ke kameře.

  • usb_vid – USB vendor ID.

  • usb_pid – USB product ID.

Velikosti paměti (vše v kilobajtech)

  • flash_size_kb – celková interní flash paměť.

  • ram_size_kb – celková RAM.

  • framebuffer_size_kb – RAM vyhrazená pro zachycení obrazu.

  • stream_buffer_size_kb – RAM vyhrazená pro streamovací kanál, který posílá snímky hostiteli.

Příznaky schopností (jedna booleovská hodnota na funkci, všechny pojmenované <feature>_present)

  • gpu_present – grafická procesorová jednotka.

  • npu_present – neuronová procesorová jednotka.

  • isp_present – procesor obrazového signálu.

  • venc_present – videokodér.

  • jpeg_present – hardwarový kodér JPEG.

  • dram_present – externí DRAM.

  • crc_present – akcelerátor CRC.

  • pmu_present – jednotka pro monitorování výkonu.

  • wifi_present – Wi-Fi rádio.

  • bt_present – Bluetooth rádio.

  • sd_present – slot na SD kartu.

  • eth_present – Ethernet PHY.

  • multicore_present – více jader CPU.

Ostatní

  • usb_highspeed – booleovská hodnota, True, když se USB enumerovalo v režimu high-speed (USB 2.0 HS, 480 Mbps).

  • pmu_eventcnt – počet dostupných čítačů událostí PMU; 0, když není žádné PMU.

Camera.print_system_info() None#

Zaloguje formátovaný blok systémových informací do logging na úrovni INFO. CLI to používá při připojení.

13.4.1.6.7. Diagnostika#

Camera.host_stats() dict#
Vrací:

Čítače transportní vrstvy sledované na straně hostitele: sent, received, checksum, sequence.

Camera.device_stats() dict#
Vrací:

Čítače transportní vrstvy sledované na straně kamery: sent, received, checksum, sequence, retransmit, transport, sent_events, max_ack_queue_depth.

13.4.1.6.8. Profiler#

Profiler hlásí počty volání jednotlivých funkcí a minimální / maximální / celkové doby provádění pro instrumentované moduly firmwaru – aktuálně image, ml a ulab. Vstup a výstup funkcí jsou zachyceny při kompilaci; běhové prostředí na každém z nich navzorkuje monotónní mikrosekundový čítač, akumuluje výsledek pro každou funkci a zpřístupňuje tabulku hostiteli prostřednictvím kanálu profile.

Profiler je do firmwaru zabudován pouze tehdy, když je do make předáno PROFILE_ENABLE=1. Standardní obrazy firmwaru jej neobsahují – příznak -finstrument-functions, který sestavení přidává ke sledovaným modulům, má nezanedbatelnou běhovou režii, takže profilovací sestavení se vyrábějí ze zdrojového kódu pro konkrétní ladicí relaci, která je potřebuje. Když firmware nebyl s tímto příznakem sestaven, kanál profile se neregistruje a každá metoda profileru na této stránce se tiše vrátí, aniž by cokoli udělala.

Arm Performance Monitoring Unit (PMU) je blok hardwarových čítačů procesoru Cortex-M55 – malá sada konfigurovatelných čítačů, které sledují počty cyklů, zásahy a chyby cache, chování větvení a další architekturou definované události, aniž by zpomalovaly měřený kód. Na kamerách, které jej mají – AE3 a N6, dvě kamery v sortimentu OpenMV postavené kolem M55 – profiler navzorkuje tyto čítače spolu s časovými údaji a souhrny událostí se objeví v každém záznamu jednotlivé funkce. Kamery bez PMU stále produkují časové záznamy; pole událostí se vracejí jako nula a profiler_event() nemá žádný efekt.

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

Přepíná mezi inkluzivním a exkluzivním měřením času. Inkluzivní měření přičítá čas volaných funkcí volajícímu; exkluzivní měření nikoli.

Parametry:

exclusiveTrue zvolí exkluzivní měření, False zvolí inkluzivní.

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

Vynuluje všechny čítače profileru. config=None také obnoví výchozí přiřazení událostí PMU.

Parametry:

config – Rezervováno pro budoucí konfigurační přepisy jednotlivých čítačů. Předejte None pro zachování výchozích hodnot.

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

Přiřadí jeden ze slotů čítačů PMU ke konkrétní hardwarové události.

Parametry:
  • counter_num – Index čítače.

  • event_id – Architekturou definovaný identifikátor události.

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

Vrátí záznamy profilu jednotlivých funkcí shromážděné od posledního resetu. Každý záznam je slovník s address, caller, call_count, min_ticks, max_ticks, total_ticks, total_cycles a n-ticí events o velikosti odpovídající pmu_eventcnt kamery.

Vrací:

Seznam slovníků se záznamy, nebo None, pokud profilovací kanál není dostupný nebo nebyla shromážděna žádná data.

13.4.1.6.9. Vytváření podtříd a interní mechanismy kanálů#

Výše zdokumentované metody pokrývají každé běžné použití balíčku. Několik vzorů – zpracování událostí na straně kamery, na které chce hostitel reagovat, uzamčení kanálu pro vícekrokovou výměnu, komunikace s kanály, které nesou strukturovaná data místo bajtových streamů, nebo řízení příkazů specifických pro kanál – vyžaduje metody, které Camera udržuje s prefixem podtržítka. Tato jména jsou soukromá podle konvence (Python na ně neaplikuje name-mangling) a od aplikací, které je potřebují, se očekává, že buď vytvoří podtřídu Camera, nebo budou metody volat přímo.

Vytvoření podtřídy pro reakci na události. Každá událost, kterou kamera vyšle, dorazí přes Camera._handle_event(). Vytvoření podtřídy Camera a přepsání této metody je způsob, jak aplikace reaguje na události vyvolané jejím skriptem na straně kamery; stránka Události provádí celým vzorem.

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

Zpracuje jednu událost z kamery. Voláno transportní vrstvou, kdykoli dorazí paket s událostí. Přepište v podtřídě pro přidání zpracování specifického pro aplikaci; zavolejte super()._handle_event(...) pro zachování výchozího chování (obnova seznamu kanálů při CHANNEL_REGISTERED, sledování připravenosti snímku na kanálu stream, logování spuštění / zastavení kanálu stdin).

Parametry:
  • channel_id0 pro systémové události, jinak ID registrovaného kanálu.

  • event – Identifikátor události; hodnoty pocházejí z výčtu EventType pro systémové události a z čehokoli, co backend kanálu na straně kamery zvolil pro události kanálu.

Podtřída, která přidává své vlastní metody komunikující s protokolem, by je měla ozdobit dekorátorem retry_if_failed(), aby zdědily stejné chování resynchronizace a opakování, jaké má každá dodávaná metoda na této stránce.

static Camera.retry_if_failed(func)#

Dekorátor. Obalí instanční metodu tak, aby jednou zopakovala pokus, když transport vyvolá ResyncException. Každá metoda, která volá _send_cmd_wait_resp() (přímo nebo přes některou z obálek _channel_*), by měla nést tento dekorátor:

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

Uzamčení kanálu zajišťuje, že se stav kanálu mezi dvěma souvisejícími operacemi nezmění (například _channel_size() následované _channel_read() na kanálu, který stále přidává data). read_frame() a read_profile() to používají interně; aplikace řídící vlastní kanál s vícekrokovým přístupem dělá totéž.

Camera._channel_lock(channel_id: int) bool#

Získá exkluzivní zámek na kanál. Ostatní hostitelské operace na témže kanálu se zablokují, dokud není zámek uvolněn.

Parametry:

channel_id – Číselné ID kanálu, obvykle získané pomocí get_channel().

Vrací:

True, když byl zámek udělen.

Camera._channel_unlock(channel_id: int) bool#

Uvolní zámek dříve získaný pomocí _channel_lock(). Vždy se páruje s voláním zámku; použijte try / finally, abyste zajistili, že k odemčení dojde i tehdy, když čtení mezi nimi vyvolá výjimku.

Parametry:

channel_id – Číselné ID kanálu, obvykle získané pomocí get_channel().

Strukturované kanály nesou strukturované záznamy spíše než plochý bajtový stream. Profilovací kanál je dodávaný příklad: jeho tvar je (record_count, record_size) a hostitel, který chce zjistit, kolik záznamů čeká, čte tvar místo velikosti v bajtech.

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

Přečte deskriptor tvaru kanálu.

Parametry:

channel_id – Číselné ID kanálu, obvykle získané pomocí get_channel().

Vrací:

N-tice 32bitových celých čísel bez znaménka popisujících rozvržení kanálu. Význam je specifický pro daný kanál.

Řídicí příkazy specifické pro kanál – start, stop, reset, configure – jsou přenášeny přes jediný opcode (CHANNEL_IOCTL) s číslem příkazu specifickým pro kanál a volitelným payloadem struct.pack. Dodávané metody jako stop(), exec() a streaming() jsou tenké obálky kolem volání _channel_ioctl() vůči kanálům stdin a stream; vlastní kanál na straně kamery, který definuje svou vlastní nabídku ioctl, se řídí stejným způsobem.

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

Vydá příkaz ioctl na kanálu.

Parametry:
  • channel_id – Číselné ID kanálu, obvykle získané pomocí get_channel().

  • cmd – Číslo příkazu definované backendem kanálu na straně kamery.

  • fmt – Volitelný formátovací řetězec struct pro n-tici argumentů. Předejte None pro ioctl příkazy, které nepřijímají žádné argumenty.

  • args – Hodnoty odpovídající fmt.

Vrací:

Jakýkoli payload, který kanál vrátil, nebo None.

Varianty bajtového streamu podle ID veřejných metod kanálu přeskakují vyhledání ID podle jména a přijímají explicitní bajtový offset – užitečné pro čtení bloku ze středu velkého bufferu (například záznamy kanálu profile).

Camera._channel_size(channel_id: int) int#
Parametry:

channel_id – Číselné ID kanálu, obvykle získané pomocí get_channel().

Vrací:

Bajty aktuálně dostupné na kanálu.

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

Přečte length bajtů počínaje od offset. Vícepaketová čtení se automaticky znovu složí.

Parametry:
  • channel_id – Číselné ID kanálu, obvykle získané pomocí get_channel().

  • offset – Bajtový offset, od kterého se má začít číst.

  • length – Počet bajtů ke čtení.

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

Zapíše data na daný offset. Vícepaketové zápisy se automaticky rozdělí do paketů.

Parametry:
  • channel_id – Číselné ID kanálu, obvykle získané pomocí get_channel().

  • data – Payload typu bytes-like k zápisu.

  • offset – Bajtový offset, od kterého se má začít zapisovat.

Primitiva protokolu jsou nejnižší úroveň, kterou třída zpřístupňuje – záznamy pro syrové odeslání příkazu, načtení syrového seznamu kanálů a ruční resynchronizaci, na kterých je vše výše nakonec postaveno. Aplikace po nich sáhne, když odesílá opcode, který třída ještě neobaluje, nebo když implementuje vlastní obnovu v podtřídě.

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

Odešle příkaz protokolu a počká na odpověď kamery. Primitivum, na kterém je postavena každá další metoda v této sekci.

Parametry:
  • opcode – Číslo příkazu. Dodávaný výčet Opcode uvádí kódy, se kterými se firmware dodává, ale tento parametr je jen celé číslo – vlastní sestavení firmwaru může definovat a odpovídat na své vlastní.

  • channel – ID kanálu, nebo 0 pro systémové příkazy.

  • data – Payload specifický pro příkaz.

Vrací:

Payload odpovědi, nebo None pro příkazy jako Opcode.SYS_RESET a Opcode.SYS_BOOT, které přeruší připojení.

Camera._channel_list() dict#

Načte aktuální seznam kanálů z kamery bez dotčení mezipaměťových slovníků channels_by_id a channels_by_name, které naplňuje update_channels(). Užitečné pro podtřídu, která chce zkoumat stav kanálů kamery přímo.

Vrací:

Slovník mapující ID kanálu na {'name': str, 'flags': int}.

Camera._resync() None#

Spustí handshake protokolu znovu od začátku. Voláno automaticky metodou connect() při počátečním připojení a každou veřejnou metodou, která zachytí OMVException z transportu. Aplikace implementující vlastní smyčku obnovy v podtřídě může toto volat přímo po zpracování základní chyby.

13.4.1.6.10. Výjimky#

exception openmv.OMVException#

Základní třída pro každou chybu na úrovni protokolu. Tři níže uvedené podtřídy z ní všechny dědí, takže jediné except OMVException pokrývá celou plochu chyb.

exception openmv.TimeoutException#

Kamera neodpověděla v rámci nakonfigurovaného časového limitu. Podtřída OMVException.

exception openmv.ChecksumException#

CRC paketu se neshodovalo. Vyvoláno poté, co protokol vyčerpal svůj rozpočet na opakování. Podtřída OMVException.

exception openmv.SequenceException#

Paket dorazil s neočekávaným pořadovým číslem po opakovaných pokusech. Podtřída OMVException.