中国自动化学会专家咨询工作委员会指定宣传媒体
文摘详情
gkongbbs

连续轨迹加工和速度前瞻:EtherCAT超高速实时运动控制卡XPCIE1032H上位机C#开发(十二)

http://www.gkong.com 2024-03-01 11:23 深圳市正运动技术有限公司

XPCIE1032H功能简介

XPCIE1032H是一款基于PCI Express的EtherCAT总线运动控制卡,可选6-64轴运动控制,支持多路高速数字输入输出,可轻松实现多轴同步控制和高速数据传输。

XPCIE1032H运动控制卡集成了强大的运动控制功能,结合MotionRT7运动控制实时软核,解决了高速高精应用中,PC Windows开发的非实时痛点,指令交互速度比传统的PCI/PCIe快10倍。

运动控制卡XPCIE1032H.png

XPCIE1032H运动控制卡 支持PWM,PSO功能,板载16进16出通用IO口,其中输出口全部为高速输出口,可配置为4路PWM输出口或者16路高速PSO硬件比较输出口。输入口含有8路高速输入口,可配置为4路高速色标锁存或两路编码器输入。

XPCIE1032H运动控制卡搭配MotionRT7实时内核,使用本地LOCAL接口连接,通过高速的核内交互 ,可以做到更快速的指令交互,单条指令与多条指令一次性交互时间可以达到3-5us左右。

XPCIE1032H控制卡架构图.png

?XPCIE1032H运动控制卡与MotionRT7运动控制实时内核的配合具有以下优势:

优势.png

1.支持多种上位机语言开发,所有系列产品均可调用同一套API函数库;

2.借助核内交互,可以快速调用 运动指令,响应时间快至微秒级,比传统PCI/PCIe快10倍;

3.解决传统PCI/PCIe运动控制卡在Windows环境下控制系统的非实时性问题;

4.支持一维/二维/三维PSO(高速硬件位置比较输出),适用于视觉飞拍、精密点胶和激光能量控制等应用;

5.提供高速输入接口,便于实现位置锁存;

6.支持EtherCAT总线和脉冲输出混合联动、混合插补。

多种上位机开发方式.png

?使用XPCIE1032H运动控制卡和MotionRT7进行项目开发时,通常需要进行以下步骤:

1.安装驱动程序,识别XPCIE1032H;

2.打开并执行文件“MotionRT710.exe”,配置参数和运行运动控制实时内核;

3.使用ZDevelop软件连接到控制器,进行参数监控。连接时请使用PCI/LOCAL方式,并确保ZDevelop软件版本在3.10以上;

4.完成控制程序开发,通过LOCAL链接方式连接到运动控制卡,实现实时运动控制。

运动控制项目开发.png

?与传统PCI/PCIe卡和PLC的测试数据结果对比:

核内交互数据.png

我们可以从测试对比结果看出,XPCIE1032H运动控制卡配合实时运动控制内核MotionRT7,在LOCAL链接(核内交互)的方式下,指令交互的效率是非常稳定,当测试数量从1w增加到10w时,单条指令交互时间与多条指令交互时间波动不大,非常适用于高速高精的应用。

XPCIE1032H控制卡安装

  • 关闭计算机电源。

  • 打开计算机机箱,选择一条空闲的XPCIE卡槽,用螺丝刀卸下相应的挡板条。

  • 将运动控制卡插入该槽,拧紧挡板条上的固定螺丝。

XPCIE1032H驱动安装与建立连接参考往期文章 EtherCAT超高速实时运动控制卡XPCIE1032H上位机C#开发(一):驱动安装与建立连接

一、C#语言进行运动控制项目开发

创建项目.png

1.到正运动技术官网的下载中心选择需要的平台库文件。

库文件下载地址: http://www.zmotion.com.cn/download_list_21.html

库文件下载路径.png

2.解压下载的安装包找到“ Zmcaux.cs ”,“ zauxdll.dll ”,“ zmotion.dll ”放入到项目文件中。

(1)“Zmcaux.cs”放在项目根目录文件中,与bin目录同级。

1.png

(2)“zauxdll.dll”,“zmotion.dll”放在bin → Debug。

2.png

3.用vs打开新建的项目文件,在右边的解决方案资源管理器中点击显示所有,然后鼠标右键点击zmcaux.cs文件,点击包括在项目中。

3.png

4.双击Form1.cs里面的Form1,出现代码编辑界面,在文件开头写入using cszmcaux,并声明控制器句柄g_handle。

4.png

二、PC函数介绍

相关PC函数介绍详情可参考“ZMotion PC函数库编程手册 V2.1.1”。

指令11.png

指令171.png

指令173.png

指令175.png

指令181.png

指令183.png

三、C#进行连续轨迹加工和速度前瞻运动开发

连续轨迹加工和速度前瞻控制人机交互界面如下。

1.png

例程模拟连续轨迹为六边形,可根据需要更改每段运动坐标走出相应轨迹。

2.png

1.在Form1的构造函数中调用接口ZAux_FastOpen(),使在系统初始化的时候自动链接控制器。

private void C_Open_local_Click_Click(object sender, EventArgs e)      //local链接
{
    if (g_handle == (IntPtr)0)
    {
        C_Close_Card_Click(sender, e);
    }
    zmcaux.ZAux_FastOpen(5, "LOCAL", 1000, out g_handle);
    if (g_handle != (IntPtr)0)
    {
        this.Text = "已链接 Local";
        label2.Text = "已链接";
        label2.BackColor = Color.Green;
        timer1.Enabled = true;
    }
    else
    {
        MessageBox.Show("链接失败,请选择正确的LOCAL!");
    }
}

2.通过定时器更新控制器轴状态(当前坐标、剩余缓冲数,运动状态等)。

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 ? " 运行状态:运行" : "  运行状态:停止"  );
}

3.通过启动按钮的事件处理函数来设置轴参数以及前瞻参数并开始按照设点轨迹进行运动。

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));
        zmcaux.ZAux_Direct_SetSramp(g_handle, axislist[0], Convert.ToSingle(textBox_sramp.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)* Convert.ToSingle(Math.PI / 180));
        zmcaux.ZAux_Direct_SetStopAngle(g_handle, axislist[0], Convert.ToSingle(textBox_StopAngle.Text) * Convert.ToSingle(Math.PI / 180));
        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;
            }
        }
    }
}

4.停止按钮,通过函数接口ZAux_Direct_Single_Cancel()停止运动。

private void Button2_Click(object sender, EventArgs e)              //停止
{
    if (g_handle == (IntPtr)0)
    {
        MessageBox.Show("未链接到控制器!", "提示");
        return;
    }
    int iret = 0;
    iret = zmcaux.ZAux_Direct_Single_Cancel(g_handle, m_AxisMaster, 2);
}

 5.坐标清零按钮通过函数接口ZAux_Direct_SetDpos()来重置当前运动坐标位置。

private void Button_zero_Click(object sender, EventArgs e)      //坐标清零
{
    if (g_handle == (IntPtr)0)
    {
        MessageBox.Show("未链接到控制器!", "提示");
    }
    else
    {
        for (int i = 0; i < 3; i++)
        {
            zmcaux.ZAux_Direct_SetDpos(g_handle, i, 0);
        }
    }
}

四、调试与监控

CornerMode功能前瞻设置说明:

系统的速度前瞻功能:一方面可以对指令进行整体规划,即对各段速度进行整体规划,再配合指令段内的加减速控制,可以使机床保持高速运行提高效率,使负载运动更加流畅,告别停停走走,系统通过Merge 速度融合功能实现;另一方面,再保证高速运行基础上为了限制机械冲击和过切等,还需进行减速识别,通过提前识别轨迹变化,从而按照安全的减速度提前减速,系统通过减速/停止融合功能、抑制冲击功能实现。

整体来看,速度前瞻功能既可提升整机效率,也可减少冲击增加柔性,降低零部件磨损,增加设备使用寿命。

01 拐角减速

ZAux_Direct_SetCornerMode=2

拐角减速应用场合: 不改变运动轨迹,仅在拐角处自动判断是否减速,一般用于改善机台抖动的问题,对轨迹精度有要求,对速度要求没那么快的场合。

拐角减速功能解决的问题是: 当指令间夹角过大时,如果仍以较大速度运行,会在夹角处产生较大的机械冲击,轨迹偏离。

控制器会对指令间轨迹变化的夹角进行提前识别,比较其与减速/停止角的大小关系,提前决定是否进行减速,保证在指令连接处平稳过渡。

如图,OA过渡AB段位置时角度小于减速角度则,S1-S2段不进行减速,AB过渡BC段时角度大于减速角度则进行减速处理过渡过程如S2-S3段,BC过渡CD段角度大于停止角度速度需要降到零如S3-S4段位置处理。

3.png

4.png

减速角度是指电机的参考角度相对上一条运动的变化值。如下图。此角度值不是实际轨迹的角度,是换算到电机变换的角度,此角度值仅为参考。

5.png

(1)拐角减速未开启

6.png

(2)拐角减速开启,运动达到减速条件

7.png

8.png

02  自动倒角

ZAux_Direct_SetCornerMode=32

自动倒角应用场合: 改变运动轨迹,不会降低速度, 针对轨迹拐角较大的场合,倒角处运动轨迹做自动平滑处理,所以一般应用在对速度要求快,对轨迹精度要求不高的场合。

自动倒角功能一般是用于拐角处按照一定的倒角半径进行轨迹的弧度化处理,使速度变化更平滑。

(1)倒角未开启

9.png

(2)倒角开启,拐角位置图形变平滑

10.png

11.png

03 小圆限速

ZAux_Direct_SetCornerMode=8

小圆限速应用场合: 不改变运动轨迹,一般应用在圆弧加工,根据圆弧半径计算当前圆弧的限制速度。

小圆限速功能用于处理,在运行轨迹中可能运行圆弧轨迹拟合成的小圆,由于角度偏转较大导致出现轨迹偏转,因此在这种位置需要进行速度限制的处理。开启小圆限速,小圆半径超过限速半径的时候不会对速度限制,小圆半径小于限速半径的时候则会开始对速度进行限制。

(1)开启小圆限速,小圆半径100 > 限速半径30,速度正常达到顶点。

12.png
13.png

(2)开启小圆限速,小圆半径100 < 限速半径150,速度受到限制。

14.png

15.png

连续轨迹加工和速度前瞻讲解视频。

企业微信截图_20240226151307.png

本次,正运动技术连续轨迹加工和速度前瞻 :EtherCAT超高速实时运动控制卡XPCIE1032H上位机C#开发(十二),就分享到这里。

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

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

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

二维码-02.jpg

版权所有 中华工控网 Copyright©2024 Gkong.com, All Rights Reserved