CodeSys运动控制进阶:MC_MoveAdditive与Superimposed叠加运动实战解析
很多PLC工程师做运动控制起步都是从JOG和点位定位开始的。JOG负责手动点动MC_MoveAbsolute、MC_MoveRelative负责把轴送到固定位置。但设备跑起来以后如果还要在线叠一段修正量、改一下运行速度这套老办法就不灵了——要么把轴停下来改参数要么在工艺上绕弯子。CodeSys里的MC_MoveAdditive和SuperImposed指令专门处理这种“运动中再加一段运动”的叠加需求。这篇文章我把这两个指令的原理、区别以及和在线调速配合的实战方式一次讲清楚适合被现场工艺“逼着”进阶的PLC工程师。1. 先搞懂“动中改”的需求才知道MC_MoveAdditive有多香1.1 传统JOG和定位能解决什么做运动控制这些年我看到太多同行对运动控制的理解停留在“JOG 回原点 绝对定位/相对定位”这个阶段。JOG一般只在调试时用来手动点动试方向、找原点定位指令则适合那种目标位置固定、轴可以自由启停的场合比如上料台、升降机构、简单的分度转盘。这类应用有一个共同点轴的动作是由“待机状态”启动走到目标位置后停止等待下一次命令。整个过程目标值明确运动轮廓可控就算中途要改位置也得先取消当前定位命令再下发新的定位命令。如果设备停下来再改问题不大可一旦设备在全速连续运行需要在线插入一段修正运动传统方式就会非常尴尬。举个最常见的例子贴标机的送料轴正在以固定速度连续送膜色标检测到当前标签位置有偏差需要快速补偿几毫米。如果你用MC_Stop停止再重新给定位命令整个产线都会停顿后续工序全部乱掉。这就是我理解“动中改”需求的第一步——必须在不打断当前运动的前提下插入一段附加运动。1.2 连续运动中的增量修正所谓叠加运动用大白话讲就是主体运动不发生中断只是在当前运动轨迹上额外叠加一段增量运动。类比开车主命令是“保持100公里/小时巡航”叠加运动就相当于巡航途中你轻踩一脚油门超车超完以后车辆自动回到正常车速继续跑整个巡航状态并没有被取消。在PLCopen运动控制体系里MC_MoveAdditive就是用来干这件事的。它能够在一个正在执行的运动命令基础上附加一段相对位移而不会把原来的运动命令清除掉。注意这和MC_MoveRelative完全是两个语义MC_MoveRelative本质上是新的运动命令如果不加缓冲区设置它会把轴当前的运动直接打断MC_MoveAdditive则更像“插队”在当前运动轮廓里多叠加一段修正距离。SuperImposed标准拼写是Superimposed机制则是更广义的“叠加”概念。它既能用在单轴上也可以通过叠加轴/主从轴的配置把一段附加运动叠到已经存在的连续运动上。很多色标追踪、电子凸轮相位补偿、飞剪动态追剪的应用底层用的都是这个思路。1.3 典型适用场景与设备我实际接触到的场景主要有这么几类。第一类是连续送料/进给轴的位置补偿。比如包装机、印刷机、贴标机主轴保持匀速送料从产品上游检测到的位置误差通过叠加指令实时修正确保每一次切标、贴标位置准确。第二类是飞剪和动态剪切。飞剪最核心的动作就是“跟着材料走的同时完成剪切动作”这里既有电子齿轮同步又需要在同步基础上叠加一段剪切速度。只靠纯电子齿轮做不到这一点必须引入叠加运动。第三类是卷绕和张力控制。卷径变化、材料打滑、张力波动都会造成位置误差与其频繁改动主速度不如在张力辊轴上叠加一段微小修正量让系统保持平滑。顺便提一句现在国内很多PLC用的都是CodeSys内核比如汇川的H5U/Easy系列、台达部分系列指令体系跟“CODESYS 3.5 SoftMotion”基本一致下面的方法换平台也能照搬。很多朋友在入门时总纠结“CODESYS怎么下载”“手册在哪”其实官网安装包和软件自带的帮助文件就够了真没必要到处找百度云资料。工程联机方面先把PLC的IP地址和MAC地址对应关系确认好再谈轴配置和功能块不然连不上轴参数都没法监视。2. 指令拆解MC_MoveAdditive和Superimposed到底怎么用2.1 MC_MoveAdditive功能块关键参数在CodeSys SoftMotion库中MC_MoveAdditive的调用方式和其他运动控制块类似关键看几个引脚。引脚类型说明ExecuteBOOL上升沿触发一次叠加运动AxisAXIS_REF_SM3要执行叠加运动的轴引用DistanceREAL叠加的相对位移正负代表方向VelocityREAL叠加运动过程中的速度AccelerationREAL加速度DecelerationREAL减速度JerkREAL加加速度0表示梯形加减速BufferModeMC_BUFFER_MODE与当前运动命令的缓冲/混合方式DoneBOOL叠加运动完成BusyBOOL叠加运动执行中CommandAbortedBOOL命令被其他命令中止ErrorBOOL错误标志大部分参数都容易理解最容易出问题的是BufferMode。默认情况下很多运动指令会采用ABORTING模式意思是“新命令一来旧命令立刻退位”。如果主轴正在执行MC_MoveVelocity连续运行你用默认的ABORTING去执行MC_MoveAdditive主轴连续运动会先被打断等叠加运动走完之后轴就停住了。正确的做法是把BufferMode设成BLENDINGNEXT、BUFFERED这一类模式让叠加运动附着在当前运动后面执行。Jerk这个参数也容易被忽略。速度变化不突变时Jerk设置为0通常够用但如果叠加距离很小、速度要求又高可以考虑增加Jerk做S曲线规划能明显减少机械冲击和震动。2.2 Superimposed叠加轴与MC_MoveSuperImposed如果你接触过PLCopen标准还会看到另一个指令叫MC_MoveSuperImposed。它和MC_MoveAdditive的定位略有不同MC_MoveAdditive你可以理解为“在同一根轴上叠加一段位移”而MC_MoveSuperImposed更强调“叠加轴”的概念。什么叫叠加轴我打个比方主轴是一辆行驶中的列车列车自身有一个运动状态而你在列车车厢里又放了一个可移动的小车小车可以相对列车再走一段距离。对外部世界来说小车最终的运动是“列车运动 小车自身运动”的叠加结果。在机器上这个“小车”可能是凸轮滚子、飞剪刀座、或者是某个精细的补偿轴。在CodeSys SoftMotion里你可以预先配置一根从轴把它定义成“叠加轴”指定它的主轴是哪一个。之后执行MC_MoveSuperImposed时附加的增量运动就会作用在这根叠加轴上同时不会影响主轴的连续运动。这种结构特别适合电子凸轮上的相位修正、印刷机的套准补偿因为修正量通常只作用于局部而不是重新改写主轴运动。如果你只是单轴设备上做简单修正用MC_MoveAdditive就够了没必要非去配叠加轴但如果是多轴联动、主从耦合的机构建议认真理解Superimposed轴方式它能把连续运动和补偿运动彻底分开程序逻辑会清晰很多。2.3 两个方案怎么选根据自己的实际项目我一般按下面的思路来选择。维度MC_MoveAdditiveMC_MoveSuperImposed / 叠加轴对象轴数量单轴主轴从轴或叠加轴配置复杂度低直接在轴引用上调用较高需要创建叠加轴并指定Master最合适的场景连续运动中的单轴修正、在线改位置主从轴耦合、电子凸轮相位修正、飞剪动态补偿对当前命令的影响通过BufferMode控制可保持当前运动天然叠加在主运动之上不影响主命令调试难度中等较高需要关注主轴和从轴的位置关系实际项目里我不是非黑即白地用一个。简单的辊筒补偿、送料误差修正直接用MC_MoveAdditive如果设备本身就有电子齿轮、凸轮表或者复杂的轴组我会用Superimposed叠加轴去做这样主轴的运动规划完全不受修正逻辑影响后期维护也更容易。3. 在线调速与运动叠加的实战组合3.1 在线调速别用“重新触发”来做先说一个大家容易踩的坑在线调速不是重新给MC_MoveVelocity的Execute一个上升沿就行。重新触发一次速度运动等于把原来的运动命令打断轴的加速度曲线可能会重新走一遍设备会有明显一顿的感觉甚至可能导致跟随误差瞬间变大。正确的在线调速方案是用速度倍率指令常见的是MC_SetOverride不同版本的库可能叫SMC_SetControllerOverride之类的名称原理一致。这个功能块可以实时地改变轴的运动速度倍率作用范围是从0到1或者0到100%它不会中断当前运动命令只会缩放当前运动的速度。代码风格大致是这样MC_SetOverride_0( Axis : AxisRefMain, Enable : TRUE, Override : rSpeedPercent // 0.5就是50%速度1.0就是100%速度 );实战中这个rSpeedPercent可以从HMI上直接写也可以用Modbus RTU从触摸屏、上位机或者模拟量模块读取。我在一些老设备改造时就用Modbus RTU读外部电位器转成倍率值效果很稳定。3.2 工艺场景连续送料轴 色标偏差修正 在线倍率下面我完整演示一个可复现的案例。假设有一根送料轴正常工作速度是100mm/s材料连续向前走。在材料进入下一道工序前色标检测器检测到当前标签位置有偏差需要在线补偿30mm。同时操作员在HMI上可以随时把整线速度从100%调到120%也可以降到80%不能停机。如果不用叠加运动这个工艺基本没法做——要么停下来手动调要么只能由主PLC计算出新的同步关系。而有了MC_MoveAdditive主程序逻辑可以非常清晰主轴一直执行MC_MoveVelocity连续运动检测到偏差时触发一次MC_MoveAdditive在连续运动之上叠一段30mm的修正位移操作员调速只是改变MC_SetOverride的倍率值三条路径完全独立。先声明主程序和功能块VAR bRun : BOOL; // 主轴运行命令 bAddCmd : BOOL; // 叠加修正触发信号 rBaseSpeed : REAL : 100.0; // 基础速度 mm/s rCompValue : REAL : 30.0; // 叠加修正量 mm rSpeedPercent : REAL : 1.0; // 在线调速倍率 MC_MoveVelocity_0 : MC_MoveVelocity; MC_MoveAdditive_0 : MC_MoveAdditive; MC_SetOverride_0 : MC_SetOverride; R_TRIG_Add : R_TRIG; END_VAR主轴连续运动启动MC_MoveVelocity_0( Execute : bRun, Axis : AxisRefMain, Velocity : rBaseSpeed, Acceleration : 500.0, Deceleration : 500.0, Jerk : 0.0 );当色标检测到偏差时置位bAddCmd通过上升沿触发叠加运动。这里建议用R_TRIG避免Execute一直被置位导致同一个叠加命令重复执行R_TRIG_Add(CLK : bAddCmd); IF R_TRIG_Add.Q THEN MC_MoveAdditive_0.Execute : TRUE; END_IF MC_MoveAdditive_0( Execute : MC_MoveAdditive_0.Execute, Axis : AxisRefMain, Distance : rCompValue, Velocity : 80.0, // 叠加运动速度 Acceleration : 400.0, Deceleration : 400.0, Jerk : 0.0, BufferMode : MC_BUFFERMODE_BLENDINGNEXT, // 关键不要用ABORTING Done bAddDone, Busy bAddBusy, CommandAborted bAddAborted, Error bAddError );这里有几个关键点要记住。第一BufferMode一定要选好。我实测下来主轴连续运行时用BLENDINGNEXT叠加运动能很平滑地插进来完成后主轴继续按原速跑。用ABORTING的话主轴会停下来整个工艺直接崩。第二叠加运动执行期间MC_MoveAdditive_0.Execute要保持有效还是自动复位很多版本的功能块要求Execute保持高电平直到Done或者CommandAborted。所以上面的写法里我用MC_MoveAdditive_0.Execute自身作为下一次的输入这在某些功能块实现里是可行的但你也要确认自己用的库版本对Execute时长的要求。如果版本要求必须恒定为真就把状态逻辑改成一个Set/Reset结构确保Execute在Done之前不被清掉。第三在线调速的倍率值rSpeedPercent不要直接从0跳到1.2建议在PLC里做斜坡处理比如每个扫描周期最多改变0.001让机械平稳加速。MC_SetOverride本身只负责缩放不会帮你做平滑。3.3 参数计算叠加距离、速度、加速度的匹配在线修正看起来只是“给一个距离”但如果你不做速度规划机器就会很难受。我一般会先算一组速度规划参数。经典的加速距离公式加速距离 v² / (2a)如果按上面案例叠加运动速度是80mm/s加速度是400mm/s²那么加速段距离80² / (2×400) 6400 / 800 8mm同理减速段距离也是8mm加起来16mm。修正量是30mm大于16mm所以能跑出一个有匀速段的梯形速度曲线。如果修正量只有10mm而你强行把速度设80mm/s那根本到不了设定速度就会形成一个三角波速度曲线边加速边减速对机械冲击很大。所以现场调试时我的习惯是叠加量越小叠加速度就设得越低。比如只有3mm修正量时叠加速度甚至只给20mm/s加速度可以给到300mm/s²这样电机能够在短距离内快速启停又不会撞击机械。在线调速对叠加运动的影响也要提前想清楚。MC_SetOverride的倍率会作用在轴的整体运动上也就是说当你把整线速度从100%调到120%时叠加运动的速度和距离也会被按比例缩放。如果客户要求“无论整线怎么变速补偿量都必须精确30mm”那光靠Override倍率不行需要在触发叠加前把rCompValue先除以当前倍率换算成实际距离或者在叠加运动执行期间暂时锁住倍率变化。3.4 调试步骤与现场心得第一次在现场玩叠加运动建议按下面的顺序来。先在CodeSys里建虚拟轴调试。SoftMotion支持虚拟轴把所有指令先跑通观察Busy、Done、CommandAborted的状态变化尤其要看MC_MoveAdditive执行期间主运动有没有被意外打断。虚拟轴上把状态机搞明白能省下大量现场时间。再用小叠加量试。真正上伺服轴以后第一次叠加量建议不超过1mm让速度慢慢加上去观察机械有没有异响、电机有没有抖动。确认没问题以后再逐步加大到3mm、10mm、30mm。接着用Trace工具观察曲线。CodeSys的Trace功能非常实用把目标位置、实际位置、速度反馈同时记录下来看叠加运动期间有没有丢步、过冲、跟随误差偏大。如果速度曲线在叠加开始和结束时有明显突变就适当降低速度或增加Jerk。最后一定要做急停和复位测试。现场工艺要求叠加运动后急停能不能正常复位如果急停之后轴还在叠加运动状态下次启动会不会撞机这些都是要提前和机械、电气同事一起梳理的。4. 常见报错和调试问题我在现场踩过的坑4.1 典型故障速查表故障现象常见原因处理方法执行MC_MoveAdditive后主轴停住了BufferMode用了ABORTING当前运动被中断改成BUFFERED或BLENDINGNEXT叠加运动过程中有机械冲击速度过快或加速度过大叠加距离短形成三角波降低叠加速度增大加减速时间必要时加Jerk在线调速时叠加位移不准倍率同时缩放了叠加运动触发叠加前把叠加量换算成实际值或倍率锁存MC_MoveAdditive的Execute一直有效没法复位功能块状态机要求Execute保持但逻辑里没做复位用上升沿触发并锁存状态Done后复位Execute叠加运动触发后报错ErrorID轴处于未使能、回原点状态不对等先检查轴状态再复位错误重新使能多轴叠加时从轴位置偏差越来越大主轴和从轴没有建立同步关系检查电子齿轮、叠加轴Master配置必要时用MC_GearIn4.2 几个必须记住的避坑点第一叠加运动不是“随便插一段位置”那么简单它本质上是和当前运动命令做融合。因此你在写程序时必须清楚当前轴到底在执行什么命令、命令优先级是怎样的。我的经验是在一个轴的运动控制逻辑里最好只使用一个主运动指令比如MC_MoveVelocity或一个持续运行的定位指令其他修正动作全部用MC_MoveAdditive或叠加轴的方式避免多个运动指令互相抢占轴控制权。第二CommandAborted不是错误它只是告诉你“这个命令被别的命令中止了”。在急停、复位、切换模式时这个信号经常出现。你要做的不是在每次出现CommandAborted时就弹出报警而是把它作为一种状态切换提示在程序里妥善处理后续动作。比如急停后再启动要先把轴状态复位到正常再重新触发主运动。第三在线修改PLC程序要用好Online Change能力。CodeSys支持在线修改工程但运动控制块的状态机是实时运行的改程序时一定要小步快走不要一次性改一大片。我有一个教训在线修改时把BufferMode参数从BLENDINGNEXT改成了默认结果现场叠加运动直接打断了主轴幸好当时工艺速度不快不然后果很严重。第四关于国产CodeSys内核PLC比如汇川H5U/Easy系列很多朋友会花大量时间研究“怎么读MAC”“怎么改IP”“怎么下载工程”这些联机层面的事情相对简单照着设备文档做就行。真正拉开差距的还是指令状态机的理解和对运动控制逻辑的把握。等你把MC_MoveAdditive、Superimposed这些指令玩熟了再去回看那些联机问题真会觉得都是小事。第五如果你在调叠加运动时发现位置始终对不上先别怀疑指令先检查机械回差和伺服刚性。很多“运动控制软件问题”其实出在机械间隙、联轴器打滑、伺服刚性不足这些物理环节。CodeSys只能保证你发给它命令它去执行机械反馈不准再好的叠加算法也白搭。最后分享一个我自己的调试习惯每次现场调叠加运动我都先在程序里写一个“测试模式”把叠加量设成3mm、速度设成20%先在手动状态下触发测试确认机械动作正常再切自动。等这个习惯养成以后我后面再调飞剪、贴标机这类设备时基本没有出过大岔子。运动叠加这个东西不难难的是你对运动过程有没有敬畏心每一步都验证到位它就能成为你手上最好用的工具。