13.3.1.6. Dokumentacja API

Publiczny interfejs pakietu openmv stanowi klasa Camera służąca do komunikacji z kamerą oraz hierarchia OMVException obsługująca błędy protokołu. Oba elementy zostały opisane na tej stronie.

13.3.1.6.1. Klasa Camera

class openmv.Camera(port: str, *, baudrate: int = 921600, crc: bool = True, seq: bool = True, ack: bool = True, events: bool = True, timeout: float = 1.0, max_retry: int = 3, max_payload: int = 4096, drop_rate: float = 0.0)

Działające po stronie hosta proxy dla kamery OpenMV osiągalnej przez port szeregowy USB.

Parametry:
  • port – Ścieżka urządzenia szeregowego. W systemie Linux jest to /dev/ttyACMx dla USB CDC oraz /dev/ttyUSBx dla mostka USB-do-UART. W systemie macOS /dev/tty.usbmodem... lub /dev/cu.usbmodem.... W systemie Windows COMx.

  • baudrate – Szybkość transmisji (baud) portu szeregowego. Przez USB wartość 921600 jest wartością magiczną, która przełącza kamerę z REPL MicroPython na protokół OpenMV – każda inna wartość na łączu USB pozostawia kamerę w trybie REPL, więc należy użyć wartości domyślnej. Na łączu UART wartość ta jest rzeczywistą szybkością transmisji linii i może być dowolnie ustawiana po obu stronach.

  • crc – Włącza walidację CRC dla każdego pakietu.

  • seq – Włącza numery sekwencyjne dla poszczególnych pakietów.

  • ack – Wymaga potwierdzenia odbioru pakietu.

  • events – Włącza powiadomienia o zdarzeniach z kamery.

  • timeout – Limit czasu pojedynczej operacji w sekundach.

  • max_retry – Liczba ponownych prób przed zgłoszeniem błędu dla nieudanego pakietu.

  • max_payload – Maksymalny negocjowany rozmiar ładunku w bajtach. Kamera może wynegocjować mniejszą wartość.

  • drop_rate – Prawdopodobieństwo odrzucenia pakietu, wyłącznie do testów, w zakresie [0.0, 1.0]. W środowisku produkcyjnym pozostaw 0.0.

Klasa obsługuje protokół menedżera kontekstu; with Camera(port) as cam: wywołuje connect() przy wejściu oraz disconnect() przy wyjściu.

13.3.1.6.2. Połączenie

Camera.connect() None

Otwiera port szeregowy i wykonuje uzgadnianie protokołu (handshake). Buforowany stan (lista kanałów, informacje o systemie, informacje o wersji) jest wypełniany jako efekt uboczny. Wywoływane automatycznie przez menedżer kontekstu.

Camera.disconnect() None

Zamyka port szeregowy i zwalnia transport. Wywoływane automatycznie przy wyjściu z menedżera kontekstu.

Camera.is_connected() bool
Zwraca:

True, jeśli port szeregowy jest otwarty.

Camera.reset() None

Resetuje kamerę. Połączenie zostaje zerwane, ponieważ kamera uruchamia się ponownie.

Camera.boot() None

Przełącza kamerę do jej bootloadera. Połączenie zostaje zerwane, ponieważ kamera uruchamia się ponownie.

Camera.update_capabilities() None

Ponownie negocjuje możliwości protokołu (CRC, sprawdzanie sekwencji, ACK, zdarzenia, maksymalny ładunek) z kamerą. Kamera zgłasza maksymalny ładunek, jaki jest w stanie obsłużyć; żądanie hosta jest przycinane do tej wartości, a uzgodnione ustawienia są odsyłane z powrotem. Wywoływane automatycznie przez connect() – nie ma powodu wywoływać tego z kodu użytkownika, chyba że flagi konstruktora muszą zostać ponownie wynegocjowane na istniejącym połączeniu.

Camera.poll_events() None

Uruchamia jednorazowo ścieżkę odbioru transportu, aby skonsumować wszelkie oczekujące zdarzenia z kamery bez wysyłania polecenia. Przydatne w długo działających programach, które przez wiele minut nie wykonują innych operacji I/O, a chcą szybko ujawniać zdarzenia rejestracji kanałów.

13.3.1.6.3. Wykonywanie skryptu

Camera.exec(script: str) None

Wgrywa script (łańcuch ze źródłem w Pythonie) do bufora stdin kamery i rozpoczyna jego wykonywanie.

Parametry:

script – Kod źródłowy MicroPython do wykonania.

Camera.stop() None

Przerywa działający skrypt. Odpowiednik przycisku Stop w IDE.

Camera.read_stdout() str | None

Odczytuje wszystkie bajty, które działający skrypt zapisał do stdout od ostatniego wywołania.

Zwraca:

Wyjście jako zdekodowany łańcuch znaków lub None, jeśli żadne dane nie oczekują.

13.3.1.6.4. Strumieniowanie

Camera.streaming(enable: bool, raw: bool = False, resolution: tuple[int, int] | None = None) None

Włącza lub wyłącza strumień ramek i wybiera format przesyłania.

Parametry:
  • enableTrue włącza strumieniowanie, False je wyłącza.

  • raw – Gdy False (domyślnie), kamera kompresuje każdą ramkę do formatu JPEG przed umieszczeniem jej w kanale strumienia, a read_frame() dekompresuje ją po stronie hosta. Gdy True, kamera wysyła przechwycony bufor pikseli bez kompresji – właściwy wybór dla kamer bez sprzętowej obsługi JPEG, gdzie programowa kompresja jest najwolniejszym etapem w pętli.

  • resolution(width, height) – docelowy rozmiar, do którego kamera skaluje w dół każdą surową ramkę przed wysłaniem, ponieważ ramki nieskompresowane są znacznie większe niż skompresowane do JPEG. Wymagane, gdy raw=True; w przeciwnym razie ignorowane.

Camera.read_frame() dict | None

Odczytuje najnowszą ramkę z kanału strumienia.

Zwraca:

None, jeśli żadna ramka nie oczekuje, albo słownik z kluczami width (int, piksele), height (int, piksele), format (int, identyfikator formatu pikseli zadeklarowany przez kamerę), depth (int, rozmiar skompresowanego obrazu w bajtach dla ramek JPEG / PNG; nieużywany dla formatów nieskompresowanych), data (bytes, RGB888 o długości width * height * 3) oraz raw_size (int, liczba bajtów wysłanych przez kamerę przez USB przed dekodowaniem).

13.3.1.6.5. Kanały niestandardowe

Camera.has_channel(name: str) bool
Zwraca:

True, jeśli na kamerze istnieje kanał zarejestrowany pod nazwą name.

Camera.channel_size(name: str) int
Zwraca:

Liczba bajtów aktualnie dostępnych w nazwanym kanale lub 0, gdy kanał jest pusty albo nie istnieje.

Camera.channel_read(name: str, size: int | None = None) bytes | None

Odczytuje dane z kanału niestandardowego.

Parametry:
  • name – Nazwa kanału zarejestrowana przez skrypt po stronie kamery.

  • size – Liczba bajtów do odczytania lub None, aby odczytać wszystko, co jest dostępne.

Zwraca:

Bajty lub None, jeśli kanał nie istnieje.

Camera.channel_write(name: str, data: bytes) bool

Zapisuje data do kanału niestandardowego. Zapisy większe niż ładunek są automatycznie dzielone na pakiety.

Parametry:
  • name – Nazwa kanału zarejestrowana przez skrypt po stronie kamery.

  • data – Ładunek typu bytes-like do wysłania.

Zwraca:

True, jeśli kanał istnieje, a zapis został wysłany, w przeciwnym razie False.

Camera.read_status() dict[str, bool]

Odpytuje każdy zarejestrowany kanał.

Zwraca:

Słownik mapujący nazwę kanału na wartość logiczną „dane są gotowe do odczytu”.

Camera.update_channels() None

Odświeża buforowaną listę kanałów z kamery. Uruchamia się automatycznie przy następnym wyszukiwaniu kanału po nazwie po nadejściu zdarzenia rejestracji kanału; aplikacja, która chce natychmiast poznać nowo zarejestrowany kanał, może wywołać to bezpośrednio.

Camera.get_channel(name: str | None = None, channel_id: int | None = None) int | str | None

Wyszukuje kanał po nazwie (zwracając jego numeryczny identyfikator) lub po identyfikatorze (zwracając jego nazwę). Najpierw odświeża pamięć podręczną kanałów poprzez update_channels(), jeśli oczekują zdarzenia rejestracji kanałów.

Parametry:
  • name – Nazwa kanału do rozwiązania na identyfikator.

  • channel_id – Identyfikator kanału do rozwiązania na nazwę.

Zwraca:

Odpowiadający identyfikator lub nazwa albo None, gdy kanał nie istnieje. Należy podać jeden z argumentów name lub channel_id.

13.3.1.6.6. Introspekcja urządzenia

Camera.version() dict

Zwraca trójki wersji protokołu, bootloadera i oprogramowania układowego kamery. Buforowane po connect(). Każda trójka jest krotką (major, minor, patch) typu int:

  • protocol_version – wersja protokołu przewodowego OpenMV implementowanego przez kamerę.

  • bootloader_version – obraz bootloadera rezydujący w pamięci flash.

  • firmware_version – aktualnie działające oprogramowanie układowe MicroPython.

Camera.system_info() dict

Zwraca informacje o możliwościach sprzętowych i pamięci kamery. Buforowane po connect(). Klucze zwróconego słownika dzielą się na cztery grupy.

Tożsamość

  • cpu_id – 32-bitowy identyfikator CPU.

  • device_id – 3-elementowa krotka 32-bitowych słów, unikalny numer seryjny urządzenia wypalony w krzemie.

  • chip_id – 3-elementowa krotka 32-bitowych słów, po jednym wpisie na każdy sensor obrazu podłączony do kamery.

  • usb_vid – identyfikator producenta USB (VID).

  • usb_pid – identyfikator produktu USB (PID).

Rozmiary pamięci (wszystkie w kilobajtach)

  • flash_size_kb – całkowita wewnętrzna pamięć flash.

  • ram_size_kb – całkowita pamięć RAM.

  • framebuffer_size_kb – pamięć RAM zarezerwowana na przechwytywanie obrazu.

  • stream_buffer_size_kb – pamięć RAM zarezerwowana na kanał strumienia, który przesyła ramki do hosta.

Flagi możliwości (po jednej wartości logicznej na funkcję, wszystkie nazwane <feature>_present)

  • gpu_present – jednostka przetwarzania grafiki.

  • npu_present – jednostka przetwarzania neuronowego.

  • isp_present – procesor sygnału obrazu.

  • venc_present – enkoder wideo.

  • jpeg_present – sprzętowy enkoder JPEG.

  • dram_present – zewnętrzna pamięć DRAM.

  • crc_present – akcelerator CRC.

  • pmu_present – jednostka monitorowania wydajności.

  • wifi_present – moduł radiowy Wi-Fi.

  • bt_present – moduł radiowy Bluetooth.

  • sd_present – gniazdo karty SD.

  • eth_present – układ PHY Ethernet.

  • multicore_present – wiele rdzeni CPU.

Inne

  • usb_highspeed – wartość logiczna, True, gdy USB wyliczyło się w trybie high-speed (USB 2.0 HS, 480 Mbps).

  • pmu_eventcnt – liczba dostępnych liczników zdarzeń PMU; 0, gdy brak PMU.

Camera.print_system_info() None

Zapisuje sformatowany blok informacji o systemie do logging na poziomie INFO. CLI używa tego przy połączeniu.

13.3.1.6.7. Diagnostyka

Camera.host_stats() dict
Zwraca:

Liczniki warstwy transportowej śledzone po stronie hosta: sent, received, checksum, sequence.

Camera.device_stats() dict
Zwraca:

Liczniki warstwy transportowej śledzone po stronie kamery: sent, received, checksum, sequence, retransmit, transport, sent_events, max_ack_queue_depth.

13.3.1.6.8. Profiler

Profiler raportuje liczbę wywołań poszczególnych funkcji oraz minimalny / maksymalny / całkowity czas wykonania dla instrumentowanych modułów oprogramowania układowego – obecnie image, ml oraz ulab. Wejście i wyjście funkcji są przechwytywane w czasie kompilacji; w czasie wykonania próbkowany jest monotoniczny licznik mikrosekund przy każdym z nich, wynik jest akumulowany dla każdej funkcji, a tabela jest udostępniana hostowi przez kanał profile.

Profiler jest wbudowywany w oprogramowanie układowe tylko wtedy, gdy do make przekazano PROFILE_ENABLE=1. Standardowe obrazy oprogramowania układowego go nie zawierają – flaga -finstrument-functions, którą kompilacja dodaje do śledzonych modułów, ma nietrywialny narzut w czasie wykonania, więc kompilacje z profilowaniem są tworzone ze źródeł na potrzeby konkretnej sesji debugowania, która ich wymaga. Gdy oprogramowanie układowe nie zostało skompilowane z tą flagą, kanał profile nie jest rejestrowany, a każda metoda profilera na tej stronie zwraca cicho, nie wykonując żadnych działań.

Performance Monitoring Unit (PMU) firmy Arm to blok sprzętowych liczników rdzenia Cortex-M55 – niewielki zestaw konfigurowalnych liczników, które śledzą liczbę cykli, trafienia i chybienia pamięci podręcznej, zachowanie rozgałęzień oraz inne zdarzenia zdefiniowane przez architekturę, nie spowalniając mierzonego kodu. Na kamerach, które go posiadają – AE3 oraz N6, dwie kamery z linii OpenMV zbudowane wokół M55 – profiler próbkuje te liczniki wraz z danymi czasowymi, a sumy zdarzeń pojawiają się w rekordzie każdej funkcji. Kamery bez PMU nadal generują rekordy czasowe; pola zdarzeń zwracane są jako zero, a profiler_event() nie wykonuje żadnej operacji.

Camera.profiler_mode(exclusive: bool = False) None

Przełącza między pomiarem czasu inkluzywnym a ekskluzywnym. Pomiar inkluzywny dolicza czas wywoływanych funkcji do funkcji wywołującej; pomiar ekskluzywny tego nie robi.

Parametry:

exclusiveTrue wybiera pomiar ekskluzywny, False wybiera inkluzywny.

Camera.profiler_reset(config: list | None = None) None

Czyści wszystkie liczniki profilu. config=None przywraca także domyślne przypisanie zdarzeń PMU.

Parametry:

config – Zarezerwowane na przyszłe nadpisania konfiguracji poszczególnych liczników. Przekaż None, aby zachować wartości domyślne.

Camera.profiler_event(counter_num: int, event_id: int) None

Przypisuje jeden ze slotów liczników PMU do określonego zdarzenia sprzętowego.

Parametry:
  • counter_num – Indeks licznika.

  • event_id – Identyfikator zdarzenia zdefiniowany przez architekturę.

Camera.read_profile() list[dict] | None

Zwraca rekordy profilu poszczególnych funkcji zebrane od ostatniego resetu. Każdy rekord jest słownikiem z polami address, caller, call_count, min_ticks, max_ticks, total_ticks, total_cycles oraz krotką events o rozmiarze odpowiadającym pmu_eventcnt kamery.

Zwraca:

Lista słowników rekordów lub None, jeśli kanał profilu nie jest dostępny albo nie zebrano żadnych danych.

13.3.1.6.9. Tworzenie podklas i wewnętrzne mechanizmy kanałów

Metody opisane powyżej obejmują każde typowe użycie pakietu. Kilka wzorców – obsługa zdarzeń po stronie kamery, na które host chce zareagować, blokowanie kanału na czas wieloetapowej wymiany, komunikacja z kanałami przenoszącymi dane o określonym kształcie zamiast strumieni bajtów albo sterowanie poleceniami kontrolnymi specyficznymi dla kanału – wymaga metod, które Camera przechowuje z prefiksem podkreślenia. Nazwy te są prywatne zgodnie z konwencją (Python ich nie zniekształca przez name-mangling), a od aplikacji, które ich potrzebują, oczekuje się utworzenia podklasy Camera albo bezpośredniego wywołania tych metod.

Tworzenie podklas w celu reagowania na zdarzenia. Każde zdarzenie emitowane przez kamerę przychodzi przez Camera._handle_event(). Utworzenie podklasy Camera i nadpisanie tej metody to sposób, w jaki aplikacja reaguje na zdarzenia zgłaszane przez jej skrypt po stronie kamery; strona Zdarzenia przedstawia pełny wzorzec.

Camera._handle_event(channel_id: int, event: int) None

Rozsyła jedno zdarzenie z kamery. Wywoływane przez warstwę transportową za każdym razem, gdy nadejdzie pakiet zdarzenia. Nadpisz w podklasie, aby dodać obsługę specyficzną dla aplikacji; wywołaj super()._handle_event(...), aby zachować domyślne zachowanie (odświeżenie listy kanałów przy CHANNEL_REGISTERED, śledzenie gotowości ramki na kanale stream, rejestrowanie startu / stopu kanału stdin).

Parametry:
  • channel_id0 dla zdarzeń systemowych, w przeciwnym razie identyfikator zarejestrowanego kanału.

  • event – Identyfikator zdarzenia; wartości pochodzą z wyliczenia EventType dla zdarzeń systemowych oraz z tego, co wybrał backend kanału po stronie kamery dla zdarzeń kanałowych.

Podklasa dodająca własne metody komunikujące się z protokołem powinna dekorować je za pomocą retry_if_failed(), aby dziedziczyły to samo zachowanie resynchronizacji i ponawiania, które ma każda dostarczana metoda na tej stronie.

static Camera.retry_if_failed(func)

Dekorator. Opakowuje metodę instancji tak, aby ponowiła próbę raz, gdy transport zgłosi ResyncException. Każda metoda wywołująca _send_cmd_wait_resp() (bezpośrednio lub przez jeden z wrapperów _channel_*) powinna posiadać ten dekorator:

class MyCamera(Camera):
    @Camera.retry_if_failed
    def my_custom_command(self, payload):
        return self._send_cmd_wait_resp(Opcode.MY_CMD,
                                        0, payload)

Blokowanie kanału zapewnia, że stan kanału nie zmieni się pomiędzy dwiema powiązanymi operacjami (na przykład _channel_size() po którym następuje _channel_read(), na kanale, który wciąż dopisuje dane). read_frame() i read_profile() korzystają z tego wewnętrznie; aplikacja sterująca kanałem niestandardowym z dostępem wieloetapowym robi to samo.

Camera._channel_lock(channel_id: int) bool

Uzyskuje wyłączną blokadę na kanale. Inne operacje hosta na tym samym kanale są blokowane do czasu zwolnienia blokady.

Parametry:

channel_id – Numeryczny identyfikator kanału, zazwyczaj rozwiązany za pomocą get_channel().

Zwraca:

True, gdy blokada została przyznana.

Camera._channel_unlock(channel_id: int) bool

Zwalnia blokadę pobraną wcześniej za pomocą _channel_lock(). Zawsze w parze z wywołaniem blokady; użyj try / finally, aby upewnić się, że odblokowanie nastąpi nawet wtedy, gdy odczyt pomiędzy nimi zgłosi wyjątek.

Parametry:

channel_id – Numeryczny identyfikator kanału, zazwyczaj rozwiązany za pomocą get_channel().

Kanały o określonym kształcie przenoszą uporządkowane rekordy zamiast płaskiego strumienia bajtów. Kanał profilera jest dostarczanym przykładem: jego kształt to (record_count, record_size), a host, który chce wiedzieć, ile rekordów oczekuje, odczytuje kształt zamiast rozmiaru w bajtach.

Camera._channel_shape(channel_id: int) tuple[int, ...]

Odczytuje deskryptor kształtu kanału.

Parametry:

channel_id – Numeryczny identyfikator kanału, zazwyczaj rozwiązany za pomocą get_channel().

Zwraca:

Krotka 32-bitowych liczb całkowitych bez znaku opisujących układ kanału. Znaczenie jest specyficzne dla kanału.

Polecenia kontrolne specyficzne dla kanału – start, stop, reset, konfiguracja – przesyłane są pojedynczym kodem operacji (CHANNEL_IOCTL) z numerem polecenia specyficznym dla kanału oraz opcjonalnym ładunkiem struct.pack. Dostarczane metody takie jak stop(), exec() i streaming() są cienkimi wrapperami wokół wywołań _channel_ioctl() na kanałach stdin i stream; niestandardowy kanał po stronie kamery, który definiuje własne menu ioctl, jest sterowany w ten sam sposób.

Camera._channel_ioctl(channel_id: int, cmd: int, fmt: str | None = None, *args) bytes | None

Wydaje polecenie ioctl na kanale.

Parametry:
  • channel_id – Numeryczny identyfikator kanału, zazwyczaj rozwiązany za pomocą get_channel().

  • cmd – Numer polecenia zdefiniowany przez backend kanału po stronie kamery.

  • fmt – Opcjonalny łańcuch formatu struct dla krotki argumentów. Przekaż None dla wywołań ioctl, które nie przyjmują argumentów.

  • args – Wartości pasujące do fmt.

Zwraca:

Dowolny ładunek zwrócony przez kanał lub None.

Warianty strumienia bajtów według identyfikatora publicznych metod kanału pomijają wyszukiwanie nazwy na identyfikator i przyjmują jawny bajtowy offset – przydatne do odczytu fragmentu ze środka dużego bufora (na przykład rekordów kanału profile).

Camera._channel_size(channel_id: int) int
Parametry:

channel_id – Numeryczny identyfikator kanału, zazwyczaj rozwiązany za pomocą get_channel().

Zwraca:

Liczba bajtów aktualnie dostępnych na kanale.

Camera._channel_read(channel_id: int, offset: int, length: int) bytes

Odczytuje length bajtów począwszy od offset. Odczyty wielopakietowe są automatycznie składane.

Parametry:
  • channel_id – Numeryczny identyfikator kanału, zazwyczaj rozwiązany za pomocą get_channel().

  • offset – Przesunięcie bajtowe, od którego rozpocząć odczyt.

  • length – Liczba bajtów do odczytania.

Camera._channel_write(channel_id: int, data: bytes, offset: int = 0) None

Zapisuje data pod podanym offset. Zapisy wielopakietowe są automatycznie dzielone na pakiety.

Parametry:
  • channel_id – Numeryczny identyfikator kanału, zazwyczaj rozwiązany za pomocą get_channel().

  • data – Ładunek typu bytes-like do zapisania.

  • offset – Przesunięcie bajtowe, od którego rozpocząć zapis.

Prymitywy protokołu to najniższy poziom udostępniany przez klasę – surowe wysłanie polecenia, pobranie surowej listy kanałów oraz ręczna resynchronizacja, na których ostatecznie zbudowane jest wszystko powyżej. Aplikacja sięga po nie, gdy wysyła kod operacji, którego klasa jeszcze nie opakowuje, albo gdy implementuje niestandardowe odzyskiwanie w podklasie.

Camera._send_cmd_wait_resp(opcode: int, channel: int = 0, data: bytes = b'') bytes | None

Wysyła polecenie protokołu i czeka na odpowiedź kamery. Prymityw, na którym zbudowana jest każda inna metoda w tej sekcji.

Parametry:
  • opcode – Numer polecenia. Dostarczane wyliczenie Opcode zawiera kody dostarczane wraz z oprogramowaniem układowym, ale parametr jest po prostu liczbą całkowitą – niestandardowa kompilacja oprogramowania układowego może zdefiniować własne kody i na nie odpowiadać.

  • channel – Identyfikator kanału lub 0 dla poleceń systemowych.

  • data – Ładunek specyficzny dla polecenia.

Zwraca:

Ładunek odpowiedzi lub None dla poleceń takich jak Opcode.SYS_RESET i Opcode.SYS_BOOT, które zrywają połączenie.

Camera._channel_list() dict

Pobiera bieżącą listę kanałów z kamery bez naruszania buforowanych słowników channels_by_id i channels_by_name, które wypełnia update_channels(). Przydatne dla podklasy, która chce bezpośrednio zbadać stan kanałów kamery.

Zwraca:

Słownik mapujący identyfikator kanału na {'name': str, 'flags': int}.

Camera._resync() None

Ponownie uruchamia uzgadnianie protokołu od zera. Wywoływane automatycznie przez connect() przy początkowym połączeniu oraz przez każdą publiczną metodę, która przechwytuje OMVException z transportu. Aplikacja implementująca własną pętlę odzyskiwania w podklasie może wywołać to bezpośrednio po obsłużeniu błędu źródłowego.

13.3.1.6.10. Wyjątki

exception openmv.OMVException

Klasa bazowa dla każdego błędu na poziomie protokołu. Wszystkie trzy poniższe podklasy z niej dziedziczą, więc pojedyncze except OMVException obejmuje całą powierzchnię błędów.

exception openmv.TimeoutException

Kamera nie odpowiedziała w skonfigurowanym limicie czasu. Podklasa OMVException.

exception openmv.ChecksumException

CRC pakietu nie pasował. Zgłaszane po wyczerpaniu przez protokół budżetu ponownych prób. Podklasa OMVException.

exception openmv.SequenceException

Pakiet nadszedł z nieoczekiwanym numerem sekwencyjnym po ponownych próbach. Podklasa OMVException.