今天,正运动技术给大家分享一下EtherCAT运动控制卡之ECI2828如何使用C#进行设置前瞻功能并使用在连续插补运动中。
一 运动控制卡硬件介绍
ECI2828系列运动控制卡支持多达 16 轴直线插补、任意圆弧插补、空间圆弧、螺旋插补、电子凸轮、电子齿轮、同步跟随、虚拟轴、机械手指令等;采用优化的网络通讯协议可以实现实时的运动控制。
ECI2828系列运动运动控制卡支持以太网,232 通讯接口和电脑相连,接收电脑的指令运行,可以通过EtherCAT总线和CAN总线去连接各个扩展模块,从而扩展输入输出点数或运动轴。
ECI2828系列运动控制卡的应用程序可以使用 VC,VB,VS,C++,C#等软件来开发,程序运行时需要动态库 zmotion.dll。调试时可以把ZDevelop软件同时连接到控制器,从而方便调试、方便观察。
二 C#语言运动控制开发
(一)新建MFC项目并添加函数库
1.在VS2015菜单“文件”→“新建”→“项目”,启动创建项目向导。
2.选择开发语言为“Visual C#”和.NETFramework 4以及Windows 窗体应用程序。
3.找到厂家提供的光盘资料里面的C#函数库,路径如下(64位库为例):
1)进入厂商提供的光盘资料找到“8.PC函数”文件夹,并点击进入。
2)选择“函数库2.1”文件夹。
3)选择“Windows平台”文件夹。
4)根据需要选择对应的函数库这里选择64位库。
5)解压C#的压缩包,里面有C#对应的函数库。
6)函数库具体路径如下。
4.将厂商提供的C#的库文件以及相关文件复制到新建的项目中。
1)将zmcaux.cs文件复制到新建的项目里面中。
2)将zaux.dll和zmotion.dll文件放入bin\debug文件夹中。
5.用vs打开新建的项目文件,在右边的解决方案资源管理器中点击显示所有,然后鼠标右键点击zmcaux.cs文件,点击包括在项目中。
6.双击Form1.cs里面的Form1,出现代码编辑界面,在文件开头写入 using cszmcaux,并声明控制器句柄g_handle。
至此项目新建完成,可进行C#项目开发。
(二)查看PC函数手册
1.PC函数手册也在光盘资料里面,具体路径如下:“光盘资料\8.PC函数\函数库2.1\ZMotion函数库编程手册 V2.1.pdf”。
2.PC编程,一般如果网口对控制器和工控机进行链接。网口链接函数接口是ZAux_OpenEth();如果链接成功,该接口会返回一个链接句柄。通过操作这个链接句柄可以实现对控制器的控制。
3.使用连续插补运动相关的指令操作链接句柄“g_handle”,对控制器进行连续插补运动控制,连续插补运动相关的指令如下。
(三)C#进行小线段前瞻连续插补运动开发
1.小线段前瞻连续插补运动控制人机交互界面如下。
2.CornerMode功能前瞻设置说明:
系统的速度前瞻功能,一方面可以对指令进行整体规划,即对各段速度进行整体规划,再配合指令段内的加减速控制,可以使机床保持高速运行提高效率,使负载运动更加流畅,告别停停走走,系统通过Merge 速度融合功能实现;另一方面,再保证高速运行基础上为了限制机械冲击和过切等,还需进行减速识别,通过提前识别轨迹变化,从而按照安全的减速度提前减速,系统通过减速/停止融合功能、 抑制冲击功能实现。整体来看,速度前瞻功能既可提升整机效率,也可减少冲击增加柔性,降低零部件磨损,增加设备使用寿命。
1)拐角减速:
拐角减速功能解决的问题是:当指令间夹角过大时,如果仍以较大速度运行,会在夹角处产生较大的机械冲击,轨迹偏离。
控制器会对指令间轨迹变化的夹角进行提前识别,比较其与减速/停止角的大小关系,提前决定是否进行减速,保证在指令连接处平稳过渡。
如图,OA过渡AB段位置时角度小于减速角度则,S1-S2段不进行减速,AB过渡BC段时角度大于减速角度则进行减速处理过渡过程如S2-S3段,BC过渡CD段角度大于停止角度速度需要降到零如S3-S4段位置处理。
2)小圆限速:
小圆限速功能用于处理,在运行轨迹中可能运行圆弧轨迹拟合成的小圆,由于角度偏转较大导致出现轨迹偏转,因此在这种位置需要进行速度限制的处理。开启小圆限速,小圆半径超过限速半径的时候不会对速度限制,小圆半径小于限速半径的时候则会开始对速度进行限制。
如图:
小圆半径100,限速半径50:
小圆半径100,限速半径150:
3)自动倒角:
自动倒角功能一般是用于拐角处按照一定的倒角半径进行轨迹的弧度化处理,使速度变化更平滑。如图:
未倒角:
设置倒角后轨迹
3.例程简易流程图。
4.在Form1的构造函数中调用接口ZAux_OpenEth(),使在系统初始化的时候自动链接控制器。
public Form1()
{
InitializeComponent();
//链接控制器
zmcaux.ZAux_OpenEth("192.168.0.11", out g_handle);
if (g_handle != (IntPtr)0)
{
MessageBox.Show("控制器链接成功!", "提示");
timer1.Enabled = true;
}
else
{
MessageBox.Show("控制器链接失败,请检测IP地址!", "警告");
}
}
5.通过定时器更新控制器轴状态:当前坐标、外设信息等等。
//定时器刷新
private void timer1_Tick(object sender, EventArgs e)
{
int[] runstate = new int[4];
float[] curpos = new float[4];
int RemainBuffer = 0;
for (int i = 0; i < 4; i++)
{
zmcaux.ZAux_Direct_GetIfIdle(g_handle, i, ref runstate[i]);
zmcaux.ZAux_Direct_GetDpos(g_handle, i, ref curpos[i]);
}
zmcaux.ZAux_Direct_GetRemain_LineBuffer(g_handle, 0, ref RemainBuffer);
label_runstate.Text = "x:" + curpos[0] + " y:" + curpos[1] + " z:" + curpos[2] + " 剩余缓冲数: " + RemainBuffer + Convert.ToString(runstate[0] == 0 ? " 运行状态:运行" : " 运行状态:停止");
}
6.通过启动按钮的事件处理函数来设置轴参数以及前瞻参数并开始运动。
//启动
private void Button_start_Click(object sender, EventArgs e)
{
if (g_handle == (IntPtr)0)
{
MessageBox.Show("未链接到控制器!", "提示");
}
else
{
int RemainBuffer = 0;
int CornerMode = 0;
int[] axislist = {0,1,2};
float[] poslist = { Convert.ToSingle(endpos1.Text), Convert.ToSingle(endpos2.Text), Convert.ToSingle(endpos3.Text)};
float[] midlist = { Convert.ToSingle(midpos1.Text), Convert.ToSingle(midpos2.Text), Convert.ToSingle(midpos3.Text) };
float[] firstlist = { Convert.ToSingle(firstpos1.Text), Convert.ToSingle(firstpos2.Text), Convert.ToSingle(firstpos3.Text) };
float[] seclist = { Convert.ToSingle(secpos1.Text), Convert.ToSingle(secpos2.Text), Convert.ToSingle(secpos3.Text) };
float[] thirdlist = { Convert.ToSingle(thirdpos1.Text), Convert.ToSingle(thirdpos2.Text), Convert.ToSingle(thirdpos3.Text) };
float[] fourlist = { Convert.ToSingle(fourpos1.Text), Convert.ToSingle(fourpos2.Text), Convert.ToSingle(fourpos3.Text) };
float[] fivelist = { Convert.ToSingle(fivepos1.Text), Convert.ToSingle(fivepos2.Text), Convert.ToSingle(fivepos3.Text) };
float[] sixlist = { Convert.ToSingle(sixpos1.Text), Convert.ToSingle(sixpos2.Text), Convert.ToSingle(sixpos3.Text) };
zmcaux.ZAux_Direct_Base(g_handle, 3, axislist); //选择运动轴列表
zmcaux.ZAux_Direct_SetMerge(g_handle, axislist[0], 1);
//插补运动使用的是主轴参数,及BASE的第一个轴
zmcaux.ZAux_Direct_SetSpeed(g_handle, axislist[0],Convert.ToSingle(textBox_speed.Text));
zmcaux.ZAux_Direct_SetAccel(g_handle, axislist[0], Convert.ToSingle(textBox_acc.Text));
zmcaux.ZAux_Direct_SetDecel(g_handle, axislist[0], Convert.ToSingle(textBox_dec.Text));
if (checkBox1.Checked == true)
CornerMode += 2;
if (checkBox2.Checked == true)
CornerMode += 8;
if (checkBox3.Checked == true)
CornerMode += 32;
//设置前瞻模式及对应参数
zmcaux.ZAux_Direct_SetCornerMode(g_handle, axislist[0], CornerMode);
zmcaux.ZAux_Direct_SetDecelAngle(g_handle, axislist[0], Convert.ToSingle(textBox_DecelAngle.Text));
zmcaux.ZAux_Direct_SetStopAngle(g_handle, axislist[0], Convert.ToSingle(textBox_StopAngle.Text));
zmcaux.ZAux_Direct_SetFullSpRadius(g_handle, axislist[0], Convert.ToSingle(textBox_SpRadius.Text));
zmcaux.ZAux_Direct_SetZsmooth(g_handle, axislist[0], Convert.ToSingle(textBox_ZSmooth.Text));
zmcaux.ZAux_Direct_SetForceSpeed(g_handle, axislist[0], Convert.ToSingle(textBox_speed.Text));
//触发示波器
zmcaux.ZAux_Trigger(g_handle);
if (run_mode == 1) //绝对
{
//判断缓冲区,如果缓冲不够则等待完成再加载指令
while (RemainBuffer < 50)
zmcaux.ZAux_Direct_GetRemain_LineBuffer(g_handle, axislist[0], ref RemainBuffer);
switch (move_mode)
{
case 2: //XY圆弧
zmcaux.ZAux_Direct_MoveCirc2Abs(g_handle,2,axislist, midlist[0], midlist[1],poslist[0], poslist[1]);
break;
case 3: //XYZ直线
zmcaux.ZAux_Direct_MoveAbs(g_handle, 3, axislist, firstlist);
zmcaux.ZAux_Direct_MoveAbs(g_handle, 3,axislist, seclist);
zmcaux.ZAux_Direct_MoveAbs(g_handle, 3, axislist, thirdlist);
zmcaux.ZAux_Direct_MoveAbs(g_handle, 3, axislist, fourlist);
zmcaux.ZAux_Direct_MoveAbs(g_handle, 3, axislist, fivelist);
zmcaux.ZAux_Direct_MoveAbs(g_handle, 3, axislist, sixlist);
break;
case 4: //螺旋插补
zmcaux.ZAux_Direct_MHelical2Abs(g_handle, 3, axislist, midlist[0], midlist[1], poslist[0], poslist[1], poslist[2], 0);
break;
default:
break;
}
}
else
{
switch (move_mode)
{
case 2:
zmcaux.ZAux_Direct_MoveCirc2(g_handle, 2, axislist, midlist[0], midlist[1], poslist[0], poslist[1]);
break;
case 3:
zmcaux.ZAux_Direct_Move(g_handle, 3, axislist, firstlist);
zmcaux.ZAux_Direct_Move(g_handle, 3, axislist, seclist);
zmcaux.ZAux_Direct_Move(g_handle, 3, axislist, thirdlist);
zmcaux.ZAux_Direct_Move(g_handle, 3, axislist, fourlist);
zmcaux.ZAux_Direct_Move(g_handle, 3, axislist, fivelist);
zmcaux.ZAux_Direct_Move(g_handle, 3, axislist, sixlist);
break;
case 4:
zmcaux.ZAux_Direct_MHelical2(g_handle, 3, axislist, midlist[0], midlist[1], poslist[0], poslist[1], poslist[2], 0);
break;
default:
break;
}
}
}
}
7.通过坐标清零按钮的事件处理函数来重置当前运动坐标位置。
(四)调试与监控
编译运行例程,同时连接ZDevelop软件进行调试,对运动控制的轴参数和运动情况进行监控。
使用不同的前瞻模式以及参数会导致速度和运行轨迹发生变化,如下面加工轨迹以及对应的运行轨迹以及速度曲线图:
拐角减速开启,运动达到减速条件:
视频演示:
本次,正运动技术EtherCAT运动控制卡小线段前瞻的连续插补运动,就分享到这里。
更多精彩内容请关注“正运动小助手”公众号,需要相关开发环境与例程代码,请咨询正运动技术销售工程师:400-089-8936。
本文由正运动技术原创,欢迎大家转载,共同学习,一起提高中国智能制造水平。文章版权归正运动技术所有,如有转载请注明文章来源。