The value of Zmotion is to bring customers more success!
今天,正运动技术为大家分享一下应用C++开发一个激光振镜的运动控制例程。
我们主要从新建MFC项目,添加函数库讲起,最后通过项目实战——激光振镜打标例程讲解,来让大家熟悉它的项目开发。
在正式学习之前,我们先了解一下正运动技术的运动控制器ZMC420SCAN。这款产品是20轴运动控制器。
ZMC420SCAN 总线控制器支持 ECAT/RTEX 总线连接,支持多达20轴运动控制,支持直线插补、任意圆弧插补、空间圆弧、螺旋插补、电子凸轮、电子齿轮、同步跟随、虚拟轴设置等;采用优化的网络通讯协议可以实现实时的运动控制。
ZMC420SCAN 总线控制器支持脉冲轴/总线轴/振镜轴混合插补。
ZMC420SCAN 支持10路脉冲输出与编码器反馈且支持4路振镜轴,板载24点输入,12点输出,2AD,2DA,所有输出口都支持高速PWM控制。
接线方式如下图1所示:
图1
ZMC420SCAN使用一套API函数,支持C、C++、C#、LabVIEW、Python、Delphi等开发语言,支持VC6.0、VB6.0、Qt、.Net等平台,支持Windows、Linux、WinCE、iMac等操作系统。
图2
ZMC420SCAN 的PWM 输出受正常输出功能的控制,输出口“ON”状态下才能进行PWM输出,便于控制激光能量。
ZMC420SCAN 的输出0-7的具有精准输出的功能,每个输出的精准输出功能相互独立,通过MOVEOP_DELAY 与AXIS_ZSET ,来设置每个MOVE_OP 指令是否使用精准输出以及精准输出的延时,从而实现激光的PSO 控制。
ZMC420SCAN 的输出0-7支持精准输出且相互独立,通过指令:MOVE_OP,AXIS_ZSET,MOVEOP_DELAY来分别控制激光的开关,精准输出开关及延时,从而实现激光PSO控制。
振镜轴:
ZMC420SCAN支持XY2-100振镜协议,支持运动控制与振镜联合插补运动。
上位机通过网口与控制器相连,获取对应控制器的句柄,通过XY2-100协议控制振镜轴,通过总线协议或者脉冲模式控制伺服或步进轴。
本地轴号4/5可以ATYPE=21 配置为第1个振镜, 本地轴号6/7可以ATYPE=21 配置为第2个振镜,可通过 AXIS_ADDRESS 配置轴号。
以下是激光振镜
控制开发流程
一 新建MFC项目 添加函数库
1.在VS2017菜单“文件”→“新建”→“项目”,启动创建项目向导。
2.选择开发语言为“Visual C++”和程序类型“MFC/ATL”中的“MFC应用程序”。
3.选择类型为“基于对话框”,下一步或者完成。下一步则往后继续配置,完成就直接完成即可。把类型选好,其他的可以在项目中编辑。
4.找到厂家提供的光盘资料,路径如下(64位库为例):
A.进入光盘资料找到PC函数文件夹。
B.选择函数库2.1。
C.Windows平台。
D.根据需要选择对应的函数库这里选择64位库。
E.解压C++的压缩包,里面有C++对应的函数库。
F.函数库具体路径如下。
5.将厂商提供的C++的库文件和相关头文件复制到新建的项目里面。
6.在项目中添加静态库和相关头文件。
静态库:zauxdll.lib, zmotion.lib
相关头文件:zauxdll2.h, zmotion.h
A.先右击头文件,接着依次选择:“添加”→“现有项”。
B.在弹出的窗口中依次添加静态库和相关头文件。
7.声明用到的头文件和定义控制器连接句柄。
至此项目新建完成。
二 查看PC函数手册 了解其用法
1.PC函数手册也在光盘资料里面,具体路径如下:
2.PC编程,一般先根据控制器连接方式选择对应的连接函数连接控制器,返回控制器句柄。接着用返回的控制器句柄,实现对控制器的控制。
3.比如通过网口连接控制器,先使用ZAux_OpenEth()链接控制器,获取控制器句柄handle。
4.通过获取到的控制器句柄handle,对控制器进行激光振镜轴类型的设置。
第三个参数的值有以下的模式选择,使用振镜轴需选择轴类型为21的模式,设置轴为振镜轴类型,振镜轴类型系统周期与刷新周期都要比普通轴快很多。
5.通过获取到的控制器句柄handle,控制控制器的振镜轴进行多轴运动控制,可以进行搭配振镜轴与普通轴进行混合插补运动。
三 项目实操之激光振镜打标例程
1.例程以建立板卡的连接,并设置振镜轴的拐角减速以及速度参数,对内部进行设置的运动轨迹进行处理完成对圆形的打标。
2.例程简易流程图。
3.通过网口连接控制器,获取控制器连接句柄。
//ip连接
void CMarkDemoDlg::OnBnClickedButton2()
{
// TODO: 在此添加控件通知处理程序代码
char buffer[256];
char item[256] = {0};
float ftemp = 0.0;
char atemp[256] = {0}; //存放控制器型号
uint32 uitemp = 0;
int32 iresult;
if(NULL != g_handle)
{
ZMC_Close(g_handle);
g_handle = NULL;
}
GetDlgItemText(IDC_IP_COMBO,buffer,255); //获取当前框内的IP地址
buffer[255] = '\0';
iresult = ZMC_OpenEth(buffer, &g_handle); //获取与控制器建立连接的结果
if(ERR_SUCCESS != iresult)
{
g_handle = NULL;
MessageBox(_T("Connect Failed"));
SetWindowText(_T("ZControlTest-Connect Failed"));
return;
}
SetWindowText("succse");
//
CComboBox *m_pEthList;
m_pEthList = (CComboBox *)GetDlgItem(IDC_IP_COMBO); //获取ip地址
if(NULL == m_pEthList)
{
return;
}
//
if(CB_ERR != m_pEthList->FindString(0, buffer))
{
return;
}
//加入
m_pEthList->AddString(buffer); //将ip地址加入框内
}
4.通过串口连接控制器,获取控制器连接句柄。
void CMarkDemoDlg::OnBnClickedButton4()
{
// TODO: 在此添加控件通知处理程序代码
int32 iresult;
uint8 icomid;
float ftemp = 0.0;
char atemp[256] = {0}; //存放控制器型号
uint32 uitemp = 0;
int m_icombaud;
if(NULL != g_handle)
{
ZMC_Close(g_handle);
g_handle = NULL;
}
CComboBox *m_pParityList;
m_pParityList = (CComboBox *)GetDlgItem(IDC_COMBO_PARITY);
m_icombaud = GetDlgItemInt(IDC_BAUD_COMBO);
ZMC_SetComDefaultBaud(m_icombaud, 8, m_pParityList->GetCurSel(), ONESTOPBIT);
icomid = GetDlgItemInt(IDC_PORT_COMBO);
iresult = ZMC_OpenCom(icomid, &g_handle);
if(ERR_SUCCESS != iresult)
{
g_handle = NULL;
MessageBox(_T("Connect Failed"));
return;
}
SetWindowText("success");
CString Comname;
CComboBox *m_pComList;
m_pComList = (CComboBox *)GetDlgItem(IDC_PORT_COMBO);
if(NULL == m_pComList)
{
return;
}
Comname.Format("%d",icomid);
//
if(CB_ERR != m_pComList->FindString(0, Comname))
{
return;
}
//加入
m_pComList->AddString(Comname);
}
5.利用生成的句柄进行配置轴参数,轴类型等。
int axislist[2] = {4,5};
char cbuf[32] = {};
//设置主轴
ZAux_Direct_Base(g_handle, 2, axislist);
//获取编辑框内要设置的参数
int MachSpeed = GetDlgItemInt(IDC_EDIT_SPEED);
int MachAddSpeed = GetDlgItemInt(IDC_EDIT_ADDSPEED);
int MachDecSpeed = GetDlgItemInt(IDC_EDIT_DECSPEED);
float MachDecAngle = GetDlgItemInt(IDC_EDIT_DECANGLE) * 3.14 / 180;
float MachStopAngle = GetDlgItemInt(IDC_EDIT_STOPANGLE) * 3.14 / 180;
//轴初始化
for (int i = 4; i <= 5; i++)
{
//设置轴类型为振镜轴类型
ZAux_Direct_SetAtype(g_handle, i, 21);
//设置每圈脉冲数
ZAux_Direct_SetUnits(g_handle, i, 300);
//设置速度
ZAux_Direct_SetSpeed(g_handle, i, MachSpeed);
//设置加速度
ZAux_Direct_SetAccel(g_handle, i, MachAddSpeed);
//设置减速度
ZAux_Direct_SetDecel(g_handle, i, MachDecSpeed);
//打开振镜轴连续插补
ZAux_Direct_SetMerge(g_handle, i, 1);
//设置拐角减速模式以及自动倒角模式
ZAux_Direct_SetCornerMode(g_handle, i, 32+2);
//设置拐角半径
ZAux_Direct_SetZsmooth(g_handle, i, 0.1);
//设置小圆限速半径
ZAux_Direct_SetFullSpRadius(g_handle, i, 20);
//设置减速角度
ZAux_Direct_SetDecelAngle(g_handle, i, MachDecAngle);
//设置停止角度
ZAux_Direct_SetStopAngle(g_handle, i, MachStopAngle);
//设置SP速度
ZAux_Direct_SetForceSpeed(g_handle, i, 5000);
}
//打开精准输出功能
ZAux_DirectCommand(g_handle, "AXIS_ZSET(4)=2", cbuf, 32);
ZAux_Direct_SetOp(g_handle, 11, 1);
ZAux_Direct_Base(g_handle, 2, axislist);
ZAux_Direct_SetOp(g_handle, 1, 1);
6.本例程的轨迹移动数据都是以小线段的模式自己输入的,运行的过程中利用了多段小线段进行圆弧拟合的方式进行加快速度的处理操作。
单个圆CAD轨迹图:
对应部分轨迹数据以及使用代码如下:
//单个圆相对
double x1[] = {-0.038000, -0.113000, -0.184000, -0.250000, -0.308000, -0.357000, -0.395000, -0.421000, -0.434000, -0.434000, -0.421000, -0.395000, -0.357000, -0.308000, -0.250000, -0.184000, -0.113000, -0.038000, 0.038000, 0.113000, 0.184000, 0.250000, 0.308000, 0.357000, 0.395000, 0.421000, 0.434000, 0.434000, 0.421000, 0.395000, 0.357000, 0.308000, 0.250000, 0.184000, 0.113000, 0.038000};
double yh1[] = {0.434000, 0.421000, 0.395000, 0.357000, 0.308000, 0.250000, 0.184000, 0.113000, 0.038000, -0.038000, -0.113000, -0.184000, -0.250000, -0.308000, -0.357000, -0.395000, -0.421000, -0.434000, -0.434000, -0.421000, -0.395000, -0.357000, -0.308000, -0.250000, -0.184000, -0.113000, -0.038000, 0.038000, 0.113000, 0.184000, 0.250000, 0.308000, 0.357000, 0.395000, 0.421000, 0.434000};
小线段转圆弧函数说明:
/*************************************************************
Description: //小线段变为圆弧
Input: //handle:连接的控制器句柄
//pXPos:线段的x坐标数组
//pYPos:线段的y坐标数组
//nMaxNum:最大点数
//nMaxFitNum:最大拟合段数(100~1000)
//nAbs:1=绝对;0=相对;表示传入的x、y坐标数据为绝对还是相对
//refDistance:参考精度
Output: //
Return: //错误码
*************************************************************/
int __stdcall ZGraphProcess_SegFitArc(ZMC_HANDLE handle, double *pXPos, double *pYPos, int nMaxNum, int nMaxFitNum, int nAbs, double refDistance);
使用此函数将多段小线段拟合成圆弧简化操作步骤,不用单独进行每段小线段的插补运动操作。此函数为内部函数,如有需求联系请正运动技术工程师给予支持。
代码中利用单个圆拟合进行横纵循环打标阵列圆的方式进行打标。
int axislist[2] = {4,5};
char cbuf[32] = {};
//设置主轴
ZAux_Direct_Base(g_handle, 2, axislist);
for (int k = 0; k < 1; k++)
{
for (int i = 0; i < 5; i++)
{
//移动到一个指定位置
ZAux_DirectCommand(g_handle, "MOVE (0, -15)", cbuf, 32);
for (int j = 0; j < 5; j++)
{
ZAux_DirectCommand(g_handle, "MOVE (-15, 0)", cbuf, 32);
ZAux_Direct_MoveOp(g_handle, 0, 1);
//进行小线段转圆弧
int err_seg = ZGraphProcess_SegFitArc(g_handle, x1, yh1, sizeof(x1)/sizeof(double), 1000, 0, 0.01);
ZAux_Direct_MoveOp(g_handle, 0, 0);
}
ZAux_DirectCommand(g_handle, "MOVE (75, 0)", cbuf, 32);
}
ZAux_DirectCommand(g_handle, "MOVE (0, 75)", cbuf, 32);
}
7.编译运行演示。
(1)编译运行示教例程。
(2)同时通过ZDevelop软件连接同一个控制器,对运动控制的轴参数进行监控。
标刻25个圆形用时以及示波器显示图形如下:
标刻25个圆形用时以及示波器显示图形
正运动技术激光振镜演示实拍
本次,正运动技术的运动控制卡应用开发教程之激光振镜控制就分享到这里,更多精彩内容请关注“正运动小助手”公众号。
本文由正运动技术原创,欢迎大家转载,共同学习,一起提高中国智能制造水平。文章版权归正运动技术所有,如有转载请注明文章来源。