|
今天,正运动小助手给大家分享一下如何通过Qt开发正运动Delta机械手。
运动控制实时内核MotionRT750
MotionRT750是正运动技术自主研发的首款基于x86架构、可在Windows或Linux系统下裸跑CPU的强实时运动控制内核。

该方案采用CPU内核独占技术,实现裸机级的强实时运动控制。它将核心运动控制、机器人算法、数控(CNC)及机器视觉等强实时任务集中运行在1-2个专用CPU核上。与此同时,其余CPU核则专注于处理Windows/Linux相关的非实时任务。

此外,该方案集成了MotionRT750 Runtime实时层与操作系统非实时层,并利用高速共享内存进行数据交互,显著提升运动控制与上层应用间的通信效率及函数执行速度,最终实现更稳定、更高效的智能装备控制,确保运动控制任务的绝对实时性与系统稳定性,特别适用于半导体、电子装备等高速、高精度应用场合。

强实时运动控制卡XPCIE1032H

-
支持4-64轴运动控制可选。
-
16个数字输入,其中8路高速输入,4路高速锁存输入,2路单端编码器反馈。
-
16个数字输出,其中16路高速PSO、4路PWM输出和4路单端脉冲输出。
-
视觉飞拍、精密点胶和激光能量控制。
-
点位、凸轮、直线、圆弧、连续轨迹以及50+机械手模型算法。
-
EtherCAT轴和脉冲轴可以混合使用。
强实时运动控制卡XPCIE2032H

-
支持4-128轴运动控制可选。
-
2路EtherCAT独立主站,可125us 32轴,支持EtherCAT冗余功能。
-
可选配16+16输入,16+16路输出,含8路高速输入和16路高速输出,其中4路单端脉冲输出和16路硬件位置比较输出PSO。
-
支持直线插补、任意空间圆弧插补、螺旋插补、连续插补,电子凸轮、电子齿轮、位置锁存、同步跟随、虚拟轴等功能。
-
支持RtBasic多文件多任务编程。
-
多种程序加密手段,保护客户的知识产权。
强实时运动控制卡XPCIE6032H

-
支持4-254轴运动控制可选。
-
6路EtherCAT独立主站,EtherCAT周期125us~1ms,每路主站可自由配置,支持EtherCAT冗余功能。
-
可选配16输入16输出,含8路高速输入和16路高速输出,其中4路单端脉冲输出。
-
支持直线插补、任意空间圆弧插补、螺旋插补、连续插补,电子凸轮、电子齿轮、位置锁存、同步跟随、虚拟轴等功能。
-
支持RTBasic多文件多任务编程。
-
多种程序加密手段,保护客户的知识产权。
基于Linux的强实时EtherCAT运动控制器ZMC600M
ZMC600M系列高性能多轴运动控制器是一款EtherCAT总线立式运动控制器,控制器本身最多支持6-32轴的复杂的控制需求。
ZMC600M是基于“ARM架构 + 纯国产Linux运动控制实时内核MotionRT750 + EtherCAT”的总线型运动控制器,打破平台壁垒,实现了嵌入式系统与运动控制和实时内核技术的无缝衔接。

ZMC600M硬件特性:
-
内置Linux系统,搭载强实时内核MotionRT750;
-
可选6-32轴运动控制,EtherCAT总线最快通讯周期可达250μs;
-
24路高速IO输入,2路高速锁存,3路单端编码器接口;
-
16路高速IO输出,4路PWM/PSO,4路单端脉冲轴接口;
-
2路AD,2路DA(0-10V,12bit);
-
支持EtherNET、CAN、RS232、RS485通讯;
-
1路MPG手轮接口;
-
支持掉电存储;
-
特殊型号支持5V/24V推挽输出功能;
-
支持多文件多任务编程,可支持PC程序和控制器内置程序同时工作。

更多关于ZMC600M详情点击→基于Linux的强实时EtherCAT运动控制器ZMC600M。
ZMC600M介绍视频→基于Linux的强实时EtherCAT运动控制器ZMC600M
软硬件全国产运动控制器ZMC432HG
EtherCAT运动控制器ZMC432HG是正运动推出的一款软硬件全国产自主可控控制器,专为满足客户在信息安全与供应链安全需求而开发的国产运动控制平台,能够适配大多数工业控制协同工业互联网应用需求。
ZMC432HG支持正运动远程显示、网络组态显示,可实时监控和调整参数配置,也可根据现场需求灵活组网,提升系统部署的适配性与扩展性。

ZMC432HG硬件特性:
-
多支持6-32轴运动控制;
-
EtherCAT总线最快1ms的刷新周期;
-
6路10MHz高速差分脉冲输出,总线轴、脉冲轴可混合插补;
-
2路模拟量输入(AD),2个模拟量输出(DA);
-
4路通用IO输入,4路高速输入,支持高速锁存;
-
12路通用IO输出,4路高速输出,支持PWM和硬件比较输出功能;
-
轴正负限位信号/原点信号可以随意配置为任意通用数字输入口;
-
EtherCAT接口、RS232串口、RS485串口、以太网接口、CAN接口;
-
支持掉电检测、掉电存储,多种程序加密方式,能够有效防止系统故障,保护项目工程文件数据,提高系统的可靠性。

更多关于ZMC432HG详情点击→100%元器件全国产化认证:EtherCAT运动控制器ZMC432HG。
Qt进行Delta机械手的开发
一.Qt项目的创建
1.打开Qt Creator参考如下步骤创建新的Qt项目。





2.把厂商提供的zmotion.dll、zmotion.lib、zmotion.h、zmcaux.cpp、zmcaux.h库文件拷贝到新建的QT项目下(Linux系统的使用libzmotion.so的动态库)。

3.添加外部库【选择项目后右键】→【添加库】→【外部库】。

4.引入头文件并定义控制器的句柄。

至此,Qt项目新建完成,可以进行项目开发了。
二.PC函数介绍
1.PC函数手册可在光盘资料查看,具体路径如下。

2.链接控制器,获取链接句柄。

3.机械手模型正解的建立。

4.机械手模型逆解的建立。

5.机械手坐标系旋转,用于得到用户坐标系。

Qt例程建设之Delta正逆解的建立
控制器型号带R后缀的才支持该机械手模型。
一.轴方向要求
使用正运动的Delta机械手模型,要先保证3个关节轴向下旋转时为正向,末端旋转轴逆时针旋转为正(俯视)。

电机旋转方向错误可能导致的问题有:三轴联动轨迹错误;正运动学、逆运动学使用的关节角符号不一致;末端位置会偏离目标,轨迹可能变形。
二.结构参数(结构参数由机械手本体厂家提供)
机械手的结构参数要先写进控制器的TABLE寄存器后,才可以调接口建立机械手的正逆解。


本体结构参数错误可能导致的问题有:
①实际XYZ与指令不一致;中心位置看似正常,向外围移动后误差增大;计算出的工作空间与实际不符。
②定位偏差、不同位置的误差不同;水平移动可能伴随高度变化;靠近边缘时出现不可达或越限。
三.原点定义
各关节轴的连杆L1都处于水平位置时,认为是关节零点位置。(一般本体会提供定位销,没有提供的可以通过水平仪确保零点时L1处于水平位置)
此时轴0和轴1连线方向为直角坐标系X方向,直角坐标系零点位于连杆L1水平面的中心。

Delta本体原点标定流程:
1.三个关节轴的电气原点(以脉冲轴为例子),通常是原点传感器来辅助完成,首先确定好基本的轴参数,调用控制器回零模式4等待回零完成,此时没有偏移的情况下为电气原点(粗原点),正常情况下是和模型零点有一个角度偏移。
2.Delta几何模型零位,零点位置参考上图所示。实现模型零点的标定,目前常见的两种方案是:定位销法和定位工装法。普通的水平仪设备是无法满足末端精度需求的,只能用于临时常规调试。

?定位销法:
①第一步在每个关节的固定支座和上臂上分别加工定位孔。当关节转到规定的几何零位角θ0时,两孔正好同轴。J1、J2、J3 三根销全部插入后,读取三个关节轴当前的角度值,根据理论零位角计算并写入各轴零位角度偏移。
②第二步退出伺服使能或确保轴不运动,拔出定位销,重新使能并运动到零位,检查定位孔是否能够再次自然对齐。
3.回零参数精调,当找到Delta几何模型零位的偏移角度后,就可以自动回零来验证了,需要再次确认:回零方向;回零模式;回零速度;二次爬行速度;原点开关有效电平;回零后偏移量。
回零完成后,就可以进行最后一步,验证末端tcp点的运动精度(如何控制走末端tcp运动后面的内容会详细介绍)
垂直升降:
固定X、Y,只改变Z。
检查:
?末端是否保持在同一垂直线上。
?是否存在横向漂移。
?三个关节是否协调运动。
X方向直线:
固定Y、Z,移动X正负方向。
检查:
?轨迹是否直线。
?Z是否变化。
?正负方向误差是否对称。
Y方向直线:
固定X、Z,移动Y正负方向。
检查内容同上。
平面矩形:
依次运动到四个角点,检查:
?四边是否平行。
?起点和终点是否重合。
?各点误差是否一致。
四.用户坐标系的标定
Delta标定新的用户坐标系,本质上是建立一个“用户坐标系相对于机器人基坐标系的位姿关系”:Pbase=RuserPuser+Tuser。
其中:
Tuser:用户坐标系原点在机器人基坐标系中的位置。
Ruser:用户坐标系X、Y、Z轴相对于基坐标系的旋转关系。
Delta本体的R、r、L1、L2等结构参数不需要重新修改。前提是上面的步骤已经完成。
标定通常使用三点法(三点的定义如下):
dtzero:工件零点在原来坐标系上的位置。
dtx:工件坐标系X轴上的点在原来坐标系上的位置。
dty:工件坐标系Y轴上的点在原来坐标系上的位置。
具体的操作步骤可以分为5步:

1
第一步:
固定标定板,将标定板安装在实际工作位置。
2
第二步:
低速移动到原点,让TCP移动到原点P0,尖端对准孔中心。
3
第三步:
移动到X轴点,沿预计的X正方向移动到PX,同时需要注意的是,X点与基准线重合,Y和Z方向没有明显偏离。
4
第四步:
移动到Y轴点PY,该点必须位于用户坐标系的XY平面中,不能只凭大致目测。需要依照这个标定板。
5
第五步:
delta软件保存这个点位,来计算ZAux_Direct_FrameRotate旋转转换的参数。切换用户坐标系后进行运动验证。
例程介绍
1.链接控制器获取句柄,上位机操作通过获取到的句柄来操作控制器。
const int connectResult = QCoreApplication::arguments().contains(QStringLiteral("--offline")) ? -1 : motion.connectEth(QStringLiteral("LOCAL1"));if (connectResult == 0) { const int initResult = motion.initialize(); ui->connectState->setText(QStringLiteral(u"控制器: 已连接")); setWindowTitle(QStringLiteral(u"Delta运动模块(已连接)")); log(QStringLiteral(u"控制器连接成功")); if (initResult == 0) loadControllerParameters(); else showResult(QStringLiteral(u"控制器初始化"), initResult);} else { ui->connectState->setText(QStringLiteral(u"控制器: 未连接")); setWindowTitle(QStringLiteral(u"Delta运动模块(未连接)"));log(QStringLiteral(u"控制器连接失败,错误码 %1").arg(connectResult));}int DeltaMotion::connectEth(const QString& localName){ close(); QByteArray b = localName.toLatin1(); int r = controllerCall([&] { return ZAux_FastOpen(5, b.data(), 1000, &m_h); }); if (r) m_h = nullptr; emit connectionChanged(m_h); return r;}
2.Delta机械手参数设置。



3.机械手正逆解的建立。
/************************************************************************************
'任务编号: 无
'函数功能: 机械手的正逆解的建立
'Input: mode —— 运动模式
1:建立逆解,直角坐标转换为关节坐标
2:建立正解,关节坐标转换为直角坐标
3:停止运动并断开机械手正逆解连接
'Output: 无
'返回值: 0:表示机械手建立成功; -1:表示机械手建立失败
'备注: 1、控制器型号带R后缀的才支持该机械手模型
' 2、正解状态时,虚拟轴的MTYPE=34
' 3、逆解状态时,关节轴的MTYPE=33
' 4、机械手处于逆解状态时不要断使能,不然操作不当容易飞车。
**************************************************************************************/
int DeltaMotion::establish(int mode) const
{
if (check())
return -1;
if (mode == 3)
{
// RapidStop 会终止运动并断开当前机械手正逆解连接。
m_mode = 0;
return ZAux_Direct_Rapidstop(m_h, 2);
}
int mt = 0;
int r;
if (mode == 1)
{
// MTYPE=33 表示 CONNFRAME 已建立,无需重复连接。
r = ZAux_Direct_GetMtype(m_h, m_j[0], &mt);
if (r)
return r;
if (mt != 33)
{
r = ZAux_Direct_Connframe(m_h, 4, const_cast(m_j.constData()), 14, m_tableStart,
4, const_cast(m_v.constData()));
if (r)
return r;
}
}
else if (mode == 2)
{
// MTYPE=34 表示 CONNREFRAME 已建立,无需重复连接。
r = ZAux_Direct_GetMtype(m_h, m_v[0], &mt);
if (r)
return r;
if (mt != 34)
{
r = ZAux_Direct_Connreframe(m_h, 4, const_cast(m_v.constData()), 14, m_tableStart,
4, const_cast(m_j.constData()));
if (r)
return r;
}
}
m_mode = mode;
return 0;
}

4.手动运动界面。
下图是例程手动运动的界面。
【关节坐标系手动控制】的手动按钮是进行关节轴的手动运动的按下时会自动建立机械手的正解。
【直角坐标系手动控制】的手动按钮是进行虚拟轴XYZ的手动运动的按下时会自动建立机械手的逆解。当手动速度降低到一定值时会自动切换到寸动模式。

5.Delta机械手关节点位运动指令(正解模式)。

/************************************************************************************
任务编号: 无
函数功能: 关节轴或虚拟轴手动运动,正向、负向按钮按下时调用
Input: linear —— false:关节轴;true:虚拟轴
index —— 轴索引,范围为 0~3,不是控制器实际轴号
direction —— 运动方向,1:正向;-1:负向
Output: 无
返回值: 无
备注: 当前采用 ±999 的相对位移模拟按住运动,
松开按钮时调用 stopJog() 停止。
*************************************************************************************/
void MainWindow::startJog(bool linear, int index, int direction)
{
if (!motion.connected()) { log(QStringLiteral(u"控制器未连接")); return; }
const float speed = (linear ? ui->TX_SpeedL : ui->TX_SpeedJ)->text().toFloat();
const float milliseconds = (linear ? ui->TX_AccelL : ui->TX_AccelJ)->text().toFloat();
const float accel = milliseconds > 0 ? speed / (milliseconds / 1000.0f) : speed;
int result = motion.setSpeed(speed, accel, accel, 50);
if (!result) {
QVector displacement(4, 0.0f);
displacement[index] = direction * 999.0f;
result = linear ? motion.moveLinear(displacement, false) : motion.moveJoint(displacement, false);
}
if (result) showResult(QStringLiteral(u"手动运动"), result);
}
int DeltaMotion::setSpeed(float speed, float accel, float decel, float sramp) const
{
if (check() || m_homeActive || !qIsFinite(speed) || !qIsFinite(accel)
|| !qIsFinite(decel) || !qIsFinite(sramp) || speed <= 0 || accel <= 0 || decel <= 0 || sramp < 0)
return -1;
// 两种运动模式共用一套速度设置,因此同时更新虚拟轴和关节轴。
for (const QVector* axes : {&m_v, &m_j})
for (int a : *axes)
{
int r = controllerCall([&] { return ZAux_Direct_SetSpeed(m_h, a, speed); });
if (r)
return r;
if ((r = controllerCall([&] { return ZAux_Direct_SetAccel(m_h, a, accel); })))
return r;
if ((r = controllerCall([&] { return ZAux_Direct_SetDecel(m_h, a, decel); })))
return r;
if ((r = controllerCall([&] { return ZAux_Direct_SetSramp(m_h, a, sramp); })))
return r;
if ((r = controllerCall([&] { return ZAux_Direct_SetForceSpeed(m_h, a, speed); })))
return r;
}
return 0;
}
int DeltaMotion::moveJoint(const QVector& v, bool abs, int zone, float speed) const
{
if (check() || m_homeActive || v.size() < 4 || (zone != 0 && zone != -1))
return -1;
for (float value : v)
if (!qIsFinite(value)) return -1;
int r = establish(1);
if (r)
return r;
if (speed != -1 && (r = setBufferedSpeed(false, speed)))
return r;
float values[4];
for (int i = 0; i < 4; ++i)
values[i] = v[i];
const int result = controllerCall([&] {
return abs ? ZAux_Direct_MoveR2_JABS(m_h, 4, const_cast(m_j.constData()), values)
: ZAux_Direct_MoveR2_J(m_h, 4, const_cast(m_j.constData()), values);
});
return finishTrajectory(result, zone);
}
/************************************************************************************
任务编号: 无
函数功能: 停止手动运动,关节轴或虚拟轴手动按钮松开时调用
Input: 无
Output: 无
返回值: 无
备注: 当前停止整个运动模式对应的四个轴,
不是只停止刚才按下按钮对应的单个轴。
本函数不主动断开正逆解连接。
*************************************************************************************/
void MainWindow::stopJog()
{
// 停止当前运动模式对应的轴组。
// 虚拟轴模式停止四个虚拟轴,关节轴模式停止四个关节轴。
const int result = motion.stop();
// 停止失败时,将返回码写入日志。
if (result) log(QStringLiteral(u"手动停止失败 %1").arg(result));
}
int DeltaMotion::stop() const
{
if (check())
return -1;
m_homeCancelled = true;
const QVector& axes = m_mode == 2 ? m_v : m_j;
return controllerCall([&] { return ZAux_Direct_CancelAxisList(m_h, 4, const_cast(axes.constData()), 2); });
}
6.Delta机械手直线运动指令(逆解模式)。

/************************************************************************************
任务编号: 无
函数功能: 关节轴或虚拟轴手动运动,正向、负向按钮按下时调用
Input: linear —— false:关节轴;true:虚拟轴
index —— 轴索引,范围为 0~3,不是控制器实际轴号
direction —— 运动方向,1:正向;-1:负向
Output: 无
返回值: 无
备注: 当前采用 ±999 的相对位移模拟按住运动,
松开按钮时调用 stopJog() 停止。*************************************************************************************/
void MainWindow::startJog(bool linear, int index, int direction)
{
if (!motion.connected()) { log(QStringLiteral(u"控制器未连接")); return; }
const float speed = (linear ? ui->TX_SpeedL : ui->TX_SpeedJ)->text().toFloat();
const float milliseconds = (linear ? ui->TX_AccelL : ui->TX_AccelJ)->text().toFloat();
const float accel = milliseconds > 0 ? speed / (milliseconds / 1000.0f) : speed;
int result = motion.setSpeed(speed, accel, accel, 50);
if (!result) {
QVector displacement(4, 0.0f);
displacement[index] = direction * 999.0f;
result = linear ? motion.moveLinear(displacement, false) : motion.moveJoint(displacement, false);
}
if (result) showResult(QStringLiteral(u"手动运动"), result);
}
int DeltaMotion::setSpeed(float speed, float accel, float decel, float sramp) const
{
if (check() || m_homeActive || !qIsFinite(speed) || !qIsFinite(accel)
|| !qIsFinite(decel) || !qIsFinite(sramp) || speed <= 0 || accel <= 0 || decel <= 0 || sramp < 0)
return -1;
// 两种运动模式共用一套速度设置,因此同时更新虚拟轴和关节轴。
for (const QVector* axes : {&m_v, &m_j})
for (int a : *axes)
{
int r = controllerCall([&] { return ZAux_Direct_SetSpeed(m_h, a, speed); });
if (r)
return r;
if ((r = controllerCall([&] { return ZAux_Direct_SetAccel(m_h, a, accel); })))
return r;
if ((r = controllerCall([&] { return ZAux_Direct_SetDecel(m_h, a, decel); })))
return r;
if ((r = controllerCall([&] { return ZAux_Direct_SetSramp(m_h, a, sramp); })))
return r;
if ((r = controllerCall([&] { return ZAux_Direct_SetForceSpeed(m_h, a, speed); })))
return r;
}
return 0;
}
int DeltaMotion::moveLinear(const QVector& v, bool abs, int zone, float speed) const
{
if (check() || m_homeActive || v.size() < 4 || (zone != 0 && zone != -1))
return -1;
for (float value : v)
if (!qIsFinite(value)) return -1;
int r = establish(2);
if (r)
return r;
if (speed != -1 && (r = setBufferedSpeed(true, speed)))
return r;
float values[4];
for (int i = 0; i < 4; ++i)
values[i] = v[i];
const int result = controllerCall([&] {
return abs ? ZAux_Direct_MoveRV_LABS(m_h, 4, const_cast(m_v.constData()), values, -1)
: ZAux_Direct_MoveRV_L(m_h, 4, const_cast(m_v.constData()), values, -1);
});
return finishTrajectory(result, zone);
}
/************************************************************************************
任务编号: 无
函数功能: 停止手动运动,关节轴或虚拟轴手动按钮松开时调用
Input: 无
Output: 无
返回值: 无
备注: 当前停止整个运动模式对应的四个轴,
不是只停止刚才按下按钮对应的单个轴。
本函数不主动断开正逆解连接。
*************************************************************************************/
void MainWindow::stopJog()
{
// 停止当前运动模式对应的轴组。
// 虚拟轴模式停止四个虚拟轴,关节轴模式停止四个关节轴。
const int result = motion.stop();
// 停止失败时,将返回码写入日志。
if (result) log(QStringLiteral(u"手动停止失败 %1").arg(result));
}
int DeltaMotion::stop() const
{
if (check())
return -1;
m_homeCancelled = true;
const QVector& axes = m_mode == 2 ? m_v : m_j;
return controllerCall([&] { return ZAux_Direct_CancelAxisList(m_h, 4, const_cast(axes.constData()), 2); });
}
轨迹前瞻与基础速度规划
正解模式下Mover2运动指令为例。
一.速度、加速度设置
1.FORCE_SPEED
点位运动(PTP:MOVER2_JABS/PABS/ARCHP)
?通过关节轴主轴号设置运行速度,取值0~1.0(1=满速)。
?MOVER2_JABS关节轴→取关节主轴号。
?修改后各关节轴速度与加速度柔性变化。
轨迹运动(MOVER2_L/ARC/ARCHPL)
?线速度:虚拟主轴号FORCE_SPEED(虚拟主轴),单位mm/s。
?末端旋转/偏摆速度:虚拟旋转轴号FORCE_SPEED(旋转轴),单位度/s(如delta/SCARA的RX轴)。
?若末端RX旋转轴FORCE_SPEED=0或加速度=0,内部自适应规划。
2.ACCEL/DECEL
轨迹线加速度/减速度:
?虚拟主轴ACCEL(虚拟主轴)/DECEL(虚拟主轴),单位mm/s²。
末端姿态加速度/减速度:
?虚拟旋转轴ACCEL(旋转轴)/DECEL(旋转轴),单位度/s²。
int DeltaMotion::setSpeed(float speed, float accel, float decel, float sramp) const
{
if (check() || m_homeActive || !qIsFinite(speed) || !qIsFinite(accel)
|| !qIsFinite(decel) || !qIsFinite(sramp) || speed <= 0 || accel <= 0 || decel <= 0 || sramp < 0)
return -1;
// 两种运动模式共用一套速度设置,因此同时更新虚拟轴和关节轴。
for (const QVector* axes : {&m_v, &m_j})
for (int a : *axes)
{
int r = controllerCall([&] { return ZAux_Direct_SetSpeed(m_h, a, speed); });
if (r)
return r;
if ((r = controllerCall([&] { return ZAux_Direct_SetAccel(m_h, a, accel); })))
return r;
if ((r = controllerCall([&] { return ZAux_Direct_SetDecel(m_h, a, decel); })))
return r;
if ((r = controllerCall([&] { return ZAux_Direct_SetSramp(m_h, a, sramp); })))
return r;
if ((r = controllerCall([&] { return ZAux_Direct_SetForceSpeed(m_h, a, speed); })))
return r;
}
return 0;
}
二.普通连续轨迹平滑和几何倒角
模式1(普通cp模式):

普通CP按前一段保存的ZSMOOTH比例,提前启动下一段运动。前后两段在过渡区同时运行,控制器按两段的空间速度方向合成末端速度。
?ZSMOOTH越大,前后段重叠时间通常越长,拐角越圆,运行效率越高。
?固定ZSMOOTH后改变FORCE_SPEED,前后段的加速、减速和重叠距离会改变,因此末端经过拐角的几何形状也会改变。
?急转角、短段、方向抵消或其它轴达到限制时,合成线速度可能低于FORCE_SPEED。速度保护不会为了维持恒速而突破轴能力。
int DeltaMotion::smooth(float value) const
{
if (check() || m_homeActive || !qIsFinite(value) || value < 0 || value > 100)
return -1;
int result = controllerCall([&] { return ZAux_Direct_SetZsmooth(m_h, m_j[0], value); });
if (result)
return result;
result = controllerCall([&] { return ZAux_Direct_SetZsmooth(m_h, m_v[0], value); });
if (result)
return result;
return controllerCall([&] { return ZAux_Direct_MOVER2_ZSMOFFSET(m_h, -1); });
}

【平滑系数等级为0时规划速度】

【平滑系数等级为0时规划位置】

【平滑系数等级为100时规划速度】

【平滑系数等级为100时规划位置】
模式2(几何倒角):

设置CORNER_MODE=32+512后,控制器在轨迹进入执行队列时,根据相邻LINE/ARC的几何关系和ZSMOOTH生成过渡轨迹。
几何倒角同时支持轨迹中的姿态轴、机械手辅助轴和已开启的外部轴变化。位置和其它通道会沿同一倒角区间连续过渡,避免在内部段边界直接跳变。
?只有相邻的直线指令和圆弧指令能生成几何倒角;关节指令等PTP与轨迹之间不能生成固定半径圆角。
?ZSMOOTH是参考倒角半径/倒角尺度。转角不是90°、前后段过短或圆弧几何受限时,实际倒角会按可用路径自动缩小。
int DeltaMotion::setCornerMode(int iValue = 32 + 512) const
{
if (check() || m_homeActive || iValue < 0)
return -1;
// 为虚拟轴 (m_v[0]) 设置拐角模式 CORNER_MODE = 32 + 512
int result = result = controllerCall([&] { return ZAux_Direct_SetCornerMode(m_h, m_v[0], iValue); });
if (result)
return result;
// 原 smooth 函数末尾是运动平滑偏移指令,SetCornerMode 属于参数配置,配置成功返回 0
return 0;
}
【(CORNER_MODE=32+512,ZSMOOTH=10)速度规划】

【(CORNER_MODE=32+512,ZSMOOTH=10)轨迹规划】
二.两种模式的对比
两种连续过渡方式。两种方式都可以减少相邻轨迹段之间的停顿,但轨迹含义不同。

“连续”不等于“任何情况下恒速”。无论使用哪种方式,轨迹仍必须满足用户设置的线加减速度、加加速度、姿态轴、外部轴和关节轴能力。
普通CP适合追求效率和整体光顺的运动。对于不同加工速度必须保持相同材料去除轨迹的场景,建议使用几何倒角或显式编写圆弧/样条轨迹。
Delta机械手仿真工具使用
打开【ZRobotView】软件,点击【连接】输入控制器的IP(默认IP:192.168.0.11),点击连接,待连接成功后点击切换即可3D仿真机械手的运动情况。


教学视频请点击→WindowsLinux下强实时运动控制内核(二)基于Qt的Delta机械手的开发应用
完整代码获取地址
▼


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