|
01
ZMC432-V2運動控製器介紹
ZMC432-V2高性能多軸運動控製器是一款兼容EtherCAT總線和脈衝型的獨立式運動控製器,自帶6軸本地差分脈衝軸,最多可擴展至32軸,能實現總線軸+脈衝軸混合插補的多軸運動控製場合。同時支持正運動遠程顯示功能,能提供網絡組態顯示,可實時監控和調整參數配置。

ZMC432-V2硬件功能特性:
(1)支持32軸運動控製(脈衝+EtherCAT總線),EtherCAT最小通訊周期可達125us;
(2)24路通用輸入、12路通用輸出,2路模擬量輸出(DA),其中包括2路高速輸入和2路高速輸出;
(3)6路差分脈衝軸輸出,總線軸、脈衝軸可混合插補;
(4)內置多項實時性運動控製功能,例如視覺飛拍、多維PSO、高速位置鎖存,多軸同步運行等;
(5)可通過EtherCAT擴展模塊進行IO硬件資源擴展,可擴展至4096個隔離輸入口和4096個隔離輸出口;
(6)具備豐富的運動控製功能,如點位運動、電子凸輪、直線插補、圓弧插補、連續軌跡加工;
(7)支持掉電檢測、掉電存儲,多種程序加密方式,能夠有效防止係統故障,保護項目工程文件數據,並提高係統的可靠性;
(8)通過純國產IDE開發環境RTSys進行項目開發,可實時仿真、在線跟蹤以及診斷與調試,簡便易用,支持多種高級上位機語言聯合編程進行二次開發。

02
C#運動控製+CAD導圖DEMO概述
本期示教DEMO是以正運動的運動控製函數庫,CAD導圖函數庫,在VS環境下使用C#進行編程開發。
DEMO內容主要實現CAD圖紙解析(導入CAD文件,軌跡數據解析,編輯軌跡)後下發給控製器進行運動(運動前瞻,運動指令下發,狀態監控)。用戶可以參考例程更快的使用正運動函數庫進行相關開發。
後期我們將推出以下3篇教程介紹該示教例程的開發流程和使用方法,方便用戶快速上手該例程,並掌握C#運動控製與CAD導圖相結合編程開發的相關知識。
? C#運動控製開源(一): CAD導圖和小線段速度前瞻的優化之CAD導圖
? C#運動控製開源(二): CAD導圖和小線段速度前瞻的優化之前瞻優化
? C#運動控製開源(三): CAD導圖和小線段速度前瞻的優化的軟件框架
03
C#使用ZMOTION CAD庫進行CAD導圖的開發
正運動技術提供開放的ZmotionCadEx庫,可導入DXF、Ai、Plt、Dst圖紙,可以生成運動坐標數據轉G代碼、zbasic運動指令、或直接PC函數執行運動。
1.在VS2019菜單“文件”→“新建”→“項目”,啟動創建項目向導。

2.選擇開發語言為“C#”和Windows窗體應用程序,點擊下一步。

3.配置好項目名稱和位置,以及相應框架,點擊創建。

4.找到廠家提供的光盤資料裏麵的C#函數庫,路徑如下(64位庫為例)。
進入廠商提供的光盤資料,找到ZmotionCadEx.dll,ZmotionCadEx.cs這兩個個庫文件。庫文件路徑:【00光盤資料】→【04PC函數】→【03Zmotion CAD庫V3.1】→【庫文件】→【Windows平台】→【C#】→【64位】。

5.將廠商提供的C#的庫文件以及相關文件複製到新建的項目中。
(1)將ZmotionCadEx.cs文件複製到新建的項目裏麵中。

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

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

6.雙擊Form1.cs裏麵的Form1,出現代碼編輯界麵,在文件開頭寫入using ZmotionCadDll。

至此,項目新建完成,可進行C#項目開發。
例程界麵如下:

CAD解析與編輯流程:

04
實現CAD文件解析與顯示
1.CAD解析相關函數介紹
①連接控製器。
Description: //與控製器建立鏈接,成功後解鎖高級功能
Input: //IP地址,字符串的方式輸入
Output: //控製器句柄
Return: //錯誤碼
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);
②導入CAD圖形。
/*************************************************************
Description: //導入圖形文件(支持dxf、plt、ai、dst)
Input: //
lpszFileFullPathname 路徑和文件名
duUnit PLT的比例 Option 預留, 缺省都轉換為seg
refDistance 轉換時參考精度
Output: //
Return: //錯誤碼
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);
③提取圖形數組。
/*************************************************************
Description: // 提取當前圖形數組
Input: //struct_Array 提取的數組
//nStructNum 數組的數量
Output: //
Return: //錯誤碼
*************************************************************/
//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);
④圖形數組格式。

⑤獲取CAD圖形的範圍。
/*************************************************************
Description: // 範圍 坐標方向是向上為正
Input: //
Output: //
Return: //錯誤碼
*************************************************************/
//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:連接控製器並導入需要解析的CAD文件。
ZmotionCad.ZMotionCadArray_ImportVectGraph導入CAD文件(支持DXF、Ai、Plt、Dst格式);
參數3可以設置是否把曲線強製轉換為小線段,本例程是轉化成小線段解析的。
使用ZMotionCadArray_GetRange獲取到CAD圖形的範圍,並和顯示用的PictureBox長寬進行計算,獲得轉換比例和偏移。
if(G_CardHandle == (IntPtr)0)
{
MessageBox.Show("檢測到尚未連接控製器,請先連接控製器再進行操作");
return;
}
if (G_CadHandle == (IntPtr)0)
{
iret = ZmotionCad.ZMotionCadArray_OpenEth(連接控製器.Adrr, out G_CadHandle);
}
if (G_CadHandle != (IntPtr)0) //開始導入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); //曲線強製轉換為小線段
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); //獲取圖形數據
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:通過函數獲取VectArray數據並解析。
使用ZMotionCadArray_GetVectArray獲取到圖形數組,通過Show_Picture()解析圖形數組並繪製到PictureBox圖象上顯示。
//獲取數據
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); //獲取圖形數據
choosevectnum = 0;
closevectnum = 0;
for (int i = 0; i < ZCad_ArrayLen; i++) //遍曆數組
{
if ((ZCad_ArrayInfo[i].m_nInVectFrist == 1)) //是曲線起始
{
if (ZCad_ArrayInfo[i].m_nChoose == 1) //是否選中
{
choosevectnum++;
}
closevectnum++;
}
}
Show_Picture();
}
}
解析圖形數組和繪圖函數Show_Picture()
//顯示圖形
public void Show_Picture()
{ g.Clear(Color.Black); if (坐標係ToolStripMenuItem.Checked)
{
//繪製坐標係
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); //原點
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));
//標注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));
//標注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++) //遍曆數組
{
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: //點
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()); //標記數字
}
if (空移ToolStripMenuItem.Checked)
{
p_color = Color.Gray; //默認顏色
My_Pen = new Pen(p_color, (float)0.1); //畫筆顏色,寬度
My_Pen.DashPattern = new float[] { 3, 3 }; //設置短劃線和空白部分的數組
Draw_Line((int)PrePosx, (int)PrePosy, (int)dXPrevPos_x1, (int)dXPrevPos_y1);
}
iCloseLine++;
}
if (ZCad_ArrayInfo[i].m_nChoose == 1) //是否選中
{
p_color = Color.Red; //默認顏色
My_Pen = new Pen(p_color, 1); //畫筆顏色,寬度
}
else
{
p_color = Color.White; //默認顏色
My_Pen = new Pen(p_color, 1); //畫筆顏色,寬度
} // 計算線段長度
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 (起點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
實現CAD文件編輯修改
1.CAD編輯相關函數介紹。
/*************************************************************
Description: // 新建一個對象並插入到圖層的末尾
Input: //struct_Vect 新建的對象
Output: //
Return: //錯誤碼
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 需要刪除的對象的序號
Output: //
Return: //錯誤碼
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: // 移動對象
Input: // m_x x方向移動的距離
// m_y y方向移動的距離
// nMoveVect 需要移動的對象的序號,-1為移動所有
Output: //Return: //錯誤碼
*************************************************************/
//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: //錯誤碼
*************************************************************/
//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 輸入的數組數量
// nInsertNo 插入的位置
Output: //
Return: //錯誤碼
*************************************************************/
//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 輸入的數組數量
// nInsertNo 修改的對象位置
Output: //
Return: //錯誤碼
*************************************************************/
//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鼠標事件響應函數實現框選功能。
鼠標按下響應函數
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;
}
}
鼠標移動響應函數
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();
}
}
鼠標鬆開響應函數
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) //更改起點完成
{
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:對選中圖案進行平移操作。
通過按鈕對選中圖案進行平移,對應平移函數movechoose,xy為平移相對距離
ZMotionCadArray_Move參數3傳的值是遍曆m_nInVectFrist,=1的時候表示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++) //遍曆數組
{
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); //獲取圖形數據
choosevectnum = 0;
closevectnum = 0;
for (int i = 0; i < ZCad_ArrayLen; i++) //遍曆數組
{
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++) //遍曆數組
{
if ((ZCad_ArrayInfo[i].m_nInVectFrist == 1)) //是曲線起始
{
if (ZCad_ArrayInfo[i].m_nChoose == 1) //是否選中
{
ZmotionCad.ZMotionCadArray_DelOne(iclosenum);
break;
}
iclosenum++;
}
}
}
Get_Array();
}
步驟4:插入新圖案。
通過界麵按鈕選擇插入新圖案類型,利用PicBox鼠標響應事件獲取插入圖案所在點位,使用ZMotionCadArray_NewOne或者ZMotionCadArray_ItemInsert
插入VectArray圖案數組插入圓弧或者整圓時可以通過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)//三點圓弧
{
multpointX[multnum] = Point_MouseDown.X;
multpointY[multnum] = Point_MouseDown.Y;
multnum++;
if (multnum == 3) //三點圓弧
{
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];
//獲取轉換長度
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];
//獲取數據
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.點擊控製器→連接控製器。

2.點擊文件→打開,選擇對應CAD文件。

3.打開後顯示圖形,此時可以方向鍵進行平移或者鼠標滾輪進行縮放操作。

4.點擊編輯可以進行圖形優化或者排序操作。

5.視圖中可以選擇空移,順序,標號坐標係的顯示。

6.點擊右側編輯標簽,進入編輯界麵,此時可以框選選中需要編輯的圖案。

7.設置好移動距離,並點擊上下左右移動,可以平移選中圖案。

8.點擊刪除可以刪除對應圖案。

9.點擊添加圖形中的圖案類型,可以添加新圖案。

教學視頻請點擊→C#運動控製開源(一): CAD導圖和小線段速度前瞻的優化之CAD導圖
完整代碼獲取地址
▼

本次,正運動技術C#運動控製開源(一):CAD導圖和小線段速度前瞻的優化之CAD導圖,就分享到這裏。
更多精彩內容請關注“正運動小助手”公眾號,需要相關開發環境與例程代碼,請谘詢正運動技術銷售工程師:400-089-8936。
benwenyouzhengyundongjishuyuanchuang,huanyingdajiazhuanzai,gongtongxuexi,yiqitigaozhongguozhinengzhizaoshuiping。wenzhangbanquanguizhengyundongjishusuoyou,ruyouzhuanzaiqingzhumingwenzhanglaiyuan。

正運動技術專注於運動控製技術研究和通用運動控製軟硬件產品的研發,是國家級高新技術企業。正運動技術彙集了來自華為、中(zhong)興(xing)等(deng)公(gong)司(si)的(de)優(you)秀(xiu)人(ren)才(cai),在(zai)堅(jian)持(chi)自(zi)主(zhu)創(chuang)新(xin)的(de)同(tong)時(shi),積(ji)極(ji)聯(lian)合(he)各(ge)大(da)高(gao)校(xiao)協(xie)同(tong)運(yun)動(dong)控(kong)製(zhi)基(ji)礎(chu)技(ji)術(shu)的(de)研(yan)究(jiu),是(shi)國(guo)內(nei)工(gong)控(kong)領(ling)域(yu)發(fa)展(zhan)最(zui)快(kuai)的(de)企(qi)業(ye)之(zhi)一(yi),也(ye)是(shi)國(guo)內(nei)少(shao)有(you)、完整掌握運動控製核心技術和實時工控軟件平台技術的企業。主要業務有:運動控製卡_運動控製器_EtherCAT運動控製卡_EtherCAT控製器_運動控製係統_視覺控製器__運動控製PLC_運動控製_機器人控製器_視覺定位_XPCIe/XPCI係列運動控製卡等等。
|