protocol — OpenMV-protokollkanaler¶
Modulen protocol exponerar OpenMV-värdprotokollet till Python. Den gör det möjligt att initiera och konfigurera protokollstacken på fast programvara-sidan, och låter användarkod registrera anpassade logiska kanaler som backas av ett Python-objekt som implementerar kanalgränssnittet (read, write, size, poll osv.). Det är detta som följeslagarverktyg på skrivbordet kommunicerar med när de strömmar bilddata eller exponerar interaktiva widgetar mot en ansluten kamera.
Exempel¶
Strömma en RGB565-bild till ett värdverktyg med en anpassad backend som implementerar det råa kanalgränssnittet (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
Det matchande värdskriptet, som använder Python-paketet openmv (pip install openmv) för att ansluta, skicka skriptet till kameran och hämta varje bildruta:
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()
Ersätt /dev/ttyACM0 med kamerans serieport (t.ex. COM3 på Windows). Konstruktorn openmv.camera.Camera accepterar samma protokollparametrar som init (crc / seq / ack / events / max_payload / max_retry / timeout) när stacken på kamerasidan har omkonfigurerats för att matcha.
Funktioner¶
- 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¶
Initiera (eller omkonfigurera) protokollstacken och registrera standardlogiska datakanaler (
stdin,stdout,streamoch, om inkompilerad,profile). HöjerRuntimeErrorom initieringen misslyckas. Den fasta programvaran startar med en standard-USB-protokollstack som redan körs, så detta anrop behövs endast för att byta transport eller åsidosätta standardparametrarna för ramning.crcaktiverar CRC-validering på protokollramar.seqaktiverar spårning av sekvensnummer.ackaktiverar bekräftelser per ram.eventsaktiverar aviseringar om kanalhändelser.max_payloadär den maximala nyttolaststorleken i byte. Om den utelämnas används standardvärdet per kamera nedan; det härleds från varje korts protokollbuffertstorlek sombuffer - 10 (header) - 4 (CRC).Kamera
Buffertstorlek
Max nyttolast
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_retriesär antalet återsändningsförsök. Standard3.rtx_timeout_msär återsändningstimeouten i millisekunder (fördubblas efter varje timeout). Standard500.lock_interval_msär det minsta låsintervallet i millisekunder. Standard10.poll_msär pollningsintervallet i millisekunder.0(standard) inaktiverar timerbaserad pollning.
- protocol.is_active() bool¶
Returnerar
Trueom en värd är ansluten för närvarande och protokollstacken är aktiv, annarsFalse.
- protocol.register(name: str, *, backend: object, flags: int = 0) ProtocolChannel¶
Registrera ett Python-
backend-objekt som en ny logisk kanal och returnera ettProtocolChannel-handtag. De metoder som finns tillgängliga påbackend-objektet (se Backend-gränssnitt nedan) bestämmer kanalens kapacitet;protocol.CHANNEL_FLAG_READ,protocol.CHANNEL_FLAG_WRITEochprotocol.CHANNEL_FLAG_LOCKläggs till iflagsautomatiskt när motsvarande metoder är implementerade.nameär kanalnamnet som en sträng. Trunkeras till storleken på den fasta programvarans kanalnamnsbuffert. Obligatorisk.backendär Python-objektet som implementerar backend-gränssnittet. Obligatorisk. Skickas vanligtvis med nyckelord (backend=...).flagsär ytterligare kanalflaggbitar (se konstanternaCHANNEL_FLAG_*). Valfri; standardvärdet är0.Höjer
RuntimeErrorom kanalen inte kan registreras (t.ex. inga lediga kanalplatser).
Klasser¶
- class protocol.ProtocolChannel¶
Handtag som returneras av
protocol.register. Instanser konstrueras inte direkt.
Backend-gränssnitt¶
Ett backend-objekt som skickas till protocol.register kan implementera valfri delmängd av följande metoder. Endast de metoder som finns på objektet kopplas till C-protokolllagret; metoder som saknas lämnar motsvarande kapacitet inaktiverad.
- class protocol.backend¶
Kanal-backend-objekt som skickas till
protocol.register. Metoderna nedan beskriver det valfria gränssnitt som en Python-backend kan implementera.- init() object¶
Anropas en gång när kanalen initieras. Returnera ett värde som inte är
Nonevid lyckat resultat; ett undantag eller en utebliven retur behandlas som ett fel.
- shape() tuple¶
Returnerar en tupel med upp till fyra heltal som beskriver dataformen (t.ex. bildmått). Upp till fyra element konsumeras av protokolllagret.
- flush() object¶
Töm eventuell väntande data. Returnera ett värde som inte är
Nonevid lyckat resultat.
- read(offset: int, size: int) bytes¶
Returnerar upp till
sizebyte från och medoffsetsom ettbytes-liknande objekt som stöder buffertprotokollet.
- readp(offset: int, size: int) bytes¶
Nollkopieringsvariant av
read. Returnerar en buffert vars underliggande minne läses direkt av protokolllagret; bufferten måste förbli giltig under hela överföringen.
- write(offset: int, data: bytearray) int¶
Skriv
datavidoffset.dataär enbytearraysom refererar direkt till C-bufferten. Returnera antalet skrivna byte, eller0vid standardmässigt lyckat resultat.
- class protocol.CBORChannel(on_read: Callable | None = None, on_write: Callable | None = None)¶
En Python-backend på högre nivå (tillhandahållen av det frysta paketet
protocol) som serialiserar namngivna fält till CBOR med SenML-kompatibla heltalsnycklar. Stöder visningswidgetar (label,depth) och interaktiva kontroller (toggle,slider,select) medon_read/on_write-återanrop.on_readär ett valfritt anropbart objekton_read(channel)som anropas innan kanalen serialiseras för värden. Använd det för att uppdatera fältvärden.on_writeär ett valfritt anropbart objekton_write(channel, name, value)som anropas när värden skriver ett nytt värde för ett namngivet fält.- 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¶
Lägg till ett namngivet fält i kanalen.
nameär visningsnamnet; måste vara unikt inom denna kanal.typeär widgettypen:"label","toggle","slider","select"eller"depth".valueär startvärdet. Standardvärdet beror påtype.unitär enhetssträngen förlabel/slider(t.ex."Cel","%RH").minär minimivärdet (skjutreglagets intervall eller djupintervall).maxär maxvärdet (skjutreglagets intervall eller djupintervall).stepär stegstorleken (skjutreglage).optionsär listan med alternativsträngar (select).widthär pixelbredden (depth).heightär pixelhöjden (depth).
- __getitem__(name: str) object¶
Returnerar det aktuella värdet för det namngivna fältet. För
depth-fält returneras den binära databufferten, annars skalärvärdet.
- __setitem__(name: str, value: Any) None¶
Sätt värdet för det namngivna fältet. För
slider-fält uppdaterar en tupel(min, max, value)intervallet och det aktuella värdet samtidigt. Fördepth-fält ärvalueden binära databufferten.
- poll() bool¶
Metod i backend-gränssnittet. Returnerar
Truenär serialiserad data är tillgänglig för värden.
- size() int¶
Metod i backend-gränssnittet. Anropar
on_read(om den är satt) och returnerar storleken på den serialiserade bufferten.
Konstanter¶
Kanalflaggbitar (kombineras bitvis; skickas till protocol.register via flags eller sätts automatiskt baserat på backendens metoder).
- protocol.CHANNEL_FLAG_PHYSICAL: int¶
Kanalen representerar en fysisk transport (till skillnad från en logisk datakanal).
Inbyggda kanalidentifierare.