Dobot手臂程式繪圖

--

這一節,我們要使用Blockly積木控制手臂繪圖,在這之前還需要對手臂的坐標系以及機體特性有更多的了解,並在繪圖的過程中學習使用Blockly變數跟函式的用法。

變數與高度定位

在每一次開始使用機器,按下Home鍵機器歸零之後,從左側數值面板可以看到,其中Y、R的數值是精準歸零的,但是X跟Z兩個數值還是很不乾淨,因此首先要先用程式將末端引導到整數座標上。

找到Dobot API中Motion類別裡的第一個JumpTo積木,拉出來放在程式編輯區,不需要調整任何數值,直接按下Start執行程式,手臂的末端就會運動到(200,0,0)這個座標數值相對乾淨的位置上。

拿出一張A4紙如上圖擺放,移動紙張讓手臂末端對到白紙的中間靠左側,並用紙膠帶做簡單固定,這樣的擺放布局讓手臂直角坐標系的方位最為直觀,橫向為X軸、縱向為Y軸,與數學課上學的直角座標系相合,完成之後將JumpTo積木拖到右下角的垃圾桶刪除積木。

回想之前使用Write&Draw模式時,最一開始有個很重要的步驟叫做AutoZ,按下這個按鈕手臂就會以當下這個高度作為繪圖的平面,那在Blockly模式下沒有這個按鈕了,要怎麼讓手臂知道要在哪個高度下繪圖呢?

在此我們要先用左側的圖形介面,輕按Z-慢慢往下調整筆尖的高度,直到筆尖剛剛好碰到紙面,紙張可以吸到墨水就好,以免繪圖過程中筆尖刮破紙張,並留意在面板上Z軸目前的數值,這裡顯示的是-36.8131。

接著我們需要一個變數來記錄當下的高度,從Variables裡取出一個[set item to]的積木,這裡的item就是變數名稱,點下item出現下拉選單並點Rename Variable…將變數名稱改成PaperHeight,或其他方便記憶的變數名稱。

接著從Motion類別中找出[GetCurrentCoordinate X]這個積木,放到[set paperHeight to]之後,並點下X的下拉選單切換成Z軸,以此將當下Z軸的數值塞進變數中。

通常為了確保抓到的數值是正確的,會將變數內容輸出做雙重確認double check,取出Text類別中的[Print]積木,以及Variables中的[PaperHeight],並將兩者相結合,放在先前的程式積木之下,是的你沒看錯Variables類別中的積木變多了,每當新宣告一個變數,Variables類別中就會多一組專屬於此變數的積木。

執行這一段積木,旁邊的Running Log中就顯示了paperHeight當中的數值,也是-36.8131,與面板上的數值相同,雖然這個步驟看起來有點多此一舉,但是小心駛得萬年船,手臂的程式在執行時如果數值沒有設定正確,沒有辦法正常完成工作就算了,還有可能造成手臂損壞,另外也是以此示範變數的使用,以及記錄機體數值的方法。

確立坐標系

確定好高度之後就要開始畫圖了,要先從當前的點順著X+的方向,劃一條橫線,取出[JumpTo(200,0,0)]積木並在Z軸放進paperHeight變數,之後會以此作為紙張上繪圖區的原點。

在取出Motion類別中的第二個積木[MoveTo(200,0,0)],Z軸一樣擺paperHeight變數,而X軸數值設為300,執行這段程式之後,手臂就會在紙上畫出一道橫線。

對一個積木點右鍵,點選Duplicate可以複製此積木,複製兩組畫線的積木,並將XY的數值按照下圖設定,執行後的軌跡除了橫線重畫一次之外,還從下到上多畫了兩條直線形成一個H字型,以此框出的兩個10x10cm正方形範圍,X軸介於200~300之間、Y軸介於+-100之間,就是最適合用程式控制手臂工作的區域,之後每換一張空白的紙或是手臂移動了位置,就要重新標記出這個區域的範圍。

在上面的程式中我們主要用到了兩個控制運動的積木,分別是[JumpTo]以及[MoveTo]兩種積木,想想看為甚麼會交替使用這兩種積木呢?如果設定的座標相同,只是都換成[JumpTo]或是都用[MoveTo]又會發生甚麼狀況呢?

隨機多邊形

前面說到每次換白紙就要重新畫出H字型的安全工作範圍,像這樣一個常會用到的重複的動作,就很適合用函式包裝起來,直接拿出Functions裡的第一個積木,將繪製H範圍的程式拖到裡面,並命名為plotH。

重新點開Functions類別,會發現裡面多了一個[plotH]小積木,這時[plotH]就像一個方便的小工具,不要的時候可以直接丟掉、需要時直接拿出來用,不需要一整堆積木重新建構,還要慢慢設定參數,將此積木拖放到原本程式的最下面,執行出來的效果跟先前一模一樣。

接著我們試著在圖紙上畫出隨機的線段,但這些線段不能超過H的範圍,為此需要使用到有隨機功能的積木,從Math類別中找到[random integer from 1 to 100]這個積木,使用這個積木他會在1~100之間隨機回傳一個整數,兩個輸入框就是用於設定上下區間用的。

例如在畫圖時X軸就要設定200跟300,Y軸則為-100跟100,按照下圖建構程式並執行,手臂就會在H範圍內畫出一條直線,反覆執行多次會發現每一次畫出來的線段都不一樣,而且真的怎麼畫都不會超出H範圍,這就是隨機數的效果。

看到這段程式積木,你是否有跟我一樣的感覺,隨然程式結構不複雜但實在是太寬了,一個random積木就好寬,兩個在一起就更寬,難道為了要用他就只能容忍了沒有解決的辦法嗎?

這裡我們就可以用上Functions裡的第二個積木了,用它來建構帶有return的函式,拉出兩個這種積木分別命名為[ranX]與[ranY],並將原本放在X與Y軸的隨機數分別接在兩個函數的return上,這樣就建構出了兩個產生特殊隨機數的函式

接著重新點開Functions類別,會發現心產生出來的[ranX]與[ranY]積木與[plotH]積木長的不太一樣,前面是帶著拼圖的公端表示會產出數值,與之前的[paperHeight]取得變數內容一樣,這也是Blockly有意思的地方,積木的形狀直接暗示這種積木該怎麼用,免去很多拼錯程式的可能。

把原本的隨機數換上新的隨機函數,是不是整個程式積木都變得簡潔許多呢,如此一來才能進一步開發更複雜的功能,下一步我想畫出隨機的三角形,延續剛才的思路三角形不過就是三條段組成,就像下圖寫的程式這樣,再畫出隨機的兩條線就好了嗎?(當然不是)

上面這一段程式也回答了之前問的[JumpTo]、[MoveTo]的用法,簡而言之每一次使用[JumpTo]就相當於,提起筆來重新到該點開啟新的一筆劃,所以[JumpTo]後面可以接很多個[MoveTo]構成複雜的圖形,如果都只有[JumpTo]就相當於再紙面上打點而已沒有畫下去。

但這一段程式其實是沒有辦法構築出三角形的,原因是這一筆劃的頭尾不相連,第三條線的終點要與第一條線的起點是同一個位置,才能夠形成封閉的三角形,因此需要兩個變數來記錄起點位置。

加入X0、Y0兩個變數後將程式改寫如上圖所示,就能畫出封閉的三角形,換了不同顏色的筆畫出來畫面有點混亂,下一節會試著讓手臂畫出更有意思的幾何圖形。

--

--

No responses yet