[其他] 开放式激光振镜运动控制器:C++快速开发

[复制链接]
查看39738 | 回复0 | 4 天前 | 显示全部楼层 |阅读模式
点击上方“正运动小助手”,随时关注新动态!
今天,正运动技术为大家分享一下应用ZMC408SCAN开放式激光振镜运动控制器的C++开发,实现激光振镜打标,可在文章末尾扫码获取例程源码。

除了C++还支持使用其他上位机软件来开发,上位机程序运行时需要动态库“zmotion.dll”,上位机开发调试时可以把ZDevelop软件同时连接到控制器辅助调试。
01ZMC408SCAN控制器介绍



ZMC408SCAN是正运动技术新推出的一款支持EtherCAT总线的开放式激光振镜运动控制器,专为工业激光+振镜+运动控制方面的应用而设计。通过EtherCAT总线和脉冲轴接口能实现多轴联动运动控制。

ZMC408SCAN支持ETHERNET、EtherCAT、USB、CAN、RS485、RS232等通讯接口,通过CAN、EtherCAT总线可以连接各个扩展模块,从而扩展数字量、模拟量或运动轴。



(1)ZMC408SCAN内置高精度PSO位置同步输出功能,在加工圆角、曲线部分时即使进行了减速调整,在高速加工的场合,也能控制激光输出的间距保持恒定;

(2)支持激光振镜控制和振镜反馈,包含2个振镜接口,支持2D振镜和3D振镜,配合不带加减速的运动指令MOVESCAN,拐角处振镜加工自动延时,完成精准高效的激光控制,提高激光加工设备的产能;

(3)通过指令在运动中灵活的调节激光开光/关光延时,响应快,精确到us级别的控制,且设置过程简单,大大缩短了工程师的调参时间;

(4)自带LASER激光器控制接口,支持IPG、YLR、YLS等类型激光电源,还带一个EXIO扩展IO接口,通过定制转接板,灵活控制市场上主流的各种激光器;

(5)支持PC同时控制16个ZMC408SCAN控制器同时工作,形成一种振镜阵列的激光加工;

(6)板载4路高速差分脉冲输出,并带4路高速差分编码器反馈,支持EtherCAT总线驱动器的控制,支持5轴XYZAC轴的插补,支持振镜轴与运动轴混合插补;

(7)支持直线插补、任意圆弧插补、空间圆弧、螺旋插补、电子凸轮、电子齿轮、同步跟随、虚拟轴设置等多种运动控制功能。

02系统架构



下图为ZMC408SCAN开放式激光控制器的参考架构,支持多种不同类型的激光器控制。



03上位机和控制器通讯


上位机和控制器通讯调用正运动封装好的函数库,提供运动控制和激光控制等众多函数库接口,激光振镜的系统架构参见下图。



本例采用EtherNET网口连接控制器,通过函数ZAux_OpenEth()建立通讯连接,用户可在设置好的界面中选择当前网段下的控制器IP完成连接,控制器出厂IP地址192.168.0.11,参见下图。



04激光控制


一、指令介绍
下面是我们程序中用到的接口函数,主要包含激光控制和激光振镜控制两部分,程序的实现可直接使用封装好的接口函数发送命令给控制器。

本例采用FIBER激光器和2D激光振镜,用到下面的函数接口:

    ZAux_Direct_MoveScanAbs:振镜轴多轴绝对直线插补SCAN运动,不带加减速过程,我们这里用来控制振镜轴运动,通过小线段的形式拟合圆形轨迹;ZAux_Direct_MoveOpDelay:缓冲输出延时,提前开光时将延时时间设置为负数;ZAux_Direct_MoveDelay:缓冲输出延时,我们这里用来延时关光。
激光功率设置:提供模拟量ZAux_Direct_SetDA、PWM的占空比ZAux_Direct_SetPwmDuty和频率ZAux_Direct_SetPwmFreq等方式控制设置振镜轴拐角处自动延时:
ZAux_Direct_SetCornerMode

1.振镜轴直线插补
ZAux_Direct_MoveScanAbs绝对运动,ZAux_Direct_MoveScan相对运动。

指令27

ZAux_Direct_MoveScanAbs

指令原型

int32 __stdcall ZAux_Direct_MoveScanAbs(ZMC_HANDLE handle, int imaxaxises, int  *piAxislist,float  *pfDisancelist)

指令说明

振镜轴多轴相对直线插补Scan运动。

输入参数


参数名

描述

handle

连接句柄。

imaxaxises

运动轴数。

piAxislist

轴列表数组。

pfDisancelist

运动的距离列表。



输出参数

/

返回值

成功返回值为0,非0详见错误码说明。

详细说明

插补运动距离X=

运动时间T=X/主轴速度

插补运动时只有主轴速度参数有效,主轴是轴列表数组的第一个轴,运动参照这个轴的参数。

2.设置开关光
输出状态为0关光,输出状态为1开光。

指令1

ZAux_Direct_SetOp

指令原型

int32 __stdcall ZAux_Direct_SetOp(ZMC_HANDLE handle, int ionum,uint32 iValue);

指令说明

打开输出口,参见软件手册里面的“OP”指令。

输入参数


参数名

描述

handle

连接句柄。

ionum

输入口编号。

piValue

设置的输出口的状态值。


输出参数

/

返回值

成功返回值为0,非0详见错误码说明。

详细说明

ZIO扩展板的IO通道号与拨码有关,起始值为(16 +拨码组合值*16),EIO总线扩展IO使用NODE_IO指令,只能设置为8的倍数,详细查看硬件手册。

注意IO映射编号要大于控制器自身最大的IO编号,不能与控制器的编号重合。

最多可操作32个输出口。

3.开关光延时

指令13

ZAux_Direct_MoveDelay

指令原型

int32  __stdcall  ZAux_Direct_MoveDelay(ZMC_HANDLE  handle, int  iaxis, int  itimems)

指令说明

运动缓冲里面写入延时。

输入参数


参数名

描述

handle

连接标识。

iaxis

轴号。

itimems

延时时间MS。


输出参数

/

返回值

成功返回值为0,非0详见错误码说明。

指令示例

ZAux_Direct_Single_Move(handle, 0, 100);//轴0正向运动100

ZAux_Direct_MoveDelay(handle, 0,1000);//轴0正向运动100后延时1s,才执行下一条缓冲

详细说明

前面的运动指令结束时速度会自动降为0,然后延时等待。

4.提前/延时开关光
正数时间延时,负数时间提前开关光。

指令14

ZAux_Direct_MoveOpDelay

指令原型

int32  __stdcall  ZAux_Direct_MoveOpDelay(ZMC_HANDLE handle, float uTime, int nAxis)

指令说明

轴缓冲中MOVEOP精准高速输出口提前/延时输出。

输入参数

参数名

描述

handle

连接标识。

uTime

延时时间MS,支持小数到us控制。

nAxis

轴号。

输出参数

/

返回值

成功返回值为0,非0详见错误码说明。

指令示例

ZAux_Direct_MoveOpDelay(handle,0,-1.5); //后面轴0的MOVE_OP输出口提前1.5ms动作。

ZAux_Direct_Single_Move(handle, 0, 100);//轴0正向运动100

ZAux_Direct_MoveOp(handle, 0,0, 1);//轴0正向运动100后把out0的状态置为1

详细说明

不影响插补轴速度曲线,只对MOVE_OP输出口进行延时操作,设置负值时表示提前输出。

5.设置激光能量(功率)
通过改变模拟量输出的电压值来控制激光能量大小。

指令7

ZAux_Direct_SetDA

指令原型

int32 __stdcall ZAux_Direct_SetDA(ZMC_HANDLE handle, int ionum, float fValue);

指令说明

打开模拟量输出口,参见软件手册里面的“AOUT”指令。

输入参数


参数名

描述

handle

连接句柄。

ionum

DA输出口编号。

fValue

设置值


输出参数

/

返回值

成功返回值为0,非0详见错误码说明。

详细说明

12位刻度值范围0~4095对应0~10V电压。

16位刻度值范围0~65536对应0~10V电压。

6.PWM占空比
通过设置PWM的占空比来调整激光频率,在开始打轨迹之前一定要先设置好。

指令4

ZAux_Direct_SetPwmDuty

指令原型

int32 __stdcall ZAux_Direct_SetPwmDuty(ZMC_HANDLE handle, int ionum, float fValue);

指令说明

pwm占空比设置,参见软件手册里面的“PWM_DUTY”指令。

输入参数


参数名

描述

handle

连接句柄。

ionum

PWM口编号。

fValue

设置值



输出参数

/

返回值

成功返回值为0,非0详见错误码说明。

详细说明

PWM只能通过设置占空比为0来关闭,不能通过设置PWM频率为0实现,PWM频率一定要在PWM开关之前调整。

占空比指有效电平占整个周期的比例。

一个周期中先输出有效电平,再输出无效电平。



PWM的实际输出受输出口的控制,必须输出口打开,PWM才能输出,否则输出被屏蔽掉。可以先开PWM功能,然后再开输出口,这样实现激光电源的首脉冲抑制功能。

7.PWM频率

指令3

ZAux_Direct_SetPwmFreq

指令原型

int32 __stdcall ZAux_Direct_SetPwmFreq(ZMC_HANDLE handle, int

ionum, float fValue);

指令说明

pwm 频率设置, 参见软件手册里面的“ PWM_FREQ”指令。

输入参数


参数名

描述

handle

连接句柄。

ionum

PWM口编号。

fValue

设置值



输出参数

/

返回值

成功返回值为0,非0详见错误码说明。

详细说明

PWM只能通过设置占空比为0来关闭,不能通过设置PWM频率为0实现,不要将频率设为0,PWM频率一定要在PWM开关之前调整。
8.振镜轴拐角延时

指令15

ZAux_Direct_SetCornerMode

指令原型

int32 __stdcall ZAux_Direct_SetCornerMode(ZMC_HANDLE handle, int iaxis, int iValue);

指令说明

设置振镜轴SCAN指令拐角延时模式。针对非Scan运动指令意义不同。

输入参数


参数名

描述

handle

连接句柄。

iaxis

轴号。

iValue

模式设置





描述

0

1

预留

1

2

自动拐角延时





输出参数

/

返回值

成功返回值为0,非0详见错误码说明。

详细说明

mode:不同的位代表不同的意义,位可以同时使用。





描述

0

1

预留

1

2

自动拐角延时

拐角延时时间以ZSmooth值为最大参考时间根据DECEL_ANGLE和STOP_ANGLE值线性的计算减速时间。

拐角时间=(拐角角度-DECEL_ANGLE)/(STOP_ANGLE-DECEL_ANGLE)*ZSmooth
9.拐角延时起始角度

指令16

ZAux_Direct_SetDecelAngle

指令原型

int32 __stdcall ZAux_Direct_SetDecelAngle(ZMC_HANDLE handle, int iaxis, float fValue);

指令说明

设置拐角减速角度,开始减速角度,单位为弧度。

输入参数


参数名

描述

handle

连接句柄。

iaxis

轴号。

fValue

设置的拐角减速角度。



输出参数

/

返回值

成功返回值为0,非0详见错误码说明。

详细说明

拐角延时时间以ZSMOOTH为参考,一定要设置合理的FORCE_SPEED。

角度转换弧度公式:角度值*(PI/180)

减速角度是指电机的参考角度相对上一条运动的变化值。如下图。

此角度值不是实际轨迹的角度,是换算到电机变换的角度,此角度值仅为参考。



下一插补运动轨迹处于下方时取绝对值。

直线与圆弧相连时按照圆弧的切线方向计算角度。

与STOP_ANGLE一起使用,当实际运动的角度处于DECEL_ANGLE(上限)与STOP_ANGLE(下限)之间线性自动计算延时时间。

10.拐角延时结束角度

指令17

ZAux_Direct_SetStopAngle

指令原型

int32 __stdcall ZAux_Direct_SetStopAngle(ZMC_HANDLE handle, int iaxis, float pfValue);

指令说明

设置停止减速角度。

输入参数


参数名

描述

handle

连接句柄。

iaxis

轴号。

pfValue

停止减速角度。



输出参数

/

返回值

成功返回值为0,非0详见错误码说明。

详细说明

拐角延时时间以ZSMOOTH为参考,一定要设置合理的FORCE_SPEED。

角度转换弧度公式:角度值*(PI/180)

减速角度是指电机的参考角度相对上一条运动的变化值。如下图。

此角度值不是实际轨迹的角度,是换算到电机变换的角度,此角度值仅为参考。



下一插补运动轨迹处于下方时取绝对值。

直线与圆弧相连时按照圆弧的切线方向计算角度。

与STOP_ANGLE一起使用,当实际运动的角度处于DECEL_ANGLE(上限)与STOP_ANGLE(下限)之间线性自动计算延时时间。。
二、程序流程

先建立控制器通讯,获取连接句柄,激光器选择及参数设置,然后编辑红光与激光口控制开关,运动参数设置,轨迹参数进行小线段处理,开始运动,停止运动。




三、主要程序展示

初始化定义相关变量,初始化轴参数,配置好FIBER转接板的方向为输出,后续的激光轨迹加工控制由按钮触发。
在运动之前我们要设置好空移速度、打标速度、开关光延时、轨迹圆半径、标刻行列数、圆心距等参数。运动开始直接调用这些相关参数执行,获取完轨迹后调用3次文件执行。

1.初始化408FIBER转换板针脚定义,不同激光器类型定义一套不同的输出口,输出口可以在选择激光器类型后对应在界面上进行修改。
408 FIBER转换板参数初始化程序:
void CZmc_fontToMoveDlg::OnCbnSelchangeComboLaser(){// TODO: 在此添加控件通知处理程序代码    UpdateData(TRUE);if(m_nLaserType == FIBER_408)  //408 FIBER转换板参数设置    {char  cmdbuffAck[2048] = "";int iresult = ZAux_Execute(m_Handle,"EXIO_DIR(0, $8FFFF)",cmdbuffAck,2048);        m_nEnableIO = 47;  //使能io        m_nLaserIO = 8;    //出关io        m_nRedIO = 48;     //红光io        m_nAout = 3;       //功率io        m_nPwmIo = 9;      //频率io    }elseif(m_nLaserType == YLR_408)    {        m_nEnableIO = 31;  //使能io        m_nLaserIO = 8;    //出关io        m_nRedIO = 32;     //红光io        m_nAout = 2;       //功率io        m_nPwmIo = 9;      //频率io    }elseif(m_nLaserType == YAG_408)  //408 YAG转换板参数设置    {char  cmdbuffAck[2048] = "";int iresult = ZAux_Execute(m_Handle,"EXIO_DIR(0, $AFBBF)",cmdbuffAck,2048);        m_nEnableIO = 47;   //使能io        m_nLaserIO = 8;     //出关io        m_nRedIO = 48;      //红光io        m_nAout = 3;        //功率io        m_nPwmIo = 9;      //频率io    }elseif(m_nLaserType == FIBER_504)    //504    {        m_nEnableIO = 5;    //使能io        m_nLaserIO = 6;     //出关io        m_nRedIO = 28;     //红光io        m_nAout = 2;      //功率io        m_nPwmIo = 7;     //频率io    }    UpdateData(FALSE);}2.设置拐角延时与激光功率,再调用运动执行,程序如下。void CZmc_fontToMoveDlg::OnBnClickedBtnMove(){// TODO: 在此添加控件通知处理程序代码    UpdateData(TRUE);//设置拐角减速此ZSMOOTH为拐角延时int iresult = ZAux_Direct_SetCornerMode(m_Handle,SCAN_AxisX,2);  //设置精准输出    iresult = ZAux_Direct_SetParam(m_Handle,"AXIS_ZSET",SCAN_AxisX,3);      //设置拐角延时    iresult = ZAux_Direct_SetZsmooth(m_Handle,SCAN_AxisX,m_nCorDelay);      //设置拐角起始角度,减速时间在DecelAngle-StopAngle线性变化    iresult = ZAux_Direct_SetDecelAngle(m_Handle,SCAN_AxisX,0);            //设置拐角结束角度    iresult = ZAux_Direct_SetStopAngle(m_Handle,SCAN_AxisX,90/180*3.1415926);       //设置激光功率    iresult = ZAux_Direct_SetDA(m_Handle,m_nAout,m_nAoutVal);          //设置激光频率    iresult = ZAux_Direct_SetPwmDuty(m_Handle,m_nPwmIo,0.5);            iresult = ZAux_Direct_SetPwmFreq(m_Handle,m_nPwmIo,m_nPwmFreq);    //获取轨迹数据,(0,0)为圆外接起点,5*5间距画半径为5的小圆    Cal_WorkData(m_fStartX, m_fStartY, m_nStepDis, m_nColNum, m_nRowNum, m_fRadius);         Run_3FileMode();}
3.圆弧转小线段是将我们的设置的圆弧轨迹转换为小线段存起来,然后转换后由3次文件的形式加载执行。

圆弧转小线段程序如下:
void CZmc_fontToMoveDlg::Cal_WorkData(float fStartX, float fStartY, float iStepDis, int iColNum, int iRowNum, float fRadius){//圆弧转小线段int ilen = -1;double ArcX;double ArcY;//获取单个整圆转换长度int iret = ZMotionOptimize_TransArcSeges(m_Handle,fStartX - fRadius, fStartY,  fStartX + fRadius, fStartY + 2 * fRadius, 0, -2 * PI, m_refDistance, &ArcX, &ArcY, &ilen);if (iret != 0 || ilen < 0)    {        CString StrErr;        StrErr.Format("圆弧转小线段失败错误码:%d",iret);        MessageBox(StrErr);return;    }double *ArcToLineX;double *ArcToLineY;    ArcToLineX = (double*)malloc(sizeof(double)*ilen);    ArcToLineY = (double*)malloc(sizeof(double)*ilen);//获取数据    iret = ZMotionOptimize_TransArcSeges(m_Handle, fStartX - fRadius, fStartY, fStartX + fRadius, fStartY + 2 * fRadius, 0, -2 * PI, m_refDistance, ArcToLineX, ArcToLineY, &ilen);//轨迹总长度    m_GraphTotalLen = ilen * iColNum * iRowNum;    m_GraphData  = (struct_GraphPos*)malloc(sizeof(struct_GraphPos)*m_GraphTotalLen);    //申请分配内存//填写数据int iAcr = 0;for (int icol = 0; icol < iColNum ; icol++)    {for(int irow = 0 ;irow<iRowNum;irow++)        {for (int i = 0; i < ilen; i++)            {                m_GraphData[iAcr * ilen + i].itype = 1;if (i == 0)                {                    m_GraphData[iAcr * ilen + i].itype = 0;     //空移起点                }                m_GraphData[iAcr * ilen + i].fposx = (float)ArcToLineX + iStepDis * irow  ;                m_GraphData[iAcr * ilen + i].fposy = (float)ArcToLineY + iStepDis * icol;            }        iAcr++;        }    }free(ArcToLineX);free(ArcToLineY);}
4.这里程序完成空移,然后移动完成之前,如果下一条运动指令执行的是轨迹运动,那么提前将激光打开。
//空移到打标点起始点void CZmc_fontToMoveDlg::Zscan_Z3pFile_StartString(struct_GraphPos *iGraphData){char  cmdbuff[2048] = "";      char  tempbuff[2048] = "";//生成命令sprintf(tempbuff, "BASE(%d,%d)\n",SCAN_AxisX,SCAN_AxisY);    //设置打标轴strcat(cmdbuff, tempbuff);//空移到起点sprintf(tempbuff, "FORCE_SPEED = %f\n",m_dEmpSpeed);    //设置空移速度strcat(cmdbuff, tempbuff);sprintf(tempbuff, "MOVESCANABS(%f,%f)\n",(*iGraphData).fposx,(*iGraphData).fposy);    //移动strcat(cmdbuff, tempbuff);//设置提前开光if (m_nStartDelay < 0)      //提前出光    {sprintf(tempbuff, "MOVEOP_DELAY = %f\n",m_nStartDelay/1000);strcat(cmdbuff, tempbuff);    }else    {sprintf(tempbuff, "MOVE_DELAY(%f)\n",m_nStartDelay/1000);strcat(cmdbuff, tempbuff);    }//开光sprintf(tempbuff, "MOVE_OP(%d,1)\nMOVE_DELAY(10)\nMOVE_OP(%d,1)\n",m_nEnableIO,m_nLaserIO);  strcat(cmdbuff, tempbuff);//判断命令长度是否发送strcat(g_MoveStr,cmdbuff);    Zscan_Z3pFile_Down();}
//生成打标直线段字符串void CZmc_fontToMoveDlg::Zscan_Z3pFile_LineString(struct_GraphPos *iGraphData){char  cmdbuff[2048] = "";      char  tempbuff[2048] = "";//生成命令//空移到起点sprintf(tempbuff, "FORCE_SPEED = %f\n",m_dSpeed);    //设置打标速度strcat(cmdbuff, tempbuff);sprintf(tempbuff, "MOVESCANABS(%f,%f)\n",(*iGraphData).fposx,(*iGraphData).fposy);    //移动strcat(cmdbuff, tempbuff);//判断命令长度是否发送strcat(g_MoveStr,cmdbuff);    Zscan_Z3pFile_Down();}
5.延时关光是在打标轨迹完成后,将激光延时关闭。

延时关光程序如下:
void CZmc_fontToMoveDlg::Zscan_Z3pFile_EndString(struct_GraphPos *iGraphData){char  cmdbuff[2048] = "";      char  tempbuff[2048] = "";//生成命令sprintf(tempbuff, "FORCE_SPEED = %f\n",m_dEmpSpeed);    //设置空移速度strcat(cmdbuff, tempbuff);sprintf(tempbuff, "MOVESCANABS(%f,%f)\n",(*iGraphData).fposx,(*iGraphData).fposy);    //移动strcat(cmdbuff, tempbuff);//延时关光if(m_nLastDelay >0)    {//延时关光sprintf(tempbuff, "MOVEOP_DELAY = 0\nMOVE_DELAY(%f)\n",m_nLastDelay/1000);strcat(cmdbuff, tempbuff);    }else    {sprintf(tempbuff, "MOVEOP_DELAY = %f\n",m_nLastDelay/1000);strcat(cmdbuff, tempbuff);    }//关光sprintf(tempbuff, "MOVE_OP(%d,OFF)\n",m_nLaserIO);  strcat(cmdbuff, tempbuff);//判断命令长度是否发送strcat(g_MoveStr,cmdbuff);    Zscan_Z3pFile_Down();}
四、最终效果
首先点击下拉框选择控制器IP,点击连接,依次设置好激光器参数、运动参数,设置好后输入打轨迹的参数,点击运动开始打圆形轨迹,点击停止结束。


通过Zdevelop软件的示波器采样运动结果:先从其他位置空移到起始位置,然后提前1ms开光,走完一个圆形轨迹,关闭激光(延时关光),再空移到下一个圆形轨迹的起点,开光(提前1ms开光),又走完一个轨迹后,关光(延时5ms关光),如此循环执行,直到设置的行列数打完停止(打轨迹中也能点击停止)。



XY模式下的轨迹,轨迹包括了圆形打标轨迹和空走轨迹:



实际效果运行视频:



video: https://mp.weixin.qq.com/mp/readtemplate?t=pages/video_player_tmpl&action=mpvideo&auto=0&vid=wxv_2619208335883681793
代码获取地址



本次,正运动技术开放式激光振镜运动控制器:C++快速开发 ,就分享到这里。

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

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

关于正运动技术

正运动技术专注于运动控制技术研究和通用运动控制软硬件产品的研发,是国家级高新技术企业,主要产品有运动控制器、运动控制卡、视觉运动控制一体机、人机界面以及扩展模块等。正运动技术汇集了来自华为、中兴等公司的优秀人才,在坚持自主创新的同时,积极联合各大高校协同运动控制基础技术的研究,是国内工控领域发展最快的企业之一,也是国内少有、完整掌握运动控制核心技术和实时工控软件平台技术的企业。
正运动技术背靠蓬勃发展的制造业,与时俱进,富有创新,致力于智能制造设备商和终端用户不断提升技术应用和制造水平。经过众多合作伙伴多年的应用开发,产品广泛应用于国内外的3C电子、半导体、印刷包装、纺织服装、激光加工、机械加工、机器人、新能源、医疗保健、舞台娱乐等领域。



- END -

热门文章

25家工控企业总市值排行榜

入门:工业机器人主要参数
2022上半年工控大事件盘点

新控制架构:边缘与云连接


汇川伺服电机年产1100万套

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册哦

x
您需要登录后才可以回帖 登录 | 注册哦

本版积分规则