תוכן עניינים:

A Hearing MeArm, Google Coral TPU מאיץ מונע: 3 שלבים
A Hearing MeArm, Google Coral TPU מאיץ מונע: 3 שלבים

וִידֵאוֹ: A Hearing MeArm, Google Coral TPU מאיץ מונע: 3 שלבים

וִידֵאוֹ: A Hearing MeArm, Google Coral TPU מאיץ מונע: 3 שלבים
וִידֵאוֹ: Gesture control Robot Arm MediaPipe MeArm 2024, יולי
Anonim
A Hearing MeArm, Google Coral TPU Accelerator מונע
A Hearing MeArm, Google Coral TPU Accelerator מונע
A Hearing MeArm, Google Coral TPU Accelerator מונע
A Hearing MeArm, Google Coral TPU Accelerator מונע
A Hearing MeArm, Google Coral TPU Accelerator מונע
A Hearing MeArm, Google Coral TPU Accelerator מונע
A Hearing MeArm, Google Coral TPU Accelerator מונע
A Hearing MeArm, Google Coral TPU Accelerator מונע

להלן ברצוני לתאר גרסה מבוקרת קולית של ה- MeArm, זרוע רובוט קטנה xyz עם אחיזה. השתמשתי ב- MeArm Pi מתעשיות MIME, אך המערכת צריכה להיות ישימה לכל גרסה של MeArm, או התקנים דמויי סרוו.

השימוש במאיץ ה- TPU Accelerator של גוגל מאפשר להריץ סקריפטים לזיהוי קולי מהיר לא מקוון ב- TensorFlow ב- Raspberry Pi, ולשלוט בזאת במכשירים פיזיים לפי פקודות מדוברות, עם חביון מתחת לשנייה.

המכשיר המתואר כאן הוא שילוב והרחבה של מושגים המתוארים בשני הוראות קודמות. זהו הרחבה של יישום מוקדם יותר של בקרת הקול של Google Coral, ג'ק מקפץ, המתואר כאן ושיפור עצום של MeArm הנשלט על ידי קול AI של Google המתואר כאן.

ה- MeArm הנשלט על ידי הקול באמצעות מערכת Google Voice AIY נדרש גישה מקוונת, לא היה פשוט ליישום, נדרש ללחוץ על כפתור כדי להפעיל האזנה להזמנות קוליות והיה לו זמן חביון ארוך. מאיץ ה- TPU Accelerator של Google Coral המשמש כעת מאפשר להריץ דגמי TensorFlowLite במצב לא מקוון במהירות גבוהה ב- Raspberry Pi או במכשירי לינוקס אחרים. בין הדוגמאות בדף Google Coral Github יש דוגמה שנקראת "נחש שמיעה" למערכת זיהוי קולי שיכולה להבין 140 ביטויי מפתח (ספטמבר 2019), אשר ממופים לאחר מכן להקשות וירטואליות. חיבור "הקשות" אלה לביצוע כמה פונקציות המתוכנתות בפייתון מאפשר לבנות מכשיר המבוקר על ידי פקודה קולית. לאחרונה תיארתי יישום ראשון, שקע קפיצה אלקטרומכני הנשלט על ידי קול. היישום כאן הוא קצת יותר מורכב ומאפשר לשלוט בכל ארבעת הסרוואות של ה- MeArm כדי להזיז את ה- MeArm ברציפות או לעבור למספר מוגדרים מראש. תפקידים, או לבצע כמה משימות מורכבות יותר.

באמצעות התסריט המובא כאן כדוגמא, צריך להיות פשוט יחסית לבנות מכשירים אחרים הנשלטים על ידי קול, למשל. מכוניות רובוטיות או יחידות טכנולוגיות מסייעות.

אספקה

  • MeArm. בשימוש כאן: MeArm Pi מתעשיות MIME
  • פטל פי 4
  • מאיץ TPU TPC של אלמוגים
  • מצנפת סרוו של Adafruit 16 ערוצים
  • כמה כבלי מגשר
  • אופציונלי: קבל למכסה סרוו, כ- 400 µF ל -4 סרוו (מומלץ על ידי Adafruit)
  • מקור כוח של 5-6 וולט למכסה המנוע של סרוו. השתמשתי כאן במטען 6V ישן, וגם סוללת 4x AA עובדת
  • מִיקרוֹפוֹן. השתמשתי במצלמת אינטרנט ישנה של מיקרוסופט HD3000 כמיקרופון.

שלב 1: הגדרת המערכת

הגדרת המערכת
הגדרת המערכת
הגדרת המערכת
הגדרת המערכת

הורד את תמונת ה- Raspian שהוגדרה מראש למאיץ TPU Google Coral מדף Google Coral Github והתקן אותה על כרטיס µSD. התמונה מכילה גם מספר סקריפטים לדוגמה. הגדר את ה- Pi כמצוין.

התקן את דוגמת איתור מילות המפתח מאתר Google Coral GitHub, אם אינו כלול בתמונה, וכל התוכניות הנדרשות. חבר את המיקרופון ל- Pi. אני ממליץ לשחק עם הדוגמה "נחש שמיעה" כדי לוודא שהכל עובד.

הורד והתקן את תוכנת מצנפת Adafruit 16 ערוצים, כמתואר כאן. התקן את מכסה המנוע ושחק עם דוגמאות Adafruit כדי לוודא שהכל פועל כראוי.

הורד את הקבצים המצורפים להוראה זו והעתק אותם לתיקיה "פרויקט מילות מפתח לפרויקט". יש להעתיק את קובץ "command_v1_MeArm.txt" לתיקיית המשנה "config".

חבר את סרוו MeArm שלך למכסה המנוע של הסרוו כמצוין. השתמשתי ביציאה 15 למעלה/למטה, ביציאה 11 לפנים/אחורה, ביציאה 7 לסיבוב וביציאה 3 לסרוווס האחיזה.

בתוך הסקריפט ייתכן שיהיה עליך להתאים את ערכי min/center/max לכל סרוו לתצורה שלך. הגדרות אלה עוזרות למנוע נזק לסרוווס. ייתכן שיהיה עליך גם לשנות את רשימות "העמדות", "התחבורה 1" ו"הובלה 2 "הכלולות.

הפעל את התסריט. עד כה הפעלתי אותו מה- IDE.

למקרה שתרצה לשנות את ביטויי המפתח המעוררים פונקציה מסוימת בהתאם לצורך שלך. רשימה מלאה של KeyPhrases זמינים נמצאים בקובץ "labels_gc2 raw.txt" בתיקיית המשנה config.

למערכת זמן חביון של כשנייה אחת, אך תלוי במידה רבה באילו פעולות מבוצעות. במקרים מסוימים יש לחזור על שלב המפתח, דיוק ההכרה אינו תמיד 100%.

שלב 2: שימוש במכשיר

אם הכל מוגדר ונבדק, תוכל להפעיל את המכשיר.

מגבלה נוכחית היא שהזמנה נתונה מבוצעת שוב ושוב כל עוד היא לא נעצרת (באמצעות "משחק עצור") או שניתן פקודה אחרת. משימות מורכבות מרובות שלבים, למשל "transport1" (המעורר על ידי הביטוי "משחק השקה") מבוצעים תמיד עד השלב האחרון.

אז על ידי "פנה ימינה" המכשיר יזוז בצעדים קטנים ימינה עד שיעצר, או יגיע הערך המרבי המוגדר מראש. "משחק ההשקה", "המשחק הבא" או "התחל_וידאו" יתחילו סדרה של מהלכים המוגדרים על ידי רשימות המכילות את ההגדרה של כל סרוו בשלב נתון. "משחק אקראי" המכשיר יקפוץ משלב אחד לשלב, שנבחר באופן אקראי מרשימת הגדרות.

כפי שאתה יכול לראות בסרטון המצורף, בניתי אובייקט בצורת דיאבלו מ- LEGO שניתן לאסוף אותו על ידי ה- MeArm ולהעביר אותו ממיקום אחד למשנהו באמצעות מערכת תנועות מוגדרת מראש. תוכל להגדיר פונקציות משלך על ידי שינוי רשימות 'transport1' או 'transport2'.

שלב 3: התסריט

התסריט המופיע כאן הוא שינוי של הדוגמה "נחש שמיעה" מתוך "פרויקט מילות מפתח לפרויקט". הדוגמה הופשטה למינימום, ואז נוסף החלק לנהיגה בסרוווס, בהתבסס על התוכנה והדוגמאות שניתנו עבור מצנפת סרוו Adafruit.

התסריט לא הופעל עד כה. השתמש באחריותך האישית, אל תהסס לשנות ולייעל.

בנוסף לסקריפט הפיתון יש את הפקודות-קובץ וקובץ התוויות המשומש. מקם אותו בתיקיית התצורה-תת.

כפי שצוין קודם לכן, ייתכן שיהיה צורך במספר התאמות של פרמטרים כדי להתאים את הסקריפט עבור ה- MeArm המיוחד שלך או מכשיר אחר.

# זכויות יוצרים 2019 Google LLC#

# מורשה תחת רישיון Apache, גירסה 2.0 ("הרישיון"); # אינך רשאי להשתמש בקובץ זה אלא בהתאם לרישיון. # תוכל לקבל עותק של הרישיון בכתובת # # href = "https://www.apache.org/licenses/LICENSE-2.0" href = "https://www.apache.org/licenses/LICENSE-2.0" https://www.apache.org/licenses/LICENSE-2.0 # # אלא אם נדרש על פי החוק החל או הוסכם בכתב, תוכנה # המופצת במסגרת הרישיון מופצת על בסיס "כפי שהוא", # ללא אחריות או תנאים של כל סוג, מפורש או משתמע. # עיין ברישיון לקבלת השפה הספציפית המסדירה הרשאות ו- # מגבלות תחת הרישיון. # קוד "שמיעה_נחש" המקורי שונה לצורך יישום ל- MeArm על ידי ד"ר ח '' 'הוראות ההטמעה שלי משתמשת ב- Raspbery Pi 4 עם מאיץ אלמוגים של גוגל ומכסה מנוע סרוו של Adafruit 16 ערוצים. סרוו של MeArm (תעשיות MIME) הוצמדו ליציאות 3, 7, 11 ו -15 של המכסה. לפרטים, אנא עיין במדריך "Hearing MeArm". פקודות: "מיקום x", x = 0 עד 9, מעביר את המכשיר למיקום מוגדר מראש. "לזוז/לעלות", "לזוז/לרדת", "ללכת/לסובב קדימה", "ללכת/לסובב אחורה", "לפנות/ללכת שמאלה" ו"סובב/ללכת ימינה "מעורר תנועה איטית, צעד אחר צעד בנתון כיוון, "משחק עצור" עוצר את התנועות. "כרטיסייה פתוחה" ו"סגור לשונית "פותחים או סוגרים את הלוחץ. "התחל סרטון" מעורר את המכשיר לעקוב אחר סדר עמדות מוגדר מראש, המוגדר על ידי הרשימה 'עמדות'. "משחק אקראי" גורם לדפוס תנועות אקראי, "משחק עצירה" מסיים אותו. "משחק ההשקה" מתחיל סדרה נוספת של מהלכים שהוגדרו מראש ברשימה 'transport1', 'המשחק הבא' הפעולה ההפוכה שהוגדרה מראש על ידי 'transport2' שימוש על אחריותך בלבד. '' מ- _ עתיד _ יבוא אבסולוטי_יבוא מ _ עתיד _ חטיבת ייבוא מ _ עתיד _ יבוא הדפס_פונקציה יבוא ארגפרס מיבוא אקראי רנדינט מיבוא השחלה זמן ייבוא חוטים מיבוא edgetpu.basic.basic_engine דגם יבוא מ- pygame.locals יבוא * תור יבוא מ ייבוא אקראי randrange מ- adafruit_servokit יבוא לוח ServoKit יבוא busio יבוא adafruit_pca9685 זמן יבוא i2c = busio. I2C (board. SCL, board. SDA) hat = adafruit_pca9685. PCA9685 (i2c) hat.frequency = 60 ערכה = ServoKit (ערוצים = 16) # מספר ערוצים מוגדר # kit.servo [0]. actuation_range = 160 # kit.servo [0].set_pulse_width_range (1000, 2000) # דקות, מרכז ומקס הגדרות up_l = 145 # סרוו למעלה/למטה: למעלה md_l = 95 dn_l = 45 למעלה_ר = 135 # סרוו קדימה/אחורה md_r = 90 dn_r = 50 ri_t = 30 # סיבוב זרוע ימינה או שמאלה: מיקום ימין md_t = 90 # סיבוב זרוע ימינה או שמאלה: עמדת מרכז le_t = 150 op_g = 65 # אחיזה פתוחה md_g = 90 # אחיזה מרוכזת cl _g = 130 # אחיזה סגורה vert = 15 # מספר יציאת סרוו, סרוו למעלה/למטה קדמית = 11 # מספר יציאת סרוו, סיבוב סרוו קדימה/אחורה = 7 # יציאת סרוו לסיבוב אחיזת סרוו = 3 # יציאת סרוו לאחיזה סרוו #רשימת הגדרות זרוע לתנוחת עמדות = [(md_l, md_r, md_t, op_g), (up_l, md_r, ri_t, op_g), (up_l, md_r, md_t, cl_g), (up_l, md_r, le_t, cl_g), (md_l, md_r, md_t, op_g), (md_l, md_r, md_t, md_g), (md_l, md_r, md_t, cl_g), (dn_l, dn_r, ri_t, op_g), (dn_l, dn_r,), (dn_l, dn_r, le_t, md_g)] # מגדיר 10 עמדות בסיס, המסומנות במספרים שלמים 0-9 # נהלי תחבורה [vert/קדימה/סיבוב/אחיזה] transport1 = [(140, 70, 65, op_g), (110, 50, 65, op_g), (65, 50, 65, op_g), (65, 70, 65, cl_g), (120, 70, 65, cl_g), #get object (100, 70, 135, cl_g), (100, 80, 135, cl_g), (100, 80, 135, md_g), (100, 80, 135, op_g), (140, 70, 135, op_g), (140, 70, 90, op_g), (140, 70, 65, op_g)]

transport2 = [(140, 70, 65, op_g), (140, 70, 135, op_g), (95, 70, 135, op_g), (95, 80, 135, op_g), (95, 80, 135, cl_g), (110, 70, 135, cl_g), (110, 70, 65, cl_g), (70, 70, 65, cl_g), (70, 70, 65, op_g), (80, 50, 65, op_g)]

ריקוד 1 = (0, 8, 7, 4, 1, 2, 3, 6, 9, 8, 5, 2, 1, 4, 7, 8, 9, 6, 3, 2, 0) # "ריקוד"

#moving MeArm to Zero position status = [md_l, md_r, md_t, md_g] kit.servo [vert].angle = status [0] kit.servo [forw].angle = status [1] kit.servo [turn]. זווית = סטטוס [2] kit.servo [אחיזה].angle = סטטוס [3] הדפסה (סטטוס) מחלקת בקרה (אובייקט): פונקציית התקשרות def _init _ (עצמי, q): self._q = q def callback (עצמי, פקודה): self._q.put (command) class יישום: def _init _ (self): self._running = True def on_init (self): pygame.init () self.game_started = true self._running = True return True def on_event (עצמי, אירוע): אם event.type == pygame. QUIT: self._running = False def MeArmPos (self, keys): # מניע את MeArm למיקומים מוגדרים מראש, מילות מפתח: "position x" key = int (מפתחות) p = מיקום [מפתח] a = p [0] b = p [1] c = p [2] d = p [3] הדפס ("עמדות:", מקש, "vert/forw/turn/grip:", a, "/", b, "/", c, "/", d, "degrees") status = [a, b, c, d] # מסמכים הדפס סטטוס נוכחי (סטטוס) # sys.stdout.write ("מיקום: ", מפתח," שמאל/ימין: ", a,"/", b," תואר ") kit.servo [vert].angle = kit.servo [forw].angle = b kit.servo [turn].angle = c kit.servo [grip].angle = d time.sleep (0.5) def DancingMeArm (עצמי): # שולט במחול MeArm, מילת מפתח: "start_video" dnce = dance1 sp = (len (dnce)) עבור r בטווח (sp): #ריקוד של עמדות, צעדים sp dc = dnce [r] p = מיקום [dc] a = p [0] b = p [1] c = p [2] d = p [3] kit.servo [vert].angle = kit.servo [forw].angle = b kit.servo [סיבוב].angle = c kit.servo [אחיזה].angle = d time.sleep (1) # מגדיר את מהירות התנועות time.sleep (0.5) # הפסקה בסוף ההליך def TransMeArm1 (עצמי): # שולט ב- MeArm transport 1, מילת מפתח: "משחק השקה" tr1 = transport1 sp = (len (tr1)) #לחשב את מספר השלבים עבור r בטווח (sp): #עבור לכל שלב p = tr1 [r] a = p [0] b = p [1] c = p [2] d = p [3] ערכה. סרוו [vert]. מלבן = ערכה. סרווו [פורוו]. מלבן = ב ערכה. סרבו [סיבוב]. אנגל = קיט. סרבו [אחיזה]. מלבן = דפוס (p) זמן. שינה (1) # סטים מהירות התנועות time.sleep (0.5) def TransMeArm2 (עצמי): # שולט בריקוד MeArm, מילת מפתח: "המשחק הבא" tr2 = transport2 sp = (len (tr2)) עבור r בטווח (sp): #ריקוד של עמדות, צעדים sp p = tr2 [r] a = p [0] b = p [1] c = p [2] d = p [3] kit.servo [vert].angle = a kit.servo [forw].angle = b kit.servo [turn].angle = c kit.servo [אחיזה].angle = d הדפסה (p) time.sleep (1) # קובע את מהירות התנועות זמן.שינה (0.5) def RandomMoves (עצמי): # קפיצות אקראיות בין עמדות מוגדרות מראש, מילת מפתח: "משחק אקראי" dr = randrange (9) # בוחרת באופן אקראי מיקום p = position [dr] # קוראת פרמטרי מיקום a = p [0] b = p [1] c = p [2] d = p [3] kit.servo [vert].angle = a kit.servo [forw].angle = b kit.servo [turn].angle = c kit.servo [אחיזה]. זווית = d זמן. שינה (1) # קובע את מהירות התנועות def MoveUp (עצמי): # אחיזת הרמה בצעדים קטנים u0 = סטטוס [0] # קריאת הסטטוס הנוכחי u1 = u0 + 5 # פלוס x מעלות אם (u1 > up_l): # בדיקות אם לא יעלה על הפרמטרים min/max u1 = up_l # אחרת מוגדר לערך min/max kit.servo [vert].angle = u1 # הזז סטטוס סרוו [0] = u1 # התאם הערך סטטוס ערך (" למעלה ", סטטוס) time.sleep (1) # מגדיר מהירות def MoveDown (עצמי): ד 0 = status [0] d1 = d0 - 5 # מינוס x מעלות אם (d1 up_r): f1 = up_r kit.servo [forw].angle = f1 # הזז סטטוס סרוו [1] = הדפס f1 ("קדימה", סטטוס) time.sleep (1) def MoveBack (עצמי): b0 = סטטוס [1] b1 = b0 - 5 # מינוס x מעלות אם (b1 le_t): l1 = le_t kit.servo [turn].angle = l1 # להעביר סרוו status [2] = l1 הדפסה ("שמאל", סטטוס) time.sleep (0.2) def MoveRight (self): r0 = status [2] r1 = r0 - 2 #מינוס x מעלות אם (r1 <ri_t): r1 = ri_t kit.servo [turn].angle = r1 # move servo status [2] = r1 print ("ימין", סטטוס) time.sleep (0.2) def OpenGrip (self): kit.servo [grip].angle = op_g # הגדר אחיזה למיקום "פתוח": "open_tab" time.sleep (0.5) סטטוס [3] = op_g def CloseGrip (עצמי): kit.servo [אחיזה].angle = cl_g # הגדר אחיזה למיקום "סגור": " close_tab "time.sleep (0.5) status [3] = cl_g def StopMove (self): # אינו עושה דבר, אך מפסיק תנועות הדפסה (" עצור ", סטטוס) time.sleep (0.25) def spotter (עצמי, args): מנוע = BasicEngine (args.model_file) mic = args.mic אם args.mic אינו Int אחר אחר (args.mic) model.classify_audio (מיקרופון, מנוע, labels_file = "config/labels_gc2.raw.txt", command_file = "config/commands_v1_MeArm.txt", dectection_callback = self._controler.callback, sample_rate_hz = int (args.sample_rate_hz), int (args.num_frames_hop)) def on_execute (self, args): אם לא self.on_init (): self._running = False q = model.get_queue () self._controler = בקר (q) אם לא args.debug_keyboard: t = Thread (target = self.spotter, args = (args,)) t.daemon = true t.start () item = -1 while self._running: pygame.event.pump () if args.debug_keyboard: keys = pygame.key.get_pressed () else: try: new_item = q.get (True, 0.1) למעט queue. Empty: new_item = None אם new_item אינו None: item = new_item if (args.debug_keyboard ומפתחות [pygame. K_ESCAPE]) או item == "stop": self._running = False # if (args.debug_keyboard ומפתחות [pygame. K_SPACE]) או item == "go": # self. MeArmPos (7) # if (args.debug_keyboard ומפתחות [pygame. K_RIGHT]) או item == "right": # פנה ימינה self. MoveRight () if (args.debug_ke yboard ומפתחות [pygame. K_LEFT]) או item == "שמאל": # פנה שמאלה self. MoveLeft () אם (args.debug_keyboard ומפתחות [pygame. K_UP]) או item == "למעלה": self. MoveUp () if (args.debug_keyboard and keys [pygame. K_DOWN]) or item == "down": self. MoveDown () if (args.debug_keyboard and keys [pygame. K_B]) or item == "b": # לאחור self. MoveBack () אם (args.debug_keyboard ומפתחות [pygame. K_F]) או item == "f": # מעביר את עצמי. MoveForw () if (args.debug_keyboard ומפתחות [pygame. K_O]) או item == "o": # אחיזה פתוחה: self. OpenGrip () אם (args.debug_keyboard ומפתחות [pygame. K_C]) או item == "c": # אחיזה קרובה: self. CloseGrip () if (args.debug_keyboard ומפתחות [pygame. K_S]) או item == "s": # stop movement: "start_game" self. StopMove () if (args.debug_keyboard and keys [pygame. K_0]) or item == "0": self. MeArmPos (0) אם (args.debug_keyboard ומפתחות [pygame. K_1]) או item == "1": self. MeArmPos (1) if (args.debug_keyboard ומפתחות [pygame. K_2]) או item == "2": self. MeArmPos (2) if (args.debug_keyboard and keys [pygame. K_3]) או שהוא em == "3": self. MeArmPos (3) if (args.debug_keyboard and keys [pygame. K_4]) או item == "4": self. MeArmPos (4) if (args.debug_keyboard and keys [pygame. K_5]) או item == "5": self. MeArmPos (5) if (args.debug_keyboard ומפתחות [pygame. K_6]) או item == "6": self. MeArmPos (6) if (args.debug_keyboard ו- מפתחות [pygame. K_7]) או item == "7": self. MeArmPos (7) if (args.debug_keyboard ומפתחות [pygame. K_8]) או item == "8": self. MeArmPos (8) אם (args.debug_keyboard and keys [pygame. K_9]) or item == "9": self. MeArmPos (9) if (args.debug_keyboard and keys [pygame. K_a]) or item == "d": self. DancingMeArm () #dancing MeArm, ב- "game_ next" אם (args.debug_keyboard ומפתחות [pygame. K_r]) או item == "r": self. RandomMoves () #ריקוד אקראי "משחק אקראי" אם (args.debug_keyboard ומפתחות [pygame. K_j]) או item == "j": self. TransMeArm1 () # אובייקט תחבורה: "lunch_game" if (args.debug_keyboard and keys [pygame. K_k]) or item == "k": self. TransMeArm2 () # אובייקט תחבורה כיוון הפוך: "next_game" '' 'if (args.debug_keyboard ו- מפתחות [pygame. K_l]) או item == "l": self. JumpingJack2 (1) #LED למצמץ "יעד" '' 'time.sleep (0.05) self.on_cleanup () אם _name_ ==' _main_ ': מנתח = argparse. ArgumentParser () parser.add_argument ('-debug_keyboard', help = 'השתמש במקלדת לשליטה ב- MeArm.', action = 'store_true', default = False) model.add_model_flags (parser) args = parser.parse_args () the_app = App () the_app.on_execute (args)

מוּמלָץ: