13.1.10. หน้าต่างเทอร์มินัลแบบแยกต่างหาก¶
เมนู Tools → Open Terminal เปิดหน้าต่างเทอร์มินัลแบบอิสระ แต่ละหน้าต่างเป็นเซสชัน OpenMV IDE ขนาดย่อในหน้าต่างของตัวเอง มีตัวดูบัฟเฟอร์เฟรม ฮิสโตแกรม และเทอร์มินัลแบบโต้ตอบ เชื่อมต่อผ่านช่องทางการส่งข้อมูลที่คุณเลือก การเชื่อมต่อของหน้าต่างหลักไม่ได้รับผลกระทบ ดังนั้นเทอร์มินัลแบบแยกต่างหากช่วยให้คุณดูกล้องตัวที่สองได้ในขณะที่ตัวแรกยังเชื่อมต่ออยู่ หรือดีบักกล้องที่อยู่อีกฝั่งหนึ่งของเครือข่าย
หน้าต่างเทอร์มินัลแบบแยกต่างหากผ่านพอร์ตอนุกรม: เทอร์มินัลแบบโต้ตอบทางซ้ายพร้อมแถบเครื่องมือ run / stop / reset บัฟเฟอร์เฟรมและฮิสโตแกรมทางขวา ซึ่งจะแสดงผลเมื่อกล้องส่งสตรีมเฟรมแบบ in-band¶
New Terminal ขอให้เลือกช่องทางการส่งข้อมูลหนึ่งในสาม:
Serial port -- พอร์ตอนุกรมใด ๆ ที่อัตราบอดใด ๆ (ค่าเริ่มต้น 115,200) ครอบคลุมพอร์ต USB ของกล้องตัวที่สอง กล้องที่ต่อผ่านบริดจ์ USB-to-UART ลิงก์อนุกรม Bluetooth (ซึ่งแสดงเป็นพอร์ตอนุกรมปกติ) หรืออุปกรณ์ที่ไม่ใช่ OpenMV ที่ต้องการเทอร์มินัล บนพอร์ต USB อัตราบอดไม่จำกัดความเร็ว ข้อมูลจะเคลื่อนที่ด้วยความเร็วของลิงก์ USB เสมอ แต่บนพอร์ต USB ของกล้องควรหลีกเลี่ยง 921,600 และ 12,000,000 ซึ่งจะสลับกล้องจาก REPL ไปยังโปรโตคอลดีบักของ IDE
TCP -- เชื่อมต่อกับเซิร์ฟเวอร์ที่โฮสต์และพอร์ตที่กำหนด หรือรับฟังในฐานะเซิร์ฟเวอร์บนพอร์ตที่กำหนด
UDP -- บทบาทคู่เดียวกัน แต่ใช้ UDP
IDE จดจำการกำหนดค่าสิบรายการล่าสุดและแสดงในเมนูย่อย Open Terminal เพื่อเปิดใช้งานซ้ำด้วยคลิกเดียว โดย Clear Menu จะลบออก
ต่างจากแผงเอาต์พุตเท่านั้นของหน้าต่างหลัก เทอร์มินัลแบบแยกต่างหากใช้งานแบบโต้ตอบได้เต็มรูปแบบ: มันคือ REPL พิมพ์ที่พรอมต์และ Python จะรันบนกล้องที่เชื่อมต่อทีละบรรทัด พร้อมประวัติและการเติมแท็บที่จัดเตรียมโดย MicroPython เอง แถบเครื่องมือเพิ่มทางลัดคลิกเดียวสำหรับลำดับการควบคุมทั่วไป ได้แก่ รันสคริปต์ในตัวแก้ไขปัจจุบัน หยุดสคริปต์ที่รันอยู่ และ soft reset รวมถึงตัวควบคุมล้าง บันทึก และตัดบรรทัดแบบเดียวกับแผงเทอร์มินัลหลัก
บัฟเฟอร์เฟรมเหนือเทอร์มินัลก็ทำงานสดเช่นกัน เมื่อกล้องที่เชื่อมต่อส่งสตรีมเฟรมที่บีบอัดแบบ in-band ซึ่งฝังในสตรีมเดียวกับเอาต์พุต print เทอร์มินัลจะถอดรหัสและแสดงผล และปุ่ม Record กับ Zoom ทำงานเหมือนกับในหน้าต่างหลักทุกประการ การผสมผสานนี้คือแนวทางการดีบักผ่านเครือข่ายของ IDE: กล้องที่เปิดเผย REPL ผ่าน Wi-Fi จะได้รับขั้นตอนแก้ไข-รัน-ดูตัวอย่างแบบครบวงจรโดยไม่ต้องใช้สาย USB
13.1.10.1. การส่งสตรีมเฟรมแบบ in-band¶
การเข้ารหัสที่เทอร์มินัลเข้าใจนั้นเรียบง่าย: ไบต์ 0xFE เปิดเฟรม ไบต์ 0xFE ที่สองปิด และทุกไบต์ payload ระหว่างนั้นจะมีบิตสูงสุดถูกตั้งค่าและบรรจุหกบิตของภาพที่บีบอัด โดยทุกสามไบต์ภาพกลายเป็นสี่ไบต์ payload ข้อความธรรมดาไม่ใช้ค่าไบต์เหล่านั้น ดังนั้นเฟรมและเอาต์พุต print() ใช้สตรีมร่วมกันโดยไม่ชนกัน: เทอร์มินัลแสดงข้อความและแสดงเฟรม
สคริปต์ด้านล่างจับภาพ แปลงแต่ละเฟรมเป็น JPEG และพิมพ์ออกมาในรูปแบบนั้น การบีบข้อมูลบิตรันผ่าน ulab (ซึ่งไม่มีตัวดำเนินการ shift ดังนั้น shift จึงเขียนเป็นการคูณและหาร) และเร็วพอที่จะทันกับกล้อง:
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())
สิ่งนี้ทำงานในเทอร์มินัลแบบแยกต่างหากเนื่องจากการพิมพ์ REPL รอ: กล้องบล็อกจนกว่าเทอร์มินัลจะรับข้อมูล ดังนั้นทุกไบต์ของเฟรมจะมาถึง และ JPEG เคลื่อนที่อย่างรวดเร็วผ่านลิงก์ USB full-speed หรือ high-speed สคริปต์เดียวกันทำงานได้ไม่เปลี่ยนแปลงผ่านเทอร์มินัล TCP ซึ่งเป็นเส้นทางดีบักเครือข่ายข้างต้น จุดเดียวที่ไม่ทำงานคือการเชื่อมต่อดีบักหลักของ IDE ซึ่งช่องเอาต์พุตจะรีเซ็ตตัวเองเมื่อ overflow แทนที่จะรอ แต่ตัวดูบัฟเฟอร์เฟรมในหน้าต่างหลักแสดงเฟรมของกล้องโดยตรงอยู่แล้ว ดังนั้นจึงไม่มีอะไรพลาด