13.1.9. Подання «Канали»#

Кадровий буфер показує те, що камера бачить; подання «Канали» показує те, що скрипт вимірює та вирішує. Скрипт публікує іменовані значення через протокол налагодження – температуру, кількість виявлень, осцилограму мікрофона, карту глибини від сенсора часу прольоту або елемент керування, який користувач має змогу змінювати – а IDE відображає кожне з них у реальному часі як віджет, графік або карту на панелі під кадровим буфером. Нічого не треба малювати на зображенні чи вичленовувати з термінала. На боці камери це кілька рядків із protocol.CBORChannel; на боці IDE це пункт Канали селектора панелі.

The Channels view showing a thermal camera script's controls channel: FPA and AUX temperature readouts with their unit, Measurement and High Temp toggles, Temp Min and Temp Max sliders, and H-Mirror and V-Flip toggles

Елементи керування скрипта теплової камери: два показники температури, перемикачі режимів вимірювання та повзунки діапазону температур. Зміна будь-якого з них надсилає нове значення скрипту.#

Подання організоване за каналами. Кожен канал, який реєструє скрипт, стає секцією із назвою каналу як заголовком, а кожен запис у каналі – рядком під нею, у порядку, в якому скрипт їх додав. Коли скрипт реєструє канал або змінює форму одного з них, подання перебудовується; коли скрипт зупиняється, останні значення залишаються на екрані з вимкненими елементами керування до запуску наступного скрипта.

13.1.9.1. Віджети#

Показники та елементи керування мають очевидні форми. label – це значення лише для читання з одиницею вимірювання; запис text – це блок статичного форматованого тексту для заголовків і пояснень. Записувані типи надсилають нове значення назад скрипту в момент зміни, де зворотний виклик on_write скрипта отримує ім’я запису та значення: toggle – це перемикач, slider і spinbox задають число в межах діапазону та кроку скрипта (поле-лічильник для точного вводу), радіокнопки radio і select вибирають один із варіантів скрипта, lineedit – це поле вільного тексту, а pushbutton запускає миттєву дію. Подання зберігає ваше редагування на екрані, а не повертає його до останнього опублікованого камерою значення, поки запис триває.

На стороні скрипта весь набір – це protocol.CBORChannel з одним add на віджет і зворотним викликом для записів:

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)

Запустіть його та перемкніть панель на Канали: з’явиться секція з назвою controls із п’ятьма віджетами, а переміщення повзунка друкує в терміналі. Інші типи віджетів – spinbox, radio, lineedit, text – це ще по одному add кожен; розділ про протокол хоста розглядає їх усі.

13.1.9.2. Графіки осцилограм#

Запис waveform – це блок чергованих вибірок із частотою дискретизації (аудіо, осі акселерометра, трасування АЦП), і подання малює його як графік, що прокручується, по одній серії на вісь, з назвами від скрипта. Елементи керування графіком розташовані на його панелі інструментів і на самому графіку:

  • Тягніть, щоб панорамувати, і прокручуйте, щоб масштабувати; двічі клацніть, щоб повернутися до стеження за живим краєм. Історія задає, скільки минулих даних зберігається, щоб можна було прокрутити назад.

  • Автомасштаб підганяє вертикальну вісь під дані; при вимкненні вісь відповідає діапазону, оголошеному скриптом.

  • Клацніть правою кнопкою по графіку, щоб поставити маркер і зчитати точний час та значення вибірки або щоб встановити рівень тригера. Коли Тригер увімкнено, графік стоїть на місці, доки сигнал не перетне рівень за висхідним або спадним фронтом – осцилографічний спосіб упіймати перехідний процес – а Увімкнути знову чекає наступного.

  • Спектр перемикає графік на частотний графік тих самих даних з вибором вікна (Ганна, Геммінга, Блекмана, прямокутне), Усереднення та Утримання піку між кадрами і віссю Лог. частота. Показник під графіком називає пікову частоту та її рівень.

  • Пауза заморожує графік, не впливаючи на запис; Статистика додає рядок min / max / RMS; а меню правої кнопки миші зберігає графік як зображення.

The Channels view with two waveform records scrolling live: a 16 kHz microphone trace and a three-series accelerometer trace with its X, Y, and Z legend, each with its Record, Spectrum, Pause, and Stats buttons

Два записи осцилограм, що прокручуються в реальному часі: трасування мікрофона та трисерійне трасування IMU.#

Поле осцилограми приймає частоту дискретизації і, для кількох сигналів одночасно, кількість чергованих series та їхні назви; кожне оновлення – це сирі байти array вибірок у typecode поля:

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. Карти глибини#

Запис depth – це сітка відстаней (кадри, які створює сенсор часу прольоту), і подання малює її як карту в умовних кольорах, збільшену до висоти графіка. Панель інструментів вибирає спосіб відтворення: палітру (власні палітри камери Depth, Rainbow та Ironbow, а також світла й темна палітри для камер подій), фільтр масштабування, що збільшує маленьку сітку сенсора (бікубічний для гладкої поверхні, білінійний або найближчий сусід для одного блоку на піксель сенсора), і тональне відображення, що перетворює відстань на колір: Діапазон скрипту використовує діапазон, оголошений скриптом, Авто-діапазон розтягує кольори на відстані, фактично присутні в кожному кадрі (ігноруючи кілька крайніх відсотків), а Вирівнювання розподіляє їх за розподілом кадру, тож плоска сцена все одно показує свої деталі. Заголовок повідомляє розмір карти, оголошений діапазон та мінімум, максимум і середнє кадру; наведення курсору на карту показує відстань під ним, а Зберегти зображення записує відтворену карту в PNG.

The Channels view showing an 8 x 8 time-of-flight depth map scaled up smoothly with the Depth palette, the palette, scaling, and tone-mapping selectors in its toolbar, and the header reporting the size, declared range, and the frame's minimum, maximum, and mean

Карта глибини від сенсора часу прольоту з рукою перед сенсором, із селекторами палітри, масштабування та тонального відображення на панелі інструментів.#

Поле глибини оголошує розмір сітки та діапазон; кожне оновлення – це сітка у вигляді упакованих 32-бітних чисел з рухомою комою, саме те, що створює зчитувач модуля 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. Запис#

Кожен графік і карта мають кнопку Записати, а канал із більш ніж одним із них має панель Записати все, яка запускає їх разом. Запис пише дані в міру надходження – не зображення – у файл, формат якого визначається розширенням, вибраним у діалозі збереження: CSV для електронних таблиць та інструментів побудови графіків, WAV для одноканальних аудіоосцилограм, масиви NumPy .npy для Python, а також Edge Impulse JSON чи CBOR для завантаження безпосередньо в проєкт Edge Impulse як навчальних даних, з необов’язковою міткою, яка дає назву файлам. Пропонуються лише формати, здатні вмістити дані запису; карта глибини, наприклад, не може бути файлом WAV. Довге захоплення розбивається на пронумеровані частини, щоб жоден файл не розростався надмірно, а запис переживає повторну реєстрацію каналів скриптом. Показник поруч із кнопкою відстежує кількість записаних вибірок і розмір файлу.

Інтервал Channel Polling панелі, у розділі протоколу налаштувань, задає, як часто IDE запитує в камери нові дані каналів; значення за замовчуванням підходить скриптам, що публікують кілька разів на секунду, а скрипту, що передає аудіо, корисний коротший інтервал.

Дивись також

protocol.CBORChannel для сторони скрипта – типи записів, їхні аргументи та зворотний виклик on_write – і приклади 12-Protocol у File → Examples з робочими скриптами, що публікують показники, елементи керування та карту глибини.