ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

TwinCAT3运动控制实战:从使能、回零到定位的状态机编程

TwinCAT3运动控制实战:从使能、回零到定位的状态机编程 最近调一套多工位转台设备轴不多但涉及使能、回零、定位、急停复位这几个最基本的动作。本以为就是拖几个功能块、连一连线、下载一下的事结果真调起来才发现TwinCAT3这套运动控制库的脾气得摸清楚否则一个简单的使能都能折腾你半天。TwinCAT3的运动控制库本质上是基于PLCopen标准封装好的一批功能块从MC_Power到MC_Home再到MC_MoveAbsolute、MC_MoveVelocity这类运动指令它们的接口、时序、状态反馈都有一套固定逻辑。你不需要重新发明轮子但必须知道每个轮子该怎么转、什么时候该往前转、什么时候必须停下来。这篇内容就把这条从“给轴送上电”到“让轴回到原点、走到目标位置”的完整链路拆开讲结合我实际调试中踩过的坑展开。无论你刚接触TwinCAT3的伺服定位还是已经能写简单的点动程序、想系统梳理功能块时序这篇文章都值得你花十分钟读一遍。1. 先从整体看懂TwinCAT3运动控制的“套路”1.1 一个轴对象和一堆功能块的关系第一次接触TwinCAT3运动控制的人容易被满屏幕的功能块搞晕。MC_Power管使能MC_Reset管复位MC_Home管回零MC_MoveAbsolute管走绝对位置再加上MC_MoveVelocity、MC_Stop、MC_Halt……看起来彼此独立其实它们围绕着同一个目标服务一个在NC轴配置里被创建出来的轴对象Axis Reference。可以把轴对象想象成一台真实的伺服从站设备。你需要在TwinCAT的NC配置里先定义这个轴设置好单位、速度限制、加减速时间、软限位、回零模式这些基础参数。然后PLC程序里的功能块通过轴引用Axis Reference这个指针一样的变量去操作这台“虚拟伺服”。每个功能块并不是一调用就永久生效而是像发号施令一样给一个Execute的上升沿执行完成后会在Done、Active、CommandAborted这些输出上给你反馈。理解这个关系是后续所有编程的基础。指令与轴是分离的轴参数在系统配置里功能块只负责在运行中下达命令、读取状态。你在程序里看到几十个功能块实例其实它们操作的可能只是同一个轴对象。1.2 为什么必须用状态机来管理轴很多初学者在PLC里写了这样一段逻辑按一下启动按钮就把MC_Power的Enable置TRUE同时又去触发MC_Home、MC_MoveAbsolute最后发现轴完全乱套或者干脆不动。原因在于运动控制指令大多是“边沿触发、持续监控”的。MC_Power需要始终给定Enable信号才能保持使能而MC_Home的Execute只需要一个上升沿命令下发后由功能块自己追踪执行过程你强行重复触发反而会中断当前动作。这种情况下用散乱的点表逻辑去管理一个轴程序规模一上去就注定失控。所以我个人的习惯是不管项目再小都先用状态机把轴的生命周期理清楚。状态机里的状态可以很直观地用枚举变量定义IDLE空闲、POWER_ON使能中、FAULT_RESET故障复位、HOMING回零、READY就绪、MOVING运动中、STOPPING停止中。每个PLC扫描周期轮询一次状态根据当前状态决定该调用哪些功能块、给什么信号。这样逻辑清晰排查问题也方便出故障时直接看当前状态就知道卡在哪一步。2. 三个绕不开的基础功能块MC_Power、MC_Reset、MC_Home2.1 MC_Power让伺服真正“通电”的关键MC_Power是轴控制的“总开关”。在TwinCAT3里它的主要输入输出如下Enable总使能信号为TRUE时允许轴通电。bRegulatorOn调节器使能类似驱动器的伺服使能。bDriveStart驱动启动信号对应驱动器的“上电”指令。Status轴是否已正常通电的状态反馈。Error、ErrorID使能过程中出现的故障信息。在调试现场最常见的现象是Enable、bRegulatorOn、bDriveStart全都给了TRUEAxisRef上的实际电压和状态字也显示已经使能但轴一动就报警或者压根没有力矩。这时候多半不是MC_Power的问题而是轴参数里限位、跟随误差报警阈值、速度限制设置不合理。但MC_Power本身也有使用细节。比如急停回路很多项目要求急停断开时轴必须立刻断电此时不能只把Enable置FALSE就完事要考虑是尽快封锁使能还是先执行MC_Stop停车再断使能。如果负载有垂直轴、重力轴贸然断使能会导致溜车这种场合需要先保持使能并给出抱闸信号等轴停稳再断使能。MC_Power虽然简单但它背后关联的安全逻辑一点都不能简单。2.2 MC_Reset故障解除了怎么让轴恢复轴在运行中报了错比如跟随误差超差、驱动器过流、通讯中断Twincat的轴状态会被置成故障。这时候不管你怎么按启动按钮轴都不会执行任何运动指令。必须先清除故障、复位错误状态让轴状态机回到Standstill或Disabled才能继续操作。MC_Reset就是干这件事的。它的输入Execute需要上升沿触发执行成功输出Done如果复位条件不满足会一直处于Busy。使用时有几个经验复位前先检查硬条件轴驱动器是否已经准备好、急停是否已经复位、通讯是否恢复。驱动器本身处于故障状态时光靠MC_Reset可能无法清掉错误需要先处理驱动器端报警。MC_Reset不能和MC_Power同时“抢”轴。有些版本里如果使能信号还保持TRUE复位逻辑会纠结到底要不要切断驱动状态。建议的时序是先将MC_Power的Enable置FALSE等待轴状态回到Disabled或Standstill并伴随ErrorID出现再触发MC_Reset。复位完成后别急着发运动指令。我给你一个参考状态机报错后记录ErrorID到日志手动确认故障原因按复位按钮程序先把MC_Power的Enable拉低然后触发MC_Reset等MC_Reset.Done为TRUE且当前轴状态字无错误标志再重新执行使能流程。这样一套流程下来轴可以稳定恢复不会出现“复位了但一动又报错”的循环。2.3 MC_Home回零不是随便按一个按键那么简单MC_Home是用来让轴建立原点坐标的功能块。对不同工艺来说原点的定义不同有些设备直接以机械原点为位置零点有些则以夹具工位为原点还有的只是需要知道当前位置而并不需要真正的“回零动作”。MC_Home最常用也最容易搞错的参数是Mode。常见模式有Mode0当前轴位置直接被定义为原点不执行任何查找动作适合绝对编码器或已知物理位置的场合。Mode1当前位置设为原点同时设置一个偏移量适合把某个工位定义为坐标基准。Mode3找正方向或负方向的限位开关开关触发后再找零脉冲如果驱动器支持适合增量编码器系统。如果你用增量编码器伺服上电后轴的实际位置是未知的。你直接发一个MC_MoveAbsolute给一个绝对位置系统会报错或者走到错误的位置。正确做法是上电使能后先执行MC_Home等MC_Home的Done信号为TRUE轴已经建立原点坐标才能执行绝对定位指令。回零参数的设定同样关键。CalibrationVelocity指的是找开关时的速度速度太快容易冲过头太慢影响节拍MaxDistance则是回零搜索的最大距离也就是轴在这个距离内找不到原点传感器就要报错。实际项目中回零方向必须和限位开关安装位置对齐否则轴会往反方向一直找开关直到撞到硬限位。这些都是要结合机械结构去确认的。3. 运动指令与连续控制的实操细节3.1 MC_MoveAbsolute与MC_MoveVelocity的使用差异MC_MoveAbsolute是绝对定位指令它的关键输入包括Position目标绝对位置。Velocity运动速度单位由轴参数里的单位定义决定常见是mm/s。Acceleration、Deceleration加减速度。Jerk加加速度即加速度的变化率用于减小机械冲击。BufferMode缓冲模式决定新指令和当前指令的衔接方式。很多人不理解为什么要单独设置Acceleration和Deceleration。其实加减速分开设很实用比如下降轴为了减小冲击加速度可以设小一点而上升阶段为了节拍加速度可以快一些。Jerk这个参数在要求不高时可以先不设系统会按默认方式处理。MC_MoveVelocity则是不设定目标位置的持续速度运行指令。它只有速度、加减速度和缓冲模式执行后轴会一直朝某个方向运动直到你发MC_Halt或MC_Stop把它停下来。在手动调试、点动前进、连续送料这类场景里很常用。两者的区别可以这样理解MC_MoveAbsolute是“告诉我去哪里、怎么去、到了告诉我”MC_MoveVelocity是“告诉我朝哪个方向一直走、什么时候停由别的指令决定”。3.2 BufferMode让多个运动指令无缝衔接运动控制里很常见的一个需求是轴走完A点后立刻走B点中间不要停顿。如果你在程序里写“等第一个Done再触发第二个Execute”那么从第一个指令完成到第二个指令启动中间会有扫描周期延迟、功能块重新初始化时间体现在机器上就是动作顿一下。要想实现连续运动就要用BufferMode。TwinCAT的MC库提供了多种缓冲模式最常用的是mcAborting和mcBuffered。mcAborting新指令立即中止当前指令并接管运动。适合需要改变目标位置的场合比如手动示教时临时改目标点。mcBuffered新指令会在当前指令执行完成后自动启动中间无间隙。适合连续定位、轨迹拼接。我第一次用mcBuffered时踩过一个坑我把两条MC_MoveAbsolute的Execute同时给了TRUE希望它们排队执行结果第二条指令一直处于Waiting状态第一条完成后第二条自动运行逻辑本身没问题但我却因为没留意第二条的“Active”信号而以为程序卡死了。实际上缓冲模式下第二条指令虽然没开始运动但它的Active输出可能已经被置位表示“已加入队列并生效”需要读取指令的Execute状态和坐标规划器内部的剩余距离来判断当前到底执行到哪一步。后来我习惯用轴对象的“实际位置值”加“命令位置值”来跟踪再配合指令的Done信号判断逻辑才清晰起来。3.3 MC_Stop和MC_Halt多级急停怎么设计大多数设备不只有一个停止手段面板上有暂停按钮、有复位急停还有安全回路硬急停。在运动控制里MC_Halt和MC_Stop承担不同的角色。MC_Halt以设定的减速度将轴减速到零然后保持使能。适合工艺暂停场景比如临时停机待料。MC_Stop按更紧急的减速度停车停车后轴可以保持使能也可以配合外部逻辑断使能。适合报警停车、急停连锁。实际项目中急停信号进PLC后建议立即调用MC_Stop同时保存当前停止原因到报警日志。等急停复位后不要立刻自动启动而是让人工手动确认再按“故障复位→回零→重新就绪”的顺序恢复设备。这里有一个经验不要指望MC_Stop一停车就万事大吉垂直轴在停车后需要立刻输出抱闸控制信号否则电机断电后轴会下滑。你需要在功能块之外单独写抱闸逻辑而且要控制好抱闸和使能的先后顺序。4. 一套可落地的单轴控制状态机4.1 状态定义与切换逻辑前面讲了这么多功能块的细节最终要落到代码上。下面给出一套我在简单单轴项目里常用的状态机框架它不复杂但把基础生命周期都覆盖了。状态定义M_AXIS_IDLE等待启动命令。M_AXIS_POWER_ON执行使能等待MC_Power.Status。M_AXIS_FAULT_RESET检测到轴故障执行MC_Reset。M_AXIS_HOMING执行MC_Home等待Done。M_AXIS_READY轴已就绪等待定位命令。M_AXIS_MOVING执行MC_MoveAbsolute或MC_MoveVelocity。M_AXIS_STOPPING执行MC_Stop或MC_Halt。切换逻辑的核心是每个状态严格控制当前时刻调用的功能块组合避免多个运动指令同时抢轴。轴在READY状态下只接收来自HMI或上位机的定位命令。定位命令触发后进入MOVING等Done或CommandAborted再回到READY。任何状态下如果检测到急停信号直接跳转到STOPPING等待急停复位后再回到IDLE。4.2 完整ST代码示例下面我用结构化文本ST写一个简化但不失完整性的单轴控制逻辑。实际项目还要补充轴参数结构体、报警记录等功能但基本框架可以直接套用。PROGRAM AxisControl VAR bStart : BOOL; // 启动使能流程 bEStop : BOOL; // 急停信号TRUE表示正常 bHomeCmd : BOOL; // 回零命令 bMoveCmd : BOOL; // 定位命令 fTargetPos : LREAL; // 目标位置 nAxisState : INT; // 当前状态 nAxisStatePrev : INT; fbPower : MC_Power; fbReset : MC_Reset; fbHome : MC_Home; fbMoveAbs : MC_MoveAbsolute; fbMoveVel : MC_MoveVelocity; fbStop : MC_Stop; AxisRef : AXIS_REF; END_VAR// 急停或故障时强制停车 IF NOT bEStop THEN nAxisState : 7; // M_AXIS_STOPPING END_IF CASE nAxisState OF 1: // M_AXIS_IDLE fbPower.Enable : FALSE; fbPower.bRegulatorOn : FALSE; fbPower.bDriveStart : FALSE; IF bStart THEN nAxisState : 2; END_IF 2: // M_AXIS_POWER_ON fbPower.Enable : TRUE; fbPower.bRegulatorOn : TRUE; fbPower.bDriveStart : TRUE; IF fbPower.Error THEN nAxisState : 3; // 转到故障复位 ELSIF fbPower.Status THEN IF bHomeCmd THEN nAxisState : 4; ELSE nAxisState : 5; END_IF END_IF 3: // M_AXIS_FAULT_RESET fbPower.Enable : FALSE; fbReset.Execute : bFaultResetCmd; // 人工确认后的复位命令 IF fbReset.Done THEN nAxisState : 1; END_IF 4: // M_AXIS_HOMING fbPower.Enable : TRUE; fbHome.Execute : TRUE; fbHome.Mode : 3; // 以限位加零脉冲方式回零 fbHome.CalibrationVelocity : 10.0; fbHome.MaxDistance : 200.0; IF fbHome.Done THEN nAxisState : 5; ELSIF fbHome.Error THEN nAxisState : 3; END_IF 5: // M_AXIS_READY fbPower.Enable : TRUE; IF NOT bHomeCmd AND AxisRef.PlcToNc.StateDWord.2 THEN // 如果未回零则等待回零 nAxisState : 4; ELSIF bMoveCmd THEN nAxisState : 6; END_IF 6: // M_AXIS_MOVING fbPower.Enable : TRUE; fbMoveAbs.Execute : bMoveCmd; fbMoveAbs.Position : fTargetPos; fbMoveAbs.Velocity : 50.0; fbMoveAbs.Acceleration : 200.0; fbMoveAbs.Deceleration : 200.0; fbMoveAbs.BufferMode : mcAborting; IF fbMoveAbs.Done OR fbMoveAbs.CommandAborted THEN bMoveCmd : FALSE; nAxisState : 5; END_IF 7: // M_AXIS_STOPPING fbStop.Execute : NOT bEStop; IF bEStop THEN fbStop.Execute : FALSE; nAxisState : 1; END_IF END_CASE这段代码的细节值得多说几句。我特意在HOMING状态下把fbHome.Execute直接置TRUE意思是只要进入回零状态就一直发起回零请求直到Done或Error。这是一种极端简化实际项目里我更推荐用Execute的上升沿防止功能块被重复触发。另外在READY状态我检查了轴状态字的回零标志位这是通过AxisRef.PlcToNc.StateDWord解析出来的可以判断轴是否已经建立原点如果没回零则强制进入HOMING。这种方法在防止误操作上很有效。4.3 实际调试步骤和参数设置参考代码写出来只是第一步调试才是真正见功夫的地方。我在现场一般按这个顺序来先在TwinCAT的NC配置里确认轴参数单位是mm还是度速度限制是否合理软限位是否生效驱动器使能极性是否正确。手动模式下单独测试MC_Power给上Enable后观察AxisRef的Status和实际速度反馈看是否正常建立使能。在不连接机械负载或让轴悬空的前提下用MC_MoveVelocity做点动测试确认电机旋转方向是否正确编码器反馈方向是否正确。方向搞反是新手最容易犯的错会导致位置环闭环变成正反馈一给指令就飞车。设置好原点开关后测试回零动作。第一次回零速度设慢一点确保不会撞坏机械结构。回零正常后再测试绝对定位观察定位精度和跟随误差曲线微调PID参数。5. 实战问题排查与经验记录5.1 轴无法使能、使能瞬间掉电这个问题我遇到过好几次症状是MC_Power.Status始终不亮或者一亮马上灭。排查思路按顺序来先看驱动器报不报警。如果驱动器本身有报警输出PLC给使能信号它也不接受。再看有没有外部安全继电器没有闭合很多设备把急停回路串在驱动器使能信号里安全继电器没吸合驱动器永远收不到使能指令。还有一个是版本兼容问题。TwinCAT3在不同Windows环境下的安装和使用存在一些已知限制比如某些老版本的系统库自带的MC功能块在新版本上调用会报库版本不匹配。遇到这种情况我通常会到TcXxxManager的库管理里确认Tc2_MC2或Tc3_MC3的版本号与当前TwinCAT3系统版本是否兼容。热词里提到的“sysmem 3.5.5.0”这类系统库版本问题本质就是Tc3系统库和运动控制库之间版本不匹配导致的功能异常解决办法一般是在TcXxxShell里更新系统库或统一安装补丁版本。5.2 回零不触发、原点方向错误回零不触发最常见的原因是触发信号接到了错误的功能块输入上。有些人把原点传感器信号接到了NC轴配置的硬限位输入里回零时MC_Home找半天找不到原点反而把硬限位触发了。原点方向错误的排查也很快。观察一下轴在回零时实际运动方向是不是你预期要找开关的方向。如果方向反了要么修改MC_Home的方向参数不同版本参数含义不同要看功能块帮助要么把原点传感器安装位置或接线极性改掉。5.3 运动中途报跟随误差、限位报警跟随误差报警的本质是实际位置跟不上命令位置。排除机械卡死的原因后大概率是PID增益太低或速度、加速度超了。这时需要去NC轴配置的“控制回路”参数里调整Kp、Ki等参数。调参不是一下子拉满最好先小幅提高Kp观察实际位置跟随情况再配合速度前馈消除滞后。限位报警则要检查软限位和硬限位是否一致。有时候你在轴参数里设置了软限位但PLC程序里的MC_MoveAbsolute刚好把目标位置设在软限位之外轴自然会报警。排查时看报警字确定是正限位还是负限位触发再反查是机械硬限位还是参数里的软限位针对性解决。5.4 参数修改不生效的问题TwinCAT3的轴参数修改后往往需要激活配置甚至重新启动TwinCAT才能生效。很多人改了SpeedFactor或者软限位直接在线下载程序发现轴还是老样子就以为改坏了。这种情况的处理方法是修改完轴参数后在Solution Explorer里把带有NC配置的工程执行“激活配置”必要时对TwinCAT Targets进行Restart TwinCAT。需要注意激活配置时如果轴正在运行可能会导致轴的使能状态被重置所以最好在停机状态下做参数修改。另外PLC程序里的功能块实例变量和轴对象引用名称也对不上时候程序编译能过但运行时报无效引用这种问题很容易被忽略。6. 写在后面的一点个人经验从MC_Power到MC_Home再到MC_MoveAbsolute、MC_StopTwinCAT3运动控制库的功能块数量不算多但每个功能块背后都有一堆参数和时序细节。我的经验是先把轴对象当成一个有生命的“执行者”功能块只是对它下达命令的方式。你给的命令要符合它的状态它才会乖乖执行。还有一条实打实的建议每次新项目第一次调试我都会在TwincAT的监视窗口里把AxisRef的关键状态字和功能块的ErrorID放在同一屏这样报警时能一眼看出是哪一层出了问题。这个习惯帮我省了不少麻烦。希望这篇内容能让你少走几步弯路。
返回列表