iT邦幫忙

2022 iThome 鐵人賽

DAY 19
2
自我挑戰組

PixelBit 可以這樣玩!系列 第 19

(Day 19)影像辨識機械手臂(Part 2)

  • 分享至 

  • xImage
  •  

這篇文章將會接續上一篇「影像辨識機械手臂(Part 1)」。

教學原文參考:影像辨識機械手臂

八、程式解析

既然硬體已經配置好了,範例程式也有了,就讓我們看看 ESP32 與 ATmega328p 的程式分別做了什麼吧!若是您的硬體配置與教學範例的不同,也能透過範例程式,修改成適合自己的方式。

1. ATmega328p 程式

在 ATmega328p 這邊,被分配到的任務有幾項,第一項是偵測按鈕 B 是否被按下,一旦被按下,則需馬上傳送「開始辨識指令」給 ESP32。第二項任務則是接收 ESP32 傳送過來的「辨識結果」,並依照結果派送任務給機器手臂。

經由 UART 讓 ESP32 與 ATmega328p 互相溝通,這個我們在教學單元(二)已經學過了。所以傳送「開始辨識指令」與接收「辨識結果」,對我們來說已不是什麼難事,比較困難的是控制機器手臂。

每個機器手臂的控制方式各有不同,有的直接操控驅動板控制每顆馬達,有的內含控制板,並有自己的控制指令。馬達的使用也不相同,常見的馬達種類分為兩種,分別是「伺服馬達」與「步進馬達」。

我們選擇的「meArm」是使用伺服馬達,操控方式是透過連接的 MbitBot 擴充板,上面的 PWM IC 來控制。

a. 安裝 PWM IC 程式庫

為了能控制伺服馬達,請開啟 Arduino IDE 的「程式庫管理員」,並於搜尋欄位內輸入「Adafruit PWM Servo Driver」,找到這個程式庫並安裝,如下圖所示:

https://www.circuspi.com/wp-content/uploads/2022/05/15-1.jpg

b. 馬達控制步驟

請從這個單元的範例程式內開啟「servo_control」資料夾,並打開程式,完整程式如下圖所示:

https://www.circuspi.com/wp-content/uploads/2022/05/16-1.jpg

除了基本的匯入相關程式庫、參數設定與初始化之外,讓我們來看看馬達控制的部分。

「pwm.writeMicroseconds」程式會依照括號內的參數,去控制指定的馬達轉動,第一個參數是「連接馬達的編號」,第二個參數則是控制馬達的「microseconds」。MbitBot 擴充板上可以連接 8 個伺服馬達(編號是 S1~S8),對應到的程式編號是 0~7,也就是說要控制 S8 的馬達的話,在程式內要填上「7」。而 microseconds 會影響轉動角度,就一般而言會轉換成角度比較直覺,所以透過Arduino 內建的「map」方法,將我們輸入的 0~180 度的角度參數轉換成 500~2400 微秒。

https://www.circuspi.com/wp-content/uploads/2022/05/17-1.jpg

上圖的程式會讓 meArm 的四個馬達分別轉動到下表對應的位置:

https://www.circuspi.com/wp-content/uploads/2022/05/18-1.jpg

c. 記錄手臂動作參數

因為在組裝 meArm 的過程中,伺服馬達初始轉角可能不太相同,所以需要針對自己的手臂,來找到各個動作下的馬達轉動參數。

以我們建置的硬體為例,為了讓手臂在夾取與放置的過程中能順利,共可切分為 12 個動作。以下表所示,透過控制馬達轉動角度的程式,找到適合的手臂位置。

https://www.circuspi.com/wp-content/uploads/2022/05/19-1.jpg

這個步驟最為繁瑣,請依照自己的手臂找到對應的角度,並記錄下來。

d. 修改並上傳程式

請打開「pixel_pro_mini」這個資料夾,這個是完整的控制程式。我們直接挑重點看,在「loop()」區塊內有兩個「if」,第一個 if 是用來接收從 ESP32 來的辨識結果,並依照收到的辨識結果,執行特定的動作。若是收到的結果是「A」,就執行「class_box(1)」,如果是「B」則執行「class_box(2)」。

第二個 if 則是偵測「按鈕B」是否被按下,若按下則傳送開始辨識指令「I」給 ESP32。

https://www.circuspi.com/wp-content/uploads/2022/05/20.jpg

剛剛有提到的「class_box()」,是我們依照填入的結果去執行手臂移動流程的函式,如果是填入[1],也就是「class_box(1)」則執行放置貨物到 A 區的一系列動作,如果是「class_box(2)」則執行放置貨物到 B 區的一系列動作。

https://www.circuspi.com/wp-content/uploads/2022/05/21.jpg

請大家依照自己找到的對應角度,填入每個「servoList」內。修改完後即可將程式上傳至Pixel:bit 的 ATmega328p。

2. ESP32 程式

a. 安裝訓練好的模型程式庫

在「訓練模型」的階段,我們在 Edge Impulse 將訓練好的模型,編譯成 Arduino library 並下載下來,接著需要將其匯入 Arduino IDE。

https://www.circuspi.com/wp-content/uploads/2022/05/22.jpg

b. 修改並上傳程式

打開「pixel_esp32cam」這個資料夾,這是 ESP32 從接收辨識指令,接著推論結果,並回傳結果給 ATmega328p 的程式。

第一步要修改匯入的程式庫名稱,每個人在 Edge Impulse 命名專案時的名稱可能不同,請在下圖方框的對應位置內填入,自己下載下來的模型 library 名稱。

https://www.circuspi.com/wp-content/uploads/2022/05/23.jpg

接著讓我們來看一下關鍵的程式碼,在「loop()」區塊內,只要收到從 ATmega328p 傳送過來的訊息「I」,就會透過程式讓顯示螢幕顯示倒數 3 秒的效果,在這段時間中,操作者可以拿取要辨識的圖片擺在鏡頭前,當讀秒結束,會呼叫推論的程式「inference()」。

https://www.circuspi.com/wp-content/uploads/2022/05/24.jpg

在 inference() 函式內,主要就是將攝影機擷取到的資料,做一些轉換,並經由另一個函式「classify()」得出推論結果。若您仔細查看 classify() 內的程式,可以發現那個得到結果的程式,會將最終結果存放在「result」,如下圖所示:

https://www.circuspi.com/wp-content/uploads/2022/05/25.jpg

「result」存放的資料包含每個類別的名稱,還有對於這次的推論結果,各類別符合的百分比。得到結果後我們透過 Pixel:bit 正面的顯示螢幕將結果顯示出來。

https://www.circuspi.com/wp-content/uploads/2022/05/26.jpg

接著透過下方的程式檢查哪個類別的分數最高,若是第一類的百分比較高,變數「higher」將等於 0,若是第二類則變數「higher」將等於 1。

https://www.circuspi.com/wp-content/uploads/2022/05/27.jpg

得出最高分的類別後,接著顯示倒數 3 秒的資訊,主要是讓操作者有時間將要搬運的貨物放在搬運區。倒數完畢後將依照最高分的類別,傳送要搬運的區域訊息給 ATmega328p。

https://www.circuspi.com/wp-content/uploads/2022/05/28.jpg

以上就是針對較重要的程式說明,最後將程式燒錄到 Pixel:bit 的 ESP32。

九、運作展示

依照我們所撰寫的步驟,按下按鈕B後,ATmega328p 會傳送訊息給 ESP32,ESP32 辨識完畢後會顯示在畫面上,並回傳結果給 ATmega328p,最後再由 ATmega328p 控制手臂完成搬運任務。

https://www.circuspi.com/wp-content/uploads/2022/05/29.gif

十、結論

這個單元教大家在明白使用 Edge Impulse 訓練模型,以及 ESP32 和 ATmega328p 通訊後,依照設定的主題,額外加上機器手臂的控制,並整合所有功能。當然不是只有機器手臂可以這樣用,大家也可以思考看看,還有沒有能適用圖像辨識的場景,並用手上的 Pixel:bit 練習看看。本次教學就到這邊結束,若是對於訓練模型、UART 通訊還不太熟悉的朋友,可以再回去看看之前的教學單元。

更多有趣系列教學文章


上一篇
(Day 18)影像辨識機械手臂(Part 1)
下一篇
(Day 20)整合 LINE Notify 即時拍照通知
系列文
PixelBit 可以這樣玩!30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言