13.1.10. Bağımsız terminal pencereleri¶
Tools → Open Terminal, bağımsız terminal pencereleri açar – her biri kendi penceresinde küçük bir OpenMV IDE oturumudur; bir çerçeve arabelleği (frame buffer) görüntüleyicisi, bir histogram ve seçtiğiniz bir taşıma katmanı üzerinden bağlanan etkileşimli bir terminal içerir. Ana pencerenin bağlantısı etkilenmez, böylece bağımsız bir terminal, ilk kamera bağlı kalırken ikinci bir kamerayı izlemenize ya da bir ağın diğer ucundaki bir kamerada hata ayıklamanıza olanak tanır.
Bir seri bağlantı noktası üzerindeki bağımsız bir terminal penceresi: solda çalıştır / durdur / sıfırla araç çubuğuyla etkileşimli terminal, sağda çerçeve arabelleği (frame buffer) ve histogram – kamera çerçeveleri akış içinde (in-band) gönderdiğinde bunlar canlanır.¶
New Terminal üç taşıma katmanından birini ister:
Serial port – herhangi bir baud hızında herhangi bir seri bağlantı noktası (varsayılan 115,200). Bu, ikinci bir kameranın USB bağlantı noktasını, bir USB-UART köprüsü üzerinden bağlı bir kamerayı, bir Bluetooth seri bağlantısını (ki bu sıradan bir seri bağlantı noktası olarak görünür) veya terminal gerektiren OpenMV dışı herhangi bir seri aygıtı kapsar. Bir USB bağlantı noktasında baud hızı hızı sınırlamaz – veri her zaman USB bağlantısının hızında hareket eder – ancak bir kameranın USB bağlantı noktasında 921,600 ve 12,000,000 değerlerinden kaçının; bunlar kamerayı REPL’den IDE’nin hata ayıklama protokolüne geçirir.
TCP – seçilen bir ana bilgisayar ve bağlantı noktasındaki bir sunucuya bağlanın veya seçilen bir bağlantı noktasında bir sunucu olarak dinleyin.
UDP – aynı rol çifti, UDP üzerinden.
IDE son on yapılandırmayı hatırlar ve tek tıklamayla yeniden açmak için bunları Open Terminal alt menüsünde listeler; Clear Menu bunları unutur.
Ana pencerenin yalnızca çıkış veren bölmesinin aksine, bağımsız bir terminal tamamen etkileşimlidir: bir REPL’dir. Komut isteminde yazın; Python, bağlı kamerada satır satır çalışır ve geçmiş ile sekme tamamlama MicroPython’un kendisi tarafından sağlanır. Araç çubuğu, yaygın denetim dizilerinin tek tıklamayla eşdeğerlerini ekler – geçerli düzenleyici betiğini çalıştırma, çalışan betiği durdurma ve yazılımsal sıfırlama – ve ana terminal bölmesindeki aynı temizle, kaydet ve kaydır denetimlerini sunar.
Terminalin üzerindeki çerçeve arabelleği (frame buffer) de canlıdır. Bağlı kamera sıkıştırılmış çerçeveleri akış içinde (in-band) – yazdırma çıkışıyla aynı akışa gömülü olarak – gönderdiğinde, terminal bunları çözer ve görüntüler; Record ve Zoom düğmeleri tıpkı ana penceredeki gibi çalışır. Bu birleşim, IDE’nin ağ üzerinden hata ayıklama yaklaşımıdır: REPL’ini Wi-Fi üzerinden sunan bir kamera, hiçbir USB kablosu gerektirmeden tam düzenle-çalıştır-önizle döngüsünü elde eder.
13.1.10.1. Çerçeveleri akış içinde (in-band) gönderme¶
Terminalin anladığı kodlama basittir: bir 0xFE baytı bir çerçeveyi açar, ikinci bir 0xFE onu kapatır ve aralarındaki her yük baytının en üst biti ayarlanmıştır ve sıkıştırılmış görüntünün altı bitini taşır – üç görüntü baytı dört yük baytı olur. Düz metin bu bayt değerlerini hiçbir zaman kullanmaz, bu nedenle çerçeveler ve print() çıktısı çakışmadan akışı paylaşır: terminal metni gösterir ve çerçeveleri görüntüler.
Aşağıdaki betik yakalama yapar, her çerçeveyi JPEG’e dönüştürür ve onu bu biçimde yazdırır. Bit paketleme ulab üzerinden çalışır (kaydırma operatörleri yoktur, bu nedenle kaydırmalar çarpma ve bölme olarak yazılır) ve kameraya yetişecek kadar hızlıdır:
import csi
import sys
import time
from ulab import numpy as np
csi0 = csi.CSI()
csi0.reset()
csi0.pixformat(csi.RGB565)
csi0.framesize(csi.QVGA)
clock = time.clock()
def encode_for_ide(data):
n = len(data)
n3 = n - (n % 3)
m = (n3 // 3) * 4
out = bytearray(((n * 8) + 5) // 6 + 2)
out[0] = 0xFE
out[-1] = 0xFE
if n3:
src = np.frombuffer(data, dtype=np.uint8)
dst = np.frombuffer(out, dtype=np.uint8)
b0 = src[0:n3:3]
b1 = src[1:n3:3]
b2 = src[2:n3:3]
dst[1:m + 1:4] = (b0 & 0x3F) | 0x80
dst[2:m + 2:4] = (b0 // 64) | ((b1 & 0x0F) * 4) | 0x80
dst[3:m + 3:4] = (b1 // 16) | ((b2 & 0x03) * 16) | 0x80
dst[4:m + 4:4] = (b2 // 4) | 0x80
if n % 3 == 2:
x = data[n - 2] | (data[n - 1] << 8)
out[m + 1] = 0x80 | (x & 0x3F)
out[m + 2] = 0x80 | ((x >> 6) & 0x3F)
out[m + 3] = 0x80 | ((x >> 12) & 0x3F)
elif n % 3 == 1:
out[m + 1] = 0x80 | (data[n - 1] & 0x3F)
out[m + 2] = 0x80 | (data[n - 1] >> 6)
return out
while True:
clock.tick()
img = csi0.snapshot().to_jpeg(quality=80)
sys.stdout.write(encode_for_ide(img.bytearray()))
print(clock.fps())
Bu, bağımsız bir terminalde çalışır çünkü REPL yazdırması bekler: kamera, terminal veriyi alana kadar engellenir, böylece çerçevenin her baytı ulaşır ve bir JPEG bir USB tam hızlı veya yüksek hızlı bağlantı üzerinden hızla hareket eder. Aynı betik, yukarıdaki ağ üzerinden hata ayıklama yolu olan bir TCP terminali üzerinden de değiştirilmeden çalışır. Çalışmadığı tek yer, çıkış kanalı taşma durumunda beklemek yerine kendini sıfırlayan IDE’nin ana hata ayıklama bağlantısıdır – orada çerçeve arabelleği (frame buffer) görüntüleyicisi kameranın çerçevelerini zaten yerel olarak gösterir, dolayısıyla hiçbir şey kaçırılmaz.