http://www.gkong.com 2025-10-27 13:54 深圳市正运动技术有限公司
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轴125us EtherCAT冗余架构消除单点故障风险,保障连续生产。
6.安全可靠性:不惧Windows系统崩溃影响,蓝屏时仍可维持急停与安全停机功能有效,确保产线安全运行。
7.功能扩展性:实时内核支持C语言程序开发,方便功能拓展与实时代码提升效率。
MotionRT750视频介绍可点击→正运动强实时运动控制内核MotionRT750。
更多关于MotionRT750的详情介绍与使用点击→强实时运动控制内核MotionRT750(一):驱动安装、内核配置与使用。
XPCIE6032H运动控制卡集成6路独立EtherCAT主站接口。整卡最高可支持254轴运动控制;125usEtherCAT通讯周期时,两个端口配置冗余最高可支持32轴运动控制。6个EtherCAT主站各通道独立工作,多EtherCAT主站互不影响。


XPCIE6032H视频介绍可点击→全球首创!PCIe 6路高性能EtherCAT运动控制卡XPCIE6032H。
XPCIE6032H运动控制卡面向半导体设备、精密3C电子、生物医疗仪器、新能源装备、人形机器人及激光加工等高速高精场景,为固晶机、贴片机、分选机、锂电切叠一体机、高速异形插件设备等自动化装备提供核心运动控制支持。
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视频介绍可点击→高速高精运动控制!PCIe超实时2通道EtherCAT运动控制卡上市!。
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视频介绍可点击→高性能PCIe EtherCAT运动控制卡 | XPCIE1032H_。
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 等您评测!”查看。

基本使用方法
01 固件版本要求
控制器使用C函数需要使用支持C接口函数的固件版本;固件版本名称里带有“cfunc”的即为支持C函数接口。
02 函数调用限制
同一个C文件内的某一个C函数只能在某一个Basic文件内被声明调用,不可被在多个basic文件内都进行声明调用。
03 多函数声明规则
同一个C文件内的不同C函数可以分别在不同的Basic文件内被声明调用,但再次被声明后的函数名不可一致。
DEFINE_CFUNC -- 关键字

支持的数据类型定义:int、float、double、TYPE_TABLE。如果与TABLE数组交互,建议使用TYPE_TABLE类型。在4系列以上的控制器,TYPE_TABLE是double类型。
int userc_init(void)
{
int* p=(int *)malloc(sizeof(int));
p[0]=88;
printf("p[0]=%d\n",p[0]);
free(p);
return 0;
}
float divf(float a,float b)
{
return (a/b);
}
TYPE_TABLE divd(TYPE_TABLE a,TYPE_TABLE b)
{
return (a/b);
}
define_cfunc userc_init int userc_init(void) define_cfunc userc_divf float divf(float a,float b) define_cfunc userc_divd double divd(double a,double b) ?userc_init() ?userc_divf(23.1,1) ?userc_divd(23.3,1)

以下程序代码测试TABLE指针输入输出数据。
int tablefunc(TYPE_TABLE *ptable,int inum)
{
int i;
for(i=0;i<inum;i++)
{
//table数据直接修改
ptable[i] += 1;
}
return 0;
}
define_cfunc userc_tfunc int tablefunc(TYPE_TABLE *ptable,int inum) dim ptable(20) dim inum userc_tfunc(ptable,inum)

注意事项:
(1)定义的无参数函数,可以在INT_CYCLE中直接使用。
(2)BASIC调用的C函数的参数个数最多支持8个。
(3)C函数注意安全性,注意代码规范性,否则可能导致死机。
(4)C函数要注意实时性,处理必须够快,否则会影响BASIC的实时性。
注:建议调试时都下载RAM运行!
不同型号控制器编译平台有所不同,具体参照下表。目前仅以下型号控制器支持C语言,其他系列型号控制器如有疑问请与技术工程师联系。

右键单击“文件视图”中空白区域,点击弹出窗口中“设置”一栏,进行编译平台设置操作。在弹出窗口“编译平台”一栏中点击下拉列表,在下拉列表中选择相应的编译平台后单击“确定”,即可完成编译平台设置操作。

1.在RTSys软件中单击菜单栏“文件”,在下拉窗口中选择“新建项目”。选择项目文件存入的路径并且自定义命名项目名称。

2.新建项目成功后,在新建的项目下新建新的Basic文件,并且自定义相关Basic文件名。点击确定Basic文件创建成功。

3.新建.C文件。步骤可参照第二步,新建文件类型时需选择“C”。

4.右键单击“文件视图”中空白区域,点击弹出窗口中“设置”一栏,进行编译平台设置操作。

5.在弹出窗口“编译平台”一栏中点击下拉列表,在下拉列表中选择相应的编译平台后单击“确定”,即可完成编译平台设置操作,编译平台的选择可参照上一章节“编译平台选择参考”。

6.编写C函数。编写C程序时需先进行头文件声明步骤,然后再按照C语言编码规范编写C函数。
头文件声明语法:#include “xxxxx.h”。“xxxx.h”为引用内置函数的头文件。如下图所示,“.h”头文件的文件路径需与项目文件路径一致。“zmcbuildin.h”文件可联系正运动工程师获取。

7.在BASIC程序中使用C函数时需要使用关键字“DEFINE_CFUNC”对被使用C函数进行引用定义,定义后在Basic文件中使用重新赋予的函数名即可调用该C函数。

注:C函数代码在RTSys中直接编辑即可,在其他软件中编辑复制到RTSys中时可能会导致乱码或格式错误等问题。
C语言:
// 添加自定义函数声明
#include "zmcbuildin.h"
double fast_sin()
{
double sum = 0;
for(int i=0; i<100000; i++){
sum = sum + sin(i*0.01);
}
return sum;
}
Basic语言:
DEFINE_CFUNC c_sin_calc double fat_sin() ```
Basic语言:
sum = c_sin_calc()

自定义机械手模型实现
已有的机械手类型如下,更多类型可以查看《正运动机械手手册》。




对于需要实现自定义机械手模型的需求,我们内置C语言提供了CFRAME机械手结构扩展功能,用户可通过此功能自定义机械手模型,C函数部分使用 usercframe.c文件内的即可,进行算法自定义。函数用法示例相关代码介绍如下:
正运动控制器内置Frame1~Frame999的机械手类型,用户自定义机械手类型为FRAME1000~FRAME65535。
函数名自动根据frame编号生成,下面C语言部分根据1000来生成举例。

//机械手每次正逆解回调执行,用户可以初始化内部变量
// 输入:
// pzmc 控制器描述结构指针
// pframe 机械手基本状态指针
// pParaList Table 参数列表
// 返回值, 成功与否, 0-OK
********************************/
uint32 SOFRAME_INIT1000(struct_soZmcDisp *pzmc, struct_soFrameStatus* pframe, TYPE_TABLE* pParaList)
{
//初始化
int16 i;
//把connreframe的table数值赋值给臂长 和关节脉冲
g_soframeinfo[0].m_flen1 = *pParaList;
g_soframeinfo[0].m_flen2 = *(pParaList + 1);
g_soframeinfo[0].m_flen3 = *(pParaList + 2);
g_soframeinfo[0].m_flen4 = *(pParaList + 3);
//关节一圈脉冲
g_soframeinfo[0].m_pulse1 = 1000; //为了安全起见 demo故意设置 1
g_soframeinfo[0].m_pulse2 = 1000; //*(pParaList + 5);
g_soframeinfo[0].m_pulse3 = 1000;
g_soframeinfo[0].m_pulse4 = 1000;
//...
g_soframeinfo[0].m_pulsev = 1000;
for(i=0;im_pPrivate = (void *)&g_soframeinfo[0];
//更新当前机械手姿态
pframe->m_iHand = 0;//具体用户自己编写计算机械手当前实际姿态,姿态数值含义用户自己定义,
pf = (struct_userframeinfo *)pframe->m_pPrivate;
if(NULL == pf)
{
return -1;
}
//打印输出测试
rtprintf("init %.2f,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f,%d\n",pf->m_flen1,pf->m_flen2,pf->m_flen3,pf->m_flen4,pf->m_pulse1,pf->m_pulse2,pf->m_pulse3,pf->m_pulse4,pf->m_pulsev,pframe->m_iHand);
return 0;
}
//关节坐标转换世界坐标
//计算焊枪末端坐标
// 输入:
// pzmc 控制器描述结构指针
// pframe 机械手基本状态指针
// pfJointPulsein 输入关节脉冲坐标
// 输出
// pHand 输出当前姿态
// pfWorldout输出units单位世界坐标WPOS
// 返回值, 成功与否, 0-OK
********************************/
uint32 SOFRAME_TRANS1000(struct_soZmcDisp *pzmc, struct_soFrameStatus* pframe, TYPE_FRAME*pfJointPulsein, int32 *pHand, TYPE_FRAME* pfWorldout)
{
int i;
double uj[6],pout[6];
struct_userframeinfo *pf =NULL;
pf = (struct_userframeinfo *)pframe->m_pPrivate;
if(NULL == pf)
{
return -1;
}
//把输入脉冲转为角度
uj[0] = *(pfJointPulsein + 0) / pf->m_pulse1 ; //关节一 实时横焊位置 度
uj[1] = *(pfJointPulsein + 1) / pf->m_pulse2 ; //关节二 实时高度位置 度
uj[2] = *(pfJointPulsein + 2) / pf->m_pulse3 ; //关节三 实时钟摆角度 度
uj[3] = *(pfJointPulsein + 3) / pf->m_pulse4 ; //关节四 实时俯仰角度 度
//转弧度
uj[0] = uj[0] / 180 * PI;
uj[1] = uj[1] / 180 * PI;
uj[2] = uj[2] / 180 * PI;
uj[3] = uj[3] / 180 * PI;
//正解过程......
//计算姿态,返回姿态
*pHand = 0;
//demo 计算出世界坐标
pout[0] = 100; //x mm
pout[1] = 100; //y mm
pout[2] = 100; //z mm
pout[3] = 90; //Rz 角度
pfWorldout[0] = pout[0] ;
pfWorldout[1] = pout[1] ;
pfWorldout[2] = pout[2] ;
pfWorldout[3] = pout[3] ;
//打印输出测试
if(0 == g_printflag)
{
rtprintf("trans input %.2f,%.2f,%.2f,%.2f, output ,%.2f,%.2f,%.2f,%.2f\n",uj[0],uj[1],uj[2],uj[3],pfWorldout[0],pfWorldout[1],pfWorldout[2],pfWorldout[3]);
g_printflag = 1;
}
return 0;
}
//世界坐标转换关节坐标
// 输入:
// pzmc 控制器描述结构指针
// pframe 机械手基本状态指针
// pfWorldin 输入世界坐标units单位
// ihand 输入坐标对应姿态, -1表示使用当前姿态.
// 输出:
// pfJointPulseout 输出关节脉冲坐标
// 返回值, 成功与否, 0-OK
********************************/
uint32 SOFRAME_RETRANS1000(struct_soZmcDisp *pzmc, struct_soFrameStatus* pframe, TYPE_FRAME *pfWorldin, int32 ihand, TYPE_FRAME* pfJointPulseout)
{
int i;
double uw[6],pout[6];
struct_userframeinfo *pf = NULL;
pf = (struct_userframeinfo *)pframe->m_pPrivate;
if(NULL == pf)
{
return -1;
}
//把世界坐标脉冲转为mm和角度 pfWorldin 已经是除以units的值了
uw[0] = pfWorldin[0] ; // 位置 x mm
uw[1] = pfWorldin[1] ; // 位置 y mm
uw[2] = pfWorldin[2] ; // 位置 z mm
uw[3] = pfWorldin[3] ; // 位置 roll 弧度
//转弧度
uw[3] = uw[3] / 180 *PI;
//逆解过程......
//计算出关节坐标
pout[0] = uw[0]; //关节1 角度
pout[1] = 60; //关节2 角度
pout[2] = 60; //关节3 角度
pout[3] = 30; //关节4 角度
//demo 为了安全起见 不改变关节输出
pfJointPulseout[0] = pout[0] * 1000;
pfJointPulseout[1] = pout[1] * 1000;
pfJointPulseout[2] = pout[2] * 1000;
pfJointPulseout[3] = pout[3] * 1000;
//打印输出测试
if(1 == g_printflag)
{
rtprintf("retrans input %.2f,%.2f,%.2f,%.2f, output ,%.2f,%.2f,%.2f,%.2f\n",uw[0],uw[1],uw[2],uw[3],pfJointPulseout[0],pfJointPulseout[1],pfJointPulseout[2],pfJointPulseout[3]);
g_printflag = 0;
}
return 0;
}
// 输入:
// pzmc 控制器描述结构指针
// pframe 机械手基本状态指针
// pfRotate 坐标平移旋转的参数, 依次为XYZ,RX,RY,RZ
// pfin 输入虚拟轴坐标列表, units单位
// 输出
// pfout 输出世界坐标列表, units单位
// 返回值, 成功与否, 0-OK
********************************/
uint32 SOFRAME_ROTATETOWPOS1000(struct_soZmcDisp *pzmc, struct_soFrameStatus* pframe, TYPE_FRAME *pfRotate, TYPE_FRAME *pfin, TYPE_FRAME* pfout)
{
int i;
rtprintf("DPOS转换为WPOS: %0.4f, %0.4f, %0.4f\n",*(pfRotate),*(pfRotate + 1),*(pfRotate + 3));
// 输入的就是世界坐标系, 转units坐标系
for(i=0; i< pframe->m_iTotalAxisesNoAux; i++)
{
pfout[i] = pfin[i];
}
rtprintf("pfin %0.4f, %0.4f, %0.4f\n",*(pfin),*(pfin + 1),*(pfin + 3));
rtprintf("pfout %0.4f, %0.4f, %0.4f\n",*(pfout),*(pfout + 1),*(pfout + 3));
return 0;
}
// 输入:
// pzmc 控制器描述结构指针
// pframe 机械手基本状态指针
// pfRotate 坐标旋转的参数
// pfin 输入世界坐标列表, units单位
// 输出
// pfout 输出虚拟轴坐标列表, units单位
// 返回值, 成功与否, 0-OK
uint32 SOFRAME_ROTATETODPOS1000(struct_soZmcDisp *pzmc, struct_soFrameStatus* pframe, TYPE_FRAME *pfRotate, TYPE_FRAME *pfin, TYPE_FRAME* pfout)
{
int i;
rtprintf("WPOS转换为DPOS: %0.4f, %0.4f, %0.4f\n",*(pfRotate),*(pfRotate + 1),*(pfRotate + 3));
// 输入的就是世界坐标系, 转units坐标系
for(i=0; i< pframe->m_iTotalAxisesNoAux; i++)
{
pfout[i] = pfin[i];
}
rtprintf("pfin %0.4f, %0.4f, %0.4f\n",*(pfin),*(pfin + 1),*(pfin + 3));
rtprintf("pfout %0.4f, %0.4f, %0.4f\n",*(pfout),*(pfout + 1),*(pfout + 3));
return 0;
}
'''''电机、机械手参数定义 dim L1 dim L2 dim L3 dim L4 dim PulesVROneCircle '虚拟姿态轴一圈脉冲数 '函数接口声明 DEFINE_CFRAME 1000,4,1,0,1000 'framenum, totalaxises, axises_aux, max_attitudes, rotatetype '机械手参数设置 L1 =19.8736 '1轴到2轴的X偏移 L2 =455.1143 '大摆臂长度 L3 =39.8611 '3轴中心到4轴中心距离 L4 =430.9516 '4轴到5轴的距离。 PulesVROneCircle=360*1000 dim u_j1 '关节1实际一圈脉冲数 dim u_j2 '关节2实际一圈脉冲数 dim u_j3 '关节3实际一圈脉冲数 dim u_j4 '关节4实际一圈脉冲数 u_j1=360*1000 '关节1实际一圈脉冲数 u_j2=360*1000 '关节2实际一圈脉冲数 u_j3=360*1000 '关节3实际一圈脉冲数 u_j4=360*1000 '关节4实际一圈脉冲数 '''''关节轴设置 BASE(0,1,2,3) '选择关节轴号0、1、2、3 atype=0,0,0,0 '轴类型设为脉冲轴 UNITS = u_j1/360,u_j2/360,u_j3/360,u_j4/360 '把units设成每°脉冲数 DPOS=0,0,0,0 '设置关节轴的位置,此处要根据实际情况来修改。 speed=100,100,100,100 '速度参数设置 accel=1000,1000,1000,1000 decel=1000,1000,1000,1000 '''''''''''''''''''''虚拟轴设置''''''''''''''''''''' BASE(6,7,8,9) ATYPE=0,0,0,0 '设置为虚拟轴 TABLE(0,L1,L2,L3,L4,u_j1,u_j2,u_j3,u_j4,PulesVROneCircle) '根据手册说明填写参数 speed=100,100,100,100 '速度参数设置 UNITS=1000,1000,1000,1000 '运动精度,要提前设置,中途不能变化 '''''''''''''''''''''建立机械手连接''''''''''''''''''''' while 1 if scan_event(in(0))0 then '输入0下降沿触发 BASE(6,7,8,3) '选择虚拟轴号 CONNREFRAME(1000,0,0,1,2,3) '启动正解连接。 WAIT LOADED '等待运动加载。 ?"正解模式" endif wend

运行测试效果
该例子参数均为模拟,主要目的为介绍各函数接口使用方法。通过检测输入口0的状态进行正逆解切换:输入口0上升沿触发时进入正解模式,输入口0下降沿触发时进入逆解模式。实际使用时根据机械手参数进行填写。
机械手每次正逆解回调执行都会执行frame初始化函数,从参数表中读取机械手的臂长参数,设置关节脉冲参数(示例中设为固定值1000),保存参数到全局结构体并关联到机械手状态,设置初始机械手姿态为0,打印初始化参数用于调试。
进入正解模式:通过函数SOFRAME_TRANS1000,将输入的关节脉冲值转换为角度值,将角度值转换为弧度值,执行正解运动学计算(示例中除关节轴0其他直接返回固定值),设置输出姿态,将计算结果转换为世界坐标系输出,使用打印标志控制调试信息的输出频率。
进入逆解模式:通过函数SOFRAME_RETRANS1000,将输入的世界坐标转换为适当单位,执行逆解运动学计算(示例中直接返回固定值),将计算结果转换为关节脉冲值输出,使用打印标志控制调试信息的输出频率。
1.函数命名必须遵循约定:SOFRAME_前缀+功能名+Frame编号。
2.确保正确处理单位转换(脉冲↔单位)。
3.逆解函数需要处理多种姿态情况(ihand参数)。
4.自定义旋转功能仅在rotatetype≥100时需要实现。
5.所有函数返回0表示成功,非0表示错误。
通过以上步骤,可以成功实现自定义机械手的CFRAME扩展功能。
需要更详细的技术交流,请联系正运动技术。
教学视频可点击→强实时运动控制内核MotionRT750(九):内置C语言的自定义机械手模型实现查看。

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