13.1.10. Jendela terminal mandiri

Tools → Open Terminal membuka jendela terminal independen -- masing-masing merupakan sesi OpenMV IDE mini di jendelanya sendiri, dengan penampil buffer bingkai, histogram, dan terminal interaktif, terhubung melalui transport pilihan Anda. Koneksi jendela utama tidak terpengaruh, sehingga terminal mandiri memungkinkan Anda memantau kamera kedua sementara yang pertama tetap terhubung, atau men-debug kamera di sisi lain jaringan.

A standalone terminal window: interactive terminal on the left with its toolbar, frame buffer and histogram on the right

Jendela terminal mandiri melalui port serial: terminal interaktif di sebelah kiri dengan toolbar jalankan / hentikan / reset, buffer bingkai dan histogram di sebelah kanan -- keduanya aktif ketika kamera mengalirkan bingkai secara in-band.

New Terminal meminta salah satu dari tiga transport:

  • Port serial -- port serial apa pun dengan laju baud apa pun (default 115.200). Ini mencakup port USB kamera kedua, kamera yang disambungkan melalui jembatan USB-ke-UART, tautan serial Bluetooth (yang muncul sebagai port serial biasa), atau perangkat serial non-OpenMV apa pun yang membutuhkan terminal. Pada port USB, laju baud tidak membatasi kecepatan -- data selalu bergerak dengan kecepatan tautan USB -- tetapi pada port USB kamera, hindari 921.600 dan 12.000.000, yang mengalihkan kamera dari REPL ke protokol debug IDE.

  • TCP -- terhubung ke server di host dan port yang dipilih, atau dengarkan sebagai server pada port yang dipilih.

  • UDP -- pasangan peran yang sama, melalui UDP.

IDE mengingat sepuluh konfigurasi terakhir dan mencantumkannya dalam submenu Open Terminal untuk pembukaan kembali dengan satu klik; Clear Menu melupakannya.

Berbeda dengan panel output-saja di jendela utama, terminal mandiri sepenuhnya interaktif: ini adalah REPL. Ketik di prompt dan Python dieksekusi di kamera yang terhubung baris demi baris, dengan riwayat dan penyelesaian tab yang disediakan oleh MicroPython sendiri. Toolbar menambahkan padanan satu klik dari urutan kontrol umum -- jalankan skrip editor saat ini, hentikan skrip yang berjalan, dan soft reset -- serta kontrol clear, save, dan wrap yang sama seperti panel terminal utama.

Buffer bingkai di atas terminal juga berjalan langsung. Ketika kamera yang terhubung mengalirkan bingkai terkompresi secara in-band -- tertanam dalam aliran yang sama dengan output print-nya -- terminal mendekode dan menampilkannya, dan tombol Record dan Zoom bekerja persis seperti di jendela utama. Kombinasi tersebut adalah cerita debugging jaringan IDE: kamera yang mengekspos REPL-nya melalui Wi-Fi mendapatkan loop edit-jalankan-pratinjau penuh tanpa kabel USB.

13.1.10.1. Streaming bingkai secara in-band

Enkoding yang dipahami terminal ini sederhana: byte 0xFE membuka bingkai, 0xFE kedua menutupnya, dan setiap byte payload di antaranya memiliki bit teratas yang diset dan membawa enam bit dari citra terkompresi -- tiga byte citra menjadi empat byte payload. Teks biasa tidak pernah menggunakan nilai byte tersebut, sehingga bingkai dan output print() berbagi aliran tanpa bentrok: terminal menampilkan teks dan menampilkan bingkai.

Skrip di bawah ini menangkap, mengkonversi setiap bingkai ke JPEG, dan mencetaknya dalam bentuk tersebut. Pengemasan bit berjalan melalui ulab (yang tidak memiliki operator shift, sehingga shift ditulis sebagai perkalian dan pembagian), dan cukup cepat untuk mengikuti kamera:

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

Ini bekerja di terminal mandiri karena pencetakan REPL menunggu: kamera memblokir hingga terminal mengambil data, sehingga setiap byte bingkai tiba, dan JPEG bergerak cepat melalui tautan USB full-speed atau high-speed. Skrip yang sama bekerja tanpa perubahan melalui terminal TCP, yang merupakan jalur debugging jaringan di atas. Satu tempat yang tidak berfungsi adalah koneksi debug utama IDE, yang saluran outputnya mengatur ulang dirinya sendiri saat meluap alih-alih menunggu -- di sana penampil buffer bingkai sudah menampilkan bingkai kamera secara native, sehingga tidak ada yang terlewat.