01
ZMC432-V2運(yùn)動(dòng)控制器介紹
ZMC432-V2高性能多軸運(yùn)動(dòng)控制器是一款兼容EtherCAT總線和脈沖型的獨(dú)立式運(yùn)動(dòng)控制器,自帶6軸本地差分脈沖軸,最多可擴(kuò)展至32軸,能實(shí)現(xiàn)總線軸+脈沖軸混合插補(bǔ)的多軸運(yùn)動(dòng)控制場(chǎng)合。同時(shí)支持正運(yùn)動(dòng)遠(yuǎn)程顯示功能,能提供網(wǎng)絡(luò)組態(tài)顯示,可實(shí)時(shí)監(jiān)控和調(diào)整參數(shù)配置。

ZMC432-V2硬件功能特性:
(1)支持32軸運(yùn)動(dòng)控制(脈沖+EtherCAT總線),EtherCAT最小通訊周期可達(dá)125us;
(2)24路通用輸入、12路通用輸出,2路模擬量輸出(DA),其中包括2路高速輸入和2路高速輸出;
(3)6路差分脈沖軸輸出,總線軸、脈沖軸可混合插補(bǔ);
(4)內(nèi)置多項(xiàng)實(shí)時(shí)性運(yùn)動(dòng)控制功能,例如視覺(jué)飛拍、多維PSO、高速位置鎖存,多軸同步運(yùn)行等;
(5)可通過(guò)EtherCAT擴(kuò)展模塊進(jìn)行IO硬件資源擴(kuò)展,可擴(kuò)展至4096個(gè)隔離輸入口和4096個(gè)隔離輸出口;
(6)具備豐富的運(yùn)動(dòng)控制功能,如點(diǎn)位運(yùn)動(dòng)、電子凸輪、直線插補(bǔ)、圓弧插補(bǔ)、連續(xù)軌跡加工;
(7)支持掉電檢測(cè)、掉電存儲(chǔ),多種程序加密方式,能夠有效防止系統(tǒng)故障,保護(hù)項(xiàng)目工程文件數(shù)據(jù),并提高系統(tǒng)的可靠性;
(8)通過(guò)純國(guó)產(chǎn)IDE開(kāi)發(fā)環(huán)境RTSys進(jìn)行項(xiàng)目開(kāi)發(fā),可實(shí)時(shí)仿真、在線跟蹤以及診斷與調(diào)試,簡(jiǎn)便易用,支持多種高級(jí)上位機(jī)語(yǔ)言聯(lián)合編程進(jìn)行二次開(kāi)發(fā)。

02
C#運(yùn)動(dòng)控制+CAD導(dǎo)圖DEMO概述
本期示教DEMO是以正運(yùn)動(dòng)的運(yùn)動(dòng)控制函數(shù)庫(kù),CAD導(dǎo)圖函數(shù)庫(kù),在VS環(huán)境下使用C#進(jìn)行編程開(kāi)發(fā)。
DEMO內(nèi)容主要實(shí)現(xiàn)CAD圖紙解析(導(dǎo)入CAD文件,軌跡數(shù)據(jù)解析,編輯軌跡)后下發(fā)給控制器進(jìn)行運(yùn)動(dòng)(運(yùn)動(dòng)前瞻,運(yùn)動(dòng)指令下發(fā),狀態(tài)監(jiān)控)。用戶可以參考例程更快的使用正運(yùn)動(dòng)函數(shù)庫(kù)進(jìn)行相關(guān)開(kāi)發(fā)。
后期我們將推出以下3篇教程介紹該示教例程的開(kāi)發(fā)流程和使用方法,方便用戶快速上手該例程,并掌握C#運(yùn)動(dòng)控制與CAD導(dǎo)圖相結(jié)合編程開(kāi)發(fā)的相關(guān)知識(shí)。
?C#運(yùn)動(dòng)控制開(kāi)源(一): CAD導(dǎo)圖和小線段速度前瞻的優(yōu)化之CAD導(dǎo)圖
?C#運(yùn)動(dòng)控制開(kāi)源(二): CAD導(dǎo)圖和小線段速度前瞻的優(yōu)化之前瞻優(yōu)化
?C#運(yùn)動(dòng)控制開(kāi)源(三): CAD導(dǎo)圖和小線段速度前瞻的優(yōu)化的軟件框架
03
C#使用ZMOTION CAD庫(kù)進(jìn)行CAD導(dǎo)圖的開(kāi)發(fā)
正運(yùn)動(dòng)技術(shù)提供開(kāi)放的ZmotionCadEx庫(kù),可導(dǎo)入DXF、Ai、Plt、Dst圖紙,可以生成運(yùn)動(dòng)坐標(biāo)數(shù)據(jù)轉(zhuǎn)G代碼、zbasic運(yùn)動(dòng)指令、或直接PC函數(shù)執(zhí)行運(yùn)動(dòng)。
1.在VS2019菜單“文件”→“新建”→“項(xiàng)目”,啟動(dòng)創(chuàng)建項(xiàng)目向?qū)А?/p>

2.選擇開(kāi)發(fā)語(yǔ)言為“C#”和Windows窗體應(yīng)用程序,點(diǎn)擊下一步。

3.配置好項(xiàng)目名稱(chēng)和位置,以及相應(yīng)框架,點(diǎn)擊創(chuàng)建。

4.找到廠家提供的光盤(pán)資料里面的C#函數(shù)庫(kù),路徑如下(64位庫(kù)為例)。
進(jìn)入廠商提供的光盤(pán)資料,找到ZmotionCadEx.dll,ZmotionCadEx.cs這兩個(gè)個(gè)庫(kù)文件。庫(kù)文件路徑:【00光盤(pán)資料】→【04PC函數(shù)】→【03Zmotion CAD庫(kù)V3.1】→【庫(kù)文件】→【W(wǎng)indows平臺(tái)】→【C#】→【64位】。

5.將廠商提供的C#的庫(kù)文件以及相關(guān)文件復(fù)制到新建的項(xiàng)目中。
(1)將ZmotionCadEx.cs文件復(fù)制到新建的項(xiàng)目里面中。

(2)將ZmotionCadEx.dll文件放入bindebug文件夾中。

(3)將ZmotionCadEx.cs文件添加進(jìn)項(xiàng)目中。右鍵項(xiàng)目名稱(chēng),選擇添加,再選擇現(xiàn)有項(xiàng),選擇ZmotionCadEx.cs文件。

6.雙擊Form1.cs里面的Form1,出現(xiàn)代碼編輯界面,在文件開(kāi)頭寫(xiě)入using ZmotionCadDll。

至此,項(xiàng)目新建完成,可進(jìn)行C#項(xiàng)目開(kāi)發(fā)。
例程界面如下:

CAD解析與編輯流程:

04
實(shí)現(xiàn)CAD文件解析與顯示
1.CAD解析相關(guān)函數(shù)介紹
①連接控制器。
Description://與控制器建立鏈接,成功后解鎖高級(jí)功能 Input://IP地址,字符串的方式輸入 Output://控制器句柄 Return://錯(cuò)誤碼 int32__stdcallZMotionCadArray_OpenEth(char*ipaddr,ZMC_HANDLE*pHandle); *************************************************************/ [DllImport("ZmotionCadEx.dll",EntryPoint="ZMotionCadArray_OpenEth",CharSet=CharSet.Ansi,CallingConvention=CallingConvention.StdCall)] publicstaticexternInt32ZMotionCadArray_OpenEth(stringipaddr,outIntPtrphandle);
②導(dǎo)入CAD圖形。
/************************************************************* Description://導(dǎo)入圖形文件(支持dxf、plt、ai、dst) Input:// lpszFileFullPathname路徑和文件名 duUnitPLT的比例Option預(yù)留,缺省都轉(zhuǎn)換為seg refDistance轉(zhuǎn)換時(shí)參考精度 Output:// Return://錯(cuò)誤碼 int__stdcallZMotionCadArray_ImportVectGraph(LPCTSTRlpszFileFullPathname,doubleduUnit,intOption,doublerefDistance); *************************************************************/ [DllImport("ZmotionCadEx.dll",EntryPoint="ZMotionCadArray_ImportVectGraph",CharSet=CharSet.Ansi,CallingConvention=CallingConvention.StdCall)] publicstaticexternInt32ZMotionCadArray_ImportVectGraph(stringlpszFileFullPathname,doubleduUnit,intOption,doublerefDistance);
③提取圖形數(shù)組。
/************************************************************* Description://提取當(dāng)前圖形數(shù)組 Input://struct_Array提取的數(shù)組 //nStructNum數(shù)組的數(shù)量 Output:// Return://錯(cuò)誤碼 *************************************************************/ //int__stdcallZMotionCadArray_GetVectArray(Struct_ZCad_Array*struct_Array,intnStructNum); [DllImport("ZmotionCadEx.dll",EntryPoint="ZMotionCadArray_GetVectArray",CharSet=CharSet.Ansi,CallingConvention=CallingConvention.StdCall)] publicstaticexternInt32ZMotionCadArray_GetVectArray(refStruct_ZCad_Arraystruct_Array,intnStructNum);
④圖形數(shù)組格式。

⑤獲取CAD圖形的范圍。
/************************************************************* Description://范圍坐標(biāo)方向是向上為正 Input:// Output:// Return://錯(cuò)誤碼 *************************************************************/ //uint32__stdcallZMotionCadArray_GetRange(float*pLeft,float*pBottom,float*pWdith,float*pHeight,doublerefDistance); [DllImport("ZmotionCadEx.dll",EntryPoint="ZMotionCadArray_GetRange",CharSet=CharSet.Ansi,CallingConvention=CallingConvention.StdCall)] publicstaticexternInt32ZMotionCadArray_GetRange(reffloatpLeft,reffloatpBottom,reffloatpWdith,reffloatpHeight,doublerefDistance);
2.解析流程
步驟1:連接控制器并導(dǎo)入需要解析的CAD文件。
ZmotionCad.ZMotionCadArray_ImportVectGraph導(dǎo)入CAD文件(支持DXF、Ai、Plt、Dst格式);
參數(shù)3可以設(shè)置是否把曲線強(qiáng)制轉(zhuǎn)換為小線段,本例程是轉(zhuǎn)化成小線段解析的。
使用ZMotionCadArray_GetRange獲取到CAD圖形的范圍,并和顯示用的PictureBox長(zhǎng)寬進(jìn)行計(jì)算,獲得轉(zhuǎn)換比例和偏移。
if(G_CardHandle==(IntPtr)0) { MessageBox.Show("檢測(cè)到尚未連接控制器,請(qǐng)先連接控制器再進(jìn)行操作"); return; } if(G_CadHandle==(IntPtr)0) { iret=ZmotionCad.ZMotionCadArray_OpenEth(連接控制器.Adrr,outG_CadHandle); } if(G_CadHandle!=(IntPtr)0)//開(kāi)始導(dǎo)入CAD文件 { OpenFileDialogopenFileDialog1=newOpenFileDialog(); openFileDialog1.InitialDirectory=""; openFileDialog1.Filter="DXFFile(*.dxf)|*.dxf|PLTFile(*.PLT)|*.PLT|AIFile(*.AI)|*.AI|DSTFile(*.DST)|*.DST"; openFileDialog1.RestoreDirectory=true; openFileDialog1.FilterIndex=1; if(openFileDialog1.ShowDialog()==DialogResult.OK)//打開(kāi)配置文件 { strFilePath=openFileDialog1.FileName; this.Text=strFilePath; iret=ZmotionCad.ZMotionCadArray_ImportVectGraph(strFilePath,1024,0,m_refDistance);//曲線強(qiáng)制轉(zhuǎn)換為小線段 iret=ZmotionCad.ZMotionCadArray_GetVectNum(refZCad_ArrayLen);//導(dǎo)入數(shù)據(jù) ZCad_ArrayInfo=newZmotionCad.Struct_ZCad_Array[ZCad_ArrayLen]; iret=ZmotionCad.ZMotionCadArray_GetVectArray(refZCad_ArrayInfo[0],ZCad_ArrayLen);//獲取圖形數(shù)據(jù) iret=ZmotionCad.ZMotionCadArray_IfCloseVect(false);//是否只處理封閉軌跡 Get_Array(); floatImage_Left,Image_bottom,Image_Width,Image_Height; Image_Left=0; Image_bottom=0; Image_Width=0; Image_Height=0; iret=ZmotionCad.ZMotionCadArray_GetRange(refImage_Left,refImage_bottom,refImage_Width,refImage_Height,0.05); if(Image_Width?0.0001?&&?Image_Height??0.0001) ????????{ ????????????Image_Left?=?(float)0.0; ????????????Image_bottom?=?(float)0.0; ????????????Image_Width?=?(float)100.0; ????????????Image_Height?=?(float)100.0; ????????} ????????double?ObjectPixHeight,?ObjectPixWidth; ????????if?(Image_Width?*?PicHeight?<=?Image_Height?*?PicWidth) ????????{ ????????????ObjectPixHeight?=?PicHeight; ????????????ObjectPixWidth?=?ObjectPixHeight?*?Image_Width?/?Image_Height; ????????} ????????else ????????{ ????????????ObjectPixWidth?=?PicWidth; ????????????ObjectPixHeight?=?ObjectPixWidth?*?Image_Height?/?Image_Width; ????????} ????????zoomFactor?=?1; ????????dScale?=?ObjectPixHeight?/?Image_Height; ????????m_dUnitsPerMm?=?dScale?*?1; ????????//偏移 ????????m_dTranX?=?(CadShow.Width?-?ObjectPixWidth)?/?2?-?Image_Left?*?dScale; ????????m_dTranY?=?(CadShow.Height?-?ObjectPixHeight)?/?2?-?Image_bottom?*?dScale; ????????Show_Picture(); ????????If_ImportArray?=?true; ????} } else { ????MessageBox.Show("控制器連接失敗"); }
步驟2:通過(guò)函數(shù)獲取VectArray數(shù)據(jù)并解析。
使用ZMotionCadArray_GetVectArray獲取到圖形數(shù)組,通過(guò)Show_Picture()解析圖形數(shù)組并繪制到PictureBox圖象上顯示。
//獲取數(shù)據(jù) publicvoidGet_Array() { if(G_CadHandle==(IntPtr)0) { //MessageBox.Show("未鏈接到控制器!","提示"); } else { intiret=ZmotionCad.ZMotionCadArray_GetVectNum(refZCad_ArrayLen);//獲取圖形長(zhǎng)度 ZCad_ArrayInfo=newZmotionCad.Struct_ZCad_Array[ZCad_ArrayLen]; iret=ZmotionCad.ZMotionCadArray_GetVectArray(refZCad_ArrayInfo[0],ZCad_ArrayLen);//獲取圖形數(shù)據(jù) choosevectnum=0; closevectnum=0; for(inti=0;i?ZCad_ArrayLen;?i++)????????????????//遍歷數(shù)組 ????????{ ????????????if?((ZCad_ArrayInfo[i].m_nInVectFrist?==?1))?????//是曲線起始 ????????????{ ????????????????if?(ZCad_ArrayInfo[i].m_nChoose?==?1)?????????????????//是否選中 ????????????????{ ????????????????????choosevectnum++; ????????????????} ????????????????closevectnum++; ????????????} ????????} ????????Show_Picture(); ????} } 解析圖形數(shù)組和繪圖函數(shù)Show_Picture() //顯示圖形 public?void?Show_Picture() {????g.Clear(Color.Black);????if?(坐標(biāo)系ToolStripMenuItem.Checked) ????{ ????????//繪制坐標(biāo)系 ????????My_Pen?=?new?Pen(Color.Red,?1);? ???????g.DrawLine(My_Pen,?(int)(0?*?m_dUnitsPerMm?+?m_dTranX),?CadShow.Height?-?(int)(0?*?m_dUnitsPerMm?+?m_dTranY),?(int)CadShow.Width,?CadShow.Height?-?(int)(0?*?m_dUnitsPerMm?+?m_dTranY)); ????????My_Pen?=?new?Pen(Color.Green,?1); ????????g.DrawLine(My_Pen,?(int)(0?*?m_dUnitsPerMm?+?m_dTranX),?CadShow.Height?-?(int)(0?*?m_dUnitsPerMm?+?m_dTranY),?(int)(0?*?m_dUnitsPerMm?+?m_dTranX),?0);????????//原點(diǎn) ????????My_Pen?=?new?Pen(Color.White,?1); ????????g.DrawRectangle(My_Pen,?(int)(-10?*?m_dUnitsPerMm?+?m_dTranX),?CadShow.Height?-?(int)(10?*?m_dUnitsPerMm?+?m_dTranY),?(int)(20?*?m_dUnitsPerMm),?(int)(20?*?m_dUnitsPerMm)); ????????//標(biāo)注XY方向 ????????My_Pen?=?new?Pen(Color.White,?1); ????????g.DrawLine(My_Pen,?(int)(0?*?m_dUnitsPerMm?+?m_dTranX),?CadShow.Height?-?(int)(0?*?m_dUnitsPerMm?+?m_dTranY),?(int)(0?*?m_dUnitsPerMm?+?m_dTranX?+?128),?CadShow.Height?-?(int)(0?*?m_dUnitsPerMm?+?m_dTranY)); ????????My_Pen?=?new?Pen(Color.White,?1); ????????g.DrawLine(My_Pen,?(int)(0?*?m_dUnitsPerMm?+?m_dTranX),?CadShow.Height?-?(int)(0?*?m_dUnitsPerMm?+?m_dTranY),?(int)(0?*?m_dUnitsPerMm?+?m_dTranX),?CadShow.Height?-?(int)(0?*?m_dUnitsPerMm?+?m_dTranY?+?128)); ????????//標(biāo)注XY字符 ????????My_Pen?=?new?Pen(Color.White,?1); ????????Draw_String((int)(0?*?m_dUnitsPerMm?+?m_dTranX?+?124),?CadShow.Height?-?(int)(0?*?m_dUnitsPerMm?+?m_dTranY?+?11),?"X"); ????????My_Pen?=?new?Pen(Color.White,?1); ????????Draw_String((int)(0?*?m_dUnitsPerMm?+?m_dTranX?-?9),?CadShow.Height?-?(int)(0?*?m_dUnitsPerMm?+?m_dTranY?+?150),?"Y"); ????} ????for?(int?i?=?0;?i??ZCad_ArrayLen;?i++)????????????????//遍歷數(shù)組 ????{ ????????double?dXPrevPos_x1,?dXPrevPos_x2,?dXPrevPos_z1,?dXPrevPos_y1,?dXPrevPos_y2,?dXPrevPos_z2;? ???????dXPrevPos_x1?=?ZCad_ArrayInfo[i].x1?*?m_dUnitsPerMm?+?m_dTranX; ????????dXPrevPos_x2?=?ZCad_ArrayInfo[i].x2?*?m_dUnitsPerMm?+?m_dTranX; ????????dXPrevPos_z1?=?ZCad_ArrayInfo[i].z1?/?3.141596?*?180; ????????dXPrevPos_y1?=?CadShow.Height?-?(ZCad_ArrayInfo[i].y1?*?m_dUnitsPerMm?+?m_dTranY); ????????dXPrevPos_y2?=?CadShow.Height?-?(ZCad_ArrayInfo[i].y2?*?m_dUnitsPerMm?+?m_dTranY); ????????dXPrevPos_z2?=?ZCad_ArrayInfo[i].z2?/?3.141596?*?180; ????????double?Start_Pos_x,?Start_Pos_y; ????????switch?(ZCad_ArrayInfo[i].m_nItemtype) ????????{ ????????????case?ZmotionCad.ZCAD_ITEMTYPE_VECT:????????//此處開(kāi)始是曲線類(lèi)型 ?????????????????break; ????????????case?ZmotionCad.ZCAD_ITEMTYPE_VECTPoint:???//點(diǎn) ????????????????if?(ZCad_ArrayInfo[i].m_nEmptyMove?!=?0) ????????????????{ ????????????????} ????????????????break; ????????????case?ZmotionCad.ZCAD_ITEMTYPE_VECTLine:????//通過(guò)線型繪制圖形 ????????????????if?(ZCad_ArrayInfo[i].m_nInVectFrist?==?1)?????????????????//是否曲線起始 ????????????????{ ????????????????????if?(ZCad_ArrayInfo[i].m_nChoose?==?1)?????????????????//是否選中 ????????????????????????iCloseChoose?+=?1; ????????????????????Start_Pos_x?=?ZCad_ArrayInfo[i].m_dGetStartX?*?m_dUnitsPerMm?+?m_dTranX; ????????????????????Start_Pos_y?=?CadShow.Height?-?(ZCad_ArrayInfo[i].m_dGetStartY?*?m_dUnitsPerMm?+?m_dTranY); ????????????????????if?(順序ToolStripMenuItem.Checked) ????????????????????{ ????????????????????????Draw_String((int)Start_Pos_x,?(int)Start_Pos_y,?iCloseLine.ToString());??????????//標(biāo)記數(shù)字 ????????????????????} ????????????????????if?(空移ToolStripMenuItem.Checked) ????????????????????{ ????????????????????????p_color?=?Color.Gray;????????????????????????//默認(rèn)顏色 ????????????????????????My_Pen?=?new?Pen(p_color,?(float)0.1);??????????????//畫(huà)筆顏色,寬度 ????????????????????????My_Pen.DashPattern?=?new?float[]?{?3,?3?};?????????????????????????????????????//設(shè)置短劃線和空白部分的數(shù)組 ????????????????????????Draw_Line((int)PrePosx,?(int)PrePosy,?(int)dXPrevPos_x1,?(int)dXPrevPos_y1); ????????????????????}? ???????????????????iCloseLine++; ????????????????} ????????????????if?(ZCad_ArrayInfo[i].m_nChoose?==?1)?????????????????//是否選中 ????????????????{ ????????????????????p_color?=?Color.Red;????????????????????????//默認(rèn)顏色 ????????????????????My_Pen?=?new?Pen(p_color,?1);??????????????//畫(huà)筆顏色,寬度 ????????????????} ????????????????else ????????????????{ ????????????????????p_color?=?Color.White;????????????????????????//默認(rèn)顏色 ????????????????????My_Pen?=?new?Pen(p_color,?1);??????????????//畫(huà)筆顏色,寬度 ?????????????????????}????????????????//?計(jì)算線段長(zhǎng)度 ????????????????float?dx?=?(int)dXPrevPos_x1?-?(int)dXPrevPos_x2;? ???????????????float?dy?=?(int)dXPrevPos_y1?-?(int)dXPrevPos_y2; ????????????????float?dis?=?(float)Math.Sqrt(dx?*?dx?+?dy?*?dy); ????????????????TotalDis?+=?dis; ????????????????if?(起點(diǎn)ToolStripMenuItem.Checked) ????????????????{ ????????????????????if?(ZCad_ArrayInfo[i].m_nChoose?==?1) ????????????????????????g.FillEllipse(Brushes.Red,?(float)(dXPrevPos_x1?-?2),?(float)(dXPrevPos_y1?-?2),?4,?4); ????????????????????else ????????????????????????g.FillEllipse(Brushes.White,?(float)(dXPrevPos_x1?-?2),?(float)(dXPrevPos_y1?-?2),?4,?4); ????????????????} ????????????????if?((TotalDis??>50)&&(方向ToolStripMenuItem.Checked)) { Draw_Arrow((int)dXPrevPos_x1,(int)dXPrevPos_y1,(int)dXPrevPos_x2,(int)dXPrevPos_y2,5,true); TotalDis=0; } else { Draw_Line((int)dXPrevPos_x1,(int)dXPrevPos_y1,(int)dXPrevPos_x2,(int)dXPrevPos_y2); } PrePosx=dXPrevPos_x2; PrePosy=dXPrevPos_y2; break; //break; default: break; } } }
05
實(shí)現(xiàn)CAD文件編輯修改
1.CAD編輯相關(guān)函數(shù)介紹。
/************************************************************* Description://新建一個(gè)對(duì)象并插入到圖層的末尾 Input://struct_Vect新建的對(duì)象 Output:// Return://錯(cuò)誤碼 int__stdcallZMotionCadArray_NewOne(Struct_ZCad_Arraystruct_NewVect); *************************************************************/ [DllImport("ZmotionCadEx.dll",EntryPoint="ZMotionCadArray_NewOne",CharSet=CharSet.Ansi,CallingConvention=CallingConvention.StdCall)] publicstaticexternInt32ZMotionCadArray_NewOne(Struct_ZCad_Arraystruct_NewVect); /************************************************************* Description://刪除指定對(duì)象 Input://nDelVect需要?jiǎng)h除的對(duì)象的序號(hào) Output:// Return://錯(cuò)誤碼 int__stdcallZMotionCadArray_DelOne(intnDelVect); *************************************************************/ [DllImport("ZmotionCadEx.dll",EntryPoint="ZMotionCadArray_DelOne",CharSet=CharSet.Ansi,CallingConvention=CallingConvention.StdCall)] publicstaticexternInt32ZMotionCadArray_DelOne(intnDelVect); /************************************************************* Description://移動(dòng)對(duì)象 Input://m_xx方向移動(dòng)的距離 //m_yy方向移動(dòng)的距離 //nMoveVect需要移動(dòng)的對(duì)象的序號(hào),-1為移動(dòng)所有 Output://Return://錯(cuò)誤碼 *************************************************************/ //uint32__stdcallZMotionCadArray_Move(doublem_x,doublem_y,intnMoveVect); [DllImport("ZmotionCadEx.dll",EntryPoint="ZMotionCadArray_Move",CharSet=CharSet.Ansi,CallingConvention=CallingConvention.StdCall)] publicstaticexternInt32ZMotionCadArray_Move(doublem_x,doublem_y,intnMoveVect); /************************************************************* Description://縮放對(duì)象 Input://nScaleVect需要縮放的對(duì)象的序號(hào),-1為縮放所有 Output://Return://錯(cuò)誤碼 *************************************************************/ //uint32__stdcallZMotionCadArray_Scale(floatscaleX,floatscaleY,floatpointx,floatpointy,intnScaleVect); [DllImport("ZmotionCadEx.dll",EntryPoint="ZMotionCadArray_Scale",CharSet=CharSet.Ansi,CallingConvention=CallingConvention.StdCall)] publicstaticexternInt32ZMotionCadArray_Scale(floatscaleX,floatscaleY,floatpointx,floatpointy,intnScaleVect); /************************************************************* Description://插入對(duì)象 Input://nArrayNum輸入的數(shù)組數(shù)量 //nInsertNo插入的位置 Output:// Return://錯(cuò)誤碼 *************************************************************/ //uint32__stdcallZMotionCadArray_ItemInsert(Struct_ZCad_Array*struct_NewVect,intnArrayNum,intnInsertNo); [DllImport("ZmotionCadEx.dll",EntryPoint="ZMotionCadArray_ItemInsert",CharSet=CharSet.Ansi,CallingConvention=CallingConvention.StdCall)] publicstaticexternInt32ZMotionCadArray_ItemInsert(refStruct_ZCad_Arraystruct_NewVect,intnArrayNum,intnInsertNo);/************************************************************* Description://修改對(duì)象 Input://nArrayNum輸入的數(shù)組數(shù)量 //nInsertNo修改的對(duì)象位置 Output:// Return://錯(cuò)誤碼 *************************************************************/ //uint32__stdcallZMotionCadArray_ItemModify(Struct_ZCad_Array*struct_NewVect,intnArrayNum,intnModifyNo); [DllImport("ZmotionCadEx.dll",EntryPoint="ZMotionCadArray_ItemModify",CharSet=CharSet.Ansi,CallingConvention=CallingConvention.StdCall)] publicstaticexternInt32ZMotionCadArray_ItemModify(refStruct_ZCad_Arraystruct_NewVect,intnArrayNum,intnModifyNo);
2.編輯流程。
步驟1:通過(guò)PictureBox鼠標(biāo)事件響應(yīng)函數(shù)實(shí)現(xiàn)框選功能。
鼠標(biāo)按下響應(yīng)函數(shù) privatevoidMyPicture_MouseDown(objectsender,MouseEventArgse) { if(e.Button==MouseButtons.Left) { Point_MouseDown=newPoint(e.X,e.Y); if(newdrawtype==0)//框選 Start_Choose=true; } } 鼠標(biāo)移動(dòng)響應(yīng)函數(shù) privatevoidMyPicture_MouseMove(objectsender,MouseEventArgse) { Point_MouseCur=newPoint(e.X,e.Y); //Show_Picture(); if(e.Button==MouseButtons.Left) { CadShow.Invalidate(); } } 鼠標(biāo)松開(kāi)響應(yīng)函數(shù) privatevoidMyPicture_MouseUp(objectsender,MouseEventArgse) { if(e.Button==MouseButtons.Left) { doubledPrevXPos,dPrevYPos,dCurXPos,dCurYPos; dPrevXPos=(double)((Point_MouseDown.X-m_dTranX)/m_dUnitsPerMm); dPrevYPos=(double)((CadShow.Height-Point_MouseDown.Y-m_dTranY)/m_dUnitsPerMm); dCurXPos=(double)((Point_MouseCur.X-m_dTranX)/m_dUnitsPerMm); dCurYPos=(double)((CadShow.Height-Point_MouseCur.Y-m_dTranY)/m_dUnitsPerMm); if(newdrawtype==0)//框選 { if(Start_Choose==false)//更改起點(diǎn)完成 { return; } Start_Choose=false; if(G_CadHandle==(IntPtr)0) { //MessageBox.Show("未鏈接到控制器!","提示"); } else { intiret=0; if(Point_MouseDown.X>Point_MouseCur.X)//左選 { iret=ZmotionCad.ZMotionCadArray_SelRightToLeft(dPrevXPos,dPrevYPos,dCurXPos,dCurYPos,false); } elseif(Point_MouseDown.X?Point_MouseCur.X)?????????????????????????//右選 ????????????????{ ????????????????????iret?=?ZmotionCad.ZMotionCadArray_SelLeftToRight(dPrevXPos,?dPrevYPos,?dCurXPos,?dCurYPos,?false); ????????????????} ????????????????else ????????????????{ ????????????????????iret?=?ZmotionCad.ZMotionCadArray_SelOne(dPrevXPos,?dPrevYPos,?5.0?/?m_dUnitsPerMm,?false); ????????????????} ????????????} ????????} ????} }
步驟2:對(duì)選中圖案進(jìn)行平移操作。
通過(guò)按鈕對(duì)選中圖案進(jìn)行平移,對(duì)應(yīng)平移函數(shù)movechoose,xy為平移相對(duì)距離 ZMotionCadArray_Move參數(shù)3傳的值是遍歷m_nInVectFrist,=1的時(shí)候表示vect曲線第一段,傳的是vect曲線的編號(hào) publicvoidmovechoose(doublex,doubley) { inticlosenum=0; inticlosechoose=0; uintiret=0; for(inti=0;i?ZCad_ArrayLen;?i++)????????????????//遍歷數(shù)組 ????{ ????????if?((ZCad_ArrayInfo[i].m_nInVectFrist?==?1))?????//是曲線起始 ????????{ ????????????if?(ZCad_ArrayInfo[i].m_nChoose?==?1)?????????????????//是否選中 ????????????{ ????????????????if?(ZCad_ArrayInfo[i].m_nItemtype?==?ZCAD_ITEMTYPE_VECTLine) ????????????????{ ????????????????????ZmotionCad.ZMotionCadArray_Move(x,?y,?iclosenum); ????????????????????Get_Array(); ????????????????} ????????????????iclosechoose++; ????????????} ????????????iclosenum++; ????????} ????} }
步驟3:刪除選中圖案。
ZMotionCadArray_DelOne和ZMotionCadArray_Move一樣需要傳的是vect曲線的編號(hào) privatevoidCadDel_Click(objectsender,EventArgse) { while(choosevectnum>0) { intiret=ZmotionCad.ZMotionCadArray_GetVectNum(refZCad_ArrayLen);//獲取圖形長(zhǎng)度 ZCad_ArrayInfo=newZmotionCad.Struct_ZCad_Array[ZCad_ArrayLen]; iret=ZmotionCad.ZMotionCadArray_GetVectArray(refZCad_ArrayInfo[0],ZCad_ArrayLen);//獲取圖形數(shù)據(jù) choosevectnum=0; closevectnum=0; for(inti=0;i?ZCad_ArrayLen;?i++)????????????????//遍歷數(shù)組 ????????{ ????????????if?((ZCad_ArrayInfo[i].m_nInVectFrist?==?1))?????//是曲線起始 ????????????{ ????????????????if?(ZCad_ArrayInfo[i].m_nChoose?==?1)?????????????????//是否選中? ???????????????{ ????????????????????choosevectnum++; ????????????????} ????????????????closevectnum++; ????????????} ????????} ????????int?iclosenum?=?0; ????????for?(int?i?=?0;?i??ZCad_ArrayLen;?i++)????????????????//遍歷數(shù)組 ????????{ ????????????if?((ZCad_ArrayInfo[i].m_nInVectFrist?==?1))?????//是曲線起始 ????????????{ ????????????????if?(ZCad_ArrayInfo[i].m_nChoose?==?1)?????????????????//是否選中 ????????????????{ ????????????????????ZmotionCad.ZMotionCadArray_DelOne(iclosenum);? ???????????????????break; ????????????????} ????????????????iclosenum++; ????????????} ????????} ????} ????Get_Array(); }
步驟4:插入新圖案。
通過(guò)界面按鈕選擇插入新圖案類(lèi)型,利用PicBox鼠標(biāo)響應(yīng)事件獲取插入圖案所在點(diǎn)位,使用ZMotionCadArray_NewOne或者ZMotionCadArray_ItemInsert 插入VectArray圖案數(shù)組插入圓弧或者整圓時(shí)可以通過(guò)ZMotionOptimize_TransArcSeges分解成小線段再插入VectArray privatevoidMyPicture_MouseDown(objectsender,MouseEventArgse) { if(e.Button==MouseButtons.Left) { Point_MouseDown=newPoint(e.X,e.Y); if(newdrawtype==0)//框選 Start_Choose=true; elseif(newdrawtype==2)//多線段 { multpointX[multnum]=Point_MouseDown.X; multpointY[multnum]=Point_MouseDown.Y; multnum++; } elseif(newdrawtype==4)//三點(diǎn)圓弧 { multpointX[multnum]=Point_MouseDown.X; multpointY[multnum]=Point_MouseDown.Y; multnum++; if(multnum==3)//三點(diǎn)圓弧 { doublestartrad,endrad; startrad=Math.Atan2(multpointY[1]-multpointY[0],multpointX[1]-multpointX[0]); endrad=Math.Atan2(multpointY[2]-multpointY[1],multpointX[2]-multpointX[1]); doubledPrevXPos,dPrevYPos,dCurXPos,dCurYPos; dPrevXPos=(double)((multpointX[0]-m_dTranX)/m_dUnitsPerMm); dPrevYPos=(double)((CadShow.Height-Point_MouseDown.Y-m_dTranY)/m_dUnitsPerMm); dCurXPos=(double)((Point_MouseCur.X-m_dTranX)/m_dUnitsPerMm); dCurYPos=(double)((CadShow.Height-Point_MouseCur.Y-m_dTranY)/m_dUnitsPerMm); //圓弧拆分小線段處理 intilen=-1; double[]ArcToLineX=newdouble[1000]; double[]ArcToLineY=newdouble[1000]; //獲取轉(zhuǎn)換長(zhǎng)度 intiret=UserCad.ZMotionOptimize_TransArcSeges(G_CardHandle,(double)((multpointX[0]-m_dTranX)/m_dUnitsPerMm),(double)((CadShow.Height-multpointY[0]-m_dTranY)/m_dUnitsPerMm),(double)((multpointX[1]-m_dTranX)/m_dUnitsPerMm),(double)((CadShow.Height-multpointY[0]-m_dTranY)/m_dUnitsPerMm),startrad,endrad-startrad,m_refDistance,ArcToLineX,ArcToLineY,refilen); ArcToLineX=newdouble[ilen]; ArcToLineY=newdouble[ilen]; //獲取數(shù)據(jù) iret=UserCad.ZMotionOptimize_TransArcSeges(G_CardHandle,(double)((multpointX[0]-m_dTranX)/m_dUnitsPerMm),(double)((CadShow.Height-multpointY[0]-m_dTranY)/m_dUnitsPerMm),(double)((multpointX[1]-m_dTranX)/m_dUnitsPerMm),(double)((CadShow.Height-multpointY[0]-m_dTranY)/m_dUnitsPerMm),startrad,endrad-startrad,m_refDistance,ArcToLineX,ArcToLineY,refilen); ZmotionCad.Struct_ZCad_Array[]ZcadNew=newZmotionCad.Struct_ZCad_Array[ilen];//拆分出來(lái)的小線段 ZcadNew[0]=ZCad_ArrayInfo[ZCad_ArrayLen-1]; ZcadNew[0].m_nItemtype=ZCAD_ITEMTYPE_VECTLine; ZcadNew[0].m_nInVectFrist=1; ZcadNew[0].m_nEmptyMove=1; ZcadNew[0].m_dGetStartX=ArcToLineX[0]; ZcadNew[0].m_dGetStartY=ArcToLineY[0]; ZcadNew[0].x1=ZcadNew[0].m_dGetStartX; ZcadNew[0].y1=ZcadNew[0].m_dGetStartY; ZcadNew[0].x2=ZcadNew[0].m_dGetStartX; ZcadNew[0].y2=ZcadNew[0].m_dGetStartY; ZmotionCad.ZMotionCadArray_NewOne(ZcadNew[0]); for(inti=1;i?ilen;?i++) ????????????????{ ????????????????????ZcadNew[i]?=?ZcadNew[0]; ????????????????????ZcadNew[i].m_nInVectFrist?=?0; ????????????????????ZcadNew[i].m_nEmptyMove?=?0; ????????????????????ZcadNew[i].m_dGetStartX?=?ArcToLineX[0]; ????????????????????ZcadNew[i].m_dGetStartY?=?ArcToLineY[0]; ????????????????????ZcadNew[i].x1?=?ArcToLineX[i?-?1]; ????????????????????ZcadNew[i].y1?=?ArcToLineY[i?-?1]; ????????????????????ZcadNew[i].x2?=?ArcToLineX[i]; ????????????????????ZcadNew[i].y2?=?ArcToLineY[i]; ????????????????????ZmotionCad.ZMotionCadArray_NewOne(ZcadNew[i]); ????????????????} ????????????????newdrawtype?=?0; ????????????????multnum?=?0; ????????????} ????????} ????} }
06
DEMO效果演示
1.點(diǎn)擊控制器→連接控制器。

2.點(diǎn)擊文件→打開(kāi),選擇對(duì)應(yīng)CAD文件。

3.打開(kāi)后顯示圖形,此時(shí)可以方向鍵進(jìn)行平移或者鼠標(biāo)滾輪進(jìn)行縮放操作。

4.點(diǎn)擊編輯可以進(jìn)行圖形優(yōu)化或者排序操作。

5.視圖中可以選擇空移,順序,標(biāo)號(hào)坐標(biāo)系的顯示。

6.點(diǎn)擊右側(cè)編輯標(biāo)簽,進(jìn)入編輯界面,此時(shí)可以框選選中需要編輯的圖案。

7.設(shè)置好移動(dòng)距離,并點(diǎn)擊上下左右移動(dòng),可以平移選中圖案。

8.點(diǎn)擊刪除可以刪除對(duì)應(yīng)圖案。

9.點(diǎn)擊添加圖形中的圖案類(lèi)型,可以添加新圖案。

教學(xué)視頻請(qǐng)點(diǎn)擊→C#運(yùn)動(dòng)控制開(kāi)源(一): CAD導(dǎo)圖和小線段速度前瞻的優(yōu)化之CAD導(dǎo)圖
完整代碼獲取地址
▼

本次,正運(yùn)動(dòng)技術(shù)C#運(yùn)動(dòng)控制開(kāi)源(一):CAD導(dǎo)圖和小線段速度前瞻的優(yōu)化之CAD導(dǎo)圖,就分享到這里。
更多精彩內(nèi)容請(qǐng)關(guān)注“正運(yùn)動(dòng)小助手”公眾號(hào),需要相關(guān)開(kāi)發(fā)環(huán)境與例程代碼,請(qǐng)咨詢(xún)正運(yùn)動(dòng)技術(shù)銷(xiāo)售工程師:400-089-8936。
本文由正運(yùn)動(dòng)技術(shù)原創(chuàng),歡迎大家轉(zhuǎn)載,共同學(xué)習(xí),一起提高中國(guó)智能制造水平。文章版權(quán)歸正運(yùn)動(dòng)技術(shù)所有,如有轉(zhuǎn)載請(qǐng)注明文章來(lái)源。

正運(yùn)動(dòng)技術(shù)專(zhuān)注于運(yùn)動(dòng)控制技術(shù)研究和通用運(yùn)動(dòng)控制軟硬件產(chǎn)品的研發(fā),是國(guó)家級(jí)高新技術(shù)企業(yè)。正運(yùn)動(dòng)技術(shù)匯集了來(lái)自華為、中興等公司的優(yōu)秀人才,在堅(jiān)持自主創(chuàng)新的同時(shí),積極聯(lián)合各大高校協(xié)同運(yùn)動(dòng)控制基礎(chǔ)技術(shù)的研究,是國(guó)內(nèi)工控領(lǐng)域發(fā)展最快的企業(yè)之一,也是國(guó)內(nèi)少有、完整掌握運(yùn)動(dòng)控制核心技術(shù)和實(shí)時(shí)工控軟件平臺(tái)技術(shù)的企業(yè)。主要業(yè)務(wù)有:運(yùn)動(dòng)控制卡_運(yùn)動(dòng)控制器_EtherCAT運(yùn)動(dòng)控制卡_EtherCAT控制器_運(yùn)動(dòng)控制系統(tǒng)_視覺(jué)控制器__運(yùn)動(dòng)控制PLC_運(yùn)動(dòng)控制_機(jī)器人控制器_視覺(jué)定位_XPCIe/XPCI系列運(yùn)動(dòng)控制卡等等。
審核編輯 黃宇
-
運(yùn)動(dòng)控制器
+關(guān)注
關(guān)注
2文章
489瀏覽量
26081 -
CAD
+關(guān)注
關(guān)注
18文章
1144瀏覽量
76826 -
正運(yùn)動(dòng)技術(shù)
+關(guān)注
關(guān)注
0文章
133瀏覽量
905
發(fā)布評(píng)論請(qǐng)先 登錄
C#運(yùn)動(dòng)控制開(kāi)源(一): CAD導(dǎo)圖和小線段速度前瞻的優(yōu)化之CAD導(dǎo)圖# 正運(yùn)動(dòng)技術(shù)# 運(yùn)動(dòng)控制器# 開(kāi)源
MUN3CAD03-SF:多場(chǎng)景電源模塊替代的優(yōu)選方案
MUN3CAD03-SF:多場(chǎng)景電源模塊替代的優(yōu)選方案
Sub-1G系列產(chǎn)品CW32W031單片機(jī)CAD的應(yīng)用參考
MOSFET導(dǎo)通電阻Rds
強(qiáng)實(shí)時(shí)運(yùn)動(dòng)控制內(nèi)核MotionRT750(十一):C#實(shí)現(xiàn)CAD導(dǎo)圖和小線段速度前瞻優(yōu)化 #運(yùn)動(dòng)控制內(nèi)核
CAD如何繪制螺旋線
如何平衡IGBT模塊的開(kāi)關(guān)損耗和導(dǎo)通損耗
C#上位機(jī)與運(yùn)動(dòng)控制卡網(wǎng)絡(luò)通訊的周期上報(bào)
MUN3CAD05-JF 5A,高效uPOL模塊規(guī)格書(shū)
機(jī)器視覺(jué)運(yùn)動(dòng)控制一體機(jī)在數(shù)控CAD dxf導(dǎo)圖中的應(yīng)用
PCIe EtherCAT實(shí)時(shí)運(yùn)動(dòng)控制卡PCIE464的CAD導(dǎo)圖與刀向跟隨應(yīng)用
C#運(yùn)動(dòng)控制開(kāi)源(一): CAD導(dǎo)圖和小線段速度前瞻的優(yōu)化之CAD導(dǎo)圖
評(píng)論