13.1.9. Vizualizarea Canale#
Tamponul de cadre arată ce vede camera; vizualizarea Canale arată ce măsoară și decide scriptul. Un script publică valori denumite prin protocolul de depanare – o temperatură, un număr de detecții, forma de undă a unui microfon, o hartă de adâncime time-of-flight sau o comandă pe care vrea ca utilizatorul să o poată modifica – iar IDE-ul o redă pe fiecare în timp real ca un widget, un grafic sau o hartă în panoul de sub tamponul de cadre. Nimic nu trebuie desenat pe imagine sau extras din terminal. Pe partea camerei sunt câteva linii cu protocol.CBORChannel; pe partea IDE-ului este intrarea Canale a selectorului panoului.

Comenzile unui script de cameră termică: două afișaje de temperatură, comutatoare pentru modurile de măsurare și glisoare pentru intervalul de temperatură. Modificarea oricăreia dintre ele trimite noua valoare scriptului.#
Vizualizarea este organizată pe canale. Fiecare canal pe care îl înregistrează scriptul devine o secțiune cu numele canalului drept titlu, iar fiecare înregistrare din canal devine un rând sub ea, în ordinea în care le-a adăugat scriptul. Când scriptul înregistrează un canal sau schimbă forma unuia, vizualizarea se reconstruiește; când scriptul se oprește, ultimele valori rămân pe ecran, cu comenzile dezactivate, până când pornește următorul script.
13.1.9.1. Widgeturi#
Afișajele și comenzile iau formele evidente. Un label este o valoare doar pentru citire cu unitatea sa; o înregistrare text este un bloc de text formatat static pentru titluri și explicații. Tipurile care pot fi scrise trimit noua lor valoare înapoi către script în clipa în care le modificați, unde callback-ul on_write al scriptului primește numele și valoarea înregistrării: un toggle este un comutator, un slider și un spinbox stabilesc un număr în intervalul și cu pasul scriptului (caseta de incrementare pentru introducere precisă), butoanele radio și un select aleg una dintre opțiunile scriptului, un lineedit este un câmp de text liber, iar un pushbutton declanșează o acțiune momentană. Vizualizarea vă păstrează editarea pe ecran în loc să o readucă la ultima valoare publicată de cameră cât timp scrierea este în curs.
Pe partea de script, întregul set este un protocol.CBORChannel cu câte un add per widget și un callback pentru scrieri:
import time
import protocol
from protocol import CBORChannel
def on_write(ch, name, value):
print(name, "=", value) # every change lands here
ch = CBORChannel(on_write=on_write)
ch.add("Status", type="label", value="starting")
ch.add("Enable", type="toggle", value=True)
ch.add("Threshold", type="slider", min=0, max=100,
step=1, value=50, unit="%")
ch.add("Mode", type="select",
options=["Idle", "Track", "Record"], value="Idle")
ch.add("Calibrate", type="pushbutton")
protocol.register(name="controls", backend=ch)
while True:
if ch["Enable"]: # read a control back
ch["Status"] = "threshold %d%%" % ch["Threshold"]
time.sleep_ms(100)
Rulați-l și comutați panoul la Canale: apare o secțiune numită controls cu cele cinci widgeturi, iar mișcarea glisorului afișează în terminal. Celelalte tipuri de widgeturi – spinbox, radio, lineedit, text – înseamnă câte un add în plus fiecare; capitolul despre protocolul gazdă le parcurge pe toate.
13.1.9.2. Grafice de formă de undă#
O înregistrare waveform este un bloc de eșantioane intercalate cu o rată de eșantionare – audio, axele unui accelerometru, o urmă ADC – iar vizualizarea o reprezintă ca un grafic derulant, o serie per axă, denumite de script. Comenzile graficului se află în bara sa de instrumente și pe graficul însuși:
Trageți pentru a panorama și derulați pentru a mări; faceți dublu clic pentru a reveni la urmărirea marginii în timp real. Istoric stabilește câte date din trecut sunt păstrate, astfel încât să puteți panorama înapoi prin ele.
Scalare automată potrivește axa verticală la date; dezactivată, axa este intervalul declarat de script.
Faceți clic dreapta pe grafic pentru a plasa un marcator și a citi timpul și valoarea exacte ale unui eșantion, sau pentru a stabili un nivel de declanșare. Cu o Declanșare armată, graficul stă nemișcat până când semnalul traversează nivelul pe un front crescător sau descrescător – modul osciloscopului de a prinde un tranzient – iar Rearmare așteaptă următorul.
Spectru comută graficul la o reprezentare în frecvență a acelorași date, cu o alegere a ferestrei (Hann, Hamming, Blackman, dreptunghiulară), Mediere și Menținere vârf de-a lungul cadrelor și o axă Frecvență logaritmică. Afișajul de sub grafic indică frecvența de vârf și nivelul ei.
Pauză îngheață graficul fără a afecta o înregistrare; Statistici adaugă o linie min / max / RMS; iar meniul de clic dreapta salvează graficul ca imagine.

Două înregistrări waveform derulând în timp real: o urmă de microfon și o urmă IMU cu trei serii.#
Un câmp waveform primește rata de eșantionare și, pentru mai multe semnale deodată, numărul de series intercalate și numele lor; fiecare actualizare este octeții bruți ai unui array de eșantioane în typecode-ul câmpului:
import math
import time
import protocol
from array import array
from protocol import CBORChannel
RATE, CHUNK = 1000, 100 # 1 kHz, 100 ms per update
ch = CBORChannel()
ch.add("IMU", type="waveform", sample_rate=RATE, series=3,
typecode="f", min=-2.0, max=2.0,
options=["X", "Y", "Z"], unit="g")
protocol.register(name="signals", backend=ch)
t = 0
while True:
block = array("f")
for i in range(CHUNK):
phase = 2 * math.pi * 2 * (t + i) / RATE
block.extend((math.sin(phase), math.cos(phase), 1.0))
ch["IMU"] = bytes(block) # interleaved X, Y, Z
t += CHUNK
time.sleep_ms(100)
13.1.9.3. Hărți de adâncime#
O înregistrare depth este o grilă de distanțe – cadrele pe care le produce un senzor time-of-flight – iar vizualizarea o desenează ca o hartă în culori false, scalată până la înălțimea graficului. Bara de instrumente alege redarea: paleta (paletele proprii ale camerei Adâncime, Curcubeu și Ironbow, plus palete deschise și închise pentru camerele de evenimente), filtrul de scalare care mărește grila mică a senzorului (bicubic pentru o suprafață netedă, biliniar sau cel mai apropiat pentru un bloc per pixel de senzor) și maparea tonală care transformă distanța în culoare: Interval script folosește intervalul declarat de script, Interval automat întinde culorile peste distanțele prezente efectiv în fiecare cadru (ignorând cele câteva procente aberante), iar Egalizare le distribuie peste distribuția cadrului, astfel încât o scenă plată să își arate totuși detaliile. Antetul raportează dimensiunea hărții, intervalul declarat și minimul, maximul și media cadrului; trecerea cursorului peste hartă afișează distanța de sub cursor, iar Salvați imaginea scrie harta redată într-un PNG.

O hartă de adâncime time-of-flight a unei mâini în fața senzorului, cu selectoarele de paletă, scalare și mapare tonală în bara de instrumente.#
Un câmp depth își declară dimensiunea grilei și intervalul; fiecare actualizare este grila sub formă de numere în virgulă mobilă pe 32 de biți împachetate, ceea ce produce cititorul modulului tof:
import struct
import time
import tof
import protocol
from protocol import CBORChannel
tof.init()
ch = CBORChannel()
ch.add("depth", type="depth", width=tof.width(),
height=tof.height(), min=0, max=1000)
protocol.register(name="ToF", backend=ch)
while True:
try:
d, dmin, dmax = tof.read_depth(vflip=True, hmirror=True)
except RuntimeError:
continue
ch["depth"] = struct.pack("<%df" % len(d), *d)
time.sleep_ms(50)
13.1.9.4. Înregistrarea#
Fiecare grafic și hartă are un buton Record, iar un canal cu mai multe dintre ele are o bară Înregistrează tot care le pornește împreună. Înregistrarea scrie datele pe măsură ce sosesc – nu redarea – într-un fișier al cărui format urmează extensia pe care o alegeți în dialogul de salvare: CSV pentru foi de calcul și instrumente de reprezentare grafică, WAV pentru forme de undă audio cu un singur canal, matrice NumPy .npy pentru Python și Edge Impulse JSON sau CBOR pentru încărcarea directă într-un proiect Edge Impulse ca date de antrenament, cu o etichetă opțională care dă numele fișierelor. Sunt oferite doar formatele care pot conține datele unei înregistrări; o hartă de adâncime, de exemplu, nu poate fi un fișier WAV. O captură lungă este împărțită în părți numerotate, astfel încât niciun fișier să nu devină prea greu de manevrat, iar o înregistrare supraviețuiește reînregistrării canalelor de către script. Afișajul de lângă buton urmărește câte eșantioane au fost scrise și dimensiunea fișierului.
Intervalul Channel Polling al panoului, din secțiunea de protocol a preferințelor, stabilește cât de des cere IDE-ul camerei date noi de canal; valoarea implicită se potrivește scripturilor care publică de câteva ori pe secundă, iar un script care transmite audio beneficiază de un interval mai scurt.
Vezi și
protocol.CBORChannel pentru partea de script – tipurile de înregistrări, argumentele lor și callback-ul on_write – și exemplele 12-Protocol din File → Examples pentru scripturi funcționale care publică afișaje, comenzi și o hartă de adâncime.