0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

C#运动控制开源(一): CAD导图和小线段速度前瞻的优化之CAD导图

正运动技术 来源:正运动技术 作者:正运动技术 2026-04-02 14:33 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

01

ZMC432-V2运动控制器介绍

ZMC432-V2高性能多轴运动控制器是一款兼容EtherCAT总线和脉冲型的独立式运动控制器,自带6轴本地差分脉冲轴,最多可扩展至32轴,能实现总线轴+脉冲轴混合插补的多轴运动控制场合。同时支持正运动远程显示功能,能提供网络组态显示,可实时监控和调整参数配置。

wKgZPGnODbGAIXRNAACB8OYvCQk02.webp

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进行项目开发,可实时仿真、在线跟踪以及诊断与调试,简便易用,支持多种高级上位机语言联合编程进行二次开发。

wKgZO2nODbKASuGqAACN7IX6Ewc12.webp

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菜单“文件”→“新建”→“项目”,启动创建项目向导。

wKgZPGnODbKAY6t4AADDVvbdMMk64.webp

2.选择开发语言为“C#”和Windows窗体应用程序,点击下一步。

wKgZO2nODbKAM-X1AACyMtsBEKE67.webp

3.配置好项目名称和位置,以及相应框架,点击创建。

wKgZPGnODbOAZGXdAABk1o08M0I45.webp

4.找到厂家提供的光盘资料里面的C#函数库,路径如下(64位库为例)。

进入厂商提供的光盘资料,找到ZmotionCadEx.dll,ZmotionCadEx.cs这两个个库文件。库文件路径:【00光盘资料】→【04PC函数】→【03Zmotion CAD库V3.1】→【库文件】→【Windows平台】→【C#】→【64位】。

wKgZO2nODbOARqgDAAB_CK1paA444.webp

5.将厂商提供的C#的库文件以及相关文件复制到新建的项目中。

(1)将ZmotionCadEx.cs文件复制到新建的项目里面中。

wKgZPGnODbOAevX5AAFTQFNatFE21.webp

(2)将ZmotionCadEx.dll文件放入bindebug文件夹中。

wKgZPGnODbOAHEcyAABzzCqpEDE74.webp

(3)将ZmotionCadEx.cs文件添加进项目中。右键项目名称,选择添加,再选择现有项,选择ZmotionCadEx.cs文件。

wKgZO2nODbSAG3pxAAF9SEFEU1c93.webp

6.双击Form1.cs里面的Form1,出现代码编辑界面,在文件开头写入using ZmotionCadDll。

wKgZPGnODbSAHvqCAAEAqPYCepw35.webp

至此,项目新建完成,可进行C#项目开发。

例程界面如下:

wKgZO2nODbSASxdoAAB8wM9Wwu475.webp

CAD解析与编辑流程:

wKgZPGnODbSADSF6AAAy1lE2yNI10.webp

04

实现CAD文件解析与显示

1.CAD解析相关函数介绍

①连接控制器。

Description://与控制器建立链接,成功后解锁高级功能 Input://IP地址,字符串的方式输入 Output://控制器句柄 Return://错误码 int32__stdcallZMotionCadArray_OpenEth(char*ipaddr,ZMC_HANDLE*pHandle); *************************************************************/ [DllImport("ZmotionCadEx.dll",EntryPoint="ZMotionCadArray_OpenEth",CharSet=CharSet.Ansi,CallingConvention=CallingConvention.StdCall)] publicstaticexternInt32ZMotionCadArray_OpenEth(stringipaddr,outIntPtrphandle);

②导入CAD图形。

/************************************************************* Description://导入图形文件(支持dxf、plt、ai、dst) Input:// lpszFileFullPathname路径和文件名 duUnitPLT的比例Option预留,缺省都转换为seg refDistance转换时参考精度 Output:// Return://错误码 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);

③提取图形数组。

/************************************************************* Description://提取当前图形数组 Input://struct_Array提取的数组 //nStructNum数组的数量 Output:// Return://错误码 *************************************************************/ //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);

④图形数组格式。

wKgZO2nODbWASkxyAADCEJkynCM97.webp

⑤获取CAD图形的范围。

/************************************************************* Description://范围坐标方向是向上为正 Input:// Output:// Return://错误码 *************************************************************/ //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:连接控制器并导入需要解析的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,outG_CadHandle); } if(G_CadHandle!=(IntPtr)0)//开始导入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)//打开配置文件 { strFilePath=openFileDialog1.FileName; this.Text=strFilePath; iret=ZmotionCad.ZMotionCadArray_ImportVectGraph(strFilePath,1024,0,m_refDistance);//曲线强制转换为小线段 iret=ZmotionCad.ZMotionCadArray_GetVectNum(refZCad_ArrayLen);//导入数据 ZCad_ArrayInfo=newZmotionCad.Struct_ZCad_Array[ZCad_ArrayLen]; iret=ZmotionCad.ZMotionCadArray_GetVectArray(refZCad_ArrayInfo[0],ZCad_ArrayLen);//获取图形数据 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:通过函数获取VectArray数据并解析。

使用ZMotionCadArray_GetVectArray获取到图形数组,通过Show_Picture()解析图形数组并绘制到PictureBox图象上显示。

//获取数据 publicvoidGet_Array() { if(G_CadHandle==(IntPtr)0) { //MessageBox.Show("未链接到控制器!","提示"); } else { intiret=ZmotionCad.ZMotionCadArray_GetVectNum(refZCad_ArrayLen);//获取图形长度 ZCad_ArrayInfo=newZmotionCad.Struct_ZCad_Array[ZCad_ArrayLen]; iret=ZmotionCad.ZMotionCadArray_GetVectArray(refZCad_ArrayInfo[0],ZCad_ArrayLen);//获取图形数据 choosevectnum=0; closevectnum=0; for(inti=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__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://删除指定对象 Input://nDelVect需要删除的对象的序号 Output:// Return://错误码 int__stdcallZMotionCadArray_DelOne(intnDelVect); *************************************************************/ [DllImport("ZmotionCadEx.dll",EntryPoint="ZMotionCadArray_DelOne",CharSet=CharSet.Ansi,CallingConvention=CallingConvention.StdCall)] publicstaticexternInt32ZMotionCadArray_DelOne(intnDelVect); /************************************************************* Description://移动对象 Input://m_xx方向移动的距离 //m_yy方向移动的距离 //nMoveVect需要移动的对象的序号,-1为移动所有 Output://Return://错误码 *************************************************************/ //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://缩放对象 Input://nScaleVect需要缩放的对象的序号,-1为缩放所有 Output://Return://错误码 *************************************************************/ //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://插入对象 Input://nArrayNum输入的数组数量 //nInsertNo插入的位置 Output:// Return://错误码 *************************************************************/ //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://修改对象 Input://nArrayNum输入的数组数量 //nInsertNo修改的对象位置 Output:// Return://错误码 *************************************************************/ //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:通过PictureBox鼠标事件响应函数实现框选功能。

鼠标按下响应函数 privatevoidMyPicture_MouseDown(objectsender,MouseEventArgse) { if(e.Button==MouseButtons.Left) { Point_MouseDown=newPoint(e.X,e.Y); if(newdrawtype==0)//框选 Start_Choose=true; } } 鼠标移动响应函数 privatevoidMyPicture_MouseMove(objectsender,MouseEventArgse) { Point_MouseCur=newPoint(e.X,e.Y); //Show_Picture(); if(e.Button==MouseButtons.Left) { CadShow.Invalidate(); } } 鼠标松开响应函数 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)//更改起点完成 { 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:对选中图案进行平移操作。

通过按钮对选中图案进行平移,对应平移函数movechoose,xy为平移相对距离 ZMotionCadArray_Move参数3传的值是遍历m_nInVectFrist,=1的时候表示vect曲线第一段,传的是vect曲线的编号 publicvoidmovechoose(doublex,doubley) { inticlosenum=0; inticlosechoose=0; uintiret=0; for(inti=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曲线的编号 privatevoidCadDel_Click(objectsender,EventArgse) { while(choosevectnum>0) { intiret=ZmotionCad.ZMotionCadArray_GetVectNum(refZCad_ArrayLen);//获取图形长度 ZCad_ArrayInfo=newZmotionCad.Struct_ZCad_Array[ZCad_ArrayLen]; iret=ZmotionCad.ZMotionCadArray_GetVectArray(refZCad_ArrayInfo[0],ZCad_ArrayLen);//获取图形数据 choosevectnum=0; closevectnum=0; for(inti=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 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)//三点圆弧 { multpointX[multnum]=Point_MouseDown.X; multpointY[multnum]=Point_MouseDown.Y; multnum++; if(multnum==3)//三点圆弧 { 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]; //获取转换长度 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]; //获取数据 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];//拆分出来的小线段 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.点击控制器→连接控制器。

wKgZPGnODbWASnNrAABslG299g484.webp

2.点击文件→打开,选择对应CAD文件。

wKgZO2nODbWAMtkqAAEWQsHcXcI20.webp

3.打开后显示图形,此时可以方向键进行平移或者鼠标滚轮进行缩放操作。

wKgZPGnODbWANNByAAEjriz-QdY51.webp

4.点击编辑可以进行图形优化或者排序操作。

wKgZO2nODbaAfx04AAFFfiMX7Ec34.webp

5.视图中可以选择空移,顺序,标号坐标系的显示。

wKgZPGnODbaAE4uBAAE6Yijd0Yc59.webp

6.点击右侧编辑标签,进入编辑界面,此时可以框选选中需要编辑的图案。

wKgZO2nODbaAet-AAADSjMMYJ2E43.webp

7.设置好移动距离,并点击上下左右移动,可以平移选中图案。

wKgZPGnODbaAfijTAADRcN3e4cc47.webp

8.点击删除可以删除对应图案。

wKgZO2nODbeAQx0YAAC_Ks8ikno28.webp

9.点击添加图形中的图案类型,可以添加新图案。

wKgZPGnODbeAdEmnAACuhKOCJVU57.webp

教学视频请点击→C#运动控制开源(一): CAD导图和小线段速度前瞻的优化之CAD导图

完整代码获取地址

wKgZO2nODbeAbb_uAABEzLxp9nQ72.webp

本次,正运动技术C#运动控制开源(一):CAD导图和小线段速度前瞻的优化之CAD导图,就分享到这里。

更多精彩内容请关注“正运动小助手”公众号,需要相关开发环境与例程代码,请咨询正运动技术销售工程师:400-089-8936。

本文由正运动技术原创,欢迎大家转载,共同学习,一起提高中国智能制造水平。文章版权归正运动技术所有,如有转载请注明文章来源。

wKgZPGnODbiAKf5FAADemj7stp877.webp

正运动技术专注于运动控制技术研究和通用运动控制软硬件产品的研发,是国家级高新技术企业。正运动技术汇集了来自华为、中兴等公司的优秀人才,在坚持自主创新的同时,积极联合各大高校协同运动控制基础技术的研究,是国内工控领域发展最快的企业之一,也是国内少有、完整掌握运动控制核心技术和实时工控软件平台技术的企业。主要业务有:运动控制卡_运动控制器_EtherCAT运动控制卡_EtherCAT控制器_运动控制系统_视觉控制器__运动控制PLC_运动控制_机器人控制器_视觉定位_XPCIe/XPCI系列运动控制卡等等。

审核编辑 黄宇

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 运动控制器
    +关注

    关注

    2

    文章

    491

    浏览量

    26139
  • CAD
    CAD
    +关注

    关注

    18

    文章

    1144

    浏览量

    76894
  • 正运动技术
    +关注

    关注

    0

    文章

    136

    浏览量

    905
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    MUN3CAD03-SF:多场景电源模块替代的优选方案

    MUN3CAD03-SF:多场景电源模块替代的优选方案在电子设计领域,电源模块的选型直接决定系统性能与稳定性,MUN3CAD03-SF作为款主流DC-DC电源模块,虽具备过流保护(OCP)、过温
    发表于 02-02 09:51

    MUN3CAD03-SF:多场景电源模块替代的优选方案

    MUN3CAD03-SF:多场景电源模块替代的优选方案在电子设计领域,电源模块的选型直接决定系统性能与稳定性,MUN3CAD03-SF作为款主流DC-DC电源模块,虽具备过流保护(OCP)、过温
    发表于 01-30 09:11

    CW32W031CAD的应用有哪些?

    CW32W031 CAD的应用有哪些?
    发表于 01-07 07:15

    Sub-1G系列产品CW32W031单片机CAD的应用参考

    、功能介绍 CW32W031 的射频部分支持 CAD 中断。从 Deepsleep 进入 STB3,开启 CAD 功能并进入 RX 模式后, CW32W031 会检测信道中是否会有
    发表于 01-04 06:52

    MOSFET通电阻Rds

    (on)电阻值会随着电流增大轻微上升,因此选择时需要留有余量。 (3)Rds(on)低的MOSFET通常成本比较高,可以通过优化驱动电路,改进散热等方式,选用Rds(on)较大些的的低成本器件。
    发表于 12-23 06:15

    CAD如何绘制螺旋线

    在机械设计、建筑建模和工业制图中,螺旋线是种常见且实用的几何元素,广泛应用于弹簧、螺纹、螺旋楼梯等结构的绘制。掌握CAD软件中螺旋线的绘制方法,能够显著提高设计效率和建模精度。本文将详细介绍创建
    的头像 发表于 12-02 17:35 1081次阅读
    <b class='flag-5'>CAD</b>如何绘制螺旋线

    3Dfindit上发布世嘉智尼的上万个3D CAD模型,优化用户设计流程

    自7月21日起,用户可在3Dfindit工程平台上访问日本五金组件专家世嘉智尼公司(Sugatsune)的完整产品系列的CAD 3D目录。从现在起,全球的设计人员可以随时随地搜索、查看和下载超过
    发表于 08-27 15:44

    如何平衡IGBT模块的开关损耗和通损耗

    ,增加开关损耗;反之,优化开关速度可能牺牲通特性。以下是针对实际应用的平衡优化策略,结合最新技术进展和实践案例。
    的头像 发表于 08-19 14:41 3032次阅读

    C#上位机与运动控制卡网络通讯的周期上报

    使用C#上位机编程实现运动控制卡网络通讯的周期上报功能
    的头像 发表于 06-26 13:59 980次阅读
    <b class='flag-5'>C#</b>上位机与<b class='flag-5'>运动</b><b class='flag-5'>控制</b>卡网络通讯的周期上报

    MUN3CAD05-JF 5A,高效uPOL模块规格书

    电容器和分压电阻器。 MUN3CAD05-JF选用强制性PWM模式,根据稳定通设定时间,MUN3CAD05-JF提供个更高效的控制电路和
    发表于 05-17 16:50 0次下载

    机器视觉运动控制体机在数控CAD dxf图中的应用

    运动数控CADdxf的应用
    的头像 发表于 05-09 09:35 850次阅读
    机器视觉<b class='flag-5'>运动</b><b class='flag-5'>控制</b><b class='flag-5'>一</b>体机在数控<b class='flag-5'>CAD</b> dxf<b class='flag-5'>导</b>图中的应用

    PCIe EtherCAT实时运动控制卡PCIE464的CAD与刀向跟随应用

    MFC与C++编程实现CAD与刀向跟随功能
    的头像 发表于 05-08 14:42 3148次阅读
    PCIe EtherCAT实时<b class='flag-5'>运动</b><b class='flag-5'>控制</b>卡PCIE464的<b class='flag-5'>CAD</b><b class='flag-5'>导</b><b class='flag-5'>图</b>与刀向跟随应用