13.1.13. עורך ההגדרות#
יישומי מצלמה רבים זקוקים לכמה הגדרות שמי שאינו מתכנת יכול לשנות – סף, מצב, סיסמת Wi-Fi – מבלי לגעת בסקריפט. OpenMV Cam Settings Editor הוא הכלי של ה-IDE לכך: קובץ JSON מתאר את הפקדים, העורך הופך את התיאור לטופס, והסקריפט שלכם קורא בחזרה את הערכים השמורים באמצעות json.load(). הקובץ הוא גם התצורה וגם ההגדרה של העורך של עצמו, כך שאותה תצורה השומרת את הערכים גם פורשת את ה-GUI לעריכתם.
תת-התפריט Tools → OpenMV Cam Settings Editor מכיל את שלוש הפעולות שלו.
Open OpenMV Cam Settings Config File קורא את התצורה מכונן המצלמה המחוברת ופותח אותה בעורך; שמירה כותבת אותה בחזרה למצלמה.
Open Config File עושה את אותו הדבר עבור קובץ
.jsonבמחשב שלכם, לצורך הכנת תצורה במצב לא-מקוון.Create Default Config כותב תצורת התחלה לדיסק ופותח אותה – דוגמה שמפעילה כל סוג פקד, מוכנה לצמצום להגדרות שהיישום שלכם צריך.

עורך ההגדרות כאשר תצורת ברירת המחדל פתוחה – פקדי קובץ ה-JSON מסודרים כטופס (כרטיסיות, מחוונים, רשימות נפתחות, תיבות סימון), עם Save ו-Cancel בתחתית.#
13.1.13.1. מבנה של קובץ תצורה#
קובץ תצורה הוא אובייקט JSON יחיד עם שני מפתחות:
title (מחרוזת, אופציונלי) – הכותרת של חלון העורך. ברירת המחדל היא
OpenMV Cam Settings Editor.controls (מערך, נדרש) – רשימת אובייקטי הפקד שהעורך מרנדר, לפי הסדר, כשורות של טופס. זהו כל ה-GUI.
{
"title": "Camera Settings",
"controls": [
{ "type": "slider", "name": "threshold", "label": "Threshold", "value": 50 },
{ "type": "checkbox", "name": "draw_overlays", "label": "Draw Overlays", "value": true }
]
}
כל רשומה ב-controls היא פקד אחד – שדה טקסט, מספר, תיבת סימון, תפריט נפתח, מחוון, קבוצה, רצועת לשוניות, תווית סטטית וכן הלאה. ה-type שלו בוחר את הווידג’ט; שאר האובייקט מגדיר אותו. מפתחות שהעורך אינו מזהה נשארים ללא שינוי בעת שמירת הקובץ, כך שתוכלו לשמור מטא-נתונים משלכם בקובץ לצד הפקדים.
13.1.13.3. שמירה וקריאה של ערכים#
פקד שמחזיק ערך – תיבת סימון, מחוון, שדה טקסט – נושא אותו במפתח value. כשאתם לוחצים Save, העורך כותב את ה-value הנוכחי של כל פקד ישירות בחזרה לאותו אובייקט פקד עצמו, במקום, וכותב מחדש את הקובץ. הקובץ שומר על המבנה שלו: דבר אינו זז, רק מפתחות ה-value משתנים. אין מפה שטוחה נפרדת של name לערך – הערכים חיים בתוך הפקדים, בדיוק היכן שהם מוגדרים.
לכן הפריסה חשובה לסקריפט שלכם. מערכי controls ו-tabs שומרים על הסדר שבו בניתם אותם, כך שלא ניתן לאנדקס את הקובץ לפי שם כמו מילון – config["controls"]["threshold"] אינו פועל. מסייע קטן זה מגשר על הפער: תנו לו את נתיב השמות עד לערך הרצוי, והוא יטייל בעץ עבורכם.
import json
def find(node, *path):
"""Return the control at a path of names; read its value with
["value"]. The tab strip and any unnamed group are transparent,
so you list only the tabs and controls you gave a name."""
for key in path:
match = _child(node, key)
if match is None:
raise KeyError(key)
node = match
return node
def _child(node, key):
for member in node.get("controls", []) + node.get("tabs", []):
if member.get("name") == key or member.get("title") == key:
return member
if "name" not in member and ("controls" in member or "tabs" in member):
match = _child(member, key) # see through an unnamed group / the tab strip
if match is not None:
return match
return None
with open("config.json") as file:
config = json.load(file)
threshold = find(config, "threshold")["value"]
כל שלב בנתיב הוא name של פקד, או title של לשונית (לשונית אינה לוקחת name משלה, אם כי תוכלו להוסיף אחד והוא נשמר). רצועת הלשוניות וכל group שלא נתתם לו שם שקופים – find צועד דרכם – כך שאתם מפרטים רק את הלשוניות ואת הפקדים שהוספתם להם תווית, קרוב לחיפוש מקונן config[...][...]. group עם שם הוא שלב משל עצמו, כך ש-find יכול גם להחזיר את ערך תיבת הסימון שלו. תנו לכל פקד name ייחודי כדי שנתיב לעולם לא יהיה דו-משמעי. דוגמה מלאה קורא ערכים מתוך פריסת ההדגמה המקוננת.
מכיוון שהתצורה היא JSON פשוט, שום דבר בסקריפט שלכם אינו תלוי בעורך – העורך רק כותב את הקובץ שהסקריפט שלכם כבר קורא. התקן יכול לשאת את התצורה שלו ודרך ידידותית לשנות אותה, בעוד שהסקריפט נשאר קורא פשוט של ערכים.
סוג פקד אחד אוכף את הקלט שלו בעת Save: lineedit עם mask או regex מסרב לתת לעורך לשמור בעוד הטקסט שלו אינו תקין או חלקי, ומציין את השדות לתיקון. כל פקד אחר מגביל את הקלט תוך כדי עריכה – מחוון אינו יכול לצאת מהטווח שלו, spinbox נצמד לגבולותיו – כך שקובץ שמור תמיד תקין.
13.1.13.4. עיון בקובץ התצורה#
סוגי הפקדים מתועדים בעמודים שלהלן, מקובצים לפי מה שהם עושים.