2016年5月25日 星期三
grbl 05/25
1. use arduino to update firmware...
https://github.com/Protoneer/GRBL-Arduino-Library
load grbl.zip to arduino library and open the example and update it
2. in grbl library.... default baud rate is 9600 in config.h
change baud rate from 9600 to 115200....
3.
default define DEFAULTS_GENERIC ...
所以得到下面這些數值
#define DEFAULT_X_STEPS_PER_MM 250.0
#define DEFAULT_Y_STEPS_PER_MM 250.0
#define DEFAULT_Z_STEPS_PER_MM 250.0
4.
Grbl 透過多種策略自動調整轉速來避免掉步發生
假設移動銑刀走一段直線, 那麼 Grbl 會以這樣的速度控制
X 軸是時間, Y 軸是速度, 中間的面積就是移動的距離
一開始逐漸加速, 抵達最大速度時維持定速, 快到目的地後開始減速
這樣的設計和馬達的力矩有關, 參考資料:Stepping Motion Profiles in Realtime
簡略敘述:
牛頓第二運動定律 F = m * a
馬達的力矩是有限的, 所以加速度也是受限的, 能產生的加速度和負載的質量有關
加上前篇 用 A4988 控制步進馬達 敘述, 馬達低速時力矩最大, 速度越快力矩最小
所以最高速度也是受限的, 如果快到連阻動力矩都克服不了時, 它就轉不動了
一旦操作馬達時超出這些限制, 它就會掉步, 然後又沒有感測器回報, 操作就會失敗
所以如果不依賴感測器, 就必須謹慎的管控這些速度和加速度, 這樣才可迴避掉步問題
步進馬達加速的形式還有別種選擇, 有興趣可 Google 搜尋 stepper speed profile
如果總是加上這些加速度限制, 理論上就可以正常的完成工作, 那是大多數的情況
源碼裡註解有提到, 當執行大量小幅度的線段時, 這種算法會惹上麻煩, 尤其曲線
上圖左下角有條曲線, 如果要讓機器畫出這種曲線, 通常它會被轉換成許多小線段
也就是紅色箭頭指處, 如果我們依照前面的加速度規則下去運算
每段線段的速度變化會變成藍色虛線指的地方, 也就是許多三角形
意思就是因為線段過短, 所以運轉時間也短, 它還來不及升到最高速就要開始減速了
這種曲線如果是從 G code 的曲線指令下的或許還有一些調整空間
但是有些模型轉換軟體會自動產生大量線段來趨近曲線
對 CNC 機器來說看到的就是一堆線段命令, 它沒法知道我們要做曲線
自然就是依照標準速度控制, 然後就會出現超龜速移動的現象
解決這問題 Grbl 用一種應該是數值方法的方式來計算
算法原文介紹:Improving Grbl: Cornering Algorithm
當兩條線段連在一起時, 規劃移動速度會如下圖
中間的 Vjunction 就是兩線段連結點的速度, 前一線段規劃速度時不會降到 0
而是降到一個計算過的值, 這個值和兩條線之間的夾角有關
如果這兩條線夾角接近 180 度, 那它就很可能是高密度曲線
就算不是, 這樣的夾角表示前進方向並沒有改變太多, 也不需要減速
如果這夾角是 90 度或更小, 表示它會進行大迴轉, 那就要確實減速
即使這線段是曲線的一部分也要這麼做, 算法如下:
Ventry 是第一條線的速度向量, Vexit 是第二條線的速度向量
這兩條線夾角為 θ, 綠色線 δ 為一常數, R 為圓的半徑
這個圓會接觸到兩向量且距離兩向量的接點距離為 δ
我們可以透過上圖右的算式求得 R 的長度
式子(1):基本 sin 函數, θ, δ, Ventry 邊組成的三角形來計算
式子(2)(3):把它左右搬移一下, 得到求 R 的算式
由於式子 (3) 可以用其下方的算式替換, 結果就是我們只要運用兩次開根號就求得解
雖然我們畫圖可以很清楚知道 θ 的角度, 但是 CNC 機器只收到該往哪裡移動
它並沒法知道夾角, 而求這夾角需要頭痛的 acos 來先找到 θ 值
對 AVR 這種 8-bit MCU 這會是運算負擔, Grbl 改用這來算可以大幅提昇效能
這段程式在 planner.c 中的 plan_buffer_line 函數
計算後求得 R, Vjunction = sqrt(a * R), a 是加速度值, 最大值由使用者設定
我很無聊的用 gnuplot 畫出 sqrt(R) 和線段夾角的曲線, 指令如下
gnuplot -e "set terminal png size 800,400" \
-e "set xrange [0:210]" \
-e "set yrange [0:50]" \
-e "set xtics 15" \
-e "set xlabel \"Vector Angle (degrees)\"" \
-e "set ylabel \"sqrt(R)\"" \
-e "set key left" \
-e "plot \
sqrt((0.02*sin((x*pi/180)/2))/(1-sin((x*pi/180)/2))) title 'Deviation = 0.02', \
sqrt((0.1*sin((x*pi/180)/2))/(1-sin((x*pi/180)/2))) title 'Deviation = 0.1', \
sqrt((1*sin((x*pi/180)/2))/(1-sin((x*pi/180)/2))) title 'Deviation = 1'" > gplot.png
結果:
或是直接上 Google!XD
搜尋:sqrt((0.02*sin(x/2))/(1-sin(x/2)))
Deviation 即是 δ 值, 它是一使用者設定的常數, Grbl 預設為 0.02
3D 印表機預設為 0.1, 1 是我無聊亂選的誇張值XD
可以發現夾角越接近 180 度 (Google 那張圖則是 3.14), Vjunction 就會越大
當曲線轉向幅度不大時它就不會減速, 就可以消除曲線龜速移動的問題
而當夾角縮小時, Vjunction 會掉的很快, 差不多到 135 度時就幾乎是減速到 0 再重新加速
計算完成後會放到 block_buffer 中
plan_buffer_line 會由 motion_control.c 裡的 mc_line 來呼叫
mc_line 會持續填充線段, 直到緩衝區滿了才開始做事情
然後呼叫 stepper.c 中的 st_prep_buffer 把計算過的速度資料存入步進馬達控制的緩衝區
接著就由 timer 中斷不斷的移動馬達, 採用 Bresenham 演算法, 中斷函數也在 stepper.c 中
算法可參考前篇:實作 Bresenham 直線演算法
有點不同的是 Grbl 有 AMASS, 提高取樣頻率但走的步數相同, 目前不太懂其優點
Grbl 把這些線段資料以 block 命名, 而算完後進入步進馬達則是用 segment 命名
上面這些算完只有包含線段的起始速度和終止速度, 並不包含中間的速度控制
進入 st_prep_buffer 這函數後會根據起始速度和終止速度決定加速時間
這裡有一些乘除的算式, 變數名為 intersect_distance, 這裡我不太知道它怎算的
從變數名稱看來應該是求從起始速度加速以及從結束速度加速在中途的交點
Vs 為起始速度, Ve 為結束速度, X 軸為時間, Vi 為交叉點速度, 面積為距離
d1 是 Vs 加速到 Vi 走的距離, d2 是 Vi 減速到 Ve 走的距離, D 為總距離
根據 等加速度直線公式 假設加速度固定
應該可以寫出上圖右側的算式, 然後左右搬移後可以求得 d1 的距離
結果...我算出來的和程式裡的差一個運算符, 上圖右下有個紅色的減號, 程式裡是寫加號
我不太知道哪裡出錯了, 不過我相信應該是我錯的XD 這韌體已經佈署在很多機器上了
加上我數學不好, 不需要去質疑它的正確性XD
這裡算完後就可以決定這線段的速度變化曲線
有可能是梯形 (加速後恆定再減速, 即最上面第一張 v-t 圖)
也可能是三角形, 或是恆遞增, 恆遞減...等, 紀錄下後就可以讓步進馬達去運行
上面這些算式都是用來計算移動速度, 並不會動到移動的步數, 該走的步數當然是要確實走完
大致上就這樣, 這韌體還有許多細節, 像是兩端點偵測, 還有一些其他 G code 的功能
那些我目前先跳過, 目前走線方式我比較有興趣
了解移動細節後我們就可以設定原始碼以符合本機設定, 預設值會丟在 defaults.h
我只改這幾項
#ifdef DEFAULTS_GENERIC
// Grbl generic default settings. Should work across different machines.
#define DEFAULT_X_STEPS_PER_MM 1280.0
#define DEFAULT_Y_STEPS_PER_MM 1280.0
#define DEFAULT_Z_STEPS_PER_MM 1280.0
#define DEFAULT_X_MAX_RATE 450.0 // mm/min
#define DEFAULT_Y_MAX_RATE 450.0 // mm/min
#define DEFAULT_Z_MAX_RATE 450.0 // mm/min
#define DEFAULT_X_MAX_TRAVEL 200.0 // mm
#define DEFAULT_Y_MAX_TRAVEL 270.0 // mm
#define DEFAULT_Z_MAX_TRAVEL 170.0 // mm
DEFAULT_X_STEPS_PER_MM 1280.0
我的馬達加上 M8 螺桿, A4988 設 8 微步, 轉一圈 = 8 * 200 = 1600 微步
M8 的 pitch = 1.25mm, 所以每走 1mm 需要轉 1600 / 1.25 = 1280 微步
DEFAULT_X_MAX_RATE 450.0
這個要用量測的, 沒有馬達規格, 就手動下 G code, 用 feedrate 參數
下到空轉為止然後再減一點, 差不多就好XD
DEFAULT_X_MAX_TRAVEL 200.0
這是最大行程, 前篇有量測過, 直接輸入
http://wukcsoft.blogspot.tw/2014/12/cnc-grbl.html
5.
一開始寫程式之前我是用 python3, 要裝幾個插件 (python3-serial) 才能跑, 程式在此:
#!/usr/bin/python3
import time
import serial # sudo apt-get install python3-serial
import sys
argc = len(sys.argv)
if argc < 3:
print("Usage: " + sys.argv[0] + " <com_port> <gcode_file>")
sys.exit()
print("Open COM port: " + sys.argv[1])
# configure the serial connections (the parameters differs on the device you are connecting to)
ser = serial.Serial(
port = sys.argv[1],
baudrate = 115200,
parity = serial.PARITY_NONE,
stopbits = serial.STOPBITS_ONE,
bytesize = serial.EIGHTBITS,
timeout = None,
rtscts = None,
dsrdtr = None
)
# wait for welcome message and flush it
# when open device node, cnc controller will reset and print message
time.sleep(1)
ser.flushInput()
# load ngc file
print("Open Gcode file: " + sys.argv[2])
f = open(sys.argv[2])
lines = f.readlines()
f.close()
# feed g codes line by line
for line in lines:
if line[0] == ';':
# drop comment
continue;
line_for_print = line.strip()
print("Send: " + line_for_print)
ser.write(str.encode(line))
line_bytes = bytearray()
while 1:
c = ser.read()
if c == b'\n':
print("Recv: " + line_bytes.decode("utf-8"))
break
elif c >= b' ':
# drop other control character such as 0xD
line_bytes += c
ser.close()
程式就是開檔, 讀取 G code, 一行一行塞, 每塞一行就等, 等到回應再塞第二行
全部塞完就離開程式, 實驗過能用, 沒問題, 不過實際上使用會有問題
我們的土砲 CNC 並沒有自動回原位的功能, 一開機在哪裡, 哪裡就是原點
每次重新開啟 ttyACM 原點也會重設, 不知道是不是面對 USB 的 AVR 幹的好事
而我們的土砲機總是很隨意的選地方固定待加工品, 常常要先把銑刀移到參考點
然後才開始工作, 不預期的歸零我們會很困擾, 所以需要一個 UI
這 UI 總是維持 USB 連線, 手動移動完就讀 G code 發送, 不要中途歸零
桌上型電腦實現 UI 的方法很多, 也很雜, 所以我選了一個比較單純的環境
Android CNC !
UI API 可以跨版本直接執行, 也不用擔心用戶有沒有 OpenGL 驅動
因為你很難買到沒有 OpenGL 加速的 Android 平板 (其實硬要買還是有啦......(小聲))
不過裝置有限制, 因為要透過 USB, 平板上要有 USB Host 支援
目前看華碩 MeMO 系列應該都有, 我這台是 ME172V, 現在只要三張小朋友就有
加上無線網路, 自己架個網頁伺服器丟 G code 檔, 平板下載後開啟就能執行任務
原始碼附上:
AndroidCNC.zip
http://wukcsoft.blogspot.tw/2014/12/cnc-if.html
訂閱:
張貼留言 (Atom)
代码之所以是加号因为计算的d2,不是d1
回覆刪除