v5.0.0

v5.0.0 to duże wydanie. Jego najważniejsze elementy: przebudowane łącze hosta OpenMV Protocol V2, oparte na klasach API kamery csi, które skaluje się do płytek z wieloma kamerami, uruchamialny cel symulatora, estymacja pojedynczej pozy MoveNet, MicroPython 1.28 oraz duży zestaw poprawek dotyczących kamery, ML i ToF. Wprowadza ono również szereg niezgodnych wstecz zmian w API — każda widoczna dla użytkownika zmiana od v4.8.1 jest wymieniona poniżej, wraz z dokładnym opisem migracji.

Najważniejsze elementy

  • OpenMV Protocol V2. Łącze host/IDE zostało przebudowane od podstaw: ramkowane, sekwencjonowane, z kontrolą CRC, z multipleksowanymi kanałami dla stdio, podglądu strumienia i danych użytkownika. Nowy moduł protocol pozwala skryptom tworzyć własne transporty i kanały danych. Zobacz zmiany w module protocol.

  • Oparte na klasach API kamery csi. import sensor staje się import csi / csi.CSI, z natywną obsługą wielu kamer. Zobacz migrację do csi.

  • Cel symulatora. Oprogramowanie układowe buduje się i działa teraz w symulatorze Arm FVP / QEMU (MPS2/MPS3), włącznie z emulacją NPU, ROMFS i PSRAM — skrypty wizyjne i ML mogą działać bez podłączonego sprzętu.

  • Estymacja pozy MoveNet. Nowy postprocesor MoveNet oraz dołączony model movenet_singlepose_192.tflite na OpenMV AE3 i N6.

  • MicroPython 1.28 oraz ulab 6.12.0, narzędzia ST Edge AI 4.0, a także wydzielony na zewnątrz OpenMV SDK (zobacz zmiany w budowaniu / narzędziach).

Nowe funkcje

  • Moduł protocol — tworzenie własnych transportów i kanałów danych z poziomu Pythona: protocol.init(), protocol.register(), protocol.is_active() oraz klasa protocol.ProtocolChannel z metodą send_event(), a także stałe CHANNEL_FLAG_* i CHANNEL_ID_*. Ostateczna sygnatura protocol.init() jest udokumentowana w zmianach w module protocol.

  • protocol.CBORChannel — zamrożone rozszerzenie modułu protocol, które serializuje nazwane pola do CBOR z widżetami wyświetlania (etykieta, głębia) i interaktywnymi elementami sterującymi (przełącznik, suwak, wybór).

  • Pamięć hosta i introspekcja strumienia — nowe polecenie protokołu SYS_MEMORY udostępnia IDE statystyki pamięci wykonawczej dla poszczególnych pul, a nowy ioctl strumienia STREAM_SOURCE pozwala hostowi wybrać, która kamera zasila podgląd na płytkach z wieloma kamerami (wersja protokołu 1.0.1).

  • Strumieniowanie z wielu kamercsi.CSI przyjmuje argument stream=, który wybiera, który sensor zasila podgląd w IDE; nagłówek ramki strumienia niesie teraz wygładzoną metodą EMA liczbę FPS, dzięki czemu IDE pokazuje liczbę klatek na sekundę bez szablonowego kodu clock.fps(). Zobacz migrację do csi oraz uzupełnienia csi.

  • Sensor zdarzeń GenX320 — nowy filtr Spatio-Temporal Contrast (csi.IOCTL_GENX320_SET_STC z trybami csi.GENX320_STC_DISABLE, csi.GENX320_STC_ONLY, csi.GENX320_STC_TRAIL_ONLY i csi.GENX320_STC_TRAIL) oraz odczyt surowych zdarzeń (csi.IOCTL_GENX320_READ_EVENTS_RAW), wraz z nowymi przykładowymi skryptami.

  • MoveNet — nowy postprocesor MediaPipe do estymacji pojedynczej pozy (argumenty nazwane threshold, nms_threshold, nms_sigma) zwracający ((x, y, w, h), score, keypoints) z 17-punktową tablicą punktów kluczowych COCO; na AE3 i N6 dołączono model movenet_singlepose_192.tflite wraz z przykładem.

  • ml.utils.draw_predictions() — nowy opcjonalny argument scores= dołącza poziom pewności dla każdej etykiety, czcionka i grubość obrysu ramki skalują się teraz automatycznie do szerokości obrazu, a nowy tryb format="point" rysuje znacznik środka dla detektorów typu centerpoint/peak.

  • Nowa klasa display.TVDisplay (z generycznym ioctl()) zastępuje samodzielny moduł tv. Zobacz zmiany w module display.

  • Nowy detektor find_line_segments() (ED-Lines) — dostępny teraz we wszystkich kompilacjach, z nowym argumentem threshold=. Zobacz zmiany w module image.

Pozostałe zmiany i usprawnienia

  • MicroPython zaktualizowany do 1.28.0 z bazy v4.8.1. Dodaje tryb karty SD o dużej szybkości na H5/H7/N6, taktowanie AHB5 w trybie niskiego poboru mocy oraz konfigurowalne piny JTAG jako GPIO na OPENMV_AE3.

  • ulab zaktualizowany do 6.12.0 — natywny operator % na ndarrayach (pomocnik ml.utils.mod() został usunięty; zobacz zmiany w bibliotece ML).

  • Narzędzia ST Edge AI zaktualizowane do 4.0 — wpływa na kompilację i wdrażanie modeli ST na urządzeniu.

  • ml.Model — argument nazwany load_to_fb został usunięty; pamięć modelu jest obsługiwana automatycznie przez ujednolicony alokator.

  • image.Image.scale() w miejscu — skalowanie obrazu w górę w miejscu (na przykład img.scale(x_scale=2.0, y_scale=2.0)) powiększa teraz bufor ramki, aby się zmieścił, zamiast zgłaszać błąd.

  • Większy bufor stdio — domyślny bufor tekstowy do IDE wzrósł z 512 do 1024 bajtów na OpenMV 2/3/4, Nicla Vision, AE3 i N6, dzięki czemu większe serie print() nie są obcinane.

  • Płynniejszy przepływ zdarzeń do hosta — zdarzenia NOTIFY stdout do hosta są ograniczane do co najwyżej jednego na odczyt hosta, zamiast jednego na każde print() przekraczające próg bufora pierścieniowego.

  • Przerywalne długie operacje — długie pętle oczekiwania przy rysowaniu obrazu, GPU (Nema/Dave2D) i NPU obsługują teraz zdarzenia w deterministycznym interwale, dzięki czemu skrypty pozostają responsywne na przycisk Stop w IDE podczas intensywnej pracy.

Poprawki błędów

Kamera i sensory:

  • find_apriltags() nie uszkadza już wyników na płytkach z D-cache/GPU (N6, AE3) i działa teraz na AE3.

  • Naprawiono wyjście obrazu Bayer z ISP STM32 N6 po przełączeniu formatów pikseli.

  • Naprawiono przepalenie zieleni przy automatycznym balansie bieli na jasnych scenach oraz przypadek niezainicjowanych statystyk AWB pierwszej ramki; podniesiono ograniczenie gammy ISP STM32 (z 32 do 63), aby uzyskać szerszy zakres gammy/kontrastu/jasności.

  • Automatyczna ekspozycja PS5520 nie oscyluje już w jasnym świetle; zachowanie AEC/AGC PAG7936 zostało przebudowane (połączone sterowanie, skorygowany pułap wzmocnienia).

  • Przywrócono przesyłanie oprogramowania układowego autofokusa OV5640 na Portenta/Nicla (poprawka MIMXRT I2C SUSPEND).

  • Naprawiono zakleszczenie przechwytywania z kamery, gdy ograniczenie liczby klatek na sekundę jest połączone z przechwytywaniem JPEG (STM32).

  • Odczyty GenX320 csi.IOCTL_GENX320_READ_EVENTS_RAW nie zakłócają już podglądu w IDE.

  • FLIR Lepton csi.IOCTL_LEPTON_SET_MODE poprzez csi.CSI.ioctl() działa teraz, gdy jest wywoływany z pojedynczym argumentem.

Przetwarzanie obrazu:

  • Naprawiono mieszanie alfa draw_image() / blend(), gdy podana jest maska.

  • Naprawiono kolejność bitów przy kodowaniu/dekodowaniu 1-bitowego (BINARY) PNG oraz dekodowanie skali szarości z 1 bitu.

  • Naprawiono metadane czasu trwania/FPS nagrywania mjpeg.Mjpeg.

  • Naprawiono przepełnienie stosu przy programowym dekodowaniu JPEG na płytkach z małym stosem (OpenMV M7).

  • Naprawiono automatyczne wykrywanie formatu pliku JPEG/PNG na hostach innych niż ARM (symulator).

Time-of-Flight:

  • tof.read_depth() nie zgłasza już wyjątku przy przejściowych błędach pomiaru odległości i automatycznie odzyskuje sprawność po błędach magistrali; domyślny limit czasu tof.read_depth() / tof.snapshot() wynosi teraz 100 ms (zobacz zmiany w tof).

  • Naprawiono uszkodzenie danych głębi w wielu strefach VL53L5CX / VL53L8CX.

ML i system:

  • NPU jest poprawnie czyszczone, gdy wnioskowanie zostanie przerwane na N6.

  • Przywrócono wybudzanie z głębokiego uśpienia / czuwania na N6; naprawiono zawieszanie się przy skoku do bootloadera na AE3.

  • Naprawiono wycieki pamięci przy miękkim resecie (STM32 Nema GPU) oraz przedwcześnie odzyskiwany pomocniczy bufor ramki.

  • Własne kanały protokołu w Pythonie przetrwają teraz miękki restart, transport USB odzyskuje sprawność po resecie magistrali / zablokowanych punktach końcowych, a zalewanie przerwaniami USB SOF zostało naprawione.

Sprzęt i obsługa płytek

  • OpenMV N6 — włączony Ethernet (sieć przewodowa); NPU AXI SRAM (1,75 MB) scalone we współdzieloną pulę przejściową, aby zapewnić więcej RAM między wnioskowaniami; wybudzanie z głębokiego uśpienia/czuwania; dołączone modele TFLite i kaskady Haara w ROMFS.

  • OpenMV AE3 — dołączone modele i kaskady w ROMFS; cbor2 zamrożone w oprogramowaniu układowym.

  • Alif (AE3, N6) — wybudzanie z machine.RTC w trybie niskiego poboru mocy.

  • AprilTagi w wysokiej rozdzielczościfind_apriltags() w pełnej rozdzielczości sensora na AE3, Arduino Giga i Arduino Portenta H7.

  • Cele symulatora — MPS2_AN500 / MPS3_AN547 (Arm FVP / QEMU), z emulacją NPU, ROMFS i PSRAM.

Niezgodne wstecz zmiany w API

Widoczne dla użytkownika zmiany w API między v4.8.1 a v5.0.0. Zakres: moduły C Pythona w modules/ oraz biblioteki Pythona w scripts/libraries/.

Każda zmiana jest oznaczona swoim wpływem:

  • major — większość skryptów wymaga edycji.

  • minor — wąskie API; dotyczy tylko skryptów, które go używały.

  • behavior — to samo API, inne wyniki; sprawdź ponownie dostrojone skrypty.

  • tooling — dotyczy tylko budowania ze źródeł / forków pochodnych.

Zmiany są pogrupowane według wpływu w tej kolejności — najpierw major, potem minor, behavior i tooling. Jeśli chcesz po prostu przenieść swój kod, przejdź do listy kontrolnej migracji na końcu, gdzie znajdziesz skondensowaną listę zadań. Każdy skrót commita prowadzi do jego diffu na GitHubie.

sensor zastąpiony przez csi (major)

Każdy oficjalny przykład został przepisany, aby porzucić import sensor na rzecz import csi. Starsze funkcyjne API na poziomie modułu (sensor.reset(), sensor.set_pixformat(), …) jest zastąpione opartym na klasach API csi.CSI, które naturalnie skaluje się do płytek z wieloma kamerami (csi0, csi1, …) i jest wymagane dla wszystkich nowych funkcji (argument nazwany stream=, strumieniowanie z wielu sensorów, …).

Qstr sensor jest nadal podłączony w modules/py_csi.c dla kompilacji oprogramowania układowego zgodnych wstecz, ale nie otrzyma nowych funkcji, a wszystkie przykłady, dokumentacja i kod bibliotek zakładają teraz csi.

Commity: 945c5853c, 61f835b7e

Moduł na klasę

Przed (sensor):

import sensor
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(time=2000)
img = sensor.snapshot()

Po (csi):

import csi
csi0 = csi.CSI()
csi0.reset()
csi0.pixformat(csi.RGB565)
csi0.framesize(csi.QVGA)
csi0.snapshot(time=2000)
img = csi0.snapshot()

Pary setter/getter scalone w połączone akcesory

W nowym API metoda wywołana bez argumentów zwraca bieżącą wartość; wywołana z wartością ustawia ją. Przedrostki set_*/get_* zniknęły. Nazwy metod straciły również przyrostek ing tam, gdzie był zbędny (windowingwindow). Kolumna nowego API prowadzi do dokumentacji referencyjnej.

sensor (stare)

csi.CSI (nowe)

set_pixformat(fmt) / get_pixformat()

pixformat([fmt])

set_framesize(sz) / get_framesize()

framesize([sz])

set_framerate(fps) / get_framerate()

framerate([fps])

set_windowing(roi) / get_windowing()

window([roi])

set_framebuffers(n) / get_framebuffers()

framebuffers([n])

set_gainceiling(g)

gainceiling([g])

set_brightness(v)

brightness([v])

set_contrast(v)

contrast([v])

set_saturation(v)

saturation([v])

set_quality(v)

quality([v])

set_colorbar(b)

colorbar([b])

set_special_effect(e)

special_effect([e])

set_lens_correction(...)

lens_correction(...)

set_hmirror(b) / get_hmirror()

hmirror([b])

set_vflip(b) / get_vflip()

vflip([b])

set_transpose(b) / get_transpose()

transpose([b])

set_auto_rotation(b) / get_auto_rotation()

auto_rotation([b])

set_auto_gain(b, [db, ceiling]) / get_gain_db()

auto_gain(...) / gain_db()

set_auto_exposure(b, [us]) / get_exposure_us()

auto_exposure(...) / exposure_us()

set_auto_whitebal(b, [rgb]) / get_rgb_gain_db()

auto_whitebal(...) / rgb_gain_db()

set_auto_blc(b, [regs]) / get_blc_regs()

auto_blc(...) / blc_regs()

set_color_palette(p) / get_color_palette()

color_palette([p])

set_frame_callback(cb)

frame_callback(cb)

set_vsync_callback(cb)

vsync_callback(cb)

get_id()

cid()

Funkcje bez bezpośredniego odpowiednika

sensor (usunięte)

Czego użyć zamiast tego

sensor.alloc_extra_fb(w, h, pixfmt) / sensor.dealloc_extra_fb()

image.Image (w, h, pixfmt) — zwykły obraz alokowany na stercie. Bufor ramki nie jest już dzielony na bufory użytkownika.

sensor.skip_frames(time=..., frames=...)

csi.CSI.snapshot() — pomijanie ramek zostało włączone do snapshot poprzez jego argumenty time= / frames=.

sensor.disable_delays(...) / sensor.disable_full_flush(...)

Przeniesione do konstruktora csi.CSI: csi.CSI(delays=False) / csi.CSI(fflush=False).

sensor.get_frame_available()

csi.CSI.readable()

sensor.get_fb()

Usunięte. Obraz zwracany przez csi.CSI.snapshot() jest kanonicznym uchwytem.

sensor.set_framebuffers(n, expand=True)

csi.CSI.framebuffers() — argument expand został usunięty (zobacz uzupełnienia csi).

Nowe w csi.CSI

  • csi.CSI(stream=True|False) — selektor czasu konstrukcji, który wybiera, który CSI zasila bufor ramki podglądu (zastępuje argument nazwany update= per zrzut, zobacz uzupełnienia csi).

  • csi.CSI(cid=N) / csi.devices() — obsługa wielu CSI dla płytek z więcej niż jednym sensorem obrazu.

Moduł image — przebudowa sygnatur (major)

Moduł image doświadczył najszerszej zmiany API po csi — zmieniły się sygnatury rysowania, obiekty wynikowe oraz kilka detektorów.

Argumenty współrzędnych muszą być krotkami

modules/py_image.c zostało przepisane na bazie mp_arg_parse_all. Wszystkie metody rysowania / operujące na pikselach, które wcześniej przyjmowały osobne argumenty pozycyjne x, y, ..., wymagają teraz spakowania tych współrzędnych w pojedynczą krotkę.

Commity: d18bbc472, 0c60c94b9 (PR #3061)

Przed

Po

img.draw_arrow(x0, y0, x1, y1, color=...)

img.draw_arrow((x0, y0, x1, y1), color=...)

img.draw_line(x0, y0, x1, y1, ...)

img.draw_line((x0, y0, x1, y1), ...)

img.draw_cross(x, y, ...)

img.draw_cross((x, y), ...)

img.draw_circle(x, y, r, ...)

img.draw_circle((x, y, r), ...)

img.draw_rectangle(x, y, w, h, ...)

img.draw_rectangle((x, y, w, h), ...)

img.draw_string(x, y, "txt", ...)

img.draw_string((x, y), "txt", ...)

img.draw_ellipse(x, y, rx, ry, rot, ...)

img.draw_ellipse((x, y, rx, ry, rot), ...)

img.flood_fill(x, y, ...)

img.flood_fill((x, y), ...)

img.get_pixel(x, y, rgbtuple=...)

img.get_pixel((x, y), rgbtuple=...)

img.set_pixel(x, y, color)

img.set_pixel((x, y), color)

Wszystkie są metodami image.Image.

Obiekty wynikowe przekształcone w attrtuple

Te typy są teraz obiektami attrtuple MicroPythona: similarity, statistics, percentile, threshold, line, circle, rect, qrcode, apriltag, datamatrix, barcode, displacement, kptmatch. Dostęp do atrybutów bez nawiasów jest teraz kanoniczny.

Commit: 3399d302e

Przed (styl metodowy):

img.draw_cross(match.cx(), match.cy())
img.draw_rectangle(blob.rect())

Po (styl atrybutowy):

img.draw_cross((match.cx, match.cy))
img.draw_rectangle(blob.rect)

blob i histogram pozostają bez zmian — zachowują swoje istniejące typy i akcesory () (attrtuple nie potrafi wyrazić leniwie obliczanych wartości plamy ani akcesorów histogramu przyjmujących argumenty).

Zmiana nazwy parametru haar w find_features

image.Image.find_features()scale_factor= zostało przemianowane na scale=.

Commit: be4c5cd73

get_regression — teraz zawsze odporna, dodano target_size

image.Image.get_regression() używa teraz zawsze odpornej regresji (Theila-Sena). Stara szybka ścieżka najmniejszych kwadratów została usunięta, więc argument nazwany robust= zniknął — to, co kiedyś wymagało robust=True, jest teraz jedynym zachowaniem. Nowy argument nazwany target_size=(w, h) (domyślnie (80, 60)) skaluje obszarowo ROI w dół przed dopasowaniem Theila-Sena o złożoności O(N^2), aby zawsze działało na rozsądnym rozmiarze obrazu; końce dopasowanej linii są mapowane z powrotem na współrzędne źródłowe. Przykład linear_regression_robust.py został usunięty, a linear_regression_fast.py przemianowano na linear_regression.py.

Commity: c7c2e69a0, 0ff2afa72

find_line_segments — nowy algorytm

image.Image.find_line_segments() — stary detektor LSD został zastąpiony przez ED-Lines i otrzymał nowy argument nazwany threshold=50. Wyniki wcześniej dostrojonych skryptów będą się różnić.

Commity: 87da2a7b7, 2c47b5735

Zastąpiono bibliotekę AprilTag

image.Image.find_apriltags() — detektor AprilTag został zastąpiony nową implementacją. Zestaw rodzin uległ zmianie:

Commit: e813bada7

Uzupełnienie modułu csi (minor)

Mniejsze uzupełnienia csi na bazie migracji do csi.

Usunięto snapshot(update=…)

Argument nazwany update w csi.CSI.snapshot() zniknął. Aby zapobiec zasilaniu bufora ramki podglądu przez urządzenie CSI, zrezygnuj z tego w czasie konstrukcji:

csi0 = csi.CSI(stream=False)                  # was: csi0.snapshot(update=False)
csi1.snapshot(blocking=False, image=fir_img)  # was: ...(update=False, ...)

Commity: 9a8077827, 26b79a2c5

Usunięto argument expand w framebuffers()

csi.CSI.framebuffers() — trzeci argument pozycyjny (expand) zniknął; sygnatura jest teraz framebuffers([count]).

Commit: 86cb3a5de

Moduł protocol (minor)

Dotyczy tylko skryptów, które bezpośrednio sterowały łączem hosta. Zobacz protocol.

timer_ms przemianowano na poll_ms

protocol.init() — argument timer_ms został przemianowany na poll_ms.

protocol.init(..., poll_ms=10)   # was: timer_ms=10

Commity: 8a0635e8c, 95a290607

Usunięto protocol.poll()

Zadanie protokołu jest teraz planowane wewnętrznie. Wywołania protocol.poll() zgłoszą AttributeError.

Commit: 8a0635e8c

Usunięto argument konfiguracyjny soft_reboot

protocol.init() — argument soft_reboot zniknął. Wszystkie obecne transporty tolerują miękkie restarty, więc to zachowanie jest teraz bezwarunkowe.

Commit: 0bf766aa2

moduły display (minor)

Wyjście TV przechodzi teraz przez obiekt display.TVDisplay zamiast samodzielnego modułu tv. Moduł display zyskał również generyczne ioctl().

Commity: f0accb389, 1a5a87121, 920c097a0, 9eac55098

Moduł tof (behavior)

To samo API co wcześniej; zmieniły się wartości domyślne i obsługa błędów. Zobacz tof.

Zmiana domyślnego limitu czasu

tof.read_depth() i tof.snapshot() (wywoływane z timeout=-1) mają teraz domyślnie 100 ms zamiast czekać w nieskończoność. Przekaż jawnie większą wartość, jeśli potrzebujesz starego zachowania.

Commit: b6772b80d

Automatyczne odzyskiwanie sprawności

Sterownik wykonuje teraz twardy reset magistrali I2C i sensora przy błędach pomiaru odległości / przekroczenia limitu czasu. Przykłady nie wywołują już tof.reset() w swoich obsługach wyjątków — kod użytkownika, który wykonywał ręczne odzyskiwanie, powinien je usunąć (będzie kolidował z nowym automatycznym odzyskiwaniem).

Commity: b6772b80d, 80ffaa5c3

Biblioteka ML (behavior)

To samo API, inne liczby — sprawdź ponownie każdy dostrojony potok ML.

Przetwarzanie wstępne teraz rozciąga zamiast dodawać czarne pasy (letterbox)

Normalization używa teraz image.SCALE_ASPECT_IGNORE (rozciąganie) zamiast image.SCALE_ASPECT_EXPAND (czarne pasy). Postprocessing NMS również przeszedł na niezależne skalowanie x/y.

Informacja

Wpływ. Detektory typu YOLO i regresory punktów kluczowych zazwyczaj się poprawiają. Przykłady BlazeFace, BlazePalm, FaceLandmarks i HandLandmarks wymagają teraz ręcznego kwadratowego przycięcia wejściowego ROI — przykładowe skrypty zostały zaktualizowane; własny kod użytkownika musi zrobić to samo.

Commit: 68dc29a33

Usunięto pomocnik ml.utils.mod()

ulab 6.12.0 natywnie obsługuje % na ndarrayach. Kod, który importował mod z ml.utils, musi używać a % b.

Commity: 35ece5728, 82fbd858c

Budowanie / narzędzia (tooling)

Nic z tego nie wpływa na skrypty MicroPythona. Budowanie oprogramowania układowego ze źródeł wymaga teraz zewnętrznego OpenMV SDK (1.6.0, wcześniej w drzewie repozytorium). Kilka wewnętrznych narzędzi do budowania zostało usuniętych, a N6 przeniesiono na stos TinyUSB; forki pochodne powinny przejrzeć historię repozytorium oprogramowania układowego — w szczególności sygnaturę file_open(), która straciła argument buffered.

Lista kontrolna migracji

Dla czystego przeniesienia do v5.0.0 typowa praca obejmuje:

  1. Zastąp import sensor przez import csi; csi0 = csi.CSI() i przetłumacz każde wywołanie set_*/get_* na odpowiedni akcesor csi.CSI (migracja do csi).

  2. Opakuj argumenty współrzędnych w img.draw_*, get_pixel() i set_pixel() w krotki (zmiany w module image).

  3. Usuń () z akcesorów wyników typu attrtuple, jeśli chcesz nowej idiomatycznej formy, lub pozostaw stary styl, ponieważ attrtuple nadal obsługują wywoływalne akcesory (zmiany w module image).

  4. Sprawdź find_line_segments(), get_regression() oraz każdy wybór rodziny find_apriltags() (zmiany w module image).

  5. Zmień nazwę timer_mspoll_ms w wywołaniach protocol.init(); usuń protocol.poll() i soft_reboot= (zmiany w module protocol).

  6. Dla przepływów pracy ML: ponownie przyjrzyj się każdemu modelowi, który wymagał wejścia z czarnymi pasami (zmiany w bibliotece ML).