ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

PackML状态机与PackTags:从统一状态模型到设备数据标准化的落地指南

PackML状态机与PackTags:从统一状态模型到设备数据标准化的落地指南 干了十几年自动化项目我一直有个特别头痛的事车间里十台不同厂家的包装机就有十套完全不一样的状态字定义。有的设备给一个 INT0 代表运行、1 代表停机有的给一串 BOOL哪个亮了大家自己猜。每次做产线级 MES 或 SCADA 对接光翻译这套厂家黑话就能耗掉一两周。后来被一个外资项目逼着学了 PackML才算是把这块硬骨头彻底啃了下来。PackML 是 Packaging Machine Language 的缩写翻成大白话就是包装机器语言它的核心内容来自 ISA-TR88.00.02 标准本质上解决了两个问题一是给设备定义一套统一的状态模型让所有人用同一套词描述机器现在在干嘛二是给数据接口定义一套标准标签也就是 PackTags让上位机不用再对着点表猜半天。这篇笔记我不打算照抄标准原文而是按我自己从零学到在一套小型灌装线上落地的完整过程来写重点讲清楚为什么这样做以及实际踩过的坑适合刚开始接触 PackML 的 PLC 工程师、自动化集成商以及被设备对接搞得焦头烂额的项目经理。1. PackML 到底是什么从包装车间的语言不通说起1.1 为什么包装行业需要统一的状态模型包装产线有个很尴尬的现状灌装机可能是德国品牌旋盖机是意大利的贴标机是国产的三台设备控制方式、通讯协议、状态定义全都不一样。单机调试没问题一旦要联线做集中监控麻烦就来了。举个我实际遇到的例子A 品牌的灌装机用整型变量来表示状态1 是自动运行2 是手动3 是故障B 品牌的贴标机却用一组布尔量X10 亮代表待机X11 亮代表生产中。工人在 HMI 上看到的是两套完全不同的画面MES 取数更得分别写两套解析逻辑。这还只是三台设备整条线十几台设备的时候集成工作量完全失控。PackML 的思路特别朴素既然大家都要描述待机、运行、暂停、故障这些基本状态那就干脆规定一套统一的说法谁也别自己发明。这套统一说法就是 PackML 状态模型它把包装设备的所有运行工况收敛成 17 个标准状态用 9 个标准命令来控制状态切换。设备厂商按照这个模型写程序集成商按照这个模型做对接两边都不用再互相迁就。1.2 PackML 的出身ISA-88 标准家族PackML 全称 Packaging Machine Language最早其实是美国 OMACOrganization for Machine Automation and Control机器自动化与控制组织为包装行业提出来的一套实践准则后来被 ISA国际自动化协会采纳发布为 ISA-TR88.00.02 技术报告。很多人不知道 PackML 和 ISA-88 的关系。ISA-88对应 IEC 61512是流程行业的过程控制标准最出名的就是 S88 批次控制模型。PackML 可以理解为把 S88 的批处理思想降维应用到离散的包装机械设备上把设备当作一个单元Unit来管理把一批料的生产过程用状态 命令来描述。所以学 PackML 之前如果了解一点 S88 里的设备阶段Equipment Phase和控制模块思想上手会快很多。顺手说一下PackML 旁边还有个 PackTags 概念两者经常被放一起提。状态模型解决机器在干嘛PackTags 解决数据叫什么名字、怎么组织。一个是动作规范一个是数据规范合在一起才是一套完整的东西。1.3 学 PackML 前需要建立的两个基本认知第一个认知PackML 不是一种硬件也不是一种通讯协议。它和 Profinet、EtherNet/IP 不冲突相反它可以跑在任意平台上。PLC 程序里可以按 PackML 写上位机 C#、Python 里也可以按 PackML 模拟ARM 单片机上照样能做。它是一套组织逻辑的标准不是设备选型标准。第二个认知PackML 不是万能的。它规定的是设备对外呈现的状态框架但设备内部每个状态里具体怎么动作你自己说了算。比如 Execute执行状态下灌装泵转速多少、旋盖扭矩多大PackML 不关心它只关心你对外宣称我在执行。所以它解决了设备间互操作的问题但不解决单台设备怎么控制的问题。这两件事必须分清楚否则你会拿着标准去抠不该抠的细节。2. 状态模型拆解机器怎么从只会开停变成会说状态2.1 状态、命令、转换三个词看懂状态机PackML 状态模型看着有一堆术语其实核心就三个概念状态、命令、转换条件。状态就是设备当前所处的工况比如 Idle待机、Execute执行、Held保持、Aborted已中止。命令是你发给设备的控制指令比如 START、STOP、HOLD、ABORT。转换条件则是状态能不能切换过去的判断依据比如启动命令已发同时安全门关闭、无报警、伺服在原点满足这些条件状态机才允许从 Idle 走到 Starting 再走到 Execute。我习惯把它类比成电梯楼层是状态按钮是命令门关了、没超载、目标楼层到了这些就是转换条件。按了关门按钮不等于马上能走必须所有条件满足才真的启动。设备控制如果少了转换条件这一步就会出现按钮都按了设备就是不动或者状态乱跳的灵异现象。2.2 17 个状态的记忆方法稳定态与过渡态PackML 标准的 17 个状态乍一看很多背下来很痛苦。我的记忆诀窍是先分成两组稳定态和过渡态。稳定态是设备会长时间停留的状态一共 7 个Idle、Execute、Held、Suspended、Complete、Stopped、Aborted。过渡态是状态切换过程中经过的中间状态名字基本都是-ING 结尾一共 10 个Resetting、Starting、Completing、Holding、Unholding、Suspending、Unsuspending、Stopping、Aborting、Clearing。类型状态名称简单理解稳定态Idle待机允许启动稳定态Execute正在生产稳定态Held被操作员/工艺暂停稳定态Suspended因临时条件挂起稳定态Complete批次/产量完成稳定态Stopped正常停机稳定态Aborted故障中止过渡态Resetting / Starting / Completing 等切换过程瞬间掠过过渡态存在的意义在于设备从一个稳定态换到另一个稳定态往往需要执行动作。比如从 Stopped 到 Idle 不是啪一下就过去的中间可能要做复位气缸、回原点、清故障记忆这些动作这些动作执行的期间就是 Resetting。如果你把复位动作也放在 Idle 里做那么上位机读到 Idle 时会误以为设备已经准备好实际上机械还在动容易出安全问题。所以过渡态不只是为了好看它是安全语义的一部分。2.3 模式Mode机制一台机器多种身份状态模型之外PackML 还有一个容易被忽略的维度模式Mode。标准里常见模式包括 Automatic自动、Semi-Automatic半自动、Manual手动、Cleaning清洗、Maintenance维护。模式和状态是两个正交的概念。打个比方状态是车在什么档位模式是谁有资格碰方向盘。全自动模式下操作员只能按启动停止手动模式下维修工可以单动某个气缸保养模式下某些安全联锁会被旁路。同一台设备在不同模式下同一个状态里执行的动作可能完全不同。实际工程里模式和状态要分开存储、分开显示。HMI 上既要看到当前状态State也要看到当前模式Mode。我见过有的项目图省事把模式和状态合成一个变量结果 Manual 模式下运行状态让 MES 误判为自动生产产量统计全乱了。单独用两个变量逻辑清爽后面查问题也方便。3. PackTags把变量名和数据结构也变成行业通用语言3.1 PackTags 到底长什么样状态模型解决的是语义统一但这还不够。假设全厂设备都按 PackML 写了状态机结果 A 设备把状态放在 DB10.DBW0B 设备放在 MD20C 设备放在 %MW100那对接依然是噩梦。PackTags 的价值就在这里它把数据访问接口也标准化。PackTags 说白了就是一套命名规范和数据组织规范。我记得很清楚第一次在项目文档里看到Line1_Filler_PAC_State这种命名时整个人都清爽了。看到名字就知道Line1 区域、Filler 这台设备、反馈的是 PackML 状态。不需要查点表不需要问设备厂家这就是标准化的力量。下面是一个常见的 PackTags 命名例子Line1_Filler_PAC_State // 灌装机当前状态 Line1_Filler_PAC_Mode // 灌装机当前模式 Line1_Filler_FAST_ProducedCount // 灌装机总计数 Line1_Filler_FAST_ProducedGoodCount // 灌装机良品计数 Line1_Filler_FAST_OperatingTime // 运行时间累积命名规律基本是[区域]_[设备]_[标签类型]_[具体含义]区域和设备前缀由项目自己定义后面跟的核心标签名按标准字段来。这样不同项目、不同厂商的设备只要遵循同样的命名上位机程序可以做成完全通用的模板。3.2 核心 PackTag 分类与含义PackTags 标准内容很多真正高频用到的其实就三大类。第一类是命令类通常叫PAC_Command系列包括 PAC_RESET、PAC_START、PAC_STOP、PAC_HOLD、PAC_ABORT 等。上位机或 MES 要控制设备时不是直接去改设备的内部变量而是往这些命令标签上写脉冲由设备内部状态机自己判断这个命令当前允不允许执行。这样就把命令的合法性判断留在了设备侧集成商不用在每次对接到不同设备时重复写一堆防呆逻辑。第二类是状态类核心是PAC_State和PAC_Mode。PAC_State 是当前状态编号PAC_Mode 是当前模式编号。上位机只管读这两个值再配一张枚举映射表就能知道全厂设备状态。很多项目甚至直接把这个值往 HMI 的图形控件上绑状态变颜色自动变省掉大量脚本。第三类是绩效类也就是FAST_系列标签。FAST 在这里是 Factory Automation Standards Team工厂自动化标准团队的产物专门为 OEE 统计准备了累计变量比如总产量、良品数、次品数、运行时间、故障时间、停机次数等等。这些标签是 OEE 计算的数据地基如果每个设备都按统一名字提供MES 端写 OEE 报表就是标准模板插值不用每个设备单独适配。3.3 为什么说 PackTags 是 OEE 的数据地基聊到 OEE我可以多说几句。OEE 的计算公式是可用率 × 性能率 × 良品率看着简单真正统计起来最痛苦的是数据来源不统一。以可用率为例OEE 里的可用时间是用总时间减去停机时间。问题是停机的定义各厂不同有的厂家把操作员按暂停也算故障有的把换规格时间不算停机出来的 OEE 数字根本没法横向比较。PackML 的 FAST 标签把时间类变量拆成 OperatingTime、ProductionTime、FailTime、RestartTime 等标准字段每种时间的起止边界都有约定。这样大家都在同一把尺子上量OEE 才有可比性。我见过一家企业上了 PackML 改造之后MES 报表从手动填 Excel变成全自动生成而且各车间数据口径完全一致老板终于可以拿着同一套指标对比不同产线了。这就是 PackTags 的深层价值它不只是变量命名规范更是让管理数据具备可比性的基础设施。4. 实操落地一套小型灌装线的 PackML 改造实录4.1 场景设定灌装-旋盖-贴标产线理论说再多不如动手做一遍。我以一套比较典型的小型灌装线为例空瓶上料 → 灌装 → 旋盖 → 贴标 → 剔除站五个工位用一台 PLC或软 PLC控制整线。目标是按 PackML 做状态建模并向上位机提供标准数据接口。做这个项目之前先要明确每个站点的单元Unit和控制模块怎么划分。PackML 里最小单位是单元可以是一台机器也可以是一条生产线。我建议第一次落地的项目先把整条线当作一个单元对外只呈现一套状态内部五个工位的细节状态先不对外暴露。等把 PackML 的状态机跑顺了再尝试把每个工位建成独立单元形成多级状态体系。原因很简单PackML 落地最大的障碍不是标准难而是范围和粒度没定清楚。粒度越细转换条件越复杂编程量指数上升。先用整线一个单元跑通闭环建立起信心和模式比一开始就追求完美建模重要得多。4.2 第一步状态映射与转换条件表落地第一步不是写代码而是做状态映射。把你现有程序里的所有工况逐个对应到 PackML 的 17 个状态里。下面是我按灌装线做的映射表PackML 状态灌装线实际含义进入该状态的判定条件Stopped停机待复位上电初始或按下停止后停稳Idle待机等待启动无报警、安全门关、参数加载完成Starting启动中收到 START伺服回零开始Execute正常生产启动完成灌装阀、旋盖头、贴标头联动Held操作员暂停按下 HOLD且当前批次产品未完成Suspended挂起等待贴标机标签卷用完自动等待换卷Stopping正常停机中收到 STOP设备按减速曲线停稳Stopped已停机停稳完成Aborting故障中止中收到 ABORT 或安全急停触发Aborted已中止故障停止动作完成Complete批次完成产量达到目标值 5000 瓶这张表做完先别急着写状态机逐条检查转换条件是否完备。这里我有个经验转换条件最容易漏的是初始位置类条件。比如从 Idle 到 Starting很多新手只判断无报警结果启动时灌装头没在原点直接撞机械。所以转换条件表里每个伺服轴的回原点完成信号必须列进去。4.3 第二步PLC 程序里怎么写状态机状态映射做完就可以写程序了。PLC 里写 PackML 状态机我推荐用 CASE 语句配合显式的转换条件而不是用一堆 SET/RESET 位区绕来绕去。下面是一段结构化文本风格的伪代码CASE g_State OF ST_STOPPED: IF rqReset AND TC_ResetOK THEN g_State : ST_RESETTING; END_IF; ST_RESETTING: IF TC_ResetDone THEN g_State : ST_IDLE; END_IF; ST_IDLE: IF rqStart AND TC_StartOK THEN g_State : ST_STARTING; END_IF; ST_STARTING: IF TC_StartDone THEN g_State : ST_EXECUTE; END_IF; ST_EXECUTE: IF rqStop THEN g_State : ST_STOPPING; ELSIF rqHold THEN g_State : ST_HOLDING; ELSIF rqAbort THEN g_State : ST_ABORTING; END_IF; // ... 其他状态类似 END_CASE;写这段代码有几个要点。第一命令变量rqStart、rqHold 等和状态变量g_State必须分开定义。命令是上位机或按钮触发的一次性脉冲状态是设备内部持续保持的工况二者不可混用。第二每个过渡态如 RESETTING、STARTING都要有明确的完成条件否则状态机会卡在过渡态。第三ABORT 命令在几乎所有状态下都应该被响应它是最优先级的命令优先级判断要在其他命令之前。如果你项目用的是 Python、C# 做上位机模拟也可以用字典加条件判断实现同样的状态机。无论什么语言思想都是一样的状态只允许在合法转换路径上移动不允许随意跳转。这个约束看起来死板实际上保证了设备行为的可预测性出问题时也容易回溯。4.4 第三步PackTags 配置与 HMI/上位机对接状态机程序在 PLC 里跑起来之后下一步就是把这些状态映射到 PackTags 上。我通常的做法是在 PLC 里定义一个全局数据块统一存放所有对外接口标签。这个数据块就像设备的对外窗口上位机只读这里不读里面的工艺细节。数据结构大概长这样// 对外接口 DB ALine_Filler_PAC_State : DINT; // 当前状态编号 ALine_Filler_PAC_Mode : DINT; // 当前模式编号 ALine_Filler_FAST_TotalCount : DINT; // 总产量累计 ALine_Filler_FAST_ProducedGoodCount : DINT; // 良品累计 ALine_Filler_FAST_OperatingTime : LREAL; // 运行时间累计小时对接 HMI 的时候可以把整个数据块做成一个 UDT 类型画面里的状态显示、按钮、报警灯全部绑定到标准标签上。这样以后接第二台设备直接把 HMI 画面复制一份改一下设备前缀就行画面模板可以做到一套通用这是 PackML 在工程实施里最直观的效率提升。再往上对接 MES 或 SCADA我推荐用 OPC UA 把数据块暴露出去节点树直接按 PackTags 命名映射。MES 端写一个通用读取客户端扫描全厂所有设备的 PAC_State、FAST 系列标签就能实现全厂状态总览和 OEE 报表遇到新设备进来不需要改上位机代码。5. 常见问题与排查技巧实录5.1 高频问题速查表做 PackML 落地这一年多我遇到过的问题不少整理了一个排查速查表分享给大家现象可能原因排查方法状态一直卡在 Starting 无法到 Execute转换条件TC_StartDone不满足逐条检查伺服回零、安全、压力等条件信号按了 ABORT 设备没进 AbortedABORT 命令优先级被其他逻辑覆盖检查 ABORT 是否在状态程序最前面被无条件响应上位机状态和 HMI 显示不一致地址映射错误或两个端在读不同变量确认两边读的是同一个 PAC_State 变量复位后直接进入 Execute没经过 Idle复位的目标状态设置错误确认 RESET 的目标统一为 IdleMES 统计的产量比实际少FAST_ProducedCount 没有被正确累计检查计数脉冲是否只在 Execute 状态下有效HOLD 后设备还在继续走HOLD 命令被下降沿误判HOLD 应使用电平或带确认的脉冲不能用简单边沿5.2 状态卡死的三种典型原因状态卡死是我被问得最多的问题现象就是设备显示停在某个过渡态不动比如一直 Starting、一直 Resetting。按我排查下来的经验绝大多数卡死就三种原因。第一种是过渡态没有完成条件。写状态机的时候只写了进入过渡态的逻辑忘了写什么时候算完成。比如从 Stopped 进 Resetting 后程序里没有 TC_ResetDone状态自然永远困在 Resetting。这种问题代码评审时最容易抓出来用状态转换表逐条核对就能避免。第二种是完成条件信号被前面环节吞掉了。最常见的是边沿问题完成信号是转瞬即逝的脉冲PLC 扫描周期慢一点CASE 语句就错过了。解决办法是把这个脉冲锁存一拍或者状态机采用扫描周期内多次判断的方式别让一个脉冲信号直接决定生死。第三种是安全逻辑和状态机逻辑打架。设备本身有急停回路急停按钮一按安全继电器直接把输出切断状态机程序还在按部就班跑。这种情况不是状态机的错是外围安全回路没和状态机做好交互。我的处理方式是把安全电路的急停信号同时映射成一个 ABORT 触发条件让安全事件既切断输出也通知状态机实施转向 Aborting两边保持一致。5.3 新手最容易搞混的概念HOLD 和 SUSPEND最后单说一个我见过无数人搞混的点HOLD保持和 SUSPEND挂起到底有什么区别。从直觉上看这两个状态都是暂停生产很多项目图省事只用一个。但它们的设计意图完全不同。HOLD 是操作员或工艺主动介入的暂停比如发现灌装量精度异常操作员按 HOLD 停一下去检查此时产品还留在设备里工艺数据要保持住。SUSPEND 是设备自己感知到临时外部条件而挂起比如提升机里没瓶子了、贴标标签纸用完了等条件恢复后自动回来通常不需要操作员参与。换句话说HOLD 偏人SUSPEND 偏系统。设计状态机时一定要和工艺人员确认清楚哪些情况用 HOLD哪些用 SUSPEND。我见过一个项目把缺料设计成 HOLD导致操作员频繁去复位给生产添了不少乱。后来改成 SUSPEND缺料自动挂起、有料自动恢复操作员彻底解放出来了。实战里如果要选一个词先学透我觉得不是状态机本身而是这一组命令-转换条件-稳定态的三层关系。把这套思维模式建立起来就算不背 17 个状态的名字看到任何设备的管控逻辑也能很快套进 PackML 的框架里。以后碰到新项目我的习惯是第一件事先画状态转换表第二件事定义标签命名逻辑想清楚了再动 PLC这比埋头写代码有效率得多。
返回列表