protocol — OpenMV Protokol Kanalları

protocol modülü, OpenMV ana bilgisayar protokolünü Python’a sunar. Aygıt yazılımı tarafındaki protokol yığınının başlatılmasına ve yapılandırılmasına olanak tanır ve kullanıcı kodunun, kanal arayüzünü (read, write, size, poll vb.) uygulayan bir Python nesnesi tarafından desteklenen özel mantıksal kanallar kaydetmesine izin verir. Masaüstü yardımcı araçlar, görüntü verisi akıttıklarında veya bağlı bir kameraya etkileşimli widget’lar sunduklarında işte bununla iletişim kurarlar.

Örnekler

Ham kanal arayüzünü (backend.size(), backend.shape(), backend.poll(), backend.read()) uygulayan özel bir arka uç kullanarak bir ana bilgisayar aracına bir RGB565 görüntüsü akıtın:

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

Bağlanmak, kamera üzerindeki betiği göndermek ve her çerçeveyi çekmek için openmv Python paketini (pip install openmv) kullanan eşleşen ana bilgisayar tarafı betik:

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()

/dev/ttyACM0 ifadesini kameranın seri portuyla değiştirin (ör. Windows’ta COM3). openmv.camera.Camera yapıcısı, kamera tarafı yığın eşleşecek şekilde yeniden yapılandırıldığında init ile aynı protokol parametrelerini (crc / seq / ack / events / max_payload / max_retry / timeout) kabul eder.

Fonksiyonlar

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

Protokol yığınını başlatır (veya yeniden yapılandırır) ve varsayılan mantıksal veri kanallarını (stdin, stdout, stream ve derlenmişse profile) kaydeder. Başlatma başarısız olursa RuntimeError yükseltir. Aygıt yazılımı, halihazırda çalışan varsayılan bir USB protokol yığınıyla başlar, bu nedenle bunu çağırmak yalnızca taşımayı değiştirmek veya varsayılan çerçeveleme parametrelerini geçersiz kılmak için gereklidir.

crc, protokol çerçevelerinde CRC doğrulamasını etkinleştirir.

seq, sıra numarası takibini etkinleştirir.

ack, çerçeve başına onaylamaları etkinleştirir.

events, kanal olayı bildirimlerini etkinleştirir.

max_payload, bayt cinsinden maksimum yük boyutudur. Atlanırsa aşağıdaki kamera başına varsayılan değer kullanılır; bu değer her kartın protokol arabellek boyutundan buffer - 10 (header) - 4 (CRC) olarak türetilir.

Kamera

Arabellek boyutu

Maksimum yük

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, yeniden iletim denemelerinin sayısıdır. Varsayılan 3.

rtx_timeout_ms, milisaniye cinsinden yeniden iletim zaman aşımıdır (her zaman aşımından sonra ikiye katlanır). Varsayılan 500.

lock_interval_ms, milisaniye cinsinden minimum kilit aralığıdır. Varsayılan 10.

poll_ms, milisaniye cinsinden yoklama aralığıdır. 0 (varsayılan) zamanlayıcı yoklamasını devre dışı bırakır.

protocol.is_active() bool

Bir ana bilgisayar şu anda bağlıysa ve protokol yığını etkinse True, aksi takdirde False döndürür.

protocol.register(name: str, *, backend: object, flags: int = 0) ProtocolChannel

Bir Python backend nesnesini yeni bir mantıksal kanal olarak kaydeder ve bir ProtocolChannel tutamacı döndürür. backend nesnesinin mevcut metotları (aşağıdaki Arka Uç Arayüzü bölümüne bakın) kanalın yeteneklerini belirler; ilgili metotlar uygulandığında protocol.CHANNEL_FLAG_READ, protocol.CHANNEL_FLAG_WRITE ve protocol.CHANNEL_FLAG_LOCK otomatik olarak flags değerine eklenir.

name, dize olarak kanal adıdır. Aygıt yazılımının kanal adı arabellek boyutuna kısaltılır. Gerekli.

backend, arka uç arayüzünü uygulayan Python nesnesidir. Gerekli. Genellikle anahtar kelime ile geçirilir (backend=...).

flags, ek kanal bayrak bitleridir (CHANNEL_FLAG_* sabitlerine bakın). İsteğe bağlı; varsayılan değer 0.

Kanal kaydedilemezse (ör. boş kanal yuvası yoksa) RuntimeError yükseltir.

Sınıflar

class protocol.ProtocolChannel

protocol.register tarafından döndürülen tutamaç. Örnekler doğrudan oluşturulmaz.

send_event(event: int, wait_ack: bool = False) None

Ana bilgisayara bir kanal olayı bildirimi gönderir.

event, olay tanımlayıcısıdır (tam sayı).

wait_ack, True ise ana bilgisayar olayı onaylayana kadar bloke eder.

Olay gönderimi başarısız olursa RuntimeError yükseltir.

Arka Uç Arayüzü

protocol.register fonksiyonuna geçirilen bir arka uç nesnesi, aşağıdaki metotların herhangi bir alt kümesini uygulayabilir. Yalnızca nesnede mevcut olan metotlar C protokol katmanına bağlanır; eksik metotlar ilgili yeteneği devre dışı bırakır.

class protocol.backend

protocol.register fonksiyonuna geçirilen kanal arka uç nesnesi. Aşağıdaki metotlar, bir Python arka ucunun uygulayabileceği isteğe bağlı arayüzü açıklar.

init() object

Kanal başlatıldığında bir kez çağrılır. Başarı durumunda None olmayan herhangi bir değer döndürün; bir istisna veya eksik dönüş hata olarak değerlendirilir.

poll() bool

Kanalda ana bilgisayar tarafından okunmaya hazır veri varsa True döndürür.

lock() bool

Bir aktarım için kanalı edinir. Başarı durumunda True döndürür.

unlock() bool

Bir aktarımdan sonra kanalı serbest bırakır. Başarı durumunda True döndürür.

size() int

Kanaldan şu anda okunabilen bayt sayısını döndürür.

shape() tuple

Veri şeklini açıklayan en fazla dört tam sayıdan oluşan bir demet döndürür (ör. görüntü boyutları). Protokol katmanı en fazla dört öğe tüketir.

flush() object

Bekleyen herhangi bir veriyi boşaltır. Başarı durumunda None olmayan herhangi bir değer döndürün.

read(offset: int, size: int) bytes

offset konumundan başlayarak en fazla size bayt, arabellek protokolünü destekleyen bytes benzeri bir nesne olarak döndürür.

readp(offset: int, size: int) bytes

read metodunun sıfır kopyalı (zero-copy) varyantı. Altta yatan belleği protokol katmanı tarafından doğrudan okunan bir arabellek döndürür; arabellek, aktarım süresince geçerli kalmalıdır.

write(offset: int, data: bytearray) int

offset konumunda data verisini yazar. data, doğrudan C arabelleğine referans veren bir bytearray nesnesidir. Yazılan bayt sayısını veya varsayılan başarı durumunda 0 döndürür.

ioctl(cmd: int, length: int, arg: bytearray | None) int

Bir ioctl işler. length sıfır ise arg değeri None, aksi takdirde C arabelleğine referans veren bir bytearray nesnesidir. Başarı durumunda 0 veya None, hata durumunda negatif bir tam sayı döndürün.

is_active() bool

Taşıma kanalları için, altta yatan taşıma şu anda bağlıysa True döndürür.

class protocol.CBORChannel(on_read: Callable | None = None, on_write: Callable | None = None)

SenML uyumlu tam sayı anahtarları kullanarak adlandırılmış alanları CBOR formatına serileştiren daha üst düzey bir Python arka ucu (dondurulmuş protocol paketi tarafından sağlanır). on_read/on_write geri çağırmaları (callback) ile görüntüleme widget’larını (label, depth) ve etkileşimli denetimleri (toggle, slider, select) destekler.

on_read, kanal ana bilgisayar için serileştirilmeden önce çağrılan isteğe bağlı bir çağrılabilir on_read(channel) nesnesidir. Alan değerlerini yenilemek için kullanın.

on_write, ana bilgisayar adlandırılmış bir alan için yeni bir değer yazdığında çağrılan isteğe bağlı bir çağrılabilir on_write(channel, name, value) nesnesidir.

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

Kanala adlandırılmış bir alan ekler.

name, görüntülenen addır; bu kanal içinde benzersiz olmalıdır.

type, widget türüdür: "label", "toggle", "slider", "select" veya "depth".

value, başlangıç değeridir. Varsayılan değer type türüne bağlıdır.

unit, label/slider için birim dizesidir (ör. "Cel", "%RH").

min, minimum değerdir (slider aralığı veya depth aralığı).

max, maksimum değerdir (slider aralığı veya depth aralığı).

step, adım boyutudur (slider).

options, seçenek dizelerinin listesidir (select).

width, piksel cinsinden genişliktir (depth).

height, piksel cinsinden yüksekliktir (depth).

__getitem__(name: str) object

Adlandırılmış alanın mevcut değerini döndürür. depth alanları için ikili veri arabelleği, aksi takdirde skaler değer döndürülür.

__setitem__(name: str, value: Any) None

Adlandırılmış alanın değerini ayarlar. slider alanları için bir (min, max, value) demeti, aralığı ve mevcut değeri aynı anda günceller. depth alanları için value, ikili veri arabelleğidir.

poll() bool

Arka uç arayüzü metodu. Ana bilgisayar için serileştirilmiş veri mevcut olduğunda True döndürür.

size() int

Arka uç arayüzü metodu. on_read metodunu (ayarlanmışsa) çağırır ve serileştirilmiş arabelleğin boyutunu döndürür.

read(offset: int, size: int) bytes

Arka uç arayüzü metodu. Serileştirilmiş arabelleğin bir dilimini döndürür.

write(offset: int, data: bytearray) int

Arka uç arayüzü metodu. Bir CBOR güncelleme listesini çözer ve değerleri eşleşen adlandırılmış alanlara uygular; her biri için on_write metodunu çağırır.

Sabitler

Kanal bayrak bitleri (bit düzeyinde birleştirilir; flags aracılığıyla protocol.register fonksiyonuna geçirilir veya arka ucun metotlarına göre otomatik olarak ayarlanır).

protocol.CHANNEL_FLAG_READ: int

Kanal okumaları destekler.

protocol.CHANNEL_FLAG_WRITE: int

Kanal yazmaları destekler.

protocol.CHANNEL_FLAG_LOCK: int

Kanal lock/unlock işlemlerini uygular.

protocol.CHANNEL_FLAG_PHYSICAL: int

Kanal fiziksel bir taşımayı temsil eder (mantıksal bir veri kanalının aksine).

Yerleşik kanal tanımlayıcıları.

protocol.CHANNEL_ID_TRANSPORT: int

Etkin taşıma için ayrılmış kanal kimliği.

protocol.CHANNEL_ID_STDIN: int

Yerleşik stdin kanalının kanal kimliği.

protocol.CHANNEL_ID_STDOUT: int

Yerleşik stdout kanalının kanal kimliği.

protocol.CHANNEL_ID_STREAM: int

Yerleşik stream kanalının kanal kimliği.

protocol.CHANNEL_ID_PROFILE: int

Yerleşik profil oluşturucu kanalının kanal kimliği (yalnızca aygıt yazılımı profil oluşturucu etkinleştirilerek derlendiğinde mevcuttur).