正运动技术
正运动技术
EN

协助伙伴成功,是我们的价值所在

The value of Zmotion is to bring customers more success!

首页 / 支持与服务 / 技术分享

Technical support

技术分享

PCIe EtherCAT实时运动控制卡的DXF图形的CAD导图与多条运动指令的快速加工

0.png





硬件介绍

PCIE464运动控制卡是正运动推出的一款EtherCAT总线+脉冲型、PCIE接口式的运动控制卡,可选6-64轴运动控制,支持多路高速数字输入输出,可轻松实现多轴同步控制和高速数据传输。

PCIE464运动控制卡.png

PCIE464运动控制卡适合于多轴点位运动、插补运动、轨迹规划、手轮控制、编码器位置检测、IO控制、位置锁存等功能的应用。
PCIE464运动控制卡适用于3C电子加工、检测设备、半导体设备、SMT加工、激光加工、光通讯设备、锂电及光伏设备、以及非标自动化设备等高速高精应用场合。

PCIE464控制卡架构图.png

PCIE4系列控制卡的应用程序可以使用VC,VB,VS,C++,C#等软件开发,程序运行时需要动态库zmotion.dll,调试时可以将RTSys软件同时连接控制器,从而方便调试、方便观察。

上位机.png


PCIE464产品介绍视频可点击“【EtherCAT同步周期快至100us】超高实时性PCIe EtherCAT控制卡PCIE464”查看。



接线参考

1、IN数字量输入接口
数字输入分布在J400(IN0-IN7)和X400(IN8-IN39)信号接口中。

IN数字量输入接口1.png

IN数字量输入接口2.png
2、OUT数字量输出接口
数字输出分布在 J400(OUT0-7)和 X400(OUT8-OUT39)信号接口中。

OUT数字量输出接口1.png

OUT数字量输出接口2.png




C#语言进行项目开发



1、在VS2010菜单“文件”→“新建”→“项目”,启动创建项目向导。

1.png
2、选择开发语言为“Visual C#”和.NET Framework 4以及Windows窗体应用程序。

2.png

3、找到厂家提供的运动库、CAD导图库(32位库为例)。

3.png

4将厂商提供的C#的库文件以及相关文件复制到新建的项目中,以及 厂商提供的C#的相关库文件放入bin\debug文件夹中。

4.png

5、用vs打开新建的项目文件,在右边的解决方案资源管理器中点击显示所有文件,然后鼠标右击zmcaux.cs文件,点击包括在项目中,根据添加zmcaux.cs文件的步骤,将zmclaser.cs和zmotioncad.cs文件添加进工程中。

5.png

6.png

6、双击Form1.cs里面的Form1,出现代码编辑界面,在文件开头写入using cszmcaux,using ZmotionCadDll,并声明控制器句柄g_cardhandle和使用CAD中使用到的cad库函数的句柄g_cadhandle。

7.png

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




C#语言进行CAD导图



在实际的运用场景中,如果一张图纸靠人为去计算图形运动轨迹的坐标,结果既费时又费力。所以,在此情景下,如果我们让计算机去计算图形的运动轨迹,则会事半功倍,接下来我们介绍如何使用C#进行CAD导图。

1、操作步骤

首先,新建WinForm项目并添加函数库,接着用ZMotionCadArray_ImportVectGraph指令去导入打开CAD图形文件,并进行小线段的拆分精度。
再用ZMotionCadArray_GetVectNum指令去获取数组长度,接着创建一个struct_zcad_array 结构体类型 (该结构体在ZMotionCad库中已经有声明,直接定义调用即可),用来保存运动数据、运动类型等信息。
创建好该结构体数组以后,再用ZMotionCadArray_GetVectArray指令将图形的运动数据保存到该数组里面。
最后,用ZMotionCad Array_Merge Seg指令去将各个点连接成线。操作思路,如图所示。

8.png

2、指令介绍

9.png

10.png

11.png
12.png

3、生成运动轨迹数据

将.dxf文件导入进去后,使用ZMotionCadArray_ImportVectGraph指令将CAD图纸导入,并对小线段进行拆分。

用ZMotionCadArray_GetVectNum获取数据长度,获取到数据长度后,创建一个Struct_ZCad_Array类型的数组。

这时,其CAD图纸的数据就保存在这结构体数组中,获取图形数据用ZMotionCadArray_GetVectArray指令。

创建一个StringBuilder类型的数组,用循环去访问Struct_ZCad_Array类型数组的运动类型,并把其运动坐标尾插到该数组里面。

最后,用文件IO的知识创建一个bas文件,并将StringBuilder类型数组的运动数据尾插到该bas文件中。

13.png

1、导入图形文件,通过线程去获取CAD图纸的点位信息,并用画笔将点位信息显示在画板上。

14.png

获取图纸点位信息的相关代码:

//打开配置文件
if (openFileDialog1.ShowDialog() == DialogResult.OK) 
{
   strFilePath = openFileDialog1.FileName;
   label11.Text =  Path.GetFileName(strFilePath);
   textBox3.Text= textBox3.Text+"\r\n"+"导入文件:"+ Path.GetFileName(strFilePath);
   //导入CAD图形文件    m_refDistance圆弧转小线段拆分精度
   int iret = ZmotionCad.ZMotionCadArray_ImportVectGraph(strFilePath, 1024, 1, m_refDistance);   
   //导入数据, 获取数组长度 
   iret = ZmotionCad.ZMotionCadArray_GetVectNum(ref ZCad_ArrayLen);   
   //创建一个结构体变量 
   ZCad_ArrayInfo = new ZmotionCad.Struct_ZCad_Array[ZCad_ArrayLen];   
   //获取图形数据 将cad文件的数据放在ZCad_ArrayInfo数组里
   iret = ZmotionCad.ZMotionCadArray_GetVectArray(ref ZCad_ArrayInfo[0], ZCad_ArrayLen); 
   //是否只处理封闭轨迹
   iret = ZmotionCad.ZMotionCadArray_IfCloseVect(false);            
   //合并相连线
   iret = ZmotionCad.ZMotionCadArray_MergeSeg(0.5, If_Choose);
   //为了判断是否只处理封闭轨迹,又重新获取数组的长度和获取图形数据
   Get_Array();        
   //在细分0.05的情况下获取图纸的左、底、长、宽的数值
   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;
     }
     //缩放比例
     dScale = ObjectPixHeight / Image_Height;
     m_dUnitsPerMm = dScale * 1;
     //偏移
     m_dTranX = (MyPicture.Width - ObjectPixWidth) / 2 - Image_Left * dScale;
     m_dTranY = (MyPicture.Height - ObjectPixHeight) / 2 - Image_bottom * dScale;
     //用画笔将点位信息显示在画板上
     Show_Picture();

2、点击运行程序,通过线程生成运动指令下发到控制器,让控制器去跑CAD的点位坐标。

15.png

4、运行效果

上位机界面上的运动轨迹与RTSys抓到的运动轨迹作比较,与RTSys示波器上的轨迹基本上相符。

16.png




自定义封装指令函数


在实际开发过程中,为了提高效率,ZMotion PC函数库里如果没有现成的指令供开发者使用,那么开发者可以通过自定义封装指令函数的方式去实现开发者想要实现的功能来提高交互的效率。
下面正运动小助手将通过一次性下发多条的示例去说明如何自定义封装指令函数。

1、指令说明
17.png

2、示例说明

下面的示例代码中,自定义封装可以一次性发送多条运动指令的函数指令,代码思路如下:
1、正运动小助手先定义4个形参,分别为句柄、轴的个数、轴列表(从哪个轴号开始到哪个轴号结束)、各个轴的运动距离(可以有多条点位信息,以“;”作为一个点位信息的结束标记)。
2、 在自定义函数里面将形参中的axis_distance内容以“;”的方式进行剪切并保存在dir_move数组里面。
3、将dir_move数组里面的点位信息通过拼接字符串的方式,循环扫描拼接生成moveabs的运动指令保存在变量名为 cmdbuff 的 string类型里面。
4、通过ZMotion PC函数库的在线发送指令ZAux_DirectCommand去将变量名 为cmdbuff里面的多条运动指令下发给控制卡或控制器。
Description:    // 自定义封装函数,一次性下发多条运动指令
Input:          //handle 控制卡句柄/控制器句柄 
                //axis_num   总轴数
                //axis_list  轴号列表
                //axis_distance  运动的点位坐标,以“;”作为结束标记代表一条运动坐标
Return:         //错误码
int __stdcall ZMotionCadArray_DelOne(int nDelVect);
*************************************************************/
public Int32 UseDefined_Moveabs(IntPtr handle,int axis_num, string axis_list,string axis_distance)
{ 
   //用于拼接运动命令的字符串
   string cmdbuff = "";          
       string[] dir_move = axis_distance.ToString().Split(new char[] { ';' });
   //接收在线命令的信息
   StringBuilder psResponse =new StringBuilder(1024);          
   //判断轴的个数是否合理
   if (axis_num < 0)
   {
       return -1;
   }
   //生成命令
   cmdbuff= "base(" + axis_list + ")";
   for (int i = 0; i < dir_move.Length; i++)
   {
     //拼接运动指令
     cmdbuff =cmdbuff+ "moveabs("+ dir_move[i]+")";       }
     //利用在线命令的方式去发送拼接好的运动指令
     return zmcaux.ZAux_DirectCommand(handle,cmdbuff,psResponse,1024);
   }
调用自定义封装的函数指令:
//获取轴0缓冲区的大小          
 ret = zmcaux.ZAux_Direct_GetRemain_Buffer(G_CardHandle, 0, ref buf0);
 err_inform("ZAux_Direct_GetRemain_Buffer0", ret);  
 if (buf0 > 10)
 {
     //通过自定义封装的函数去发运动指令,一次发10条
     ret = UseDefined_Moveabs(G_CardHandle, 2, axis, direct_str[i]);
     err_inform("UseDefined_Moveabs", ret);
     label15.Invoke(new MethodInvoker(() => direct_num(i.ToString())));

3、代码验证

(1)形参direct_str[0]里面的数据内容。

18.png

(2)cmdbuff里面拼接好的数据。

19.png

通过以上两个变量中的数据内容查看,验证了上诉的代码思路是符合逻辑的,实现了高效率的一条指令内多条数据加工的传输。




模拟量与速度的实时转换


一、操作步骤

首先,设置工程下的Basic文件自动运行任务号,可以在RTSys软件上的“控制器状态”中查看控制器最多支持多少个任务,然后在Basic文件上填写自动运行任务号 (不能超过最大支持的任务数),最后下载到控制器上。

1、查看控制器的最大任务数。

20.png

2、填写自动运行任务号。

21.png

3、设置好自动运行任务号后,下载写好的程序到控制器运行即可。

22.png

4、在上位机上设置转换比例K值(0到1)。

23.png

二、指令介绍
24.png
25.png
注:在本示例代码中,PC指令中的ZAux_Direct_SetUserVar 的Varname形参在使用时,写的是Basic文件的全局变量s_ratio。
三、举例说明
在下方的Basic程序中,可以根据轴的速度来实现控制器模拟量输出口的大小,也通过上位机去修改模拟量与速度的转换比例K。
使用示波器将速度与模拟量的输出波形抓取之后,可以看出,速度与模拟量输出的波形基本一致。

26.png

1、Basic相关代码。

GLOBAL s_ratio    '速度的比例
WHILE 1
'将速度与模拟量的关系成正比  
AOUT(0)=4.095*VP_SPEED(0)*s_ratio
WEND
end
2、PC中的相关代码。
int ret = zmcaux.ZAux_Direct_SetUserVar(G_CardHandle, "s_ratio", Convert.ToSingle(textBox4.Text));  //设置模拟量与速度的转换比例
err_inform("比例的ZAux_Direct_SetUserVar",ret);

三、视频讲解

视频讲解可点击“PCIe EtherCAT实时运动控制卡的DXF图形的CAD导图与多条运动指令的快速加工”查看。


完整代码获取地址

00.png

本次,正运动技术PCIe EtherCAT实时运动控制卡的DXF图形的CAD导图与多条运动指令的快速加工 ,就分享到这里。

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

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

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

企业微信截图_20240321153031.png

邮箱留言

Copyright © 2013 正运动技术有限公司 Design by Zmotion 版权所有   粤ICP备13037187号    Powered by www.zmotion.com.cn 运动控制器-运动控制卡

在线咨询