13.3.1.6. מדריך ה-API¶
המשטח הציבורי של החבילה openmv הוא מחלקת Camera לתקשורת עם מצלמה והיררכיית OMVException לשגיאות פרוטוקול. שניהם מתועדים בעמוד זה.
13.3.1.6.1. מחלקת 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)¶
מתווך בצד המארח עבור מצלמת OpenMV המחוברת דרך USB serial.
- פרמטרים:
port – נתיב התקן ה-serial. ב-Linux,
/dev/ttyACMxעבור USB CDC ו-/dev/ttyUSBxעבור גשר USB-to-UART. ב-macOS,/dev/tty.usbmodem...או/dev/cu.usbmodem.... ב-Windows,COMx.baudrate – קצב הבָּאוּד (baud rate) של ה-serial. דרך USB,
921600הוא הערך הקסום שמעביר את המצלמה מ-REPL של MicroPython לפרוטוקול OpenMV – כל ערך אחר על קישור USB משאיר את המצלמה במצב REPL, ולכן יש להשתמש בברירת המחדל. דרך קישור UART הערך הוא קצב הבָּאוּד בפועל של הקו וניתן להגדירו באופן חופשי בשני הצדדים.crc – הפעלת אימות CRC על כל מנה.
seq – הפעלת מספרי רצף לכל מנה.
ack – דרישת אישור קבלה (acknowledgement) למנות.
events – הפעלת התראות אירועים מהמצלמה.
timeout – פסק זמן (timeout) לכל פעולה, בשניות.
max_retry – מספר הניסיונות החוזרים לפני העלאת חריגה על מנה שכשלה.
max_payload – גודל המטען המרבי המוסכם בבתים. ייתכן שהמצלמה תתמקח כלפי מטה.
drop_rate – הסתברות לזריקת מנה, לצורכי בדיקה בלבד, בטווח
[0.0, 1.0]. השאר על0.0בסביבת ייצור.
המחלקה תומכת בפרוטוקול ה-context-manager;
with Camera(port) as cam:קורא ל-connect()בכניסה ול-disconnect()ביציאה.
13.3.1.6.2. חיבור¶
- Camera.connect() None¶
פתיחת יציאת ה-serial וביצוע לחיצת היד (handshake) של הפרוטוקול. מצב שנשמר במטמון (רשימת ערוצים, מידע מערכת, מידע גרסה) מאוכלס כתופעת לוואי. נקרא אוטומטית על ידי ה-context manager.
- Camera.disconnect() None¶
סגירת יציאת ה-serial ושחרור ההובלה. נקרא אוטומטית כאשר ה-context manager יוצא.
- Camera.boot() None¶
קפיצת המצלמה אל המאתחל (bootloader) שלה. החיבור מתנתק מכיוון שהמצלמה מאתחלת מחדש.
- Camera.update_capabilities() None¶
ניהול משא ומתן מחדש על יכולות הפרוטוקול (CRC, בדיקת רצף, ACKs, אירועים, מטען מרבי) מול המצלמה. המצלמה מדווחת על המטען המרבי שביכולתה לטפל בו; בקשת המארח נחתכת לגודל זה וההגדרות המוסכמות נשלחות בחזרה. נקרא אוטומטית על ידי
connect()– אין סיבה לקרוא לו מקוד המשתמש אלא אם יש צורך לנהל מחדש משא ומתן על דגלי הבנאי על חיבור קיים.
13.3.1.6.3. הרצת סקריפט¶
13.3.1.6.4. הזרמה¶
- Camera.streaming(enable: bool, raw: bool = False, resolution: tuple[int, int] | None = None) None¶
הפעלה או כיבוי של זרם הפריימים ובחירת הפורמט שעל החוט.
- פרמטרים:
enable –
Trueמפעיל הזרמה,Falseמכבה אותה.raw – כאשר
False(ברירת מחדל), המצלמה דוחסת כל פריים ל-JPEG לפני הצבתו בערוץ הזרם ו-read_frame()מבצע פענוח דחיסה בצד המארח. כאשרTrue, המצלמה שולחת את חוצץ הפיקסלים שצולם ללא דחיסה – הבחירה הנכונה במצלמות ללא תמיכת חומרה ב-JPEG, שבהן דחיסה תוכנתית היא השלב האיטי ביותר בלולאה.resolution –
(width, height)היעד שאליו המצלמה מקטינה כל פריים גולמי לפני השליחה, מכיוון שפריימים לא דחוסים גדולים בהרבה מפריימים דחוסי-JPEG. נדרש כאשרraw=True; אחרת מתעלמים ממנו.
- Camera.read_frame() dict | None¶
קריאת הפריים האחרון מערוץ הזרם.
- מחזיר:
Noneאם אין פריים ממתין, או מילון עם המפתחותwidth(int, פיקסלים),height(int, פיקסלים),format(int, מזהה פורמט הפיקסל שהמצלמה הצהירה עליו),depth(int, גודל התמונה הדחוסה בבתים עבור פריימי JPEG / PNG; לא בשימוש עבור פורמטים לא דחוסים),data(bytes, RGB888 באורךwidth * height * 3), ו-raw_size(int, הבתים שהמצלמה שלחה דרך USB לפני הפענוח).
13.3.1.6.5. ערוצים מותאמים אישית¶
- Camera.channel_size(name: str) int¶
- מחזיר:
מספר הבתים הזמינים כעת בערוץ הנקוב, או
0כאשר הערוץ ריק או אינו קיים.
- Camera.channel_write(name: str, data: bytes) bool¶
כתיבת
dataלערוץ מותאם אישית. כתיבות גדולות מהמטען מפוצלות אוטומטית למספר מנות.- פרמטרים:
name – שם הערוץ שנרשם על ידי הסקריפט שבצד המצלמה.
data – מטען מסוג bytes-like לשליחה.
- מחזיר:
Trueאם הערוץ קיים והכתיבה נשלחה,Falseאחרת.
- Camera.read_status() dict[str, bool]¶
תשאול כל ערוץ רשום.
- מחזיר:
מילון הממפה שם ערוץ לערך בוליאני של ”נתונים מוכנים לקריאה“.
- Camera.update_channels() None¶
רענון רשימת הערוצים שבמטמון מהמצלמה. רץ אוטומטית בפעם הבאה שמתבצע חיפוש ערוץ-לפי-שם לאחר הגעת אירוע רישום-ערוץ; יישום שרוצה ללמוד מיד על ערוץ שזה עתה נרשם יכול לקרוא לזה ישירות.
- Camera.get_channel(name: str | None = None, channel_id: int | None = None) int | str | None¶
חיפוש ערוץ לפי שם (מחזיר את המזהה המספרי שלו) או לפי מזהה (מחזיר את שמו). מרענן תחילה את מטמון הערוצים באמצעות
update_channels()אם ממתינים אירועי רישום-ערוץ.- פרמטרים:
name – שם ערוץ לפענוח למזהה.
channel_id – מזהה ערוץ לפענוח לשם.
- מחזיר:
המזהה או השם המתאים, או
Noneכאשר הערוץ אינו קיים. יש לספק אחד מביןnameאוchannel_id.
13.3.1.6.6. התבוננות פנימית בהתקן¶
- Camera.version() dict¶
החזרת שלשות גרסת הפרוטוקול, המאתחל (bootloader) והקושחה של המצלמה. נשמר במטמון לאחר
connect(). כל שלשה היא tuple מסוג(major, minor, patch)שלint:protocol_version– גרסת פרוטוקול החוט (wire protocol) של OpenMV שהמצלמה מממשת.bootloader_version– תמונת המאתחל (bootloader) השוכנת בזיכרון פלאש (flash).firmware_version– קושחת MicroPython הרצה כעת.
- Camera.system_info() dict¶
החזרת מידע על יכולות החומרה והזיכרון של המצלמה. נשמר במטמון לאחר
connect(). מפתחות המילון המוחזר נחלקים לארבע קבוצות.זהות
cpu_id– מזהה CPU של 32 סיביות.device_id– שלשה של מילים בנות 32 סיביות, המספר הסידורי הייחודי של ההתקן הצרוב בסיליקון.chip_id– שלשה של מילים בנות 32 סיביות, רשומה אחת לכל חיישן תמונה המחובר למצלמה.usb_vid– מזהה יצרן USB.usb_pid– מזהה מוצר USB.
גדלי זיכרון (כולם בקילובתים)
flash_size_kb– סך זיכרון הפלאש (flash) הפנימי.ram_size_kb– סך זיכרון ה-RAM.framebuffer_size_kb– זיכרון RAM שמור לצילום תמונות.stream_buffer_size_kb– זיכרון RAM שמור לערוץ הזרם המשנע פריימים אל המארח.
דגלי יכולת (ערך בוליאני אחד לכל מאפיין, כולם בשם
<feature>_present)gpu_present– יחידת עיבוד גרפי.npu_present– יחידת עיבוד נוירונים.isp_present– מעבד אות תמונה.venc_present– מקודד וידאו.jpeg_present– מקודד חומרה ל-JPEG.dram_present– DRAM חיצוני.crc_present– מאיץ CRC.pmu_present– יחידת ניטור ביצועים.wifi_present– רדיו Wi-Fi.bt_present– רדיו Bluetooth.sd_present– חריץ כרטיס SD.eth_present– Ethernet PHY.multicore_present– מספר ליבות CPU.
אחר
usb_highspeed– בוליאני,Trueכאשר ה-USB נמנה במצב מהירות גבוהה (USB 2.0 HS, 480 Mbps).pmu_eventcnt– מספר מוני אירועי ה-PMU הזמינים;0כאשר אין PMU.
13.3.1.6.7. אבחון¶
13.3.1.6.8. מאתח ביצועים (Profiler)¶
מאתח הביצועים מדווח על מספר הקריאות לכל פונקציה ועל זמני הביצוע המינימליים / המרביים / הכוללים עבור מודולי הקושחה המכשורים – כיום image, ml, ו-ulab. כניסה ויציאה מפונקציה מיורטות בזמן קומפילציה; זמן הריצה דוגם מונה מיקרו-שניות מונוטוני בכל אחת מהן, צובר את התוצאה לכל פונקציה, וחושף את הטבלה למארח דרך הערוץ profile.
מאתח הביצועים נבנה בתוך הקושחה רק כאשר PROFILE_ENABLE=1 מועבר ל-make. תמונות קושחה רגילות אינן כוללות אותו – הדגל -finstrument-functions שהבנייה מוסיפה למודולים המנוטרים נושא תקורה לא-זניחה בזמן ריצה, ולכן בנייות עם איתוח (profiling) מופקות מהמקור עבור פגישת הניפוי הספציפית הזקוקה להן. כאשר הקושחה לא נבנתה עם הדגל, הערוץ profile אינו נרשם וכל שיטת מאתח-ביצועים בעמוד זה חוזרת בשקט מבלי לעשות דבר.
ה-Performance Monitoring Unit (PMU) של Arm הוא בלוק מוני החומרה של ה-Cortex-M55 – קבוצה קטנה של מונים הניתנים להגדרה אשר עוקבים אחר ספירות מחזורים, פגיעות והחטאות מטמון, התנהגות הסתעפויות, ואירועים אחרים המוגדרים בארכיטקטורה מבלי להאט את הקוד הנמדד. במצלמות שיש להן אחד כזה – ה-AE3 וה-N6, שתי המצלמות בסדרת OpenMV הבנויות סביב ה-M55 – מאתח הביצועים דוגם מונים אלה לצד נתוני התזמון וסיכומי האירועים מופיעים בכל רשומה לכל פונקציה. מצלמות ללא PMU עדיין מפיקות רשומות תזמון; שדות האירועים חוזרים כאפס, ו-profiler_event() הוא no-op.
- Camera.profiler_mode(exclusive: bool = False) None¶
מעבר בין תזמון מכליל לבלעדי. תזמון מכליל זוקף את זמן הנקראות (callees) לקורא; תזמון בלעדי אינו עושה זאת.
- פרמטרים:
exclusive –
Trueבוחר תזמון בלעדי,Falseבוחר תזמון מכליל.
- Camera.profiler_reset(config: list | None = None) None¶
ניקוי כל מוני האיתוח.
config=Noneגם משחזר את הקצאת אירועי ה-PMU כברירת מחדל.- פרמטרים:
config – שמור לעקיפות הגדרה עתידיות לכל מונה. העבר
Noneכדי לשמור על ברירות המחדל.
- Camera.profiler_event(counter_num: int, event_id: int) None¶
קישור אחד מחריצי מוני ה-PMU לאירוע חומרה ספציפי.
- פרמטרים:
counter_num – אינדקס המונה.
event_id – מזהה אירוע מוגדר בארכיטקטורה.
- Camera.read_profile() list[dict] | None¶
החזרת רשומות האיתוח לכל פונקציה שנאספו מאז האיפוס האחרון. כל רשומה היא מילון עם
address,caller,call_count,min_ticks,max_ticks,total_ticks,total_cycles, ו-tupleeventsבגודלpmu_eventcntשל המצלמה.- מחזיר:
רשימת מילוני רשומות, או
Noneאם ערוץ האיתוח אינו זמין או שלא נאספו נתונים.
13.3.1.6.9. תת-מחלקות ומבנים פנימיים של ערוצים¶
השיטות המתועדות לעיל מכסות כל שימוש נפוץ בחבילה. כמה דפוסים – טיפול באירועים שבצד המצלמה שהמארח רוצה להגיב להם, נעילת ערוץ עבור חילופי מידע רב-שלביים, תקשורת עם ערוצים הנושאים נתונים מובנים במקום זרמי בתים, או הפעלת פקודות בקרה ספציפיות לערוץ – זקוקים לשיטות ש-Camera שומרת עם קידומת קו תחתון. שמות אלה הם פרטיים מתוקף מוסכמה (Python אינו מבצע name-mangling עליהם), ומיישומים הזקוקים להם מצופה שיגדירו תת-מחלקה של Camera או יקראו לשיטות ישירות.
תת-מחלקות כדי להגיב לאירועים. כל אירוע שהמצלמה פולטת מגיע דרך Camera._handle_event(). הגדרת תת-מחלקה של Camera ודריסת השיטה היא הדרך שבה יישום מגיב לאירועים שהסקריפט שבצד המצלמה מעלה; עמוד אירועים מתאר את הדפוס המלא.
- Camera._handle_event(channel_id: int, event: int) None¶
שיגור אירוע אחד מהמצלמה. נקרא על ידי שכבת ההובלה בכל פעם שמגיעה מנת אירוע. דרוס בתת-מחלקה כדי להוסיף טיפול ספציפי ליישום; קרא ל-
super()._handle_event(...)כדי לשמור על ההתנהגות שכברירת מחדל (רענון רשימת-ערוצים ב-CHANNEL_REGISTERED, מעקב מוכנות-פריים בערוץstream, רישום התחלה / עצירה של ערוץstdin).- פרמטרים:
channel_id –
0עבור אירועי מערכת, אחרת מזהה הערוץ הרשום.event – מזהה אירוע; הערכים מגיעים מ-enum מסוג
EventTypeעבור אירועי מערכת ומכל מה שבחר ה-backend של הערוץ בצד המצלמה עבור אירועי ערוץ.
תת-מחלקה המוסיפה שיטות תקשורת-פרוטוקול משלה צריכה לעטר אותן ב-retry_if_failed() כך שיירשו את אותה התנהגות סנכרון-מחדש-וניסיון-חוזר שיש לכל שיטה שנשלחת בעמוד זה.
- static Camera.retry_if_failed(func)¶
דקורטור. עוטף שיטת מופע כך שהיא תנסה שוב פעם אחת כאשר ההובלה מעלה
ResyncException. כל שיטה הקוראת ל-_send_cmd_wait_resp()(ישירות או דרך אחד מעוטפי_channel_*) צריכה לשאת דקורטור זה:class MyCamera(Camera): @Camera.retry_if_failed def my_custom_command(self, payload): return self._send_cmd_wait_resp(Opcode.MY_CMD, 0, payload)
נעילת ערוץ מבטיחה שמצב הערוץ לא ישתנה בין שתי פעולות קשורות (למשל _channel_size() ולאחריה _channel_read(), בערוץ שממשיך לצרף נתונים). read_frame() ו-read_profile() משתמשים בזה באופן פנימי; יישום המפעיל ערוץ מותאם אישית בגישה רב-שלבית עושה אותו דבר.
- Camera._channel_lock(channel_id: int) bool¶
השגת נעילה בלעדית על ערוץ. פעולות מארח אחרות על אותו ערוץ נחסמות עד שהנעילה משוחררת.
- פרמטרים:
channel_id – מזהה ערוץ מספרי, בדרך כלל מפוענח באמצעות
get_channel().- מחזיר:
Trueכאשר הנעילה הוענקה.
- Camera._channel_unlock(channel_id: int) bool¶
שחרור נעילה שניטלה קודם לכן באמצעות
_channel_lock(). תמיד מצמד לקריאת נעילה; השתמש ב-try/finallyכדי לוודא שהשחרור יקרה גם כאשר הקריאה שביניהם מעלה חריגה.- פרמטרים:
channel_id – מזהה ערוץ מספרי, בדרך כלל מפוענח באמצעות
get_channel().
ערוצים מעוצבים (Shaped channels) נושאים רשומות מובנות במקום זרם בתים שטוח. ערוץ מאתח הביצועים הוא הדוגמה הנשלחת: צורתו היא (record_count, record_size) ומארח הרוצה לדעת כמה רשומות ממתינות קורא את הצורה במקום את גודל הבתים.
- Camera._channel_shape(channel_id: int) tuple[int, ...]¶
קריאת מתאר (descriptor) הצורה של ערוץ.
- פרמטרים:
channel_id – מזהה ערוץ מספרי, בדרך כלל מפוענח באמצעות
get_channel().- מחזיר:
tuple של מספרים שלמים לא מסומנים בני 32 סיביות המתאר את פריסת הערוץ. המשמעות ספציפית לערוץ.
פקודות בקרה ספציפיות לערוץ – start, stop, reset, configure – רוכבות על opcode יחיד (CHANNEL_IOCTL) עם מספר פקודה ספציפי לערוץ ומטען struct.pack אופציונלי. השיטות הנשלחות כמו stop(), exec(), ו-streaming() הן עוטפים דקים סביב קריאות _channel_ioctl() כנגד הערוצים stdin ו-stream; ערוץ מותאם אישית בצד המצלמה המגדיר תפריט ioctl משלו מופעל באותו אופן.
- Camera._channel_ioctl(channel_id: int, cmd: int, fmt: str | None = None, *args) bytes | None¶
הוצאת פקודת ioctl על ערוץ.
- פרמטרים:
channel_id – מזהה ערוץ מספרי, בדרך כלל מפוענח באמצעות
get_channel().cmd – מספר פקודה המוגדר על ידי ה-backend של הערוץ בצד המצלמה.
fmt – מחרוזת פורמט
structאופציונלית עבור tuple הארגומנטים. העברNoneעבור ioctls שאינם מקבלים ארגומנטים.args – ערכים התואמים ל-
fmt.
- מחזיר:
כל מטען שהערוץ החזיר, או
None.
וריאנטים של זרם-בתים לפי-מזהה של שיטות הערוץ הציבוריות מדלגות על חיפוש שם-למזהה ומקבלות offset בתים מפורש – שימושי לקריאת מקטע מאמצע חוצץ גדול (למשל רשומות הערוץ profile).
- Camera._channel_size(channel_id: int) int¶
- פרמטרים:
channel_id – מזהה ערוץ מספרי, בדרך כלל מפוענח באמצעות
get_channel().- מחזיר:
בתים הזמינים כעת בערוץ.
- Camera._channel_read(channel_id: int, offset: int, length: int) bytes¶
קריאת
lengthבתים החל מ-offset. קריאות רב-מנתיות מורכבות מחדש אוטומטית.- פרמטרים:
channel_id – מזהה ערוץ מספרי, בדרך כלל מפוענח באמצעות
get_channel().offset – היסט (offset) הבתים שממנו להתחיל לקרוא.
length – מספר הבתים לקריאה.
- Camera._channel_write(channel_id: int, data: bytes, offset: int = 0) None¶
כתיבת
dataב-offsetהנתון. כתיבות רב-מנתיות מפוצלות אוטומטית למספר מנות.- פרמטרים:
channel_id – מזהה ערוץ מספרי, בדרך כלל מפוענח באמצעות
get_channel().data – מטען מסוג bytes-like לכתיבה.
offset – היסט (offset) הבתים שממנו להתחיל לכתוב.
פרימיטיביים של פרוטוקול הם הרמה הנמוכה ביותר שהמחלקה חושפת – רשומות שליחת-פקודה-גולמית, שליפת-רשימת-ערוצים-גולמית, וסנכרון-מחדש-ידני שכל מה שלעיל נבנה עליהן בסופו של דבר. יישום פונה אליהן בעת שליחת opcode שהמחלקה אינה עוטפת כבר, או בעת מימוש התאוששות מותאמת אישית בתת-מחלקה.
- Camera._send_cmd_wait_resp(opcode: int, channel: int = 0, data: bytes = b'') bytes | None¶
שליחת פקודת פרוטוקול והמתנה לתגובת המצלמה. הפרימיטיב שעליו נבנית כל שיטה אחרת בחלק זה.
- פרמטרים:
opcode – מספר הפקודה. ה-enum
Opcodeהנשלח מפרט את הקודים שהקושחה מגיעה איתם, אך הפרמטר הוא פשוט מספר שלם – בנייית קושחה מותאמת אישית יכולה להגדיר קודים משלה ולהגיב להם.channel – מזהה ערוץ, או
0עבור פקודות מערכת.data – מטען ספציפי לפקודה.
- מחזיר:
מטען התגובה, או
Noneעבור פקודות כמוOpcode.SYS_RESETו-Opcode.SYS_BOOTשמנתקות את החיבור.
- Camera._channel_list() dict¶
שליפת רשימת הערוצים הנוכחית מהמצלמה מבלי לגעת במילונים שבמטמון
channels_by_idו-channels_by_nameש-update_channels()מאכלס. שימושי לתת-מחלקה הרוצה לבחון את מצב הערוצים של המצלמה ישירות.- מחזיר:
מילון הממפה מזהה ערוץ ל-
{'name': str, 'flags': int}.
- Camera._resync() None¶
הרצה מחדש של לחיצת היד (handshake) של הפרוטוקול מאפס. נקרא אוטומטית על ידי
connect()בחיבור הראשוני ועל ידי כל שיטה ציבורית התופסתOMVExceptionמההובלה. יישום המממש לולאת התאוששות משלו בתת-מחלקה רשאי לקרוא לזה ישירות לאחר טיפול בשגיאה הבסיסית.
13.3.1.6.10. חריגות¶
- exception openmv.OMVException¶
מחלקת בסיס לכל שגיאה ברמת הפרוטוקול. שלוש תת-המחלקות שלהלן יורשות כולן ממנה, כך ש-
except OMVExceptionיחיד מכסה את כל משטח השגיאות.
- exception openmv.TimeoutException¶
המצלמה לא הגיבה בתוך פסק הזמן (timeout) המוגדר. תת-מחלקה של
OMVException.
- exception openmv.ChecksumException¶
ה-CRC של מנה לא התאים. מועלה לאחר שהפרוטוקול מיצה את תקציב הניסיונות החוזרים שלו. תת-מחלקה של
OMVException.
- exception openmv.SequenceException¶
מנה הגיעה עם מספר רצף בלתי צפוי לאחר ניסיונות חוזרים. תת-מחלקה של
OMVException.