protocol — OpenMV protokollcsatornák#
A protocol modul az OpenMV gazdaprotokollt teszi elérhetővé a Python számára. Lehetővé teszi a firmware-oldali protokollverem inicializálását és konfigurálását, és lehetővé teszi a felhasználói kód számára, hogy egyéni logikai csatornákat regisztráljon, amelyek mögött egy a csatornainterfészt megvalósító Python-objektum áll (read, write, size, poll stb.). Ezzel kommunikálnak az asztali kísérőeszközök, amikor képadatot streamelnek vagy interaktív widgeteket jelenítenek meg egy csatlakoztatott kamerán.
Példák#
RGB565 kép streamelése egy gazdaeszköz felé egyéni háttérprogrammal, amely megvalósítja a nyers csatornainterfészt (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
A hozzá tartozó gazdaoldali szkript, amely az openmv Python-csomagot (pip install openmv) használja a csatlakozáshoz, a kamerán futó szkript feltöltéséhez és az egyes képkockák lekéréséhez:
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()
Cseréld le a /dev/ttyACM0 értéket a kamera soros portjára (pl. COM3 Windows alatt). Az openmv.camera.Camera konstruktor ugyanazokat a protokollparamétereket fogadja el, mint az init (crc / seq / ack / events / max_payload / max_retry / timeout), ha a kameraoldali vermet ehhez illeszkedően újrakonfigurálták.
Függvények#
- 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#
Inicializálja (vagy újrakonfigurálja) a protokollvermet, és regisztrálja az alapértelmezett logikai adatcsatornákat (
stdin,stdout,streamés, ha be van fordítva,profile).RuntimeErrorkivételt vált ki, ha az inicializálás meghiúsul. A firmware egy már futó, alapértelmezett USB-protokollveremmel indul, így ennek hívására csak a transzport megváltoztatásához vagy az alapértelmezett keretezési paraméterek felülbírálásához van szükség.A
crcengedélyezi a CRC-ellenőrzést a protokollkereteken.A
seqengedélyezi a sorszámkövetést.Az
ackengedélyezi a keretenkénti nyugtázásokat.Az
eventsengedélyezi a csatorna-eseményértesítéseket.A
max_payloada maximális hasznosadat-méret bájtban. Ha elhagyod, az alábbi, kameránkénti alapértelmezés érvényesül; ez az egyes lapok protokollpuffer-méretéből származik abuffer - 10 (header) - 4 (CRC)képlet szerint.Kamera
Pufferméret
Maximális hasznos adat
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
Az
rtx_retriesaz újraküldési kísérletek száma. Alapértelmezés:3.Az
rtx_timeout_msaz újraküldési időtúllépés ezredmásodpercben (minden időtúllépés után megduplázódik). Alapértelmezés:500.A
lock_interval_msa minimális zárolási időköz ezredmásodpercben. Alapértelmezés:10.A
poll_msa lekérdezési időköz ezredmásodpercben. A0(az alapértelmezés) letiltja az időzítő alapú lekérdezést.
- protocol.is_active() bool#
Trueértéket ad vissza, ha jelenleg csatlakozik egy gazda, és a protokollverem aktív, egyébkéntFalseértéket.
- protocol.register(name: str, *, backend: object, flags: int = 0) ProtocolChannel#
Regisztrál egy Python
backendobjektumot új logikai csatornaként, és visszaad egyProtocolChannelleírót. Abackendobjektum elérhető metódusai (lásd alább: Háttérprogram-interfész) határozzák meg a csatorna képességeit; aprotocol.CHANNEL_FLAG_READ, aprotocol.CHANNEL_FLAG_WRITEés aprotocol.CHANNEL_FLAG_LOCKautomatikusan hozzáadódik aflagsértékhez, amikor a megfelelő metódusok meg vannak valósítva.A
namea csatorna neve karakterláncként. A firmware csatornanév-pufferének méretére csonkolódik. Kötelező.A
backenda háttérprogram-interfészt megvalósító Python-objektum. Kötelező. Jellemzően kulcsszóval adják át (backend=...).A
flagstovábbi csatorna-jelzőbitek (lásd aCHANNEL_FLAG_*konstansokat). Opcionális; alapértelmezése0.RuntimeErrorkivételt vált ki, ha a csatorna nem regisztrálható (pl. nincs szabad csatornahely).
Osztályok#
- class protocol.ProtocolChannel#
A
protocol.registeráltal visszaadott leíró. A példányok nem hozhatók létre közvetlenül.
Háttérprogram-interfész#
A protocol.register függvénynek átadott háttérprogram-objektum az alábbi metódusok bármely részhalmazát megvalósíthatja. Csak az objektumon ténylegesen jelen lévő metódusok kapcsolódnak a C protokollréteghez; a hiányzó metódusok letiltják a megfelelő képességet.
- class protocol.backend#
A
protocol.registerfüggvénynek átadott csatorna-háttérprogram objektum. Az alábbi metódusok azt az opcionális interfészt írják le, amelyet egy Python-háttérprogram megvalósíthat.- init() object#
Egyszer hívódik meg, amikor a csatorna inicializálódik. Sikeresség esetén bármely nem
Noneértéket adjon vissza; a kivétel vagy a hiányzó visszatérési érték hibának számít.
- shape() tuple#
Visszaad egy legfeljebb négy egész számból álló rekordot, amely az adat alakját írja le (pl. képméreteket). A protokollréteg legfeljebb négy elemet használ fel.
- flush() object#
Kiüríti az összes függőben lévő adatot. Sikeresség esetén bármely nem
Noneértéket adjon vissza.
- read(offset: int, size: int) bytes#
Legfeljebb
sizebájtot ad vissza azoffsetpozíciótól kezdve, egybytes-szerű objektumként, amely támogatja a pufferprotokollt.
- readp(offset: int, size: int) bytes#
A
readnullamásolásos (zero-copy) változata. Olyan puffert ad vissza, amelynek mögöttes memóriáját közvetlenül a protokollréteg olvassa; a puffernek érvényesnek kell maradnia az átvitel teljes idejére.
- write(offset: int, data: bytearray) int#
dataírása azoffsetpozícióba. Adataegybytearray, amely közvetlenül a C puffert hivatkozza. Visszaadja a kiírt bájtok számát, vagy0értéket alapértelmezett siker esetén.
- class protocol.CBORChannel(on_read: Callable | None = None, on_write: Callable | None = None)#
Egy magasabb szintű Python-háttérprogram (amelyet a befagyasztott
protocolcsomag biztosít), amely a megnevezett mezőket CBOR-ba sorosítja SenML-kompatibilis egész kulcsok használatával. Támogat megjelenítő widgeteket (label,depth) és interaktív vezérlőket (toggle,slider,select)on_read/on_writevisszahívásokkal.Az
on_readegy opcionálison_read(channel)hívható objektum, amely a csatorna gazda felé történő sorosítása előtt hívódik meg. Használd a mezőértékek frissítésére.Az
on_writeegy opcionálison_write(channel, name, value)hívható objektum, amely akkor hívódik meg, amikor a gazda új értéket ír egy megnevezett mezőbe.- 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) None#
Megnevezett mező hozzáadása a csatornához.
A
namea megjelenítendő név; ezen a csatornán belül egyedinek kell lennie.A
typea widget típusa:"label","toggle","slider","select"vagy"depth".A
valuea kezdőérték. Az alapértelmezés atypeértékétől függ.A
unitalabel/slidermértékegység-karakterlánca (pl."Cel","%RH").A
mina minimális érték (csúszka- vagy mélységtartomány).A
maxa maximális érték (csúszka- vagy mélységtartomány).A
stepa lépésköz (csúszka).Az
optionsaz opció-karakterláncok listája (select).A
widtha képpontban megadott szélesség (depth).A
heighta képpontban megadott magasság (depth).
- __getitem__(name: str) object#
Visszaadja a megnevezett mező aktuális értékét.
depthmezők esetén a bináris adatpuffert adja vissza, egyébként a skalárértéket.
- __setitem__(name: str, value: Any) None#
Beállítja a megnevezett mező értékét.
slidermezők esetén egy(min, max, value)rekord egyszerre frissíti a tartományt és az aktuális értéket.depthmezők esetén avaluea bináris adatpuffer.
- poll() bool#
Háttérprogram-interfész metódus.
Trueértéket ad vissza, ha sorosított adat áll rendelkezésre a gazda számára.
- size() int#
Háttérprogram-interfész metódus. Meghívja az
on_readfüggvényt (ha be van állítva), és visszaadja a sorosított puffer méretét.
Konstansok#
Csatorna-jelzőbitek (bitenkénti VAGY művelettel kombinálva; a protocol.register függvénynek a flags paraméteren keresztül átadva, vagy a háttérprogram metódusai alapján automatikusan beállítva).
- protocol.CHANNEL_FLAG_PHYSICAL: int#
A csatorna fizikai transzportot képvisel (szemben a logikai adatcsatornával).
Beépített csatornaazonosítók.