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/ttyACMxdla USB CDC oraz/dev/ttyUSBxdla mostka USB-do-UART. W systemie macOS/dev/tty.usbmodem...lub/dev/cu.usbmodem.... W systemie WindowsCOMx.baudrate – Szybkość transmisji (baud) portu szeregowego. Przez USB wartość
921600jest 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 pozostaw0.0.
Klasa obsługuje protokół menedżera kontekstu;
with Camera(port) as cam:wywołujeconnect()przy wejściu orazdisconnect()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.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¶
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:
enable –
Truewłącza strumieniowanie,Falseje wyłącza.raw – Gdy
False(domyślnie), kamera kompresuje każdą ramkę do formatu JPEG przed umieszczeniem jej w kanale strumienia, aread_frame()dekompresuje ją po stronie hosta. GdyTrue, 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, gdyraw=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 kluczamiwidth(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ściwidth * height * 3) orazraw_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.
- Camera.channel_write(name: str, data: bytes) bool¶
Zapisuje
datado 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 razieFalse.
- 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ównamelubchannel_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)typuint: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.
13.3.1.6.7. Diagnostyka¶
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:
exclusive –
Truewybiera pomiar ekskluzywny,Falsewybiera inkluzywny.
- Camera.profiler_reset(config: list | None = None) None¶
Czyści wszystkie liczniki profilu.
config=Noneprzywraca 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_cyclesoraz krotkąeventso rozmiarze odpowiadającympmu_eventcntkamery.- 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 przyCHANNEL_REGISTERED, śledzenie gotowości ramki na kanalestream, rejestrowanie startu / stopu kanałustdin).- Parametry:
channel_id –
0dla zdarzeń systemowych, w przeciwnym razie identyfikator zarejestrowanego kanału.event – Identyfikator zdarzenia; wartości pochodzą z wyliczenia
EventTypedla 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żyjtry/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
structdla krotki argumentów. PrzekażNonedla 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
lengthbajtów począwszy odoffset. 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
datapod podanymoffset. 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
Opcodezawiera 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
0dla poleceń systemowych.data – Ładunek specyficzny dla polecenia.
- Zwraca:
Ładunek odpowiedzi lub
Nonedla poleceń takich jakOpcode.SYS_RESETiOpcode.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_idichannels_by_name, które wypełniaupdate_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 przechwytujeOMVExceptionz 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 OMVExceptionobejmuje 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.