13.3.1.6. Tài liệu tham khảo API

Bề mặt công khai của gói openmv là lớp Camera để giao tiếp với cam và hệ thống phân cấp OMVException dành cho các lỗi giao thức. Cả hai đều được ghi lại trên trang này.

13.3.1.6.1. Lớp 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)

Proxy phía máy chủ cho một OpenMV cam được kết nối qua USB serial.

Tham số:
  • port -- Đường dẫn thiết bị serial. Trên Linux, /dev/ttyACMx cho USB CDC và /dev/ttyUSBx cho cầu nối USB-to-UART. Trên macOS, /dev/tty.usbmodem... hoặc /dev/cu.usbmodem.... Trên Windows, COMx.

  • baudrate -- Tốc độ baud serial. Qua USB, 921600giá trị đặc biệt chuyển cam từ MicroPython REPL sang giao thức OpenMV -- bất kỳ giá trị nào khác trên liên kết USB sẽ giữ cam ở chế độ REPL, vì vậy phải sử dụng giá trị mặc định. Qua liên kết UART, giá trị là tốc độ baud thực của đường truyền và có thể được đặt tự do ở cả hai phía.

  • crc -- Bật xác thực CRC trên mỗi gói tin.

  • seq -- Bật số thứ tự cho từng gói tin.

  • ack -- Yêu cầu xác nhận gói tin.

  • events -- Bật thông báo sự kiện từ cam.

  • timeout -- Thời gian chờ cho mỗi thao tác tính bằng giây.

  • max_retry -- Số lần thử lại trước khi báo lỗi khi gói tin thất bại.

  • max_payload -- Kích thước payload tối đa đã thỏa thuận tính bằng byte. Cam có thể thỏa thuận xuống thấp hơn.

  • drop_rate -- Xác suất thử nghiệm khi làm mất gói tin, trong khoảng [0.0, 1.0]. Để là 0.0 trong môi trường sản xuất.

Lớp này hỗ trợ giao thức context-manager; with Camera(port) as cam: gọi connect() khi vào và disconnect() khi thoát.

13.3.1.6.2. Kết nối

Camera.connect() None

Mở cổng serial và thực hiện bắt tay giao thức. Trạng thái đã lưu trong bộ nhớ đệm (danh sách kênh, thông tin hệ thống, thông tin phiên bản) được điền như một hiệu ứng phụ. Được gọi tự động bởi context manager.

Camera.disconnect() None

Đóng cổng serial và giải phóng transport. Được gọi tự động khi context manager thoát.

Camera.is_connected() bool
Trả về:

True nếu cổng serial đang mở.

Camera.reset() None

Đặt lại cam. Kết nối bị ngắt vì cam khởi động lại.

Camera.boot() None

Nhảy cam vào bootloader của nó. Kết nối bị ngắt vì cam khởi động lại.

Camera.update_capabilities() None

Thương lượng lại các khả năng giao thức (CRC, kiểm tra thứ tự, ACK, sự kiện, payload tối đa) với cam. Cam báo cáo payload tối đa mà nó có thể xử lý; yêu cầu của máy chủ bị cắt xuống mức đó và các cài đặt đã thỏa thuận được đẩy lại. Được gọi tự động bởi connect() -- không có lý do để gọi nó từ mã người dùng trừ khi các cờ constructor cần được thương lượng lại trên kết nối hiện có.

Camera.poll_events() None

Chạy đường dẫn nhận của transport một lần để tiêu thụ bất kỳ sự kiện đang chờ nào từ cam mà không gửi lệnh. Hữu ích trong các chương trình chạy dài mà không có I/O khác trong nhiều phút và muốn hiển thị sự kiện đăng ký kênh kịp thời.

13.3.1.6.3. Thực thi tập lệnh

Camera.exec(script: str) None

Tải lên script (chuỗi nguồn Python) vào bộ đệm stdin của cam và bắt đầu thực thi.

Tham số:

script -- Mã nguồn MicroPython để thực thi.

Camera.stop() None

Ngắt tập lệnh đang chạy. Tương đương với nút Stop của IDE.

Camera.read_stdout() str | None

Đọc bất kỳ byte nào mà tập lệnh đang chạy đã ghi vào stdout kể từ lần gọi cuối cùng.

Trả về:

Đầu ra dưới dạng chuỗi đã giải mã, hoặc None nếu không có dữ liệu đang chờ.

13.3.1.6.4. Truyền phát

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

Bật hoặc tắt luồng khung hình và chọn định dạng truyền qua mạng.

Tham số:
  • enable -- True bật truyền phát, False tắt.

  • raw -- Khi False (mặc định), cam nén JPEG từng khung hình trước khi đặt vào kênh luồng và read_frame() giải nén trên máy chủ. Khi True, cam gửi bộ đệm điểm ảnh đã chụp mà không nén -- lựa chọn phù hợp trên các cam không có hỗ trợ JPEG phần cứng, nơi nén phần mềm là bước chậm nhất trong vòng lặp.

  • resolution -- (width, height) đích mà cam thu nhỏ mỗi khung hình thô xuống trước khi gửi, vì các khung hình không nén lớn hơn nhiều so với các khung hình nén JPEG. Bắt buộc khi raw=True; bị bỏ qua nếu không.

Camera.read_frame() dict | None

Đọc khung hình mới nhất từ kênh luồng.

Trả về:

None nếu không có khung hình đang chờ, hoặc một dict với các khóa width (int, điểm ảnh), height (int, điểm ảnh), format (int, định danh định dạng điểm ảnh mà cam đã khai báo), depth (int, kích thước ảnh nén tính bằng byte cho khung hình JPEG / PNG; không dùng cho định dạng không nén), data (bytes, RGB888 có độ dài width * height * 3), và raw_size (int, byte mà cam đã gửi qua USB trước khi giải mã).

13.3.1.6.5. Kênh tùy chỉnh

Camera.has_channel(name: str) bool
Trả về:

True nếu một kênh đã đăng ký với name tồn tại trên cam.

Camera.channel_size(name: str) int
Trả về:

Số byte mà kênh được đặt tên hiện có sẵn, hoặc 0 khi kênh trống hoặc không tồn tại.

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

Đọc từ kênh tùy chỉnh.

Tham số:
  • name -- Tên kênh được đăng ký bởi tập lệnh phía cam.

  • size -- Số byte cần đọc, hoặc None để đọc bất kỳ thứ gì có sẵn.

Trả về:

Các byte, hoặc None nếu kênh không tồn tại.

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

Ghi data vào kênh tùy chỉnh. Các lần ghi lớn hơn payload được tự động chia thành nhiều gói.

Tham số:
  • name -- Tên kênh được đăng ký bởi tập lệnh phía cam.

  • data -- Payload dạng byte để gửi.

Trả về:

True nếu kênh tồn tại và lần ghi đã được gửi, False nếu không.

Camera.read_status() dict[str, bool]

Thăm dò mọi kênh đã đăng ký.

Trả về:

Dict ánh xạ tên kênh với giá trị boolean của "dữ liệu sẵn sàng để đọc".

Camera.update_channels() None

Làm mới danh sách kênh đã lưu trong bộ nhớ đệm từ cam. Chạy tự động vào lần tiếp theo khi thực hiện tra cứu kênh theo tên sau khi sự kiện đăng ký kênh đến; một ứng dụng muốn tìm hiểu kênh mới đăng ký ngay lập tức có thể gọi trực tiếp.

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

Tra cứu một kênh theo tên (trả về ID số của nó) hoặc theo ID (trả về tên của nó). Làm mới bộ nhớ đệm kênh qua update_channels() trước nếu các sự kiện đăng ký kênh đang chờ xử lý.

Tham số:
  • name -- Tên kênh để phân giải thành ID.

  • channel_id -- ID kênh để phân giải thành tên.

Trả về:

ID hoặc tên tương ứng, hoặc None khi kênh không tồn tại. Phải cung cấp một trong name hoặc channel_id.

13.3.1.6.6. Kiểm tra thiết bị

Camera.version() dict

Trả về các bộ ba phiên bản giao thức, bootloader và firmware của cam. Được lưu trong bộ nhớ đệm sau connect(). Mỗi bộ ba là một tuple (major, minor, patch) của int:

  • protocol_version -- phiên bản của giao thức dây OpenMV mà cam triển khai.

  • bootloader_version -- ảnh bootloader cư trú trong bộ nhớ flash.

  • firmware_version -- firmware MicroPython hiện đang chạy.

Camera.system_info() dict

Trả về thông tin khả năng phần cứng và bộ nhớ của cam. Được lưu trong bộ nhớ đệm sau connect(). Các khóa của dict trả về thuộc bốn nhóm.

Danh tính

  • cpu_id -- định danh CPU 32-bit.

  • device_id -- bộ ba 3 phần tử gồm các từ 32-bit, số serial thiết bị duy nhất được tích hợp vào silicon.

  • chip_id -- bộ ba 3 phần tử gồm các từ 32-bit, một mục cho mỗi cảm biến ảnh kết nối với cam.

  • usb_vid -- ID nhà cung cấp USB.

  • usb_pid -- ID sản phẩm USB.

Kích thước bộ nhớ (tất cả tính bằng kilobyte)

  • flash_size_kb -- tổng bộ nhớ flash nội bộ.

  • ram_size_kb -- tổng RAM.

  • framebuffer_size_kb -- RAM dành riêng cho chụp ảnh.

  • stream_buffer_size_kb -- RAM dành riêng cho kênh luồng chuyển khung hình đến máy chủ.

Cờ khả năng (một boolean cho mỗi tính năng, tất cả có tên <feature>_present)

  • gpu_present -- đơn vị xử lý đồ họa.

  • npu_present -- đơn vị xử lý nơ-ron.

  • isp_present -- bộ xử lý tín hiệu ảnh.

  • venc_present -- bộ mã hóa video.

  • jpeg_present -- bộ mã hóa JPEG phần cứng.

  • dram_present -- DRAM ngoài.

  • crc_present -- bộ tăng tốc CRC.

  • pmu_present -- đơn vị giám sát hiệu năng.

  • wifi_present -- radio Wi-Fi.

  • bt_present -- radio Bluetooth.

  • sd_present -- khe cắm thẻ SD.

  • eth_present -- PHY Ethernet.

  • multicore_present -- nhiều lõi CPU.

Khác

  • usb_highspeed -- boolean, True khi USB liệt kê ở chế độ tốc độ cao (USB 2.0 HS, 480 Mbps).

  • pmu_eventcnt -- số lượng bộ đếm sự kiện PMU có sẵn; 0 khi không có PMU.

Camera.print_system_info() None

Ghi khối thông tin hệ thống đã định dạng vào logging ở mức INFO. CLI sử dụng cái này khi kết nối.

13.3.1.6.7. Chẩn đoán

Camera.host_stats() dict
Trả về:

Các bộ đếm tầng transport được theo dõi ở phía máy chủ: sent, received, checksum, sequence.

Camera.device_stats() dict
Trả về:

Các bộ đếm tầng transport được theo dõi ở phía cam: sent, received, checksum, sequence, retransmit, transport, sent_events, max_ack_queue_depth.

13.3.1.6.8. Profiler

Profiler báo cáo số lần gọi hàm và thời gian thực thi tối thiểu / tối đa / tổng cộng cho các mô-đun firmware được đo đạc -- hiện tại là image, mlulab. Lối vào và lối ra hàm được chặn lại tại thời điểm biên dịch; runtime lấy mẫu một bộ đếm microsecond đơn điệu trên mỗi lần, tích lũy kết quả cho mỗi hàm và hiển thị bảng cho máy chủ thông qua kênh profile.

Profiler chỉ được tích hợp vào firmware khi PROFILE_ENABLE=1 được truyền vào make. Các ảnh firmware tiêu chuẩn không bao gồm nó -- cờ -finstrument-functions mà build thêm vào các mô-đun được theo dõi có overhead runtime không nhỏ, vì vậy các build profiling được tạo từ nguồn cho phiên gỡ lỗi cụ thể cần chúng. Khi firmware không được build với cờ, kênh profile không được đăng ký và mọi phương thức profiler trên trang này đều trả về một cách im lặng mà không làm gì.

Performance Monitoring Unit (PMU) của Arm là khối bộ đếm phần cứng của Cortex-M55 -- một tập hợp nhỏ các bộ đếm có thể cấu hình theo dõi số chu kỳ, truy cập cache và lỗi cache, hành vi rẽ nhánh và các sự kiện được xác định theo kiến trúc khác mà không làm chậm mã đang được đo. Trên các cam có PMU -- AE3 và N6, hai cam trong dòng sản phẩm OpenMV được xây dựng trên M55 -- profiler lấy mẫu các bộ đếm này cùng với dữ liệu thời gian và tổng số sự kiện xuất hiện trong mỗi bản ghi theo hàm. Các cam không có PMU vẫn tạo ra các bản ghi thời gian; các trường sự kiện trả về bằng không và profiler_event() là no-op.

Camera.profiler_mode(exclusive: bool = False) None

Chuyển đổi giữa thời gian đo bao hàm và loại trừ. Thời gian bao hàm tính thời gian của callee vào caller; thời gian loại trừ thì không.

Tham số:

exclusive -- True chọn thời gian loại trừ, False chọn thời gian bao hàm.

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

Xóa tất cả bộ đếm profile. config=None cũng khôi phục việc gán sự kiện PMU mặc định.

Tham số:

config -- Dành cho các ghi đè cấu hình theo bộ đếm trong tương lai. Truyền None để giữ các giá trị mặc định.

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

Gắn một trong các khe bộ đếm PMU với một sự kiện phần cứng cụ thể.

Tham số:
  • counter_num -- Chỉ mục bộ đếm.

  • event_id -- Định danh sự kiện được xác định theo kiến trúc.

Camera.read_profile() list[dict] | None

Trả về các bản ghi profile theo hàm được thu thập kể từ lần đặt lại cuối cùng. Mỗi bản ghi là một dict với address, caller, call_count, min_ticks, max_ticks, total_ticks, total_cycles và một tuple events có kích thước bằng pmu_eventcnt của cam.

Trả về:

Danh sách các dict bản ghi, hoặc None nếu kênh profile không có sẵn hoặc chưa có dữ liệu được thu thập.

13.3.1.6.9. Kế thừa và nội bộ kênh

Các phương thức được ghi lại ở trên bao gồm mọi cách sử dụng phổ biến của gói. Một vài mẫu -- xử lý các sự kiện phía cam mà máy chủ muốn phản ứng, khóa kênh cho một trao đổi nhiều bước, nói chuyện với các kênh mang dữ liệu có hình dạng thay vì luồng byte, hoặc điều khiển các lệnh điều khiển dành riêng cho kênh -- cần các phương thức mà Camera giữ tiền tố với dấu gạch dưới. Các tên này là private theo quy ước (Python không làm xáo trộn tên chúng), và các ứng dụng cần chúng được kỳ vọng sẽ kế thừa Camera hoặc gọi các phương thức trực tiếp.

Kế thừa để phản ứng với sự kiện. Mọi sự kiện mà cam phát ra đều đến qua Camera._handle_event(). Kế thừa Camera và ghi đè phương thức là cách một ứng dụng phản ứng với các sự kiện mà tập lệnh phía cam của nó đưa ra; trang Sự kiện hướng dẫn toàn bộ mẫu.

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

Điều phối một sự kiện từ cam. Được gọi bởi tầng transport bất cứ khi nào một gói sự kiện đến. Ghi đè trong lớp con để thêm xử lý dành riêng cho ứng dụng; gọi super()._handle_event(...) để giữ hành vi mặc định (làm mới danh sách kênh trên CHANNEL_REGISTERED, theo dõi sẵn sàng khung hình trên kênh stream, ghi nhật ký bắt đầu / dừng kênh stdin).

Tham số:
  • channel_id -- 0 cho sự kiện hệ thống, nếu không thì là ID kênh đã đăng ký.

  • event -- Định danh sự kiện; các giá trị đến từ enum EventType cho sự kiện hệ thống và từ bất kỳ thứ gì mà backend kênh phía cam đã chọn cho sự kiện kênh.

Lớp con thêm các phương thức nói chuyện giao thức của riêng mình nên trang trí chúng bằng retry_if_failed() để chúng kế thừa cùng hành vi đồng bộ lại và thử lại mà mọi phương thức được cung cấp trên trang này có.

static Camera.retry_if_failed(func)

Decorator. Bao bọc một phương thức instance để nó thử lại một lần khi transport đưa ra ResyncException. Bất kỳ phương thức nào gọi vào _send_cmd_wait_resp() (trực tiếp hoặc qua một trong các wrapper _channel_*) nên mang decorator này:

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

Khóa kênh đảm bảo trạng thái của kênh không thay đổi giữa hai thao tác liên quan (ví dụ _channel_size() theo sau là _channel_read() trên kênh tiếp tục thêm dữ liệu). read_frame()read_profile() sử dụng điều này nội bộ; một ứng dụng điều khiển kênh tùy chỉnh với quyền truy cập nhiều bước cũng làm tương tự.

Camera._channel_lock(channel_id: int) bool

Lấy khóa độc quyền trên một kênh. Các thao tác máy chủ khác trên cùng kênh sẽ bị chặn cho đến khi khóa được giải phóng.

Tham số:

channel_id -- ID kênh số, thường được phân giải bằng get_channel().

Trả về:

True khi khóa được cấp.

Camera._channel_unlock(channel_id: int) bool

Giải phóng khóa đã lấy trước đó bằng _channel_lock(). Luôn được ghép với một lần gọi khóa; sử dụng try / finally để đảm bảo việc mở khóa xảy ra ngay cả khi việc đọc ở giữa đưa ra lỗi.

Tham số:

channel_id -- ID kênh số, thường được phân giải bằng get_channel().

Kênh có hình dạng mang các bản ghi có cấu trúc thay vì luồng byte phẳng. Kênh profiler là ví dụ được cung cấp: hình dạng của nó là (record_count, record_size) và máy chủ muốn biết có bao nhiêu bản ghi đang chờ đọc hình dạng thay vì kích thước byte.

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

Đọc bộ mô tả hình dạng của một kênh.

Tham số:

channel_id -- ID kênh số, thường được phân giải bằng get_channel().

Trả về:

Tuple của các số nguyên 32-bit không dấu mô tả bố cục của kênh. Ý nghĩa là dành riêng cho kênh.

Các lệnh điều khiển dành riêng cho kênh -- bắt đầu, dừng, đặt lại, cấu hình -- sử dụng một opcode duy nhất (CHANNEL_IOCTL) với số lệnh dành riêng cho kênh và payload struct.pack tùy chọn. Các phương thức được cung cấp như stop(), exec()streaming() là các wrapper mỏng xung quanh các lệnh gọi _channel_ioctl() với các kênh stdinstream; một kênh phía cam tùy chỉnh xác định menu ioctl riêng của nó được điều khiển theo cách tương tự.

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

Phát lệnh ioctl trên một kênh.

Tham số:
  • channel_id -- ID kênh số, thường được phân giải bằng get_channel().

  • cmd -- Số lệnh được xác định bởi backend kênh phía cam.

  • fmt -- Chuỗi định dạng struct tùy chọn cho tuple tham số. Truyền None cho các ioctl không nhận tham số.

  • args -- Các giá trị khớp với fmt.

Trả về:

Bất kỳ payload nào mà kênh trả về, hoặc None.

Các biến thể luồng byte theo ID của các phương thức kênh công khai bỏ qua tra cứu tên-thành-ID và chấp nhận một offset byte rõ ràng -- hữu ích để đọc một đoạn từ giữa bộ đệm lớn (ví dụ các bản ghi kênh profile).

Camera._channel_size(channel_id: int) int
Tham số:

channel_id -- ID kênh số, thường được phân giải bằng get_channel().

Trả về:

Số byte hiện có sẵn trên kênh.

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

Đọc length byte bắt đầu từ offset. Các lần đọc nhiều gói được tự động tái hợp.

Tham số:
  • channel_id -- ID kênh số, thường được phân giải bằng get_channel().

  • offset -- Offset byte để bắt đầu đọc.

  • length -- Số byte cần đọc.

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

Ghi data tại offset đã cho. Các lần ghi nhiều gói được tự động chia thành các gói.

Tham số:
  • channel_id -- ID kênh số, thường được phân giải bằng get_channel().

  • data -- Payload dạng byte để ghi.

  • offset -- Offset byte để bắt đầu ghi.

Các nguyên thủy giao thức là cấp thấp nhất mà lớp hiển thị -- các mục gửi-lệnh-thô, lấy-danh-sách-kênh-thô và đồng-bộ-lại-thủ-công mà mọi thứ bên trên cuối cùng được xây dựng trên đó. Một ứng dụng tiếp cận chúng khi gửi opcode mà lớp chưa bao bọc, hoặc khi triển khai khôi phục tùy chỉnh trong một lớp con.

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

Gửi lệnh giao thức và chờ phản hồi của cam. Nguyên thủy mà mọi phương thức khác trong phần này được xây dựng trên.

Tham số:
  • opcode -- Số lệnh. Enum Opcode được cung cấp liệt kê các mã mà firmware cung cấp, nhưng tham số chỉ là một số nguyên -- một bản build firmware tùy chỉnh có thể xác định và phản hồi các mã riêng của nó.

  • channel -- ID kênh, hoặc 0 cho lệnh hệ thống.

  • data -- Payload dành riêng cho lệnh.

Trả về:

Payload phản hồi, hoặc None cho các lệnh như Opcode.SYS_RESETOpcode.SYS_BOOT làm ngắt kết nối.

Camera._channel_list() dict

Lấy danh sách kênh hiện tại từ cam mà không chạm vào các từ điển channels_by_idchannels_by_name đã lưu trong bộ nhớ đệm mà update_channels() điền vào. Hữu ích cho lớp con muốn kiểm tra trạng thái kênh của cam trực tiếp.

Trả về:

Dict ánh xạ ID kênh với {'name': str, 'flags': int}.

Camera._resync() None

Chạy lại bắt tay giao thức từ đầu. Được gọi tự động bởi connect() khi kết nối ban đầu và bởi mọi phương thức công khai bắt OMVException từ transport. Một ứng dụng triển khai vòng khôi phục riêng trong một lớp con có thể gọi trực tiếp sau khi xử lý lỗi cơ bản.

13.3.1.6.10. Các ngoại lệ

exception openmv.OMVException

Lớp cơ sở cho mọi lỗi cấp giao thức. Ba lớp con bên dưới đều kế thừa từ nó, vì vậy một except OMVException duy nhất bao gồm toàn bộ bề mặt lỗi.

exception openmv.TimeoutException

Cam không phản hồi trong thời gian chờ đã cấu hình. Lớp con của OMVException.

exception openmv.ChecksumException

CRC của gói tin không khớp. Được đưa ra sau khi giao thức đã cạn kiệt ngân sách thử lại. Lớp con của OMVException.

exception openmv.SequenceException

Một gói tin đến với số thứ tự không mong đợi sau khi thử lại. Lớp con của OMVException.