CODESYS轴组直线与圆弧插补实战:ST语言编程与调试指南
这次我们来看一个在工业自动化领域非常实用的技术主题:CODESYS 轴组控制中的直线与圆弧插补实战。对于从事PLC编程、运动控制,特别是使用CODESYS平台进行多轴协同开发的工程师来说,直线和圆弧插补是实现复杂轨迹(如切割、焊接、涂胶、搬运)的核心功能。很多资料停留在概念讲解,但实际部署时,如何配置轴组、编写ST语言程序、处理插补过程中的使能与停止,才是真正的难点。
本文不绕弯子,直接切入实战。我们将基于CODESYS开发环境,一步步完成从轴组配置、插补指令编写到轨迹验证的全过程。重点解决几个关键问题:如何用ST语言实现轴组直线/圆弧插补?插补过程中如何安全地使能和禁用设备?常见的“跟随误差超限”、“位置不可达”报警如何排查?无论你是控制汇川伺服还是其他品牌驱动器,这套方法都具有通用性。
文章将包含完整的代码实例、配置截图(以文字描述关键点代替)和调试心得。如果你手头有CODESYS环境(即使是仿真环境),完全可以跟着操作一遍,跑通一个完整的插补任务。
1. 核心能力速览
在深入代码之前,我们先快速了解CODESYS轴组插补的核心能力和本文涉及的实战要点。
| 能力项 | 说明与本文重点 |
|---|---|
| 核心功能 | 实现2D/3D空间内,多轴协同完成直线、圆弧、甚至更复杂轨迹的连续路径运动。 |
| 开发平台 | CODESYS Development System (V3.5 SP18 或更高版本推荐)。本文基于通用环境,方法适用于多数版本。 |
| 编程语言 | 主要使用ST (Structured Text) 语言,贴近PLC工程师习惯。 |
| 硬件门槛 | 支持CODESYS Runtime的PLC硬件(如倍福、汇川、雷赛等)或使用CODESYS SoftMotion Win V3在PC上进行仿真测试。本文演示以仿真为主,降低实操门槛。 |
| 关键对象 | MC_Groups库中的MC_GroupInterpolator、MC_MoveLinearAbsolute、MC_MoveCircularAbsolute等功能块。 |
| 联动能力 | 可与MC_Power(使能)、MC_Stop(停止)、MC_ReadActualPosition(读取位置) 等功能块配合,构建完整控制逻辑。 |
| 调试支持 | CODESYS Scope 或在线监控,实时查看轴组位置、速度、跟随误差,是排查问题的利器。 |
| 适合场景 | 激光切割机、焊接机器人、数控机床、涂胶机、高精度搬运站等需要复杂轨迹规划的场合。 |
2. 适用场景与使用边界
这个功能适合谁?
- 设备开发工程师:需要为自家设备编写复杂运动轨迹程序的工程师。
- 系统集成商:在集成多个伺服轴完成协同作业时,需要可靠的插补算法。
- 自动化专业学生/研究者:学习先进运动控制理论,并进行算法验证。
- 使用支持CODESYS平台的PLC用户:如倍福、汇川、欧姆龙等品牌的部分系列。
能解决什么问题?
- 轨迹平滑性:将离散的点位运动转换为连续、平滑的路径运动,避免在拐点处停顿或抖动。
- 多轴协同:精确控制多个电机在时间上和空间上的同步关系,保证末端执行器沿预定路径运动。
- 提升效率与精度:对于加工类应用,平滑的插补运动可以提高表面加工质量,减少机械磨损,并可能提升整体节拍。
不适合什么场景?
- 极度简单的点位运动:如果只是A点移动到B点,使用单轴的
MC_MoveAbsolute更简单直接。 - 对运动学正逆解有复杂需求:CODESYS标准插补是基于笛卡尔空间的。如果需要控制六轴机器人,通常需要额外的机器人库或自己实现运动学转换。
- 超高速、纳米级精度场景:虽然CODESYS SoftMotion性能强大,但极限性能仍取决于硬件PLC的循环周期和驱动器的性能。
安全与合规边界:
- 仿真先行:任何新的插补程序务必先在CODESYS SoftMotion 仿真环境中充分测试,确认轨迹正确、无超程风险后,再下载到实体PLC。
- 使能安全:程序必须包含完备的使能(
MC_Power)、停止(MC_Stop)、错误处理机制。急停信号必须能安全切断轴组电源。 - 机械限位:在硬件和软件层面都必须配置有效的限位保护,防止插补计算错误导致设备撞击硬限位。
3. 环境准备与前置条件
工欲善其事,必先利其器。开始插补编程前,请确保你的开发环境已就绪。
CODESYS 开发环境:
- 从官网下载并安装CODESYS Development System。建议使用 V3.5 SP18 或以上版本,其对 SoftMotion 的支持更完善。
- 安装时,务必勾选“SoftMotion”相关组件。这是实现多轴插补的基础。
运动控制库:
- 新建项目后,需要添加必要的库。核心库是
MC_Groups和MC2_Groups(取决于版本),它们包含了轴组和插补器功能块。 - 通常还需要
MC_Basic或MC2_Basic库,用于单轴控制功能块(如使能、停止)。 - 在项目树的“库管理器”中右键添加。
- 新建项目后,需要添加必要的库。核心库是
仿真或硬件配置:
- 仿真测试(推荐初学者):在设备树中添加一个“SoftMotion Win V3”设备。这将创建一个虚拟的运动控制环境,可以添加虚拟轴进行测试,无需真实硬件。
- 真实硬件连接:需要正确配置你的PLC设备(如倍福CX系列)、并添加对应的运动控制驱动设备,以及实际的伺服驱动器(如汇川IS620N)。这需要正确的EtherCAT或CANopen网络组态。
基础知识储备:
- 熟悉 ST 语言的基本语法。
- 理解单轴运动控制的基本概念:使能、回零、绝对/相对定位。
- 了解笛卡尔坐标系的基本概念(X, Y, Z)。
4. 项目创建与轴组配置
让我们从零开始,创建一个测试项目。
4.1 创建新项目与添加设备
- 打开CODESYS,创建新项目,选择“Standard project”,模板可选“Empty project”。
- 在设备树中,右键“Device”,选择“Add Device”。为了仿真,我们搜索并添加“SoftMotion Win V3”。
- 添加后,设备树下会出现“SM3_CNC”等组件,这就是我们的虚拟运动控制器。
4.2 添加虚轴并配置轴组
- 在“SM3_CNC”下,找到“Axes”。右键添加两个新轴,例如
Axis_1(作为X轴) 和Axis_2(作为Y轴)。 - 配置轴参数:在轴对象的“Parameter”中,可以设置单位(如毫米)、齿轮比、软限位等。仿真环境下保持默认亦可。
- 创建轴组:在“SM3_CNC”下找到“Kinematics”。右键添加一个新的“Cartesian Kinematics”(笛卡尔运动学)。这是定义轴组的关键。
- 在笛卡尔运动学的配置中,将
Axis_1分配给 X 轴,Axis_2分配给 Y 轴。一个简单的 XY 二维轴组就定义好了。你可以将其重命名为Group_XY。
4.3 导入必要的库
在项目树的“Library Manager”上右键,选择“Add Library”。
- 添加
Motion Control Groups(库名可能为MC_Groups或MC2_Groups)。 - 添加
Motion Control Basic(库名可能为MC_Basic或MC2_Basic)。 - 添加
Standard库(通常已默认包含)。
完成以上步骤,你的项目框架就搭建好了。接下来进入核心的编程环节。
5. ST语言编程实战:直线插补
我们将编写一个完整的程序组织单元(POU),实现让XY轴组从当前位置画一条直线到目标点。
5.1 定义变量与功能块实例
在POU的VAR区,我们需要声明以下关键变量:
VAR // 轴组使能 fbPowerGroup : MC_POWER_GROUP; bEnableGroup : BOOL := FALSE; bGroupEnabled : BOOL; bGroupError : BOOL; iGroupErrorID : UDINT; // 直线插补运动 fbMoveLinear : MC_MOVE_LINEAR_ABSOLUTE_GROUP; bStartLinear : BOOL := FALSE; bLinearBusy : BOOL; bLinearDone : BOOL; bLinearError : BOOL; iLinearErrorID : UDINT; // 目标位置 (基于组坐标系) fTargetX : LREAL := 100.0; // X轴目标位置 100 mm fTargetY : LREAL := 50.0; // Y轴目标位置 50 mm fVelocity : LREAL := 50.0; // 合成速度 50 mm/s fAcceleration : LREAL := 100.0; // 加速度 100 mm/s² fDeceleration : LREAL := 100.0; // 减速度 100 mm/s² // 轴组和插补器引用 refGroup : AXIS_GROUP_REF; // 指向我们配置的 Group_XY refInterpolator : INTERPOLATOR_REF; // 插补器引用 END_VAR5.2 主程序逻辑编写
在程序体部分,我们需要按顺序调用功能块:
// 1. 轴组使能 fbPowerGroup( AxisGroup:= refGroup, Enable:= bEnableGroup, Enable_Positive:= TRUE, Enable_Negative:= TRUE, Valid:= , Busy:= , Active:= , Error:= bGroupError, ErrorID:= iGroupErrorID ); bGroupEnabled := fbPowerGroup.Status; // 获取使能状态 // 只有当轴组使能成功后,才允许执行运动 IF bGroupEnabled THEN // 2. 触发直线插补运动 fbMoveLinear( AxisGroup:= refGroup, Interpolator:= refInterpolator, Execute:= bStartLinear AND NOT bLinearBusy, // 上升沿触发且不忙时执行 PositionX:= fTargetX, PositionY:= fTargetY, Velocity:= fVelocity, Acceleration:= fAcceleration, Deceleration:= fDeceleration, CoordSystem:= , // 使用组坐标系 BufferMode:= , // 默认缓冲模式 Done=> bLinearDone, Busy=> bLinearBusy, Active=> , CommandAborted=> , Error=> bLinearError, ErrorID=> iLinearErrorID ); // 3. 运动完成后,复位触发信号(可选,取决于你的控制逻辑) IF bLinearDone THEN bStartLinear := FALSE; END_IF END_IF5.3 在线测试与监控
- 登录到你的PLC(仿真PLC)。
- 将
bEnableGroup变量置为TRUE。观察bGroupEnabled是否变为TRUE,且无错误。 - 将
bStartLinear变量置为TRUE。你会看到bLinearBusy变TRUE,然后bLinearDone变TRUE。 - 使用CODESYS Scope工具,添加
Group_XY的ActualPositionX和ActualPositionY进行监控。你将看到两个轴协调运动,实际位置轨迹是一条从起点到 (100, 50) 的直线。
关键点:MC_MOVE_LINEAR_ABSOLUTE_GROUP功能块中的PositionX和PositionY是在轴组坐标系下的绝对坐标。插补器会自动计算每个轴各自需要运动的位置。
6. ST语言编程实战:圆弧插补
圆弧插补比直线稍复杂,需要定义圆心、终点和旋转方向。我们实现一个从起点 (0,0) 经过某点,画一个90度圆弧的例子。
6.1 新增圆弧插补变量
在VAR区添加:
VAR // 圆弧插补运动 fbMoveCircular : MC_MOVE_CIRCULAR_ABSOLUTE_GROUP; bStartCircular : BOOL := FALSE; bCircularBusy : BOOL; bCircularDone : BOOL; bCircularError : BOOL; iCircularErrorID : UDINT; // 圆弧参数 fArcCenterX : LREAL := 50.0; // 圆心 X 坐标 fArcCenterY : LREAL := 0.0; // 圆心 Y 坐标 fArcEndX : LREAL := 100.0; // 圆弧终点 X fArcEndY : LREAL := 50.0; // 圆弧终点 Y ePathChoice : MC_PATH_CHOICE := MC_PATH_CHOICE.ARC1; // 选择圆弧路径(通常有两条可能路径) eRotationDirection : MC_DIRECTION := MC_DIRECTION.POSITIVE; // 旋转方向:正向 END_VAR6.2 圆弧插补程序逻辑
在主程序中,在轴组使能成功后,添加圆弧插补逻辑:
// 在轴组使能成功的IF块内,与直线插补并列 IF bGroupEnabled THEN // 圆弧插补触发 fbMoveCircular( AxisGroup:= refGroup, Interpolator:= refInterpolator, Execute:= bStartCircular AND NOT bCircularBusy, CenterX:= fArcCenterX, CenterY:= fArcCenterY, EndX:= fArcEndX, EndY:= fArcEndY, PathChoice:= ePathChoice, RotationDirection:= eRotationDirection, Velocity:= fVelocity, Acceleration:= fAcceleration, Deceleration:= fDeceleration, CoordSystem:= , BufferMode:= , Done=> bCircularDone, Busy=> bCircularBusy, Active=> , CommandAborted=> , Error=> bCircularError, ErrorID=> iCircularErrorID ); IF bCircularDone THEN bStartCircular := FALSE; END_IF END_IF6.3 圆弧参数理解与调试
- 圆心与终点:
(CenterX, CenterY)定义了圆心坐标,(EndX, EndY)定义了圆弧终点坐标。起点是轴组的当前位置。因此,执行圆弧指令前,需要确保轴组处于正确的起始位置(例如通过之前的直线运动到达 (0,0))。 - 路径选择 (
PathChoice):给定起点、圆心、终点,通常有两条可能的圆弧(一大一小)。MC_PATH_CHOICE.ARC1和MC_PATH_CHOICE.ARC2用于选择其一。务必通过Scope监控或仿真可视化确认所选路径是否符合预期。 - 旋转方向 (
RotationDirection):定义从起点到终点绕圆心的旋转方向是正转 (POSITIVE) 还是反转 (NEGATIVE)。
测试步骤:
- 先执行一个直线运动到 (0,0) 作为圆弧起点。
- 设置好圆弧参数。
- 触发
bStartCircular。 - 在Scope中观察
ActualPositionX和ActualPositionY,其轨迹应为一个圆弧。也可以使用CODESYS自带的“Visualization”创建简单的动画来观察。
7. 关键问题:使能、停止与模式切换
在实际项目中,运动控制必须安全、可控。我们结合网络热词中提到的“禁用设备和使能设备”,来完善我们的程序。
7.1 安全的使能 (MC_Power) 与停止 (MC_Stop)
轴组的使能我们使用了MC_POWER_GROUP。对于单轴,也有对应的MC_POWER。使能必须在任何运动指令之前完成,并且需要处理使能失败的情况。
停止逻辑更为关键。我们添加一个紧急停止功能:
VAR fbStopGroup : MC_STOP_GROUP; bEmergencyStop : BOOL := FALSE; bStopDone : BOOL; bStopError : BOOL; iStopErrorID : UDINT; END_VAR // 在程序主循环中调用停止功能块 fbStopGroup( AxisGroup:= refGroup, Execute:= bEmergencyStop, Deceleration:= 500.0, // 急停减速度,应设置得比较大 Done=> bStopDone, Busy=> , Error=> bStopError, ErrorID=> iStopErrorID );当bEmergencyStop为TRUE时,无论轴组正在执行直线还是圆弧插补,都会立即以设定的减速度停止。停止后,需要重新使能 (bEnableGroup先FALSE再TRUE) 才能进行新的运动。
7.2 运动模式与缓冲模式
在MC_MoveLinear和MC_MoveCircular功能块中,有一个重要的参数BufferMode。它决定了新运动指令如何与当前正在执行的运动指令衔接。
mcAborting(默认):新指令会中止当前指令并立即开始。mcBuffered:新指令会被缓冲,在当前指令完成后自动开始。这对于实现连续路径(Contour)运动至关重要。mcBlendingLow/mcBlendingHigh:混合模式,新指令会在当前指令结束前一段时间开始,实现轨迹的平滑过渡,速度不会降到零。
连续路径示例:要画一个“方框”,可以依次发送四条直线指令,并将它们的BufferMode设置为mcBuffered。这样,轴组会在完成第一条边后无缝开始第二条边,中间没有停顿。
8. 资源占用与性能观察
在CODESYS中,轴组插补的性能和资源占用主要取决于以下几点:
- PLC循环周期:运动控制任务(通常是
Motion任务)的循环周期设置。周期越短(如1ms),控制越精细,但对PLC性能要求越高。在“任务配置”中设置。 - 插补器周期:在轴组或插补器参数中,可以设置插补计算周期。通常与运动控制任务周期一致或成倍数关系。
- 轴数量与复杂度:轴越多,插补计算量越大。三维圆弧插补比二维直线插补计算更复杂。
- 监控工具:
- 系统负载:在CODESYS菜单栏“Online” -> “Set Logging Options”中可以查看任务执行时间,判断是否超时。
- 跟随误差:通过Scope监控每个轴的
FollowingError。在稳定运动时,此值应在一个很小的范围内波动。如果持续增大,可能意味着加速度设置过高、驱动器增益不足或机械负载过大。 - 轨迹精度:通过Scope同时记录指令位置 (
CommandPosition) 和实际位置 (ActualPosition),可以直观看到跟踪效果。
仿真环境性能:在PC上使用SoftMotion Win V3仿真,性能通常不是问题。重点在于逻辑正确性。下载到实体PLC前,务必在仿真中完成所有轨迹测试。
9. 常见问题与排查方法
以下是轴组插补编程和调试中常见的“坑”及其解决方法。
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
轴组使能失败(bGroupError为 TRUE) | 1. 单轴未使能。 2. 轴组中存在硬件错误或禁止状态。 3. 软限位设置不当,当前位置已在限位外。 | 1. 检查轴组中每个单轴的MC_Power状态。2. 查看 iGroupErrorID具体错误码。3. 检查轴的 SoftwareLimitPositive/Negative参数和当前位置。 | 1. 确保所有单轴先单独使能成功。 2. 根据错误码手册排查硬件或配置问题。 3. 调整软限位或先执行回零操作。 |
直线/圆弧指令不执行(Busy不变 TRUE) | 1.Execute信号非上升沿或持续为低。2. 轴组未使能 ( bGroupEnabled为 FALSE)。3. 之前有运动未完成且 BufferMode冲突。4. 插补器 ( Interpolator) 引用错误。 | 1. 监控Execute输入信号,确保是脉冲。2. 确认 bGroupEnabled状态。3. 检查是否有其他运动指令正在执行 ( Busy)。4. 检查 refInterpolator是否链接到正确的插补器对象。 | 1. 使用边沿检测触发Execute。2. 完善使能逻辑。 3. 合理使用 Stop或等待当前指令完成。4. 在轴组配置中确认插补器实例名。 |
| 运动轨迹错误(不走直线或圆弧) | 1. 轴组坐标系定义错误(轴映射反了)。 2. 圆弧参数(圆心、终点、路径选择)计算错误。 3. 单位不统一(例如轴配置是度,程序输入是毫米)。 | 1. 检查“Cartesian Kinematics”中X/Y轴与物理轴的映射关系。 2. 在图纸上画出起点、圆心、终点,验证参数。 3. 检查轴参数中的“Position Factor”(位置因子)和“Velocity Factor”(速度因子)。 | 1. 校正轴映射。 2. 重新计算几何参数,或通过可视化工具辅助验证。 3. 确保工程中所有位置、速度、加速度单位一致。 |
| 运动过程中报“跟随误差超限” | 1. 加速度/减速度设置过高,驱动器跟不上。 2. 速度设置过高。 3. 驱动器增益参数(PID)未调好。 4. 机械负载过重或传动机构有间隙。 | 1. 监控FollowingError曲线,看是否在加速段急剧上升。2. 逐步降低速度、加速度测试。 3. 检查驱动器参数。 | 1. 适当降低加速度/减速度。 2. 降低运动速度。 3. 优化驱动器伺服增益。 4. 检查机械结构。 |
| 连续路径运动有停顿 | 1. 运动指令间的BufferMode未设置为mcBuffered或混合模式。2. PLC循环周期过长,导致指令处理延迟。 | 1. 检查连续发送的多条运动指令的BufferMode参数。2. 查看运动控制任务的实际循环时间。 | 1. 将后续指令的BufferMode设为mcBuffered。2. 缩短运动控制任务的循环周期(如果硬件允许)。 |
10. 最佳实践与工程化建议
将实验室代码变成稳定可靠的设备程序,还需要一些工程化思维。
- 模块化编程:将轴组使能、直线运动、圆弧运动、停止等功能封装成独立的函数或功能块(FB)。在主程序中清晰调用,提高可读性和可维护性。
- 状态机设计:使用状态机(例如枚举型变量)来管理设备的整个工作流程(如“初始化”、“使能中”、“待机”、“加工中”、“错误处理”)。使运动控制逻辑层次清晰。
- 参数化与配方:将目标位置、速度、加速度等运动参数定义为全局变量或从配方中读取。便于工艺调整和不同产品的快速切换。
- 全面的错误处理:不仅检查每个功能块的
Error输出,还要对ErrorID进行解析和处理。可以编写一个统一的错误处理函数,将错误代码转换为可读的文本信息发送到HMI。 - 仿真与测试用例:在仿真环境中,建立一套完整的测试用例,覆盖各种运动场景(单段、多段、连续、急停恢复等)。这是保证程序健壮性的最低成本方法。
- 文档与注释:在复杂的插补计算部分(如圆弧参数计算),务必添加详细的注释,说明公式来源和参数含义。这对后续维护和团队协作至关重要。
- 版本管理:使用CODESYS内置的版本管理或外部的Git工具对项目进行版本控制,特别是当程序需要适配不同型号设备或进行功能迭代时。
CODESYS的轴组插补功能非常强大,是实现高端运动控制的利器。从简单的直线、圆弧入手,理解其工作原理和编程模式,是迈向更复杂轨迹控制(如螺旋线、样条曲线)的坚实基础。建议你按照本文的步骤,在仿真环境中亲手实现一遍,遇到问题时,善用Scope监控和错误代码,大部分难题都能迎刃而解。
