魔術方塊機器人





專案起源

此專案源起於某天,士兵 B 帶了魔術方塊來到公司被老大撞見。
「原來你會轉魔術方塊阿! 那麼做個魔術方塊機器人對你來說應該是小菜一碟吧!」老大說道,於是士兵 B 便被指派為此專案負責人。



功能說明

本專案利用 86Duino One86Duino Enjoy 及 Maixduino 實作魔術方塊機器人。


準備材料

  1. 一片 86Duino One
  2. 一片 Maixduino
  3. 8 顆 RoBoard RS-1270 伺服機
  4. OV2640 攝像頭模組
  5. 一個魔術方塊(此專案使用大雁展翅系列魔術方塊)
  6. 2.4 吋 TFT LCD螢幕(可有可無)
  7. WS2812 LED 燈條(含 18 顆 LED 燈)
  8. 7.2V 的電池
  9. 3D 列印機
  10. 螺絲、螺帽與線材



硬體架設

本專案機構參考了 OTVINTA 的魔術方塊機器人,所需列印材料的 STL 檔如下:
cover 零件 STL 下載
建議 cover 零件以白色或黑色材料列印以免光線問題影響後續顏色辨識。

機器人詳細組裝步驟請參考 OTVINTA 網站,須注意在安裝夾爪前須先將控制夾爪的馬達位置初始化至 1100us 並垂直裝上夾爪,另外將控制齒條的馬達初始化至 2100us 且使滑塊貼齊機器人身體邊緣,如圖所示:

— 伺服機初始化程式 —
#include <Servo86.h> // 使用 Servo86 函式庫
  
Servo myservo1; // 初始化 Servo 物件
  
void setup() 
{ 
  // 設定 Servo 腳位為 21
  myservo1.attach(21);
 
  // 送出 1100us 的 PWM 信號,使伺服機初始化至 1100us
  myservo1.write(1100); 
}
 
void loop() {}  

這裡介紹固定 86Duino 與 Maixduino 的層架組裝,組裝方式為由下到上:

首先,將零件 plate_holder 固定於機器人底部馬達位置並鎖上螺絲,且將零件 plate_bottom 放置於上方,如圖所示:

接著將 2 個 joint1 與 joint2 零件固定於 plate_bottom 的四個角,須特別注意安裝方向是否與圖片一致,並將 4 個 pillar_short 接上:

將 4 個 joint3 零件裝於 pillar_short 上,並裝上 plate_86duino 零件與鎖上 86Duino,可以比對零件上的螺絲孔位置與 86Duino 的方向是否正確,建議 86Duino 綠色電源端子台朝向圖片右方,RC 伺服機接頭朝向圖片左方,然後將伺服機、LED 燈條的接線接上,並將 4 個 pillar 零件裝上,注意接線盡量放於 plate_86duino 的左右兩側避免阻擋到相機畫面。

將 joint1、joint2、joint4、join5 安裝於 pillar 上,並將 plate_maixduino 裝上,同樣須注意方向是否與圖片一致:

鎖上 arm_left、arm_right 與 Maixduino,沿著兩個 arm 凹槽處黏貼上 LED 燈條,然後將 OV2640 相機嵌入 plate_maixduino,並將 Maixduino 的腳位與 86Duino 接上,plate_maixduino 有挖兩個孔供接線穿過。

蓋上 cover 於上方,並對準位置將 cover_lock 黏在 cover 上,最後與機器人鎖上。

接著介紹電路連接方式,如下圖。
86Duino 與 Maixduino 共電源,因此以 7.2V 電池對 86Duino 供電即可運作,須注意 LED 燈條與馬達可能產生較大的瞬間電流,因此須確保電源端電流至少能到 10A。



環境設定


Maixduino 的環境設定請參考 MaixPy 教學網站,裡面有詳細的解說。


程式解說


Maixduino 支援 Micropython,可支援大部分 Python 3 語法與 openMV 函式庫,在本專案中用於魔術方塊的顏色辨識,而 86Duino 則用於計算魔術方塊解法與馬達控制,程式流程如下:

— 辨識魔術方塊中心位置 —

從機構設計的角度來看魔術方塊的位置是固定的,但在實際安裝上難免會有誤差使魔術方塊無法正對於相機正中央,而此函式 findCubeCenter() 允許魔術方塊在一定誤差內修正中心方塊的位置。

— 曝光補償 —

為了進行顏色辨識,必須使相機在任何光源下都能拍出相同色彩資訊的照片,除了加上頂蓋使光源固定由 LED 燈條提供,這裡還進行了曝光補償,而函式 exposure_compensation() 會根據四個紅色爪子的亮度作為依據自動修正相機的曝光時間。

— 收集方塊六面的 HSV 色彩資訊 —

在擷取完六面的影像後,取各個方格的顏色資訊的眾數,作為代表該方格的顏色,並將其顏色資訊轉到 HSV 色彩空間以利後續顏色辨識。HSV 分別代表了顏色的色相(Hue)、飽和度(Saturation)、明度(Value)。

— 顏色辨識 —

由於白色(和黑色)與其他顏色在不同的維度上,因此需特別先辨識,這裡以飽和度排序,將 9 個飽和度最低的方格辨識為白色,而其餘色彩則以色相排序作為辨識依據。最後,將辨識結果傳回 86Duino 計算解魔術方塊的流程。

— 魔術方塊移動符號 —

魔術方塊共有 6 種面向,分別為 U(UP)上方、D(DOWN)下方、L(LEFT)左方、R(RIGHT)右方、F(FRONT)前方、B(BACK)後方 ,而所有面向都以朝向該面的順時針轉 90 度為正向,因此定義以下六個移動符號分別代表的轉動方式為:

U

D

L

R

F

B


而可以順時針轉動當然就可以逆時針轉動,定義以撇號 prime(‘) 代表逆時針轉 90 度。


U’

D’

L’

R’

F’

B’


另外,定義數字 2 代表旋轉 180 度。


U2

D2

L2

R2

F2

B2


魔術方塊解法就是由以上這些轉動方式組合而成,透過 turning() 函式即可傳入以上指令使機器人轉動魔術方塊,值得一提的是,由於機構只有四個爪分別能轉動 U、D、R、L,若要轉動 F 及 B 則程式會先將魔術方塊整面往上或往下轉,使動作 F 或 B 都變成 U。

— 神的數字(God’s Number)—

對任何隨機的解謎問題,若演算法必定能找到小於某步驟次數的解,則稱此演算法為神的演算法(God’s Algorithm),而解謎的步驟次數被稱為神的數字(God’s Number),在 2010 年時已有學者證明魔術方塊的 God’s Number 為 20。而目前的 God’s Algorithm 為 Kociemba Algorithm(或稱作 Two-Phase Algorithm),詳細演算法步驟說明可參考 Cube Explorer,在此並不贅述,本專案使用了作者 Muodov 所實現的 Kociemba 演算法,此作者也製作了自己的魔術方塊機器人 Meccano Rubik’s Shrine

— 馬達參數調整 —

調整下述參數使魔術方塊移動符號皆能正常轉動,分別為:
1. DELAY_TIME:等待馬達轉動時間(ms)
2. CLAMP_UPPER_BOUND:夾爪轉至 90 度的 PWM 位置
3. CLAMP_LOWER_BOUND:夾爪轉至 0 度的 PWM 位置(即為初始化位置)
4. SLIDE_UPPER_BOUND:滑塊移至機器人邊緣的 PWM 位置(即為初始化位置)
5. UD_SLIDE_LOWER_BOUND:上下滑塊移至夾緊魔術方塊時的 PWM 位置
6. RL_SLIDE_LOWER_BOUND:左右滑塊移至夾緊魔術方塊時的 PWM 位置

const int DELAY_TIME = 200;
const int CLAMP_UPPER_BOUND = 2100;
const int CLAMP_LOWER_BOUND = 1100;
const int SLIDE_UPPER_BOUND = 2100;
const int UD_SLIDE_LOWER_BOUND = 965;
const int RL_SLIDE_LOWER_BOUND = 760;

若個別馬達仍有些許誤差,可使用 setOffset() 函式做微調。


成果展示

— DEMO影片 —




相關資料


[1] 本專案 Github
[2] 本專案 STL 機構檔
[3] OTVINTA 網站
[4] 魔術方塊機器人作者 Muodov 的 Github
[5] 魔術方塊演算法參考網站



自造遊樂園主頁面

The text of the 86Duino reference is licensed under a Creative Commons Attribution-ShareAlike 3.0 License. Code samples in the reference are released into the public domain.