13.3.1.6. Riferimento API¶
La superficie pubblica del pacchetto openmv è costituita dalla classe Camera per comunicare con una cam e dalla gerarchia OMVException per gli errori di protocollo. Entrambe sono documentate in questa pagina.
13.3.1.6.1. La classe 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)¶
Il proxy lato host per una cam OpenMV raggiunta tramite seriale USB.
- Parametri:
port – Percorso del dispositivo seriale. Su Linux,
/dev/ttyACMxper USB CDC e/dev/ttyUSBxper un ponte USB-to-UART. Su macOS,/dev/tty.usbmodem...o/dev/cu.usbmodem.... Su Windows,COMx.baudrate – Baud rate seriale. Su USB,
921600è il valore magico che fa passare la cam dal REPL di MicroPython al protocollo OpenMV – qualsiasi altro valore su un collegamento USB lascia la cam in modalità REPL, quindi è necessario usare il valore predefinito. Su un collegamento UART il valore è il baud rate effettivo della linea e può essere impostato liberamente su entrambi i lati.crc – Abilita la validazione CRC su ogni pacchetto.
seq – Abilita i numeri di sequenza per ogni pacchetto.
ack – Richiede la conferma di ricezione dei pacchetti.
events – Abilita le notifiche di eventi dalla cam.
timeout – Timeout per operazione, in secondi.
max_retry – Numero di tentativi prima di sollevare un’eccezione su un pacchetto fallito.
max_payload – Dimensione massima negoziata del payload in byte. La cam può negoziare un valore inferiore.
drop_rate – Probabilità, solo per test, di scartare un pacchetto, in
[0.0, 1.0]. Lasciare a0.0in produzione.
La classe supporta il protocollo del context manager;
with Camera(port) as cam:chiamaconnect()all’ingresso edisconnect()all’uscita.
13.3.1.6.2. Connessione¶
- Camera.connect() None¶
Apre la porta seriale ed esegue l’handshake del protocollo. Lo stato memorizzato in cache (elenco dei canali, informazioni di sistema, informazioni sulla versione) viene popolato come effetto collaterale. Chiamato automaticamente dal context manager.
- Camera.disconnect() None¶
Chiude la porta seriale e rilascia il trasporto. Chiamato automaticamente all’uscita dal context manager.
- Camera.boot() None¶
Fa entrare la cam nel suo bootloader. La connessione viene interrotta perché la cam si riavvia.
- Camera.update_capabilities() None¶
Rinegozia le capacità del protocollo (CRC, controllo della sequenza, ACK, eventi, payload massimo) con la cam. La cam comunica il payload massimo che può gestire; la richiesta dell’host viene limitata a tale valore e le impostazioni concordate vengono rinviate. Chiamato automaticamente da
connect()– non c’è motivo di chiamarlo dal codice utente, a meno che i flag del costruttore non debbano essere rinegoziati su una connessione esistente.
- Camera.poll_events() None¶
Esegue una volta il percorso di ricezione del trasporto per consumare eventuali eventi in sospeso dalla cam senza inviare un comando. Utile in programmi di lunga durata che restano per minuti senza altro I/O e vogliono far emergere prontamente gli eventi di registrazione dei canali.
13.3.1.6.3. Esecuzione di script¶
13.3.1.6.4. Streaming¶
- Camera.streaming(enable: bool, raw: bool = False, resolution: tuple[int, int] | None = None) None¶
Attiva o disattiva lo stream dei frame e sceglie il formato sul filo.
- Parametri:
enable –
Trueabilita lo streaming,Falselo disabilita.raw – Quando è
False(predefinito), la cam comprime in JPEG ogni frame prima di inserirlo nel canale dello stream eread_frame()lo decomprime sull’host. Quando èTrue, la cam invia il buffer di pixel acquisito non compresso – la scelta giusta su cam senza supporto JPEG hardware, dove la compressione software è il passo più lento del ciclo.resolution –
(width, height)di destinazione a cui la cam riduce in scala ogni frame grezzo prima dell’invio, dato che i frame non compressi sono molto più grandi di quelli compressi in JPEG. Obbligatorio quandoraw=True; ignorato altrimenti.
- Camera.read_frame() dict | None¶
Legge l’ultimo frame dal canale dello stream.
- Ritorna:
Nonese nessun frame è in attesa, oppure un dict con le chiaviwidth(int, pixel),height(int, pixel),format(int, l’identificatore di formato pixel dichiarato dalla cam),depth(int, la dimensione dell’immagine compressa in byte per i frame JPEG / PNG; non utilizzato per i formati non compressi),data(bytes, RGB888 di lunghezzawidth * height * 3) eraw_size(int, byte inviati dalla cam su USB prima della decodifica).
13.3.1.6.5. Canali personalizzati¶
- Camera.has_channel(name: str) bool¶
- Ritorna:
Truese sulla cam esiste un canale registrato conname.
- Camera.channel_size(name: str) int¶
- Ritorna:
Numero di byte attualmente disponibili sul canale indicato, oppure
0quando il canale è vuoto o non esiste.
- Camera.channel_read(name: str, size: int | None = None) bytes | None¶
Legge da un canale personalizzato.
- Camera.channel_write(name: str, data: bytes) bool¶
Scrive
datasu un canale personalizzato. Le scritture più grandi del payload vengono automaticamente suddivise su più pacchetti.- Parametri:
name – Nome del canale registrato dallo script lato cam.
data – Payload di tipo bytes-like da inviare.
- Ritorna:
Truese il canale esiste e la scrittura è stata inviata,Falsealtrimenti.
- Camera.read_status() dict[str, bool]¶
Interroga ogni canale registrato.
- Ritorna:
Dict che mappa il nome del canale a un booleano che indica «i dati sono pronti per la lettura».
- Camera.update_channels() None¶
Aggiorna l’elenco dei canali memorizzato in cache dalla cam. Viene eseguito automaticamente alla successiva ricerca di un canale per nome dopo l’arrivo di un evento di registrazione di un canale; un’applicazione che vuole conoscere immediatamente un canale appena registrato può chiamarlo direttamente.
- Camera.get_channel(name: str | None = None, channel_id: int | None = None) int | str | None¶
Cerca un canale per nome (restituendo il suo ID numerico) oppure per ID (restituendo il suo nome). Aggiorna prima la cache dei canali tramite
update_channels()se ci sono eventi di registrazione di canali in sospeso.- Parametri:
name – Nome del canale da risolvere in un ID.
channel_id – ID del canale da risolvere in un nome.
- Ritorna:
L’ID o il nome corrispondente, oppure
Nonequando il canale non esiste. Deve essere fornito uno tranameechannel_id.
13.3.1.6.6. Introspezione del dispositivo¶
- Camera.version() dict¶
Restituisce le terne di versione di protocollo, bootloader e firmware della cam. Memorizzate in cache dopo
connect(). Ogni terna è una tupla(major, minor, patch)diint:protocol_version– la versione del protocollo OpenMV sul filo implementata dalla cam.bootloader_version– l’immagine del bootloader residente in flash.firmware_version– il firmware MicroPython attualmente in esecuzione.
- Camera.system_info() dict¶
Restituisce le informazioni sulle capacità hardware e sulla memoria della cam. Memorizzate in cache dopo
connect(). Le chiavi del dict restituito ricadono in quattro gruppi.Identità
cpu_id– identificatore della CPU a 32 bit.device_id– tupla di 3 parole a 32 bit, il numero di serie univoco del dispositivo inciso nel silicio.chip_id– tupla di 3 parole a 32 bit, una voce per ogni sensore di immagine collegato alla cam.usb_vid– USB vendor ID.usb_pid– USB product ID.
Dimensioni di memoria (tutte in kilobyte)
flash_size_kb– flash interna totale.ram_size_kb– RAM totale.framebuffer_size_kb– RAM riservata all’acquisizione di immagini.stream_buffer_size_kb– RAM riservata al canale dello stream che invia i frame all’host.
Flag di capacità (un booleano per funzionalità, tutti denominati
<feature>_present)gpu_present– unità di elaborazione grafica.npu_present– unità di elaborazione neurale.isp_present– processore di segnale immagine.venc_present– encoder video.jpeg_present– encoder JPEG hardware.dram_present– DRAM esterna.crc_present– acceleratore CRC.pmu_present– unità di monitoraggio delle prestazioni.wifi_present– radio Wi-Fi.bt_present– radio Bluetooth.sd_present– slot per scheda SD.eth_present– PHY Ethernet.multicore_present– più core CPU.
Altro
usb_highspeed– booleano,Truequando USB ha enumerato in modalità high-speed (USB 2.0 HS, 480 Mbps).pmu_eventcnt– numero di contatori di eventi PMU disponibili;0quando non è presente alcuna PMU.
13.3.1.6.7. Diagnostica¶
13.3.1.6.8. Profiler¶
Il profiler riporta i conteggi delle chiamate per funzione e i tempi di esecuzione minimo / massimo / totale per i moduli del firmware strumentati – attualmente image, ml e ulab. L’ingresso e l’uscita dalle funzioni vengono intercettati al momento della compilazione; il runtime campiona un contatore monotono in microsecondi a ciascuno, accumula il risultato per funzione ed espone la tabella all’host attraverso il canale profile.
Il profiler viene incluso nel firmware solo quando a make viene passato PROFILE_ENABLE=1. Le immagini firmware di serie non lo includono – il flag -finstrument-functions che la build aggiunge ai moduli tracciati ha un sovraccarico di runtime non trascurabile, quindi le build con profilazione vengono prodotte dai sorgenti per la specifica sessione di debug che ne ha bisogno. Quando il firmware non è stato compilato con il flag, il canale profile non viene registrato e ogni metodo del profiler in questa pagina ritorna silenziosamente senza fare nulla.
L’Arm Performance Monitoring Unit (PMU) è il blocco di contatori hardware del Cortex-M55 – un piccolo insieme di contatori configurabili che tracciano conteggi di cicli, hit e miss della cache, comportamento dei branch e altri eventi definiti dall’architettura senza rallentare il codice sotto misurazione. Sulle cam che ne dispongono – la AE3 e la N6, le due cam della gamma OpenMV costruite attorno all’M55 – il profiler campiona questi contatori insieme ai dati di temporizzazione e i totali degli eventi compaiono in ogni record per funzione. Le cam senza PMU producono comunque record di temporizzazione; i campi degli eventi tornano a zero e profiler_event() non ha effetto.
- Camera.profiler_mode(exclusive: bool = False) None¶
Passa dalla temporizzazione inclusiva a quella esclusiva e viceversa. La temporizzazione inclusiva addebita al chiamante il tempo dei chiamati; quella esclusiva no.
- Parametri:
exclusive –
Trueseleziona la temporizzazione esclusiva,Falseseleziona quella inclusiva.
- Camera.profiler_reset(config: list | None = None) None¶
Azzera tutti i contatori del profiler.
config=Noneripristina anche l’assegnazione predefinita degli eventi PMU.- Parametri:
config – Riservato a future sovrascritture di configurazione per singolo contatore. Passare
Noneper mantenere i valori predefiniti.
- Camera.profiler_event(counter_num: int, event_id: int) None¶
Associa uno degli slot di contatore PMU a un evento hardware specifico.
- Parametri:
counter_num – Indice del contatore.
event_id – Identificatore di evento definito dall’architettura.
- Camera.read_profile() list[dict] | None¶
Restituisce i record di profilo per funzione raccolti dall’ultimo reset. Ogni record è un dict con
address,caller,call_count,min_ticks,max_ticks,total_ticks,total_cyclese una tuplaeventsdimensionata in base alpmu_eventcntdella cam.- Ritorna:
Elenco di dict record, oppure
Nonese il canale del profiler non è disponibile o non sono stati raccolti dati.
13.3.1.6.9. Sottoclassi e dettagli interni dei canali¶
I metodi documentati sopra coprono ogni uso comune del pacchetto. Alcuni pattern – gestire eventi lato cam a cui l’host vuole reagire, bloccare un canale per uno scambio in più passi, comunicare con canali che trasportano dati strutturati invece di flussi di byte, o pilotare comandi di controllo specifici di un canale – richiedono metodi che Camera mantiene prefissati con un underscore. Questi nomi sono privati per convenzione (Python non li sottopone a name-mangling) e le applicazioni che ne hanno bisogno dovrebbero o derivare da Camera tramite sottoclasse o chiamare i metodi direttamente.
Sottoclassi per reagire agli eventi. Ogni evento emesso dalla cam arriva tramite Camera._handle_event(). Derivare da Camera tramite sottoclasse e sovrascrivere il metodo è il modo in cui un’applicazione reagisce agli eventi sollevati dal suo script lato cam; la pagina Eventi illustra il pattern completo.
- Camera._handle_event(channel_id: int, event: int) None¶
Smista un evento dalla cam. Chiamato dal livello di trasporto ogni volta che arriva un pacchetto di evento. Sovrascriverlo in una sottoclasse per aggiungere una gestione specifica dell’applicazione; chiamare
super()._handle_event(...)per mantenere il comportamento predefinito (aggiornamento dell’elenco dei canali suCHANNEL_REGISTERED, tracciamento della disponibilità dei frame sul canalestream, logging di avvio / arresto del canalestdin).- Parametri:
channel_id –
0per gli eventi di sistema, altrimenti l’ID del canale registrato.event – Identificatore dell’evento; i valori provengono dall’enum
EventTypeper gli eventi di sistema e da qualsiasi cosa abbia scelto il backend del canale lato cam per gli eventi di canale.
Una sottoclasse che aggiunge i propri metodi di comunicazione con il protocollo dovrebbe decorarli con retry_if_failed() in modo che ereditino lo stesso comportamento di risincronizzazione e ritentativo di ogni metodo distribuito in questa pagina.
- static Camera.retry_if_failed(func)¶
Decoratore. Avvolge un metodo di istanza in modo che riprovi una volta quando il trasporto solleva
ResyncException. Qualsiasi metodo che chiama_send_cmd_wait_resp()(direttamente o tramite uno dei wrapper_channel_*) dovrebbe portare questo decoratore:class MyCamera(Camera): @Camera.retry_if_failed def my_custom_command(self, payload): return self._send_cmd_wait_resp(Opcode.MY_CMD, 0, payload)
Il blocco dei canali garantisce che lo stato del canale non cambi tra due operazioni correlate (ad esempio una _channel_size() seguita da una _channel_read(), su un canale che continua ad aggiungere dati). read_frame() e read_profile() lo usano internamente; un’applicazione che pilota un canale personalizzato con accesso in più passi fa lo stesso.
- Camera._channel_lock(channel_id: int) bool¶
Acquisisce un lock esclusivo su un canale. Le altre operazioni dell’host sullo stesso canale si bloccano finché il lock non viene rilasciato.
- Parametri:
channel_id – ID numerico del canale, tipicamente risolto con
get_channel().- Ritorna:
Truequando il lock è stato concesso.
- Camera._channel_unlock(channel_id: int) bool¶
Rilascia un lock precedentemente acquisito con
_channel_lock(). Sempre abbinato a una chiamata di lock; usaretry/finallyper assicurarsi che lo sblocco avvenga anche quando la lettura intermedia solleva un’eccezione.- Parametri:
channel_id – ID numerico del canale, tipicamente risolto con
get_channel().
I canali strutturati trasportano record strutturati anziché un flusso piatto di byte. Il canale del profiler è l’esempio distribuito: la sua forma è (record_count, record_size) e un host che vuole sapere quanti record sono in attesa legge la forma anziché la dimensione in byte.
- Camera._channel_shape(channel_id: int) tuple[int, ...]¶
Legge il descrittore di forma di un canale.
- Parametri:
channel_id – ID numerico del canale, tipicamente risolto con
get_channel().- Ritorna:
Tupla di interi a 32 bit senza segno che descrive la disposizione del canale. Il significato è specifico del canale.
I comandi di controllo specifici di un canale – start, stop, reset, configure – viaggiano su un singolo opcode (CHANNEL_IOCTL) con un numero di comando specifico del canale e un payload struct.pack opzionale. I metodi distribuiti come stop(), exec() e streaming() sono sottili wrapper attorno a chiamate _channel_ioctl() sui canali stdin e stream; un canale personalizzato lato cam che definisce il proprio menu di ioctl viene pilotato allo stesso modo.
- Camera._channel_ioctl(channel_id: int, cmd: int, fmt: str | None = None, *args) bytes | None¶
Emette un comando ioctl su un canale.
- Parametri:
channel_id – ID numerico del canale, tipicamente risolto con
get_channel().cmd – Numero di comando definito dal backend del canale lato cam.
fmt – Stringa di formato
structopzionale per la tupla di argomenti. PassareNoneper gli ioctl che non accettano argomenti.args – Valori corrispondenti a
fmt.
- Ritorna:
Qualsiasi payload restituito dal canale, oppure
None.
Le varianti per ID a flusso di byte dei metodi pubblici dei canali saltano la ricerca da nome a ID e accettano un offset di byte esplicito – utile per leggere un blocco dal centro di un buffer di grandi dimensioni (ad esempio i record del canale profile).
- Camera._channel_size(channel_id: int) int¶
- Parametri:
channel_id – ID numerico del canale, tipicamente risolto con
get_channel().- Ritorna:
Byte attualmente disponibili sul canale.
- Camera._channel_read(channel_id: int, offset: int, length: int) bytes¶
Legge
lengthbyte a partire daoffset. Le letture su più pacchetti vengono riassemblate automaticamente.- Parametri:
channel_id – ID numerico del canale, tipicamente risolto con
get_channel().offset – Offset in byte da cui iniziare la lettura.
length – Numero di byte da leggere.
- Camera._channel_write(channel_id: int, data: bytes, offset: int = 0) None¶
Scrive
dataall”offsetindicato. Le scritture su più pacchetti vengono suddivise automaticamente su più pacchetti.- Parametri:
channel_id – ID numerico del canale, tipicamente risolto con
get_channel().data – Payload di tipo bytes-like da scrivere.
offset – Offset in byte da cui iniziare la scrittura.
Le primitive di protocollo sono il livello più basso che la classe espone – le voci grezze di invio-di-un-comando, recupero-dell’elenco-canali-grezzo e risincronizzazione-manuale su cui tutto quanto sopra è alla fine costruito. Un’applicazione vi ricorre quando invia un opcode che la classe non avvolge già, o quando implementa un ripristino personalizzato in una sottoclasse.
- Camera._send_cmd_wait_resp(opcode: int, channel: int = 0, data: bytes = b'') bytes | None¶
Invia un comando di protocollo e attende la risposta della cam. La primitiva su cui ogni altro metodo di questa sezione è costruito.
- Parametri:
opcode – Numero di comando. L’enum
Opcodedistribuito elenca i codici forniti con il firmware, ma il parametro è semplicemente un intero – una build firmware personalizzata può definire e rispondere ai propri.channel – ID del canale, oppure
0per i comandi di sistema.data – Payload specifico del comando.
- Ritorna:
Payload di risposta, oppure
Noneper comandi comeOpcode.SYS_RESETeOpcode.SYS_BOOTche interrompono la connessione.
- Camera._channel_list() dict¶
Recupera l’elenco corrente dei canali dalla cam senza toccare i dizionari memorizzati in cache
channels_by_idechannels_by_namecheupdate_channels()popola. Utile per una sottoclasse che vuole ispezionare direttamente lo stato dei canali della cam.- Ritorna:
Dict che mappa l’ID del canale a
{'name': str, 'flags': int}.
- Camera._resync() None¶
Riesegue da zero l’handshake del protocollo. Chiamato automaticamente da
connect()alla connessione iniziale e da ogni metodo pubblico che intercetta unaOMVExceptiondal trasporto. Un’applicazione che implementa il proprio ciclo di ripristino in una sottoclasse può chiamarlo direttamente dopo aver gestito l’errore sottostante.
13.3.1.6.10. Eccezioni¶
- exception openmv.OMVException¶
Classe base per ogni errore a livello di protocollo. Le tre sottoclassi seguenti ereditano tutte da essa, quindi un singolo
except OMVExceptioncopre l’intera superficie di errore.
- exception openmv.TimeoutException¶
La cam non ha risposto entro il timeout configurato. Sottoclasse di
OMVException.
- exception openmv.ChecksumException¶
Il CRC di un pacchetto non ha corrisposto. Sollevata dopo che il protocollo ha esaurito il proprio budget di tentativi. Sottoclasse di
OMVException.
- exception openmv.SequenceException¶
Un pacchetto è arrivato con un numero di sequenza inatteso dopo i tentativi. Sottoclasse di
OMVException.