[其他] 运动控制卡应用开发教程之C++

[复制链接]
查看96059 | 回复0 | 2024-10-13 09:18:25 | 显示全部楼层 |阅读模式
今天,正运动技术为大家分享一下应用C++开发一个多段连续插补的运动控制应用。

我们主要从新建MFC项目,添加函数库讲起,再了解PC函数用法,最后通过项目实战——连续插补运动例程讲解,来让大家熟悉C++的项目开发。

在正式学习之前,我们先了解一下正运动技术的运动控制卡ECI2418和ECI2618。这两款产品分别是4轴,6轴运动控制卡。



ECI2418支持4轴脉冲输入与编码器反馈,板载24点输入,16点输出,2AD,2DA,支持手轮接口,其中特定输出口支持高速PWM控制。


ECI2618支持6轴脉冲输入与编码器反馈,板载24点输入,16点输出,2AD,2DA,支持手轮接口,其中特定输出口支持高速PWM控制。



ECI2418,ECI2618均使用同一套API函数,均支持C、C++、C#、LabVIEW、Python、Delphi等开发语言,支持VC6.0、VB6.0、Qt、.Net等平台,支持Windows、Linux、WinCE、iMac等操作系统。



以下是C++

开发流程

01

新建MFC项目,添加函数库。
1、在VS2015菜单“文件”→“新建”→ “项目”,启动创建项目向导。


2、选择开发语言为“Visual C++”和程序类型“MFC应用程序”。



3、下一步即可。



4、选择类型为“基于对话框”,下一步或者完成。
下一步则往后继续配置,完成就直接完成即可。这里就不需要再配置了,无关紧要的,只要这个类型选好就行,其他的可以在项目中编辑。


5、找到厂家提供的光盘资料,路径如下(64位库为例)。
1)进入光盘资料找到PC函数文件夹。


2)选择函数库2.1。


3)Windows平台。


4)根据需要选择对应的函数库这里选择64位库。


5)解压C++的压缩包,里面有C++对应的函数库。


6)函数库具体路径如下。


6、将厂商提供的C++的库文件和相关头文件复制到新建的项目里面。


7、在项目中添加静态库和相关头文件。静态库:zauxdll.lib, zmotion.lib相关头文件:zauxdll2.h, zmotion.h1)先右击头文件,接着依次选择:“添加”→“现有项”。


2)在弹出的窗口中依次添加静态库和相关头文件。


3)声明用到的头文件和定义控制器连接句柄。


至此项目新建完成。

02

查看PC函数手册,了解其用法。
1、PC函数手册也在光盘资料里面。
具体路径如下:



2、PC编程
先根据控制器连接方式选择对应的连接函数连接控制器,返回控制器句柄。接着用返回的控制器句柄,实现对控制器的控制。
比如通过网口连接控制器,先使用ZAux_OpenEth()链接控制器,获取控制器句柄handle。




通过获取到的控制器句柄handle,对控制器进行单轴运动控制。


通过获取到的控制器句柄handle,对控制器进行多轴运动控制。



//多轴运动int    axislist[4] = { 0,1,2,3 };          //运动BASE轴列表float  dislist[4] = { 100,100,100,100 };      //运动距离列表ZAux_Direct_Move(g_handle, 4, axislist, dislist);  //多轴运动

03

项目实战之连续插补运动例程讲解
1、例程以建立板卡的连接,执行3段连续轨迹的加工为目标。


2、例程简易流程图。


// 相关函数
ZAux_OpenEth(IP_buffer, &g_handle);//连接控制器
ZAux_Direct_GetAllAxisPara(g_handle, "DPOS", 4, showpos);//获取当前轴位ZAux_Direct_GetAllAxisPara(g_handle, "MSPEED", 4, mspeed);//更新轴速度
ZAux_Direct_Single_Cancel(g_handle, 0, 2);  //停止主轴运动
ZAux_Direct_Move(g_handle, 4, axislist, dislist1);//第1段多轴插补指令ZAux_Direct_Move(g_handle, 4, axislist, dislist2);//第2段多轴插补指令ZAux_Direct_Move(g_handle, 4, axislist, dislist3);//第3段多轴插补指令
ZAux_Close(g_handle);//断开连接3、通过网口连接控制器,获取控制器连接句柄。
//Link按钮事件处理函数void CMergeDlg::OnBnClickedButtonLink(){char   buffer[256];  int32 iresult;//如果之前有连接控制器着先断开连接if (NULL != g_handle)  {    ZAux_Close(g_handle);    g_handle = NULL;  }//从IP下拉框中获取IP  GetDlgItemText(IDC_COMBOX_IP, buffer, 255);  buffer[255] = '\0';//通过PC函数库提供的连接控制器的函数接口(API),连接控制器  iresult = ZAux_OpenEth(buffer, &g_handle);if (ERR_SUCCESS != iresult)  {    g_handle = NULL;    MessageBox(_T("链接失败"));    SetWindowText("未链接");return;  }  SetWindowText("已链接");//启动定时器  SetTimer(1, 100, NULL);  SetTimer(2, 100, NULL);//初始化轴参数for (int i = 0; i<4; i++)  {    ZAux_Direct_SetAtype(g_handle, i, 1);      //轴类型    ZAux_Direct_SetUnits(g_handle, i, 1000);    //脉冲当量     ZAux_Direct_SetSpeed(g_handle, i, 100);    //速度      ZAux_Direct_SetAccel(g_handle, i, 1000);    //加速度    ZAux_Direct_SetDecel(g_handle, i, 1000);    //减速度ZAux_Direct_SetSramp(g_handle, i, 100);    //S曲线时间  }}4、通过定时器1更新控制器轴0-3的位置信息和速度信息。//定时器void CMergeDlg::OnTimer(UINT_PTR nIDEvent){if (NULL == g_handle)  {    MessageBox(_T("链接断开"));return;  }switch (nIDEvent)  {case1: //更新控制器轴0-3的位置信息和速度信息      CString Xpos, Xmspeed;    CString Ypos, Ymspeed;    CString Zpos, Zmspeed;    CString Upos, Umspeed;    float  showpos[4] = { 0 };    float    mspeed[4] = { 0 };int    status = 0;//获取当前轴位置    ZAux_Direct_GetAllAxisPara(g_handle, "DPOS", 4, showpos);             Xpos.Format("X: %.2f", showpos[0]);    Ypos.Format("Y: %.2f", showpos[1]);    Zpos.Format("Z: %.2f", showpos[2]);    Upos.Format("U: %.2f", showpos[3]);    GetDlgItem(IDC_XPOS)->SetWindowText(Xpos);    GetDlgItem(IDC_YPOS)->SetWindowText(Ypos);    GetDlgItem(IDC_ZPOS)->SetWindowText(Zpos);    GetDlgItem(IDC_UPOS)->SetWindowText(Upos);//判断主轴状态(即BASE的第一个轴)    ZAux_Direct_GetIfIdle(g_handle, 0, &status);if (status == -1)    {      GetDlgItem(IDC_RUNSTATUS)->SetWindowText("运动状态:停止中");    }else    {      GetDlgItem(IDC_RUNSTATUS)->SetWindowText("运动状态:运动中");    }//更新轴速度    ZAux_Direct_GetAllAxisPara(g_handle, "MSPEED", 4, mspeed);    Xmspeed.Format("X轴速度: %.2f", mspeed[0]);    Ymspeed.Format("Y轴速度: %.2f", mspeed[1]);    Zmspeed.Format("Z轴速度: %.2f", mspeed[2]);    Umspeed.Format("U轴速度: %.2f", mspeed[3]);    GetDlgItem(IDC_SPEED_X)->SetWindowText(Xmspeed);    GetDlgItem(IDC_SPEED_Y)->SetWindowText(Ymspeed);    GetDlgItem(IDC_SPEED_Z)->SetWindowText(Zmspeed);    GetDlgItem(IDC_SPEED_U)->SetWindowText(Umspeed);break;  }  CDialogEx::OnTimer(nIDEvent);}5、通过启动按钮的事件处理函数来启动连续插补运动。//启动按钮void CMergeDlg::OnBnClickedButtonRun(){if (NULL == g_handle)  {    MessageBox(_T("链接断开"));return;  }  UpdateData(true);//刷新参数
int corner_mode = 0;int axislist[4] = { 0,1,2,3 };    //运动BASE轴列表float dislist1[4] = { 0 };        //运动距离列表float dislist2[4] = { 0 };float dislist3[4] = { 0 };
//选择参与运动的轴,第一个轴为主轴,插补参数全用主轴参数    ZAux_Direct_SetSpeed(g_handle, axislist[0], M_Speed);  //速度    ZAux_Direct_SetAccel(g_handle, axislist[0], M_Accel);  //加速度  ZAux_Direct_SetDecel(g_handle, axislist[0], M_Decel);  //减速度ZAux_Direct_SetSramp(g_handle, axislist[0], M_SRAMP);  //S曲线时间//设置拐角模式if (m_mode1 == 1)  {    corner_mode = corner_mode + 2;  }if (m_mode2 == 1)  {    corner_mode = corner_mode + 8;  }if (m_mode3 == 1)  {    corner_mode = corner_mode + 32;  }  ZAux_Direct_SetCornerMode(g_handle, axislist[0], corner_mode);  //设置连续插补  ZAux_Direct_SetMerge(g_handle, axislist[0], m_mode);//设置SP速度  ZAux_Direct_SetForceSpeed(g_handle, axislist[0], SP_Speed);  //设置开始.结束减速角度,转换为弧度    ZAux_Direct_SetDecelAngle(g_handle, axislist[0], StartAngle * 3.14 / 180);    ZAux_Direct_SetStopAngle(g_handle, axislist[0], StopAngle * 3.14 / 180);//设置小圆限速半径  ZAux_Direct_SetFullSpRadius(g_handle, axislist[0], SP_Radius);//设置拐角半径  ZAux_Direct_SetZsmooth(g_handle, axislist[0], CornerRadius);
//SP指令中自动拐角模式中设置一个较大的startmovespeed与endmovespeed  ZAux_Direct_SetStartMoveSpeed(g_handle, axislist[0], 10000);  ZAux_Direct_SetEndMoveSpeed(g_handle, axislist[0], 10000);//更新运动数据  dislist1[0] = DPOS_X_1; dislist1[1] = DPOS_Y_1;  dislist1[2] = DPOS_Z_1; dislist1[3] = DPOS_U_1;
  dislist2[0] = DPOS_X_2; dislist2[1] = DPOS_Y_2;  dislist2[2] = DPOS_Z_2; dislist2[3] = DPOS_U_2;
  dislist3[0] = DPOS_X_3; dislist3[1] = DPOS_Y_3;  dislist3[2] = DPOS_Z_3; dislist3[3] = DPOS_U_3;
//开始运动  ZAux_Direct_Move(g_handle, 4, axislist, dislist1);  ZAux_Direct_Move(g_handle, 4, axislist, dislist2);  ZAux_Direct_Move(g_handle, 4, axislist, dislist3);}6、通过停止按钮的事件处理函数来停止插补运动。//停止按钮void CMergeDlg::OnBnClickedButtonStop(){if (NULL == g_handle)  {    MessageBox(_T("链接断开"));return;  }  ZAux_Direct_Single_Cancel(g_handle, 0, 2);        //停止主轴 BASE的一个轴}7、轴坐标清零。//坐标清零void CMergeDlg::OnBnClickedButtonClear(){if (NULL == g_handle)  {    MessageBox(_T("链接断开"));return;  }for (int i = 0; i<4; i++)  {    ZAux_Direct_SetDpos(g_handle, i, 0);        //DPOS设为零  }}8、编译运行演示。1)编译运行示教例程。


2)同时通过ZDevelop软件连接同一个控制器,对运动控制的轴参数进行监控。A、连续插补加自动倒角的位置波形。


B、不开启连续插补的速度波形。






C、连续插补加合适的拐角减速的速度波形。






正运动技术C++开发就讲到这里。更多学习视频及图文请关注我们的公众号“正运动小助手”。
本文由正运动小助手原创,欢迎大家转载,共同学习,一起提高中国智能制造水平。文章版权归正运动技术所有,如有转载请注明文章来源。


本帖子中包含更多资源

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

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

本版积分规则