MotionRT750是正运动技术首家自主自研的x86架构Windows系统或Linux系统下独占确定CPU的强实时运动控制内核。

该方案采用独占确定CPU内核技术实现超强性能的强实时运动控制。它将核心的运动控制、机器人算法、数控(CNC)及机器视觉等强实时的任务,集中运行在1-2个专用CPU核上。与此同时,其余CPU核则专注于处理Windows/Linux相关的非实时任务。
此外集成MotionRT750 Runtime实时层与操作系统非实时层,并利用高速共享内存进行数据交互,显著提升了运动控制与上层应用间的通信效率及函数执行速度,最终实现更稳定、更高效的智能装备控制,确保了运动控制任务的绝对实时性与系统稳定性,特别适用于半导体、电子装备等高速高精的应用场合。

MotionRT750应用优势:
1.跨平台兼容性:支持Windows/Linux系统,适配不同等级CPU。
2.开发灵活性:提供多语言编程接口,便于二次开发与功能定制。
3.实时性提升:通过CPU内核独占机制与高效LOCAL接口,实现2-3us指令交互周期,较传统PCI/PCIe方案提速近20倍。
4.扩展能力强化:多卡多EtherCAT通道架构支持254轴运动控制及500usEtherCAT周期。
5.系统稳定性:32轴125usEtherCAT冗余架构消除单点故障风险,保障连续生产。
6.安全可靠性:不惧Windows系统崩溃影响,蓝屏时仍可维持急停与安全停机功能有效,确保产线安全运行。
7.功能扩展性:实时内核支持C语言程序开发,方便功能拓展与实时代码提升效率。
更多关于MotionRT750的详情介绍与使用点击→强实时运动控制内核MotionRT750(一):驱动安装、内核配置与使用。
XPCIE6032H运动控制卡集成6路独立EtherCAT主站接口。整卡最高可支持254轴运动控制;125usEtherCAT通讯周期时,两个端口配置冗余最高可支持32轴运动控制。6个EtherCAT主站各通道独立工作,多EtherCAT主站互不影响。


XPCIE6032H运动控制卡面向半导体设备、精密3C电子、生物医疗仪器、新能源装备、人形机器人及激光加工等高速高精场景,为固晶机、贴片机、分选机、锂电切叠一体机、高速异形插件设备等自动化装备提供核心运动控制支持。
XPCIE6032H硬件特性:
1.EtherCAT通讯周期可到125us(需要主机性能与实时性足够)。
2.板卡集成6路独立的EtherCAT主站接口,最多可支持254轴运动控制。
3.搭载运动控制实时内核MotionRT750。
4.相较于传统的PCI/PCIe、网口等通讯方式,速度可提升了10-100倍以上。
5.板载16路高速输入,16路高速输出。
6.板载4路高速锁存,4路通用PWM输出。
更多关于XPCIE6032H的详情介绍与使用点击→全球首创!PCIe超实时6通道EtherCAT运动控制卡上市!。
XPCIE2032H集成2路独立EtherCAT接口。整卡最高可支持至254轴运动控制;125usEtherCAT通讯周期时,单接口最高可支持32轴运动控制。2个EtherCAT主站各通道独立工作,多EtherCAT主站互不影响。

双EtherCAT主站端口可任意设置为以下通道,且两个端口也设置为不同类型通道:
● 高速通道 - EtherCAT通讯周期125us
● 常规通道 - EtherCAT通讯周期250us-8ms


XPCIE2032H硬件特性:
1.EtherCAT通讯周期可到125us(需要主机性能与实时性足够)。
2.板卡集成2路独立的EtherCAT主站接口,最多可支持254轴运动控制。
3.搭载运动控制实时内核MotionRT750。
4.相较于传统的PCI/PCIe、网口等通讯方式,速度可提升了10-100倍以上。
5.板载8路高速输入,16路高速输出。
6.板载4路高速锁存,4路通用PWM输出。
更多关于XPCIE2032H的详情介绍与使用点击→高速高精运动控制!PCIe超实时2通道EtherCAT运动控制卡上市!。
XPCIE1032H是一款基于PCI Express的EtherCAT总线运动控制卡,可选6-64轴运动控制,支持多路高速数字输入输出,可轻松实现多轴同步控制和高速数据传输。


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

XPCIE1032H硬件特性:
1.6-64轴EtherCAT总线+脉冲可选,其中4路单端500KHz脉冲输出。
2.16轴EtherCAT同步周期500us,支持多卡联动。
3.板载16点通用输入,16点通用输出,其中8路高速输入和16路高速输出。
4.通过EtherCAT总线,可扩展到512个隔离输入或输出口。
5.支持PWM输出、精准输出、PSO硬件位置比较输出、视觉飞拍等。
6.支持直线插补、圆弧插补、连续轨迹加工(速度前瞻)。
7.支持电子凸轮、电子齿轮、位置锁存、同步跟随、虚拟轴、螺距补偿等功能。
8.支持30+机械手模型正逆解模型算法,比如SCARA、Delta、UVW、4轴/5轴 RTCP...
更多关于XPCIE1032H详情点击“不止10倍提速!PCIe EtherCAT实时运动控制卡XPCIE1032H 等您评测!”查看。
1、Qt进行MotionRT750项目的创建与开发
本案例开发环境是Visual Studio 2022 QT,Qt6.8.2,若使用Qtcreator开发,可跳过第一点。
在Visual Studio 2022上配置Qt的开发环境
1.点击Visual Studio上方工具栏的扩展→管理扩展。

2.如图,在浏览中搜索Qt,点击安装开始下载Qt Visual Studio Tools插件。

3.再次打开Visual Studio,进入Qt Versions。

4.点击Add添加Qt版本。

5.选中条目之后点击...去找到qmake.exe文件的位置。

6.下图标识了6.8.2版本的qmake文件在Qt安装目录中的相对位置,不同版本的qmake文件的相对位置规律是一样的,可以参考这个来确定。

7.随后使用同样的方法添加你下载的所有(MSVC)版本即可,添加完之后点击确定完成插件的设置。

开始新建VS Qt项目运行
1.新建项目。

2.在搜索框输入Qt可以查看插件为我们提供的所有VS Qt项目模板,一般我们选择Qt Widgets Application模板即可,选择后点击下一步。

3.输入项目的名称、位置、解决方案名称等信息后点击创建,上述信息一定不要包含中文、空格、特殊字符等,否则后续会报错。

4.点击next。

5.将库文件放入x64/debug中。

6.右键Header Files→添加→现有项,把zauxdll.h和zmotion.h添加进Header Files目录。

7.进入界面设计的代码编辑界面,添加头文件#include"../x64/Debug/zauxdll2.h"。

8.在界面设计的头文件里声明控制器句柄g_handle。

新项目建立完成,可以进行Qt界面开发。
2、相关函数介绍
1.PC函数手册可在光盘资料查看,具体路径如下。










3、相关测试代码介绍
本次指令交互速度测试使用三种型号的控制器对比测试,以下测试为正运动实验室测试数据,与配置的电脑与程序代码等有关系,以下测试数据仅供客户参考。客户具体项目以客户实际测试环境为准。
以下正运动实验室测试为:XPCIE1032H(需搭配MotionRT750使用)、PCIE464、ZMC432-V2,MotionRT750可以通过LOCAL和网口方式连接,故本次MotionRT750测试使用LOCAL和网口两种方式进行测试。
1.XPCIE1032H型号运动控制卡使用MotionRT750的LOCAL、网口连接方式测试。

2.ZMC432-V2型号运动控制器使用网口连接方式测试。

3.PCIE464型号运动控制卡使用PCI的连接方式测试。

4.相关测试代码如下。
①MotionRT750通过LOCAL连接按钮的事件处理函数,调用函数ZAux_FastOpen(),选择连接类型5去连接控制卡(LOCAL连接方式)。
void MainWindow::fun2()
{
ctype = 5;
}
void MainWindow::on_btn_open_clicked()
{
int32 iresult;
char * tmp_buff = new char[16];
QString str;
QString str_title;
str = ui->comboBox->currentText();
QByteArray ba = str.toLatin1();
tmp_buff = ba.data();
if(0 != g_handle)
{
ZAux_Close(g_handle);
killTimer(m_nTimerId);
}
iresult = ZAux_FastOpen(ctype,tmp_buff,1000,&g_handle);
if( 0 != iresult)
{
QMessageBox::warning(this,"提示","连接失败");
}
else
{
QMessageBox::warning(this,"提示","连接成功");
str_title = windowTitle() + tmp_buff;
setWindowTitle(str_title);
m_nTimerId = startTimer(10);
up_State();
}
}
②MotionRT750和ZMC432-V2型号控制器通过网口连接按钮的事件处理函数,调用函数ZAux_OpenEth()去连接控制器,连接类型为2,且把扫描到的IP地址添加到comboBox条目(网口连接方式)。
void MainWindow::fun3()
{
ctype = 2;
ui->comboBox->clear();
ui->comboBox->addItem("127.0.0.1");
char* ip = new char[10240];
ZAux_SearchEthlist(ip, 10230, 200);
QString ips(ip);
QStringList iplist = ips.split(' ');
qDebug() << iplist;
ui->comboBox->addItems(iplist);
}
void MainWindow::on_btn_open_clicked()
{
int32 iresult;
char * tmp_buff = new char[16];
QString str;
QString str_title;
str = ui->comboBox->currentText();
QByteArray ba = str.toLatin1();
tmp_buff = ba.data();
qDebug()<<"current ip tmp_buff"<<tmp_buff;
if(0 != g_handle)
{
ZAux_Close(g_handle);
killTimer(m_nTimerId);
}
iresult = ZAux_FastOpen(ctype,tmp_buff,1000,&g_handle);
if( 0 != iresult)
{
QMessageBox::warning(this,"提示","连接失败");
}
else
{
QMessageBox::warning(this,"提示","连接成功");
str_title = windowTitle() + tmp_buff;
setWindowTitle(str_title);
m_nTimerId = startTimer(10);
up_State();
}
}
③PCIE464型号控制卡通过PCI连接按钮的事件处理函数,调用函数ZAux_FastOpen(),选择连接类型4去连接控制卡(PCI连接方式)。
void MainWindow::fun1()
{
ctype = 4;
}
void MainWindow::on_btn_open_clicked()
{
int32 iresult;
char * tmp_buff = new char[16];
QString str;
QString str_title;
str = ui->comboBox->currentText();
QByteArray ba = str.toLatin1();
tmp_buff = ba.data();
if(0 != g_handle)
{
ZAux_Close(g_handle);
killTimer(m_nTimerId);
}
iresult = ZAux_FastOpen(ctype,tmp_buff,1000,&g_handle);
if( 0 != iresult)
{
QMessageBox::warning(this,"提示","连接失败");
}
else
{
QMessageBox::warning(this,"提示","连接成功");
str_title = windowTitle() + tmp_buff;
setWindowTitle(str_title);
m_nTimerId = startTimer(10);
up_State();
}
}
④通过单条指令交互周期的测试按钮的事件处理函数来计算单条指令的交互平均耗时和总耗时。
void MainWindow::handle_single_command_read_position()
{
float dpos = 0;
int testNum = ui->test_num->text().toInt(); // 从 QComboBox 获取测试次数
// 使用 QElapsedTimer 测量时间
QElapsedTimer timer;
timer.start();
for (int i = 0; i < testNum; i++)
{
// 进行 n 次单指令交互
ZAux_Direct_GetDpos(g_handle, 0, &dpos);
}
// 获取总耗时(纳秒)
qint64 totalNanoseconds = timer.nsecsElapsed();
// 将纳秒转换为毫秒,并保留小数点后6位
double totalMilliseconds = static_cast<double>(totalNanoseconds) / 1000000.0;
QString totalTimeString = QString::number(totalMilliseconds, 'f', 6);
// 更新 UI
// 总耗时 (ms),保留小数点后六位
ui->single_totaltime->setText(totalTimeString);
// 计算平均耗时(微秒),保留小数点后六位
double averageMicroseconds = (totalMilliseconds * 1000.0) / testNum;
QString averageTimeString = QString::number(averageMicroseconds, 'f', 6);
ui->single_time->setText(averageTimeString);
}
⑤通过多条指令交互周期的测试按钮的事件处理函数来计算多条指令的交互平均耗时和总耗时。
void MainWindow::handle_multiple_commands()
{
// 获取测试次数
int testNum = ui->test_num->text().toInt();
QString cmd = "?dpos(0),dpos(1),dpos(2),dpos(3),axisstatus(0),axisstatus(1),axisstatus(2),axisstatus(3),in(0),in(1),in(2),in(3)";
QString cmdBuff;
int star = 0;
QStringList arrS;
// 使用 QElapsedTimer 记录时间
QElapsedTimer timer;
timer.start();
for (int i = 0; i < testNum; i++)
{
// 创建一个足够大的缓冲区来存储返回的命令结果
char buffer[2048];
const char* cmdCStr = cmd.toStdString().c_str();
int result = ZAux_DirectCommand(g_handle, cmdCStr, buffer, sizeof(buffer));
// 将返回的结果追加到 cmdBuff 中
cmdBuff += QString::fromUtf8(buffer);
}
// 获取总耗时(纳秒)
qint64 totalNanoseconds = timer.nsecsElapsed();
// 将纳秒转换为毫秒,并保留小数点后6位
double totalMilliseconds = static_cast<double>(totalNanoseconds) / 1000000.0;
QString totalTimeString = QString::number(totalMilliseconds, 'f', 6);
// 更新 UI
// 总耗时 (ms),保留小数点后六位
ui->Multiple_totaltime->setText(totalTimeString);
// 计算平均耗时(微秒),保留小数点后六位
double averageMicroseconds = (totalMilliseconds * 1000.0) / testNum;
QString averageTimeString = QString::number(averageMicroseconds, 'f', 6);
ui->Multiple_time->setText(averageTimeString);
// 处理返回的字符串
QStringList responseList = cmdBuff.split('\t');
for (const QString& item : responseList)
{
arrS.append(item.trimmed());
}
}
⑥网口连接周期上报的方式获取输入口状态的总耗时测试函数如下。
void MainWindow::handle_periodic_report_input_status()
{
// 创建一个大小为1000的整数数组来存储输入状态
QVector<int> InState(1000);
int singleValue = 0;
// 打开使能周期上报
ZAux_CycleUpEnable(g_handle, 0, 1000, "IN(0,1000)");
// 强制上报一次,0为通道号
int tep0 = ZAux_CycleUpForceOnce(g_handle, 0);
// beforeDT记录交互指令前的时刻
QElapsedTimer timer; timer.start(); // 启动计时器
for (uint i = 0; i < 1000; i++)
{
//// 从周期上报内容里面读取输入口状态
int tep1 = ZAux_CycleUpReadBuffInt(g_handle, 0, "IN", i, &singleValue);
InState[i] = singleValue;
}
// 计算总耗时(纳秒)
qint64 totalNanoseconds = timer.nsecsElapsed();
// 将纳秒转换为毫秒,并保留小数点后6位
double totalMilliseconds = static_cast<double>(totalNanoseconds) / 1000000.0;
QString timeString = QString::number(totalMilliseconds, 'f', 6);
// 显示总耗时
ui->periodtime->setText(timeString);
// 关闭使能周期上报
ZAux_CycleUpDisable(g_handle, 0);
}
⑦单条指令读取1个输入口状态的总耗时测试函数如下。
void MainWindow::handle_single_command_read_one_input()
{
// 创建一个大小为1000的无符号整数数组来存储输入状态
QVector<uint> InState(1000);
uint singleValue = 0;
// beforeDT记录交互指令前的时刻
QElapsedTimer timer;
timer.start();
for (int i = 0; i < 1000; i++)
{
// 单条指令读取单个输入口状态
ZAux_Direct_GetIn(g_handle, i, &singleValue);
InState[i] = singleValue;
}
// 获取总耗时(纳秒)
qint64 totalNanoseconds = timer.nsecsElapsed();
// 将纳秒转换为毫秒,并保留小数点后6位
double totalMilliseconds = static_cast<double>(totalNanoseconds) / 1000000.0;
QString totalTimeString = QString::number(totalMilliseconds, 'f', 6);
// 将总耗时显示在 single_IO 上,保留小数点后六位
ui->single_IO->setText(totalTimeString);
}
⑧单条指令读取多个输入口状态的总耗时测试函数如下。
void MainWindow::handle_single_command_read_multiple_inputs()
{
// 创建一个大小为32的整数数组来存储输入状态
QVector<int> InState(32);
// 使用 QElapsedTimer 记录时间
QElapsedTimer timer; timer.start();
// 单条指令读取多个输入口状态,输入口状态按位进行存储
// 一个 INT 型数组可以存储 32 个输入口状态,可读取 32 个及以上
ZAux_Direct_GetInMulti(g_handle, 0, 999, InState.data());
// 获取总耗时(纳秒)
qint64 totalNanoseconds = timer.nsecsElapsed();
// 将纳秒转换为毫秒,并保留小数点后6位
double totalMilliseconds = static_cast<double>(totalNanoseconds) / 1000000.0;
QString totalTimeString = QString::number(totalMilliseconds, 'f', 6);
// 将总耗时显示在 multiple_IO 上,保留小数点后六位
ui->multiple_IO->setText(totalTimeString);
}
4、运行效果
1.MotionRT750通过LOCAL连接方式的交互时间测试结果如下图所示。


MotionRT750 LOCAL连接方式测试(1k次)

MotionRT750 LOCAL连接方式测试(1w次)

MotionRT750 LOCAL连接方式测试(10w次)
2.MotionRT750通过网口连接方式交互时间的测试结果如下图所示。


MotionRT750 网口连接方式测试(1k次)

MotionRT750 网口连接方式测试(1w次)

MotionRT750 网口连接方式测试(10w次)
3.ZMC432-V2运动控制器通过网口连接方式的交互时间测试结果如下图所示。


ZMC432-V2 网口连接方式测试(1k次)

ZMC432-V2 网口连接方式测试(1w次)

ZMC432-V2 网口连接方式测试(10w次)
4.PCIE464控制卡通过PCI连接方式的交互时间测试结果如下图所示。


PCIE464 PCI连接方式测试(1k次)

PCIE464 PCI连接方式测试(1w次)

PCIE464 PCI连接方式测试(10w次)
5、结论与分析
对于MotionRT750的LOCAL方式连接、网口方式连接以及PCI方式和控制器网口方式连接时的单条或多条指令交互时间测试,从上面的运行效果图的数据显示来看,可以看出:
当进行1k、1w次和10w次的单指令交互或多条指令交互的时候,MotionRT750的LOCAL连接方式进行单条指令交互所需要的时间(平均2.95us左右)和一次性读取12个状态的多条指令交互所需要的时间(平均4.72us左右),都是要比PCI连接和控制器网口连接的方式更快(PCI单条平均45.9us左右、多条平均67.81us左右;网口单条平均109.78us、多条平均113.68us左右)。

综上所述,我们可以从测试结果看出,MotionRT750的LOCAL连接方式展现卓越的实时性能,指令交互的效率也非常的稳定。
当测试次数从1k增加到1w、10w次时,指令交互时间波动不大,在延迟、稳定性上全面优于PCI和控制器网口的连接,更加适合高精度、高实时性、高稳定性的工业运动控制场景应用。
Qt例程讲解教学视频可点击→“强实时运动控制内核MotionRT750(七):us级高速交互之Qt,为智能装备提速”查看。
完整代码获取地址
▼

本次,正运动技术强实时运动控制内核MotionRT750(七):us级高速交互之Qt,为智能装备提速,就分享到这里。
更多精彩内容请关注“正运动小助手”公众号,需要相关开发环境与例程代码,请咨询正运动技术销售工程师:400-089-8936。
本文由正运动技术原创,欢迎大家转载,共同学习,一起提高中国智能制造水平。文章版权归正运动技术所有,如有转载请注明文章来源。

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