|
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)控制場合。同時(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)控制功能,例如視覺飛拍、多維PSO、高速位置鎖存,多軸同步運(yùn)行等;
(5)可通過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)支持掉電檢測、掉電存儲,多種程序加密方式,能夠有效防止系統(tǒng)故障,保護(hù)項(xiàng)目工程文件數(shù)據(jù),并提高系統(tǒng)的可靠性;
(8)通過純國產(chǎn)IDE開發(fā)環(huán)境RTSys進(jìn)行項(xiàng)目開發(fā),可實(shí)時(shí)仿真、在線跟蹤以及診斷與調(diào)試,簡便易用,支持多種高級上位機(jī)語言聯(lián)合編程進(jìn)行二次開發(fā)。

02
C#運(yùn)動(dòng)控制+CAD導(dǎo)圖DEMO概述
本期示教DEMO是以正運(yùn)動(dòng)的運(yùn)動(dòng)控制函數(shù)庫,CAD導(dǎo)圖函數(shù)庫,在VS環(huán)境下使用C#進(jìn)行編程開發(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ù)庫進(jìn)行相關(guān)開發(fā)。
后期我們將推出以下3篇教程介紹該示教例程的開發(fā)流程和使用方法,方便用戶快速上手該例程,并掌握C#運(yùn)動(dòng)控制與CAD導(dǎo)圖相結(jié)合編程開發(fā)的相關(guān)知識。
? C#運(yùn)動(dòng)控制開源(一): CAD導(dǎo)圖和小線段速度前瞻的優(yōu)化之CAD導(dǎo)圖
? C#運(yùn)動(dòng)控制開源(二): CAD導(dǎo)圖和小線段速度前瞻的優(yōu)化之前瞻優(yōu)化
? C#運(yùn)動(dòng)控制開源(三): CAD導(dǎo)圖和小線段速度前瞻的優(yōu)化的軟件框架
03
C#使用ZMOTION CAD庫進(jìn)行CAD導(dǎo)圖的開發(fā)
正運(yùn)動(dòng)技術(shù)提供開放的ZmotionCadEx庫,可導(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.選擇開發(fā)語言為“C#”和Windows窗體應(yīng)用程序,點(diǎn)擊下一步。

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

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

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

(2)將ZmotionCadEx.dll文件放入bin\debug文件夾中。

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

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

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

CAD解析與編輯流程:

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

⑤獲取CAD圖形的范圍。
/*************************************************************
Description: // 范圍 坐標(biāo)方向是向上為正
Input: //
Output: //
Return: //錯(cuò)誤碼
*************************************************************/
//uint32 __stdcall ZMotionCadArray_GetRange(float *pLeft, float *pBottom, float *pWdith, float *pHeight, double refDistance);
[DllImport("ZmotionCadEx.dll", EntryPoint = "ZMotionCadArray_GetRange", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern Int32 ZMotionCadArray_GetRange(ref float pLeft, ref float pBottom, ref float pWdith, ref float pHeight, double refDistance);
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長寬進(jìn)行計(jì)算,獲得轉(zhuǎn)換比例和偏移。
if(G_CardHandle == (IntPtr)0)
{
MessageBox.Show("檢測到尚未連接控制器,請先連接控制器再進(jìn)行操作");
return;
}
if (G_CadHandle == (IntPtr)0)
{
iret = ZmotionCad.ZMotionCadArray_OpenEth(連接控制器.Adrr, out G_CadHandle);
}
if (G_CadHandle != (IntPtr)0) //開始導(dǎo)入CAD文件
{
OpenFileDialog openFileDialog1 = new OpenFileDialog();
openFileDialog1.InitialDirectory = "\\";
openFileDialog1.Filter = "DXF File(*.dxf)|*.dxf|PLT File(*.PLT)|*.PLT|AI File(*.AI)|*.AI|DST File(*.DST)|*.DST";
openFileDialog1.RestoreDirectory = true;
openFileDialog1.FilterIndex = 1;
if (openFileDialog1.ShowDialog() == DialogResult.OK) //打開配置文件
{
strFilePath = openFileDialog1.FileName;
this.Text = strFilePath;
iret = ZmotionCad.ZMotionCadArray_ImportVectGraph(strFilePath, 1024,0, m_refDistance); //曲線強(qiáng)制轉(zhuǎn)換為小線段
iret = ZmotionCad.ZMotionCadArray_GetVectNum(ref ZCad_ArrayLen); //導(dǎo)入數(shù)據(jù)
ZCad_ArrayInfo = new ZmotionCad.Struct_ZCad_Array[ZCad_ArrayLen];
iret = ZmotionCad.ZMotionCadArray_GetVectArray(ref ZCad_ArrayInfo[0], ZCad_ArrayLen); //獲取圖形數(shù)據(jù)
iret = ZmotionCad.ZMotionCadArray_IfCloseVect(false); //是否只處理封閉軌跡
Get_Array();
float Image_Left, Image_bottom, Image_Width, Image_Height;
Image_Left = 0;
Image_bottom = 0;
Image_Width = 0;
Image_Height = 0;
iret = ZmotionCad.ZMotionCadArray_GetRange(ref Image_Left, ref Image_bottom, ref Image_Width, ref Image_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:通過函數(shù)獲取VectArray數(shù)據(jù)并解析。
使用ZMotionCadArray_GetVectArray獲取到圖形數(shù)組,通過Show_Picture()解析圖形數(shù)組并繪制到PictureBox圖象上顯示。
//獲取數(shù)據(jù)
public void Get_Array()
{
if (G_CadHandle == (IntPtr)0)
{
//MessageBox.Show("未鏈接到控制器!", "提示");
}
else
{
int iret = ZmotionCad.ZMotionCadArray_GetVectNum(ref ZCad_ArrayLen); //獲取圖形長度
ZCad_ArrayInfo = new ZmotionCad.Struct_ZCad_Array[ZCad_ArrayLen];
iret = ZmotionCad.ZMotionCadArray_GetVectArray(ref ZCad_ArrayInfo[0], ZCad_ArrayLen); //獲取圖形數(shù)據(jù)
choosevectnum = 0;
closevectnum = 0;
for (int i = 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: //此處開始是曲線類型
break;
case ZmotionCad.ZCAD_ITEMTYPE_VECTPoint: //點(diǎn)
if (ZCad_ArrayInfo[i].m_nEmptyMove != 0)
{
}
break;
case ZmotionCad.ZCAD_ITEMTYPE_VECTLine: //通過線型繪制圖形
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); //畫筆顏色,寬度
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); //畫筆顏色,寬度
}
else
{
p_color = Color.White; //默認(rèn)顏色
My_Pen = new Pen(p_color, 1); //畫筆顏色,寬度
} // 計(jì)算線段長度
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è)對象并插入到圖層的末尾
Input: //struct_Vect 新建的對象
Output: //
Return: //錯(cuò)誤碼
int __stdcall ZMotionCadArray_NewOne(Struct_ZCad_Array struct_NewVect);
*************************************************************/
[DllImport("ZmotionCadEx.dll", EntryPoint = "ZMotionCadArray_NewOne", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern Int32 ZMotionCadArray_NewOne(Struct_ZCad_Array struct_NewVect);
/*************************************************************
Description: // 刪除指定對象
Input: //nDelVect 需要?jiǎng)h除的對象的序號
Output: //
Return: //錯(cuò)誤碼
int __stdcall ZMotionCadArray_DelOne(int nDelVect);
*************************************************************/
[DllImport("ZmotionCadEx.dll", EntryPoint = "ZMotionCadArray_DelOne", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern Int32 ZMotionCadArray_DelOne(int nDelVect);
/*************************************************************
Description: // 移動(dòng)對象
Input: // m_x x方向移動(dòng)的距離
// m_y y方向移動(dòng)的距離
// nMoveVect 需要移動(dòng)的對象的序號,-1為移動(dòng)所有
Output: //Return: //錯(cuò)誤碼
*************************************************************/
//uint32 __stdcall ZMotionCadArray_Move(double m_x, double m_y, int nMoveVect);
[DllImport("ZmotionCadEx.dll", EntryPoint = "ZMotionCadArray_Move", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern Int32 ZMotionCadArray_Move(double m_x, double m_y, int nMoveVect);
/*************************************************************
Description: // 縮放對象
Input: //nScaleVect 需要縮放的對象的序號,-1為縮放所有
Output: //Return: //錯(cuò)誤碼
*************************************************************/
//uint32 __stdcall ZMotionCadArray_Scale(float scaleX, float scaleY, float pointx, float pointy, int nScaleVect);
[DllImport("ZmotionCadEx.dll", EntryPoint = "ZMotionCadArray_Scale", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern Int32 ZMotionCadArray_Scale(float scaleX, float scaleY, float pointx, float pointy, int nScaleVect);
/*************************************************************
Description: // 插入對象
Input: // nArrayNum 輸入的數(shù)組數(shù)量
// nInsertNo 插入的位置
Output: //
Return: //錯(cuò)誤碼
*************************************************************/
//uint32 __stdcall ZMotionCadArray_ItemInsert(Struct_ZCad_Array *struct_NewVect, int nArrayNum, int nInsertNo);
[DllImport("ZmotionCadEx.dll", EntryPoint = "ZMotionCadArray_ItemInsert", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern Int32 ZMotionCadArray_ItemInsert(ref Struct_ZCad_Array struct_NewVect, int nArrayNum, int nInsertNo);/*************************************************************
Description: // 修改對象
Input: // nArrayNum 輸入的數(shù)組數(shù)量
// nInsertNo 修改的對象位置
Output: //
Return: //錯(cuò)誤碼
*************************************************************/
//uint32 __stdcall ZMotionCadArray_ItemModify(Struct_ZCad_Array *struct_NewVect, int nArrayNum, int nModifyNo);
[DllImport("ZmotionCadEx.dll", EntryPoint = "ZMotionCadArray_ItemModify", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern Int32 ZMotionCadArray_ItemModify(ref Struct_ZCad_Array struct_NewVect, int nArrayNum, int nModifyNo);
2.編輯流程。
步驟1:通過PictureBox鼠標(biāo)事件響應(yīng)函數(shù)實(shí)現(xiàn)框選功能。
鼠標(biāo)按下響應(yīng)函數(shù)
private void MyPicture_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
Point_MouseDown = new Point(e.X, e.Y);
if (newdrawtype == 0) //框選
Start_Choose = true;
}
}
鼠標(biāo)移動(dòng)響應(yīng)函數(shù)
private void MyPicture_MouseMove(object sender, MouseEventArgs e)
{
Point_MouseCur = new Point(e.X, e.Y);
//Show_Picture();
if (e.Button == MouseButtons.Left)
{
CadShow.Invalidate();
}
}
鼠標(biāo)松開響應(yīng)函數(shù)
private void MyPicture_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
double dPrevXPos, 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
{
int iret = 0;
if (Point_MouseDown.X > Point_MouseCur.X) //左選
{
iret = ZmotionCad.ZMotionCadArray_SelRightToLeft(dPrevXPos, dPrevYPos, dCurXPos, dCurYPos, false);
}
else if (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:對選中圖案進(jìn)行平移操作。
通過按鈕對選中圖案進(jìn)行平移,對應(yīng)平移函數(shù)movechoose,xy為平移相對距離
ZMotionCadArray_Move參數(shù)3傳的值是遍歷m_nInVectFrist,=1的時(shí)候表示vect曲線第一段,傳的是vect曲線的編號
public void movechoose(double x,double y)
{
int iclosenum = 0;
int iclosechoose = 0;
uint iret = 0;
for (int i = 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曲線的編號
private void CadDel_Click(object sender, EventArgs e)
{
while (choosevectnum>0)
{
int iret = ZmotionCad.ZMotionCadArray_GetVectNum(ref ZCad_ArrayLen); //獲取圖形長度
ZCad_ArrayInfo = new ZmotionCad.Struct_ZCad_Array[ZCad_ArrayLen];
iret = ZmotionCad.ZMotionCadArray_GetVectArray(ref ZCad_ArrayInfo[0], ZCad_ArrayLen); //獲取圖形數(shù)據(jù)
choosevectnum = 0;
closevectnum = 0;
for (int i = 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:插入新圖案。
通過界面按鈕選擇插入新圖案類型,利用PicBox鼠標(biāo)響應(yīng)事件獲取插入圖案所在點(diǎn)位,使用ZMotionCadArray_NewOne或者ZMotionCadArray_ItemInsert
插入VectArray圖案數(shù)組插入圓弧或者整圓時(shí)可以通過ZMotionOptimize_TransArcSeges分解成小線段再插入VectArray
private void MyPicture_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
Point_MouseDown = new Point(e.X, e.Y);
if (newdrawtype == 0) //框選
Start_Choose = true;
else if (newdrawtype == 2) //多線段
{
multpointX[multnum] = Point_MouseDown.X;
multpointY[multnum] = Point_MouseDown.Y;
multnum++;
}
else if(newdrawtype == 4)//三點(diǎn)圓弧
{
multpointX[multnum] = Point_MouseDown.X;
multpointY[multnum] = Point_MouseDown.Y;
multnum++;
if (multnum == 3) //三點(diǎn)圓弧
{
double startrad, endrad;
startrad = Math.Atan2(multpointY[1] - multpointY[0], multpointX[1] - multpointX[0]);
endrad = Math.Atan2(multpointY[2] - multpointY[1], multpointX[2] - multpointX[1]) ;
double dPrevXPos, 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);
//圓弧拆分小線段處理
int ilen = -1;
double[] ArcToLineX = new double[1000];
double[] ArcToLineY = new double[1000];
//獲取轉(zhuǎn)換長度
int 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, ref ilen);
ArcToLineX = new double[ilen];
ArcToLineY = new double[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, ref ilen);
ZmotionCad.Struct_ZCad_Array[] ZcadNew = new ZmotionCad.Struct_ZCad_Array[ilen]; //拆分出來的小線段
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 (int i = 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)擊文件→打開,選擇對應(yīng)CAD文件。

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

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

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

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

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

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

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

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

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

正運(yùn)動(dòng)技術(shù)專注于運(yùn)動(dòng)控制技術(shù)研究和通用運(yùn)動(dòng)控制軟硬件產(chǎn)品的研發(fā),是國家級高新技術(shù)企業(yè)。正運(yùn)動(dòng)技術(shù)匯集了來自華為、中興等公司的優(yōu)秀人才,在堅(jiān)持自主創(chuàng)新的同時(shí),積極聯(lián)合各大高校協(xié)同運(yùn)動(dòng)控制基礎(chǔ)技術(shù)的研究。主要業(yè)務(wù)有:運(yùn)動(dòng)控制卡_運(yùn)動(dòng)控制器_EtherCAT運(yùn)動(dòng)控制卡_EtherCAT控制器_運(yùn)動(dòng)控制系統(tǒng)_視覺控制器__運(yùn)動(dòng)控制PLC_運(yùn)動(dòng)控制_機(jī)器人控制器_視覺定位_XPCIe/XPCI系列運(yùn)動(dòng)控制卡等等。
|