设备状态机怎么写才不乱:挡门、动作、选路,比框架更先要学会

发布时间:2026/9/1 7:14:11

设备状态机怎么写才不乱:挡门、动作、选路,比框架更先要学会
这篇解决一个问题设备软件里几乎每个模块都是while switch写着写着变成面条。判断该放哪、失败该不该改步、结批该塞哪个case。先把每个状态的形状固定下来再谈要不要上框架。一、设备流程为什么天然是状态机设备不是一次性函数。搬运台车、手臂、料道、测试台都是「做完 A 再做 B中间还要等、还可能改道」。一条很常见的物理路径去取料位 → 取料 → 去工作位 → 等对方接手 → 去出料位 → 再回到取料位中间还会插例外这盘是空盖盘取完直接出不进工作位。已经开始结批车上还有料跳过工作位直接出。工位被别人占着这一拍先别动下一圈再抢。所以设备控制几乎都会落成状态机当前在哪一步、这一步能不能开始、做完去哪、失败怎么办。问题不在「用不用状态机」而在 一个case里把所有事情搅在一起。二、面条式状态机为什么难改典型写法是一个大循环套一个大switchwhile (running) { Sleep(1); switch (step) { case 某步: if (资源锁失败) break; if (结批) { step 另一步; break; } ret 动作(); if (ret 失败) { Alarm(); break; } if (特殊盘) step A; else step B; break; } }一个case里同时出现五件事挡门现在能不能开始结批改道真正动作失败处理成功后选路看起来省事维护时会痛在这几处不知道新规则该塞哪个case。同样是break有的表示「下一圈重试」有的表示「报警停住」有的表示「已经改道」。动作做一半突然跳步气缸还顶着、锁还占着。新人不敢改因为改一步不知道会不会把别的路径带崩。这就是面条式状态机流程能跑结构不可读。三、最小可用手法每个 case 只做三件事先不换框架、不拆类。 只规定每个状态内部的形状挡门 → 动作 → 选路case 某步: { // ① 挡门这一步现在能不能开始 if (资源没抢到) break; // 重试不改步 if (该跳过的前置条件) { step 下一站; break; } // 改道 if (结批且本步不该开始) { 收尾; break; } // 拦截 // ② 动作这一步真正要干的活 auto ret 执行动作(); if (!ret.IsOK()) { Alarm(ret); StopMachine(); break; // 失败通常不改步停在原处 } // ③ 选路成功后下一步去哪 if (特殊分支) step 特殊下一站; else step 默认下一站; break; }记住一句就够没开始 → 挡门做砸了 → 失败处理做完了 → 选路。四、一个新 if 该放哪四问清单以后每加一个判断按这个顺序问问是放哪这是让设备「现在先别动」吗资源没抢到、对方没就绪、结批后不该再取新料① 挡门这是动作执行失败吗轴超时、真空失败、气缸不到位② 动作中间这是动作成功后「下一步去哪」吗空盖盘走捷径、正常盘去工作位③ 选路这是和所有步都无关的全局条件吗急停、整机已结批、暂停while循环头不要凭感觉往最近的case里塞。位置错了比条件写错更难查。五、全局闸门不要进 case急停、整机结批完成、暂停属于「不管现在哪一步都该先处理」。放到每个case里会重复、会漏。while (running) { Sleep(1); if (急停) { 停机; continue; } if (整机已结批) { Stop(); continue; } if (!允许运行) { continue; } switch (step) { ... } }循环头管「整机还让不让跑」。case里只管「这一步自己的事」。六、资源锁不是业务动作设备里很多工位是共享的顶升、Buffer、压台。常见写法是占用协议bool SetUsedBy(Actor* who) { lock_guardmutex lk(mtx); if (owner nullptr || owner who) { owner who; return true; } return false; }含义只有三句没人占用 → 登记为自己成功本来就是自己 → 成功允许重入别人在用 → 失败本轮不要继续动锁失败和动作失败不是一类事。锁失败动作失败含义现在还不能开始已经开始但没做成处理break留原步下圈再抢报警通常停机改不改步不改通常不改停在原步方便排查最常见的错法锁失败也Alarm或者锁失败直接跳到下一步。前者误报后者还没干活就假装做完了。七、结批不是一个 if而是一类规则「结批」在状态机里至少有几种完全不同的意思不能写成同一个判断到处粘贴。类型放哪做什么改不改步整机已经结完循环头停本模块不改空车且不该再取新料挡门标记本模块结批完成、放锁不改车上还有料但工作位不必再去挡门改道跳过工作位去出料改道正在等对方接手挡门副作用催对方结束自己先等通常不改以后加结批规则先问这是总闸、拦截、改道还是催下游 再决定放循环头还是某个case的挡门段。不要在动作做到一半时突然if (结批) step ...。动作做一半就跳最容易留下锁没放、气缸还顶着、真空还开着。八、一个 case 里塞了多个动作就该拆子状态取料经常不是一个动作而是一串到取料位 → 顶升 → 建真空 → 分盘/松夹 → 下降全写在一个case里会有三个后果失败时不知道卡在顶升还是真空。暂停后再进来会从头执行可能重复顶升或重复吸真空。界面只能显示「正在取料」调试信息太粗。做法是拆子状态enum class PickSub { MoveToPos, JackUp, BuildVacuum, Separate, JackDown, Done }; case Pick: { switch (sub) { case PickSub::JackUp: if (cylinderInPosition) sub PickSub::BuildVacuum; break; case PickSub::BuildVacuum: if (vacuumOk) sub PickSub::Separate; break; // ... } if (sub PickSub::Done) step NextStation; break; }父状态表示「我在取料」子状态表示「取料进行到哪一小步」。失败、暂停、恢复都有落点。原则一个 case 对应一个可命名的物理状态或原子动作。 一个名字里说不清就该拆。九、改步只能出现在少数位置一个状态里step ...最多三类挡门改道这一步确定不该做直接去另一站。失败后不改步停在原处方便看现场、看日志。成功后选路给一个默认下一站特殊分支另写。反例一个case末尾四五处赋值没有默认下一站。读代码的人要靠猜「哪条路才是主干」。正例// 成功后选路 step 默认下一站; if (空盖盘) step 出料; if (结批且有盘) step 出料;主干清晰例外是例外。十、大厂怎么写和现在该不该上框架业界常见做法场景常见选择C 设备控制HFSM2、Boost.Statechart、Boost.MSM、sml.NETStateless模型驱动Stateflow、SCXML 画图生成代码PLCSFC / 状态图自研平台事件队列 状态注册 转移注册框架带来的变化是真实的面条式框架式step是整数状态是类型转移散落在ifchangeTo显式转移进入/退出靠人记框架调enter/exit结批是到处if可以升成父状态历史靠自己记父状态切换可重置子状态但老项目不要一上来全量迁框架。原因也很实际编译器、模板报错、团队习惯可能跟不上。一台设备往往有十几套状态机全迁等于几个月加一批新 bug。框架解决的是「结构」解决不了「判断放错位置」。判断放错换框架一样乱。更稳的路径阶段做法现在老模块用「挡门-动作-选路」整理不换框架新模块新写的台车/手臂可以直接上层次状态机或自研小框架提公共能力资源占用包成 Guard动作结果包成统一ActionResult平台化结构稳定后再决定要不要统一框架先把每个case写干净再谈框架。 顺序反了是用新语法写旧面条。十一、一份可直接贴进规范的 checklist每个状态机都应满足一个case对应一个可命名的物理状态或动作。改步只出现在跳过本步的挡门改道、失败后不改、成功后选路。急停、整机结批、暂停放到while循环头。资源锁放在case最开头失败只重试。失败先报警/停机再决定是否改步默认不改步。一个case里不要串两个完整动作。结批先分类总闸 / 拦截 / 改道 / 催下游再落点。常见错误对照动作中间写结批跳步 → 资源遗留。一个case两个动作 → 失败不知道卡在哪。全局闸复制进每个case→ 漏改。锁失败和动作失败同样报警 → 误报。下一步来源太多且没有默认站 → 读不懂主干。十二、可复用结论设备状态机的核心不是框架而是 每个状态内部形状统一挡门、动作、选路。新判断先问四句现在别动、做砸了、做完去哪、是不是全局闸。资源锁失败是重试动作失败是报警两类break不能混。结批不是一个 bool而是总闸、拦截、改道、催下游四类规则。一步里有子流程就拆子状态避免暂停恢复后重复动作。老项目先整理case新项目再上层次状态机不要用框架掩盖结构混乱。设备软件的状态机追求的不是「看起来高级」而是改规则时知道改哪、失败时知道停在哪、新人敢动。while switch可以很差也可以很干净。差在把所有 if 倒进一个case干净在先固定三段再让框架成为可选项而不是第一步。

相关新闻

一线行业观察五年,塑胶颜料配色的底层运作逻辑与真实运用细节

一线行业观察五年,塑胶颜料配色的底层运作逻辑与真实运用细节

2026/9/1 7:14:11

很多刚入行的朋友问我,塑胶色母配色不就是把颜料和载体混一起搅和匀吗?怎么有的卖几块钱一公斤,有的能卖到几十块?我做这行快五年,跑过珠三角、长三角三十多家下游制品厂,见过至少十几起因为色母质量翻车的…

并发服务 系统编程与并发原语:预算有限时先优化哪一项

并发服务 系统编程与并发原语:预算有限时先优化哪一项

2026/9/1 7:04:11

并发服务 系统编程与并发原语:预算有限时先优化哪一项账单里的隐形杀手:自适应 Goroutine 池引发的算力成本暴增 云厂商发来的月度账单让架构团队陷入沉默。一个基于 Go 语言构建的实时数据流处理服务,算力成本环比飙升了 260%。 该服务引入了…

蒙古国国界SHP数据处理全攻略:从下载到ArcMap验证一步不落

蒙古国国界SHP数据处理全攻略:从下载到ArcMap验证一步不落

2026/9/1 7:04:11

简介:面向地理信息系统制图与空间分析应用的蒙古国国界矢量数据包,适合需要蒙古国行政边界基础底图的数据分析、地图制图与科研人员,可直接用于区域规划、人口密度分布、自然资源分布等专题研究,省去手工描绘国界轮廓的重复劳动&a…

华为AI岗机试面试全流程复盘:从算法题到大模型深挖

华为AI岗机试面试全流程复盘:从算法题到大模型深挖

2026/9/1 8:14:13

上周刚走完华为AI岗的完整流程,从投简历、机试到两轮技术面加一轮主管面,整个过程信息量非常大。尤其是1月21号那场机试,用的是新考试系统和C卷,双机位监考,很多细节跟网上流传的旧版本完全不一样。我把自己踩过的坑、…

广告牌识别数据集实战:从COCO JSON到YOLOv8训练部署

广告牌识别数据集实战:从COCO JSON到YOLOv8训练部署

2026/9/1 8:14:13

简介:本资源是面向计算机视觉算法工程师与深度学习初学者的广告牌目标检测专用数据集,聚焦商场、建筑及道路边等典型城市场景中的广告牌识别任务,可直接用于YOLO、Faster R-CNN等主流模型的训练与评估。压缩包共2000个文件,包含19…

AI追光免费编辑器:从文生视频到成片的完整创作指南

AI追光免费编辑器:从文生视频到成片的完整创作指南

2026/9/1 8:14:13

世界电影节参赛作品《大梦三千》最近在 AI 创作圈里被频繁提起。这里不谈艺术评价,只从技术工具角度拆解它背后出现的一个关键词:AI 追光免费编辑器。很多用户关心的是:电影节级别的短片,用免费工具能不能跑通完整流程&#xff1f…

RocketMq快速入门

RocketMq快速入门

2026/9/1 8:14:13

mqbroker.cmd -n 127.0.0.1:9876 autoCreateTopicEnabletrue开启确保 Broker 启动时就允许自动创建主题对比维度Message(普通消息)MessageExt(扩展消息)谁在用生产者(Producer) 发送消息时使用消费者&#…

光学音乐识别数据集全览:OMR-Datasets资源索引与实操指南

光学音乐识别数据集全览:OMR-Datasets资源索引与实操指南

2026/9/1 8:14:13

简介:面向光学音乐识别(OMR)研究者的数据集整合仓库,集中整理了手写与印刷乐谱的符号分类、谱线检测与删除、目标检测、端到端识别等常见任务所需的多组公开数据集及其加载工具;适合音乐信息检索、深度学习和计算机视觉…

STM32+ESP8266+MQTT+OneNet物联网远程控制方案全解析

STM32+ESP8266+MQTT+OneNet物联网远程控制方案全解析

2026/9/1 8:04:13

简介:面向STM32物联网开发者的完整实战工程包,演示如何通过ESP8266 Wi-Fi模块将STM32接入OneNet云平台,并基于MQTT协议实现手机APP远程控制。压缩包约4.54MB,共170个文件,以C源码、H头文件、Keil工程配置(u…

备战数据库管理工程师校招:索引、事务、备份恢复核心考点解析

备战数据库管理工程师校招:索引、事务、备份恢复核心考点解析

2026/9/1 1:53:39

每年校招季我都会接触不少准备数据库方向笔试的同学,看到最多的状态就是:简历上写着“熟悉 MySQL”“了解索引优化”,一碰到数据库管理工程师的笔试卷,却在索引、事务、锁、备份恢复这些题目上翻车。网易这套 2018 校园招聘数据库…

数字电路时序基石:深入理解建立时间与保持时间

数字电路时序基石:深入理解建立时间与保持时间

2026/8/31 7:20:57

1. 这不是“背公式”的事:时间参数到底在约束什么你翻过数字电路教材,一定见过这两个词:建立时间(Setup Time)和保持时间(Hold Time)。它们常被并列写在触发器(Flip-Flop&#xff09…

蓝桥杯国赛超声波测距机:从单片机原理到嵌入式系统实战

蓝桥杯国赛超声波测距机:从单片机原理到嵌入式系统实战

2026/8/31 17:18:46

1. 项目缘起:从赛题到超声波测距机的诞生第八届蓝桥杯单片机设计与开发国赛的题目,我至今记忆犹新。它没有直接给出一个花哨的名字,而是用“超声波测距机”这个朴实无华的功能描述,精准地勾勒出了考核的核心。对于当时备赛的我而言…

远程协作的工作台整理

远程协作的工作台整理

2026/9/1 0:03:36

远程协作的工作台整理远程协作的核心不是再加一个工具,而是让交接信息足够完整。异步任务要写明目标、输入位置、完成标准和需要决策的人。 工作台的最小配置 将日程、待办、代码和沟通入口收拢到少数固定位置;通知按紧急程度分层。工作台不需要模仿办公…

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

2026/9/1 0:03:36

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

2026/9/1 0:03:36

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

远程协作的工作台整理

远程协作的工作台整理

2026/9/1 0:03:36

远程协作的工作台整理远程协作的核心不是再加一个工具,而是让交接信息足够完整。异步任务要写明目标、输入位置、完成标准和需要决策的人。 工作台的最小配置 将日程、待办、代码和沟通入口收拢到少数固定位置;通知按紧急程度分层。工作台不需要模仿办公…

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

2026/9/1 0:03:36

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

2026/9/1 0:03:36

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…