• 3D列印服務
  • #maker+t=market
  • COSPLAY 3D 建模
  • 1
  • 2
  • 3

Python人工智慧圖控 - 研習交流廳 造訪社團 » 分享

原文網址 石小川
2019-11-27 11:09:22

窮忙一陣子後今天終於可偷閒寫一下文章跟大家分享一下上回談的G-Code產生器了. 我用最簡單的CNC圓形切割來圖文解釋一下, 相信應該可以很快了解其中運作原理.

先解釋一下Entity名詞, Entity在CAD工程上是實體的意思, AutoCAD出圖後的元件我們稱為Entity, 如圓弧, 直線, 雲行線等皆是實體. 上回提過由DWG/DXF檔案 經過程式剖析分解後產生一連串Entity的資料, 如圖一, 是圓的Entity, 將它送入GCodeCircle(Entity) 函式就可很快地產生切圓的G-Code, 下面是GCodeCircle(Entity) C#版程式範例:

//-------------------------------------------------------------------------
public string GCodeCircle(EntityRecord entityrecord)
{
string gCode = "";
Point3D center = new Point3D(entityrecord.Circle.Center.X, entityrecord.Circle.Center.Y, entityrecord.Circle.Center.Z);
double radius = entityrecord.Circle.Radius;
Point3D point = new Point3D(0, 0, 0);
point.X = center.X + radius;
point.Y = center.Y;
gCode += "G00 X" + (point.X - center.X).ToString("#0.0000") + " " + "Y"+ (point.Y - center.Y).ToString("#0.0000") + " " + "Z5.0000"+ "\n";
//此段是為了說明已經簡化許多參數
gCode += "G01" + " " + "Z-1.0000"+ " " + "F200"+ "\n";
gCode += "G02" + " " + "I-"+ radius.ToString("#0.0000");
return gCode;
}

圖二是產生的G-Code, 可直接送去機器做切割一個100mm的正圓.

另外之前有位朋友問我5軸聯動切向跟隨實作問題, 我列出部分程式碼給您參考一下, 基本上我大部分實作都是圓弧直線插補ArcLine()就可完成.

//---------------------------------------------------------------------------
//圓弧直線跟隨插補
//pos : Z軸直線運動位置
//axisNum = 3, 圓弧+直線運動軸數 X Y Z
public boolArcLine(int startx, intstarty, int endx, intendy, int cx, intcy, int[] pos, int[] axis, int dir = 0, intaxisNum = 3, double acc = 10, doubletgvel = 100, double endvel = 0, doublefeedRate = 1.0, int wait = 1, intfifo = (int)FIFO_SEL.SEL_PFIFO1, boolbAbs = true)
{
int st;
if(axisNum < 2 || axisNum > MAX_NAXIS)
return false;
//清空PFIFO
st = IMC_Pkg.PKG_IMC_PFIFOclear(gHandle, fifo);
if(st == 0)
return false;
//設置加速度和進給率
if(SetPFIFO(acc, feedRate, fifo) == false)
return false;
//映射軸
st = IMC_Pkg.PKG_IMC_AxisMap(gHandle, axis, axisNum, fifo);
if(st == 0)
return false;
double dx,dy;
dx = startx - cx;
dy = starty - cy;
double r1 = Math.Sqrt(dx * dx + dy * dy);
dx = endx - cx;
dy = endy - cy;
double r2 = Math.Sqrt(dx * dx + dy * dy);
//判斷, 如果起點到圓心距離r1 != 終點到圓心距離r2 表示圓弧軌跡不正確, 跳出不執行
if(r1 != r2)
return false;
//由當前位置移動到指定位置
if(bAbs) //絕對位置
st = IMC_Pkg.PKG_IMC_ArcLine_Pos(gHandle, endx, endy, cx, cy, dir, pos, axisNum - 2, tgvel, endvel, wait, fifo); //絕對位置
else
st = IMC_Pkg.PKG_IMC_ArcLine_Dist(gHandle, endx, endy, cx, cy, dir, pos, axisNum - 2, tgvel, endvel, wait, fifo); //相對位置
if(st == 0)
return false;
return true;
}

圖三是我執行雷射切割的機台, 雷射頭是5.5W藍光雷射, 下回再分享此G-Code雷射切割成果.

p.s. 在我的APP程式直接畫圖我是直接呼叫運動卡驅動CNC, 沒有經過G-Code產生器這道手續, 加快CNC處理速度, 除非是匯入DWG/DXF檔案才會呼叫G-Code 產生器。

鍾小生
2019-11-27 12:24:32

小聲問,那套App有試用版嗎?


原文網址 石小川
2019-11-27 10:57:00

對於想用CNC製作一些零組件的朋友來說,要學會AutoCAD、SolidWork、uG、Fusion360、ARTCAM、PowerMill、 MasterCAM、Mach3等,我相信會嚇跑一票人的熱血。其實CAD/CAM套裝軟體很強但有很多功能幾百年也用不到,只是浪費錢而已,在接工廠自動控制客製化軟體方面絕大部分作動都很單純,我這裡是將所有功能精簡成 : /檔案/機器/刀具/G-Code sender,只要讀檔或在螢幕寫字、繪圖後自動產生G-Code直接送至CNC銑床或雷射加工,盡量能由機器代勞的就盡量隱藏在程式裏面,操作介面就只有一個螢幕面板Panel。

要做到這點須先解析DWG檔案結構,後續追加功能才有辦法走下去,AutoCAD DWG檔案簡直就是一個複雜的巨型圖層資料庫而且每兩年改版一次,建議還是用DXF圖檔相容性較高,有機會再談談DXF檔結構。這裡先分享一下DWG解析方法給有興趣研發的好友參考一 下。

基本上程式要解析其中的資料結構如下,有點長刪減一些函數但原理不變。

讀取DWG檔後打開資料庫取實體EntityName的字串名稱(約50個標籤名稱)一層層解析後繪圖即可原圖重現,看你要加圖、刪圖或送去產生G-Code等,另外如果用不著的功能就略過,沒必要全部實作,有興趣可一起討論,下回再討論G-Code產生器。

p.s. 下列範例是C#版本,有興趣的朋友歡迎自行改成Python版本。

//-------------------------------------------------------------------
public void Draw(List<CadParse> cadparselist)
{
foreach(CadParse cadParse in cadparselist)
{
switch(cadParse.EntityName)
{
case "AcDbAlignedDimension":
break;
case "AcDbArc":
break;
case "AcDbArcDimension":
break;
case "AcDbBlockReference":
break;
case "AcDbBody":
break;
case "AcDbCircle":
DrawCircle(cadParse);
break;
case "AcDbPoint":
break;
case "AcDbDiametricDimension":
break;
case "AcDbViewport":
break;
case "AcDbEllipse":
DrawEllipse (cadParse);
break;
case "AcDbFace":
break;
case "AcDbHatch":
break;
case "AcDbLeader":
break;
case "AcDbLine":
DrawLine(cadParse);
break;
case "AcDb2LineAngularDimension":
break;
case "AcDbMInsertBlock":
break;
case "AcDbMline":
break;
case "AcDbMText":
break;
case "AcDbOle2Frame":
break;
case "AcDbOrdinateDimension":
break;
case "AcDb3PointAngularDimension":
break;
case "AcDbPolyFaceMesh":
break;
case "AcDbPolygonMesh":
break;
case "AcDbPolyline":
DrawPolyLine(cadParse);
break;
case "AcDb2dPolyline":
break;
case "AcDb3dPolyline":
break;
case "AcDbProxyEntity":
break;
case "AcDbRadialDimension":
break;
case "AcDbRasterImage":
break;
case "AcDbRay":
break;
case "AcDbRegion":
break;
case "AcDbRotatedDimension":
break;
case "AcDbShape":
break;
case "AcDbSolid":
break;
case "AcDb3dSolid":
break;
case "AcDbSpline":
break;
case "AcDbTable":
break;
case "AcDbTrace":
break;
case "AcDbWipeout":
break;
case "AcDbXline":
break;
case "AcDbPdfReference":
break;
case "AcDbDwfReference":
break;
case "AcDbDgnReference":
break;
} //end switch(cadParse.EntityName)
} //end foreach(CadParse cadParse in _cadParseList)
} //end public void Draw()


原文網址 石小川
2019-11-26 11:24:33

(之前在其他社團分享過C#版本, 現在改用Python分享給社團好友。) 這個羅技飛行搖桿本來是用在一個從頭城出發要去一個遙遠地方的大台UAV,看到挑戰國內法令的罰款可能會罰到脫褲子, 所以只能收手不玩了, 天空不能玩了, 就換地上及海上囉, 於是把程式移植到CNC, 運作起來還蠻順手的, 像是 夾娃娃機, 其實不管是CNC軸控、太空船、飛機或機器人, Joystick程式是一樣的。 以前玩Apple-II時曾經用6502組合語言改寫地球保衛戰的電玩, 大意是太空衛星發射雷射光射向入侵地球的飛碟, 但不可以射到底下建築物否則扣分, 這個CNC Demo頗有幾分神似呢, 特別是雷射扳機打開發射時, 感覺還蠻爽的^^ 下面是控制搖桿程式庫TJoystick, 分享給社團好友參考一下, 須自行想辦法最佳化, 可很容易地加入自已的機台或UAV。 因為主程式很長, 所以只列出TJoystick程式庫, 主程式就不po了, 有興趣再私下討論了。 當然, 眾所皆知, Python在資料處理方面的確非常方便, 對科學家來說可以省下很多Coding 時間, 有機會再分享Python 在光學雷達(Lidar)及數位訊號處裡(DSP)的應用實例和程式碼。 p.s. Python在將來關燈工廠會佔有一席之地, 事實上在我專案計畫裡有個1024顆Xilinx FPGA迷你超級電腦是用Python當介面。 如果對Python自動控制有興趣的朋友可上我臉書或私訊我, 我有開些課程, 參考看看是否有幫助, 光騰臉書 : https://www.facebook.com/qmlab/ #須先pip install pygame #引用搖桿模組 import pygame #------------------------------------------------------------------------------ #列舉搖桿的手柄動作型態 #------------------------------------------------------------------------------ class __JoystickDirectionType(): Center = 0 zUp = 1 zDown = 2 Up = 3 Right = 4 Down = 5 Left = 6 JoystickDirectionType = __JoystickDirectionType() #------------------------------------------------------------------------------ #搖桿控制類別 #------------------------------------------------------------------------------ class TJoystick: #------------------------------------------------------------------------ def __init__(self): self.joystickCount = 0 #搖桿數目 ,接了幾支搖桿。 self.numberButtons = 0 #按鍵數目 #串列 [ ] ,用來儲存搜尋到的搖桿名稱,一隻就一個名稱。 self.joysticks = [] self.pjoystick = None #指向選用的搖桿位址 #字典型態 { },用來儲存搖桿手柄三軸及按鍵的目前狀態。 self.Controls = { 'Trigger' : 0, # Button_0 'Axis-X' : 0, 'Axis-Y' : 0, 'Axis-Z' : 0, 'Hat-X' : 0, 'Hat-Y' : 0, 'Slider' : 0, 'Button-0' : 0, 'Button-1' : 0, 'Button-2' : 0, 'Button-3' : 0, 'Button-4' : 0, 'Button-5' : 0, 'Button-6' : 0, 'Button-7' : 0, 'Button-8' : 0, 'Button-9' : 0, 'Button-10' : 0, 'Button-11' : 0, 'Button-12' : 0 } #------------------------------------------------------------------------ #開啟搖桿設備 def Open(self): #顯示初始化設定 , 沒使用到, 但必須有這一項, 否則無法正常執行 #Console : error: video system not initialized訊息不用理會 pygame.display.init() #搖桿初始化設定 pygame.joystick.init() #取得幾隻搖桿 self.joystickCount = pygame.joystick.get_count() #print (self.joystickCount) #串列 [pointer, name, nameaxes, numbuttons, umhats], 用來暫存一個搖桿資訊。 joystick = [] #找到的搖桿名稱就放進joystick for i in range(self.joystickCount): pjoystick = pygame.joystick.Joystick(i) pjoystick.init() pygame.joystick.init() #暫存取得的一個搖桿資訊 [pointer, name, nameaxes, numbuttons, umhats] joystick.append(pjoystick) #pointer [0] joystick.append(pjoystick.get_name()) #name [1] joystick.append(pjoystick.get_numaxes()) #numaxes [2] joystick.append(pjoystick.get_numbuttons()) #numbuttons [3] joystick.append(pjoystick.get_numhats()) #numhats [4] #[pointer, name, nameaxes, numbuttons, umhats] self.joysticks.append(joystick) #指向第一個Joystick (因為只接一個搖桿) self.pjoystick = self.joysticks[0][0] self.numberButtons = pjoystick.get_numbuttons(); #取得按鍵數目 #假如沒接搖桿則傳回False if(self.joystickCount == 0): return False #正確傳回True return True #------------------------------------------------------------------------ #關閉搖桿設備 def Close(self): pygame.quit() #------------------------------------------------------------------------ #取得搖桿資訊 def JoystickInfo(self): return self.joysticks #------------------------------------------------------------------------ #取得搖桿目前所有狀態 def ControlsInfo(self): return self.Controls #------------------------------------------------------------------------ #取得搖桿目前Trigger鍵狀態 (同Button-0), 所有Button 壓下去 = 1, 放掉 = 0 def getTrigger(self): return self.Controls['Trigger'] #------------------------------------------------------------------------ #取得搖桿目前Button -0鍵狀態(同Trigger) def getButton0(self): return self.Controls['Button-0'] #------------------------------------------------------------------------ #取得搖桿目前Button -1鍵狀態 def getButton1(self): return self.Controls['Button-1'] #------------------------------------------------------------------------ #取得搖桿目前Button -2鍵狀態 def getButton2(self): return self.Controls['Button-2'] #------------------------------------------------------------------------ #取得搖桿目前Button -3鍵狀態 def getButton3(self): return self.Controls['Button-3'] #------------------------------------------------------------------------ #取得搖桿目前Button -4鍵狀態 def getButton4(self): return self.Controls['Button-4'] #------------------------------------------------------------------------ #取得搖桿目前Button -5鍵狀態 def getButton5(self): return self.Controls['Button-5'] #------------------------------------------------------------------------ #取得搖桿目前Button -6鍵狀態 def getButton6(self): return self.Controls['Button-6'] #------------------------------------------------------------------------ #取得搖桿目前Button -7鍵狀態 def getButton7(self): return self.Controls['Button-7'] #------------------------------------------------------------------------ #取得搖桿目前Button -8鍵狀態 def getButton8(self): return self.Controls['Button-8'] #------------------------------------------------------------------------ #取得搖桿目前Button -9鍵狀態 def getButton9(self): return self.Controls['Button-9'] #------------------------------------------------------------------------ #取得搖桿目前Button -10鍵狀態 def getButton10(self): return self.Controls['Button-10'] #------------------------------------------------------------------------ #取得搖桿目前Button -11鍵狀態 def getButton11(self): return self.Controls['Button-11'] #------------------------------------------------------------------------ #取得搖桿目前Button -12鍵狀態 def getButton12(self): return self.Controls['Button-12'] #------------------------------------------------------------------------ #取得搖桿目前Axis -X軸值 def getAxisX(self): return self.Controls['Axis-X'] #------------------------------------------------------------------------ #取得搖桿目前Axis -Y軸值 def getAxisY(self): return self.Controls['Axis-Y'] #------------------------------------------------------------------------ #取得搖桿目前Axis -Z軸值 def getAxisZ(self): return self.Controls['Axis-Z'] #------------------------------------------------------------------------ #取得搖桿目前Slider軸值 def getSlider(self): return self.Controls['Slider'] #------------------------------------------------------------------------ #取得搖桿目前Hat -X軸狀態 def getHatX(self): return self.Controls['Hat-X'] #------------------------------------------------------------------------ #取得搖桿目前Hat -Y軸值 def getHatY(self): return self.Controls['Hat-Y'] #------------------------------------------------------------------------ #同時取得搖桿目前Hat -X軸, Hat-Y軸值 def getHatXY(self): return self.Controls['Hat-X'], self.Controls['Hat-Y'] #------------------------------------------------------------------------ #輪循監聽搖桿所有狀態 , 此函數應該放在執行緒中執行 def poll(self): #取得搖桿事件並放入事件堆疊中 , 此函數必須放置此處 pygame.event.pump() #將偵測到的搖桿狀態儲存至字典self .Controls for i in range(self.numberButtons): self.Controls['Button-'+str(i)] = self.pjoystick.get_button(i) self.Controls['Axis-X'] = self.pjoystick.get_axis(0) self.Controls['Axis-Y'] = self.pjoystick.get_axis(1) self.Controls['Slider'] = self.pjoystick.get_axis(2) self.Controls['Axis-Z'] = self.pjoystick.get_axis(3) self.Controls['Hat-X'] = self.pjoystick.get_hat(0)[0] self.Controls['Hat-Y'] = self.pjoystick.get_hat(0)[1] self.Controls['Trigger'] = self.pjoystick.get_button(0)

Grass Lin
2019-11-26 13:20:29


原文網址 石小川
2019-11-25 18:31:38

Python語法簡單易學,最重要的是還有大量功能強大的免費模組可下載,其強大的應用層面已經發展到令人不可忽視的重要地位,甚至NASA也拿來當作航太人機介面的控制語言。

社團主要以Python程式控制軟/硬體為出發點,研習圖形自動控制、 機器視覺 、語音辨識 、人工智慧 、機器人、自動駕駛 、 無人飛行器 、 水下無人載具 、 光學雷達 、、 等 相關技術研討, 並且分享開源軟硬體。


原文網址 石小川
2019-11-25 12:06:56

Python語法簡單易學,最重要的是還有大量功能強大的免費模組可下載,其強大的應用層面已經發展到令人不可忽視的重要地位,甚至NASA也拿來當作航太人機介面的控制語言。

社團主要以Python程式控制軟/硬為出發點,研習圖形自動控制、 機器視覺 、語音辨識 、人工智慧 、機器人、自動駕駛 、 無人飛行器 、 水下無人載具 、 光學雷達 、、 等 相關技術研討, 並且分享開源軟硬體。

Steve Ku
2019-11-25 16:09:38

老師
Python 是用在那種MCU上?


原文網址 石小川
2019-11-25 11:50:10

Python語法簡單易學,最重要的是還有大量功能強大的免費模組可下載,其強大的應用層面已經發展到令人不可忽視的重要地位,甚至NASA也拿來當作航太人機介面的控制語言。

社團主要以Python程式控制軟/硬為出發點,研習圖形自動控制、 機器視覺 、語音辨識 、人工智慧 、自動駕駛 、 無人飛行器 、 水下無人載具 、 光學雷達 、、 等 相關技術研討, 並且分享開源軟硬體。


 

全不選 發文排行