protocol — OpenMV protokolni kanali#
Modul protocol izlaže OpenMV host protokol Pythonu. Omogućuje inicijalizaciju i konfiguraciju protokolnog stoga na strani ugrađenog programa te dopušta korisničkom kodu da registrira prilagođene logičke kanale poduprte Python objektom koji implementira sučelje kanala (read, write, size, poll itd.). To je ono s čime razgovaraju popratni alati na računalu kada prenose podatke slike ili izlažu interaktivne widgete povezanoj kameri.
Primjeri#
Prijenos RGB565 slike host alatu pomoću prilagođenog backenda koji implementira sirovo sučelje kanala (backend.size(), backend.shape(), backend.poll(), backend.read()):
import csi
import protocol
csi0 = csi.CSI()
csi0.reset()
csi0.pixformat(csi.RGB565)
csi0.framesize(csi.HD)
img = csi0.snapshot()
img_mv = memoryview(img.bytearray())
frame_ready = True
class FrameChannel:
def size(self):
return len(img_mv)
def shape(self):
return (img.height(), img.width(), len(img_mv))
def poll(self):
return frame_ready
def read(self, offset, size):
global frame_ready
end = offset + size
chunk = img_mv[offset:end]
if end >= len(img_mv):
frame_ready = False
return chunk
protocol.register(name="frame", backend=FrameChannel())
while True:
if not frame_ready:
img = csi0.snapshot()
img_mv = memoryview(img.bytearray())
frame_ready = True
Odgovarajuća skripta na strani hosta, koja koristi openmv Python paket (pip install openmv) za povezivanje, slanje skripte na kameru i dohvaćanje svake sličice:
import cv2
import numpy as np
from openmv.camera import Camera
# The on-cam script above, stored as a string (or read from a file).
SCRIPT = open("frame_streamer_on_cam.py").read()
with Camera("/dev/ttyACM0", baudrate=921600) as cam:
cam.stop()
cam.exec(SCRIPT)
while True:
status = cam.read_status()
if not cam.has_channel("frame") or not status.get("frame"):
continue
h, w, size = cam._channel_shape(cam.get_channel(name="frame"))
if cam.channel_size("frame") < size:
continue
data = cam.channel_read("frame", size)
rgb565 = np.frombuffer(data, dtype="<u2").reshape(h, w)
# Unpack RGB565 to an HxWx3 uint8 RGB image.
r = ((rgb565 >> 11) & 0x1F) << 3
g = ((rgb565 >> 5) & 0x3F) << 2
b = ( rgb565 & 0x1F) << 3
frame = np.dstack([r, g, b]).astype(np.uint8)
# Display with OpenCV (cv2 expects BGR, not RGB).
cv2.imshow("OpenMV", cv2.cvtColor(frame, cv2.COLOR_RGB2BGR))
if cv2.waitKey(1) == ord("q"):
break
cv2.destroyAllWindows()
Zamijenite /dev/ttyACM0 serijskim priključkom kamere (npr. COM3 na Windowsu). Konstruktor openmv.camera.Camera prihvaća iste parametre protokola kao i init (crc / seq / ack / events / max_payload / max_retry / timeout) kada je stog na strani kamere ponovno konfiguriran tako da im odgovara.
Funkcije#
- protocol.init(crc: bool = True, seq: bool = True, ack: bool = True, events: bool = True, max_payload: int = ..., rtx_retries: int = 3, rtx_timeout_ms: int = 500, lock_interval_ms: int = 10, poll_ms: int = 0) None#
Inicijalizira (ili ponovno konfigurira) protokolni stog i registrira zadane logičke podatkovne kanale (
stdin,stdout,streami, ako je ugrađen u prijevod,profile). PodižeRuntimeErrorako inicijalizacija ne uspije. Ugrađeni program pokreće se s već aktivnim zadanim USB protokolnim stogom, pa je ovo potrebno pozvati samo za promjenu transporta ili nadjačavanje zadanih parametara uokvirivanja. Ponovni poziv ponovno inicijalizira stog: prethodni timer za prozivanje se uklanja, a kanali se iznova registriraju.crcomogućuje CRC provjeru na okvirima protokola.seqomogućuje praćenje rednih brojeva.ackomogućuje potvrde po okviru.eventsomogućuje obavijesti o događajima kanala.max_payloadje maksimalna veličina korisnog tereta u bajtovima. Ako se izostavi, koristi se zadana vrijednost po kameri navedena u nastavku; izvodi se iz veličine međuspremnika protokola svake pločice kaobuffer - 10 (header) - 4 (CRC).Kamera
Veličina međuspremnika
Maks. korisni teret
OpenMV Cam M4 (
OPENMV2)512
498
OpenMV Cam M7 (
OPENMV3)512
498
OpenMV Cam H7 (
OPENMV4)512
498
OpenMV Cam H7 Plus (
OPENMV4P)4096
4082
OpenMV Pure Thermal (
OPENMVPT)4096
4082
OpenMV Cam RT1062 (
OPENMV_RT1060)4096
4082
OpenMV Cam N6 (
OPENMV_N6)8192
8178
OpenMV AE3 (
OPENMV_AE3)8192
8178
Arduino Portenta H7 (
ARDUINO_PORTENTA_H7)4096
4082
Arduino Giga (
ARDUINO_GIGA)4096
4082
Arduino Nicla Vision (
ARDUINO_NICLA_VISION)4096
4082
rtx_retriesje broj pokušaja ponovnog prijenosa. Zadano3.rtx_timeout_msje vremensko ograničenje ponovnog prijenosa u milisekundama (udvostručuje se nakon svakog isteka). Zadano500.lock_interval_msje minimalni interval zaključavanja u milisekundama. Zadano10.poll_msje interval prozivanja u milisekundama.0(zadano) onemogućuje prozivanje pomoću mjerača vremena.
- protocol.is_active() bool#
Vraća
Trueako je host trenutno povezan i protokolni stog aktivan, inačeFalse.
- protocol.poll() int#
Izvodi jednu iteraciju protokolnog zadatka: prazni prijamni međuspremnik transporta, raščlanjuje sve potpune okvire, otprema naredbe i opslužuje događaje kanala. Ugrađeni program to inače obavlja za vas iz USB prekida i iz
poll_mstimera, pa je ovo potrebno samo za prilagođene transporte koje ne pokreće ni jedno od toga – na primjer kada jepoll_ms=0i transport se proziva iz glavne petlje skripte.Vraća
0u slučaju uspjeha i-1ako nijedan aktivni transport nije registriran ili je poziv upućen iz konteksta prekida.
- protocol.register(name: str, *, backend: object, flags: int = 0) ProtocolChannel#
Registrira Python
backendobjekt kao novi logički kanal i vraćaProtocolChannelrukovatelj. Dostupne metode objektabackend(vidi Backend sučelje u nastavku) određuju sposobnosti kanala;protocol.CHANNEL_FLAG_READ,protocol.CHANNEL_FLAG_WRITEiprotocol.CHANNEL_FLAG_LOCKautomatski se dodaju uflagskada su odgovarajuće metode implementirane.nameje naziv kanala kao niz znakova. Skraćuje se na veličinu međuspremnika naziva kanala u ugrađenom programu. Obavezno.backendje Python objekt koji implementira backend sučelje. Obavezno. Obično se prosljeđuje ključnom riječi (backend=...).flagssu dodatni bitovi zastavica kanala (vidi konstanteCHANNEL_FLAG_*). Neobavezno; zadano je0.Podiže
RuntimeErrorako se kanal ne može registrirati (npr. nema slobodnih mjesta za kanale).
Klase#
- class protocol.ProtocolChannel#
Rukovatelj koji vraća
protocol.register. Instance se ne konstruiraju izravno.
Backend sučelje#
Backend objekt proslijeđen funkciji protocol.register može implementirati bilo koji podskup sljedećih metoda. Samo su metode prisutne na objektu povezane s C protokolnim slojem; nedostajuće metode ostavljaju odgovarajuću sposobnost onemogućenom.
- class protocol.backend#
Backend objekt kanala proslijeđen funkciji
protocol.register. Metode u nastavku opisuju neobavezno sučelje koje Python backend može implementirati.- init() object#
Poziva se jednom kada se kanal inicijalizira. Vraća bilo koju vrijednost različitu od
Noneu slučaju uspjeha; iznimka ili nedostajuća povratna vrijednost tretira se kao pogreška.
- shape() tuple#
Vraća n-torku do četiri cijela broja koji opisuju oblik podataka (npr. dimenzije slike). Protokolni sloj koristi do četiri elementa.
- flush() object#
Prazni sve podatke na čekanju. Vraća bilo koju vrijednost različitu od
Noneu slučaju uspjeha.
- read(offset: int, size: int) bytes#
Vraća do
sizebajtova počevši odoffsetkaobytes-sličan objekt koji podržava protokol međuspremnika.
- readp(offset: int, size: int) bytes#
Varijanta
readbez kopiranja. Vraća međuspremnik čiju temeljnu memoriju protokolni sloj izravno čita; međuspremnik mora ostati valjan tijekom trajanja prijenosa.
- write(offset: int, data: bytearray) int#
Zapisuje
datanaoffset.datajebytearraykoji izravno referencira C međuspremnik. Vraća broj zapisanih bajtova ili0pri zadanom uspjehu.
- class protocol.CBORChannel(on_read: Callable | None = None, on_write: Callable | None = None)#
Backend više razine u Pythonu (koji pruža zamrznuti paket
protocol) koji serijalizira imenovana polja u CBOR pomoću cjelobrojnih ključeva kompatibilnih sa SenML. Podržava widgete za prikaz (label,text,depth,waveform) i interaktivne kontrole (toggle,pushbutton,slider,spinbox,select,radio,lineedit) son_read/on_writepovratnim pozivima.on_readje neobavezni pozivni objekton_read(channel)koji se poziva prije serijalizacije kanala za host. Koristite ga za osvježavanje vrijednosti polja.on_writeje neobavezni pozivni objekton_write(channel, name, value)koji se poziva kada host upiše novu vrijednost za imenovano polje.- add(name: str, type: str, value: Any = None, unit: str | None = None, min: int | float | None = None, max: int | float | None = None, step: int | float | None = None, options: list | None = None, width: int | None = None, height: int | None = None, sample_rate: float | None = None, series: int = 1, typecode: str | None = None) None#
Dodaje imenovano polje u kanal.
nameje prikazni naziv; mora biti jedinstven unutar ovog kanala.typeje vrsta widgeta:"label"– numerički prikaz samo za čitanje s neobaveznom jedinicomunit."text"– prikaz niza znakova samo za čitanje."toggle"– logička sklopka."pushbutton"– trenutna radnja (okidanje, kalibracija, …). Host pri kliku zapisujeTruei ne prikazuje stanje."slider"– numerička kontrola smin/max/step."spinbox"– precizan numerički unos u koracima; dijeli polja klizača i oblik ažuriranja n-torkom(min, max, value)."select"– padajući popis nizovaoptions."radio"–optionsprikazane kao skupina radijskih gumba."lineedit"– zapisivi unos niza znakova."depth"– 2D prikaz dubinske karte veličinewidthxheight."waveform"– 1D graf vremenskog niza isprepletenih uzoraka.
valueje početna vrijednost. Zadana ovisi otype:0zalabel,""zatext/lineedit/select/radio,Falsezatoggle/pushbutton,minzaslider/spinbox.unitje niz znakova jedinice zalabel/slider/spinbox/waveform(npr."Cel","%RH").minje najmanja vrijednost (raspon klizača/spinboxa ili raspon prikaza dubine/valnog oblika).maxje najveća vrijednost (raspon klizača/spinboxa ili raspon prikaza dubine/valnog oblika).stepje veličina koraka (klizač/spinbox).optionsje popis nizova opcija (select/radio) ili popis naziva pojedinih serija (waveform).widthje širina u pikselima (depth).heightje visina u pikselima (depth).sample_rateje brzina uzorkovanja u uzorcima po sekundi (waveform). Hostu se šalje kao razdoblje uzorkovanja.seriesje broj isprepletenih serija u svakom bloku uzoraka (waveform), npr.3za XYZ trag akcelerometra.typecodejearraykod tipa uzoraka valnog oblika (npr."H","h","f"). Zadano je"H"(16-bitni bez predznaka).
- __getitem__(name: str) object#
Vraća trenutnu vrijednost imenovanog polja. Za polja
depthiwaveformvraća se binarni podatkovni međuspremnik, inače skalarna vrijednost.
- __setitem__(name: str, value: Any) None#
Postavlja vrijednost imenovanog polja. Za polja
sliderispinboxn-torka(min, max, value)istodobno ažurira raspon i trenutnu vrijednost. Za poljadepthvalueje binarni podatkovni međuspremnik. Za poljawaveformvalueje blok isprepletenih uzoraka nalik bajtovima utypecodepolja; broj uzoraka po seriji izvodi se iz njegove duljine, a prilaže se monotona vremenska oznaka (u mikrosekundama, akumulirana iztime.ticks_us()) kako bi host mogao smjestiti blok na svoju vremensku os.
- size() int#
Metoda backend sučelja. Poziva
on_read(ako je postavljen) i vraća veličinu serijaliziranog međuspremnika.
Konstante#
Bitovi zastavica kanala (kombiniraju se bitovno; prosljeđuju se funkciji protocol.register putem flags ili se postavljaju automatski na temelju metoda backenda).
- protocol.CHANNEL_FLAG_PHYSICAL: int#
Kanal predstavlja fizički transport (za razliku od logičkog podatkovnog kanala).
Ugrađeni identifikatori kanala.