Windows实时运动控制软核(二):LOCAL高速接口测试之Qt
供稿:深圳市正运动技术有限公司
- 关键词:运动控制器,运动控制卡,MotionRT7
- 作者:正运动
- 摘要:Windows下运动控制实时内核MotionRT7的安装和Qt接口的使用。
01
MotionRT7简介
(2)与MotionRT其它版本功能兼容,一次开发,可快速切换到嵌入式,Linux各种平台。
(3)统一函数库接口,快速的本地LOCAL接口,运动函数调用快至us级别,比普通PCI卡快数十倍。
(4)集成机器视觉,快速搭建各类运动控制+机器视觉的实时应用。
(5)强大多卡功能,最多240 轴联动,支持跨卡联动,脉冲与总线联动,振镜与平台联动,轻松实现位置锁存 / PSO 等高级功能。
2.持续迭代的运动控制实时内核MotionRT
MotionRT是正运动技术持续建设与发展的运动控制实时内核,已不断迭代了 7代,从 MotionRT1到 MotionRT7。
统一完善的SDK库 ,所有的第三方开发环境同一套API接口,跨平台的产品架构,提高效率,保持兼容性。
5.简单易用的运动控制功能
功能特性:
a.点位运动、直线插补、圆弧插补、螺旋插补、连续轨迹加工;
b.电子凸轮、电子齿轮、同步跟随、位置锁存、虚拟轴叠加;
c.S曲线加减速,SS曲线加减速,轨迹运动更柔和;
d.1D/2D/3D高速位置同步输出PS0,充分满足视觉飞拍、高速点胶、激光加工;
e.客户可自定义运动控制算法或者机器人正反解算法;
f. 方便与第三方视觉配合。
6.开放的EtherCAT与配置调试工具
02
MotionRT7的安装和使用
第一步:安装驱动程序
第二步:运行控制台程序
第三步:使用ZDevelop软件链接到控制器,进行参数监控
在RT控制台程序选择增加AddEcat,这时能看到对应网卡,选择上,然后启动RT。
5. MotionRT7 EtherCAT协议安装视频演示。
03
Qt Creator进行MotionRT7项目的开发
1.新建Qt项目。
2.将zmcaux.cpp、zmcaux.h、zmotion.dll、zmotion.lib、zmotion.h这5个文件放到刚刚创建的Qt项目文件夹下。 以上资料可通过百度网盘下载或联系正运动相关人员获取。
3.添加外部静态库“zmotion.lib”。
(1)右击项目文件夹,点击“添加库”。
在Qt的设计师界面,找到需要用到的 控件拖拽到窗体中进行UI界面设计,效果如下。
注:使用IP模式连接MotionRT7的时候,要将MotionRT710中的Config配置项Eth num的值设置为一个大于0的数(1-12),输入的ip为本机ip,可以在ZDevelop中直接查看。
(3)相关代码
//IP链接方式链接控制器 void MainWindow::on_IpLiskButton_clicked() { //如果链接处于断开状态 if(g_handle == NULL) { //获取下拉框里面的IP地址 QString ipAddressBuff=ui->comBoxIpList->currentText(); QByteArray ba = ipAddressBuff.toLatin1(); char *ipAddress; ipAddress=ba.data(); //连接控制器 iresult =ZAux_OpenEth(ipAddress,&g_handle); //更新链接状态 if(iresult == 0) { ui->LocalLinkStatus->setText("未链接"); ui->LocalLinkStatus->setStyleSheet("background-color: MistyRose"); ui->IpLinkStatus->setText("链接成功"); ui->IpLinkStatus->setStyleSheet("background-color: PaleGreen"); } } else { QMessageBox::critical(this, "错误", QString("请先点击断开链接按钮再进行链接操作")); } }
b.通过LOCAL链接方式的链接按钮的 槽函数来链接控制器。
//Local链接方式链接控制器 void MainWindow::on_LocalLinkButton_clicked() { //如果链接处于断开状态 if(g_handle == NULL) { //获取下拉框里面的Local连接的字符串 QString LocalAddressBuff=ui->comBoxLocal->currentText(); QByteArray ba = LocalAddressBuff.toLatin1(); char *LocalAddress; LocalAddress=ba.data(); //连接控制器 iresult = ZAux_FastOpen(ZMC_CONNECTION_LOCAL,LocalAddress,3000,&g_handle); //更新链接状态 if(iresult == 0) { ui->LocalLinkStatus->setText("链接成功"); ui->LocalLinkStatus->setStyleSheet("background-color: PaleGreen"); ui->IpLinkStatus->setText("未链接"); ui->IpLinkStatus->setStyleSheet("background-color: MistyRose"); } } else { QMessageBox::critical(this, "错误", QString("请先点击断开链接按钮再进行链接操作")); } }
c.通过断开按钮的槽函数来断开控制器的链接。
//断开上位机与控制器的链接 void MainWindow::on_CloseLinkButton_clicked() { //停止所有轴运动 iresult =ZAux_Direct_Rapidstop(g_handle,2); //断开控制器的链接 iresult = ZAux_Close(g_handle); }
d. 通过总线初始化按钮的槽函数对总线驱动器进行初始化 。
//总线扫描 void MainWindow::on_EcatAxisInitButton_clicked() { if(g_handle !=NULL) { int Err; //扫描槽位号0上的总线设备,设备数为1,超时时间为3000ms。 Err = ZAux_BusCmd_EcatScan(g_handle,0,1,3000); if(Err!=0) { if(Err == -2) { QMessageBox::critical(this, "总线扫描失败", QString("扫描超时")); } else if(Err == -1) { QMessageBox::critical(this, "总线扫描失败", QString("节点数目不一致")); } else { QMessageBox::critical(this, "总线扫描失败", QString("其他错误,详见错误码")); } return ; } //初始化总线轴,槽位号0的起始轴号为0,轴类型设置为65,PDO模式设置为模式0 Err = ZAux_BusCmd_EcatAxisInit(g_handle,0,0,65,0); if(Err!=0) { if(Err == -1) { QMessageBox::critical(this, "总线轴使能失败", QString("总线初始化错误")); } else { QMessageBox::critical(this, "总线轴使能失败", QString("其他错误")); } } } else { QMessageBox::critical(this, "错误", QString("请先链接控制器")); } }
e. 通过单条指令交互周期的测试按钮的槽函数启动新线程,对单条指令交互的周期进行测试 。
//开启新线程,对单条指令交互的周期进行测试 void MainWindow::on_SingleTestButton_clicked() { //如果链接控制器发生错误 if (g_handle != NULL) { //处理子线程发送过来的信号 Task1 = new MyThread(); void (MyThread::*pStartTestTask)(int) = &MyThread::StartTestTask; void (MainWindow::*pSingleApiTest)(int) = &MainWindow::SingleApiTest; connect(Task1,pStartTestTask,this,pSingleApiTest); //获取测试次数 TestNum = ui->SingleTestNum->currentText().toInt(); Task1->start(); } } //Task1的run函数 void MyThread::run() { //获取测试前的系统计时器时间 StartTime=clock(); for (int j=0; j<testnum; ++j) {="" ="" 获取此时此刻轴0的位置信息="" iresult =" ZAux_Direct_GetDpos(g_handle, 0, &Dpos0);" if (iresult !=" 0)" {="" ="" api执行失败报警="" emit starttesttask(1);="" return;="" }="" else="" 发送信号给ui,更新界面显示的位置信息="" emit starttesttask(2);="" }="" ="" 获取测试后的系统计时器时间="" endtime="clock();" 单条指令的交互周期="" singleavertime="(EndTime-StartTime)*1000.0)/TestNum;" 测试总时间="" singletotaltime="EndTime-StartTime;" emit starttesttask(3);="" }