33 KiB
agent业务.md
本文档是产线业务的完整描述,面向人类阅读(产线工程师、操作员、新员工)。配合 agent约束.md、data.sql、signals.sql 可还原当前项目全部代码。
禁止写入 SQL/schema/signals.sql 中已有的数据(设备参数、信号地址、槽位数等),禁止引用代码常量或函数名。
零、系统架构概述
全配置化流程引擎
系统采用全配置化流程引擎架构,所有工艺步骤的行为通过数据库配置驱动,不硬编码任何设备类型或工序行为。
引擎核心循环(4 阶段):
ACQUIRE(获取资源)→ EXECUTE(发送信号)→ WAIT(等待完成)→ COMPLETE(后置操作)
引擎不包含任何业务知识(不知道磨床、接驳台、全检台的区别),所有行为由以下数据库表配置:
| 配置表 | 作用 | 配置内容 |
|---|---|---|
recipe_step |
步骤定义 | 步骤名称、序号、默认下一步 |
recipe_step_resource |
资源需求 | 每一步需要获取哪些资源(机器人、槽位等) |
recipe_step_signal |
信号序列 | 每一步发送什么 PLC 信号、等待什么 Done 信号 |
recipe_step_action |
后置操作 | 步骤完成后释放资源、设置状态、发送额外信号 |
recipe_step_decision |
决策分支 | 条件判断→跳转到不同步骤(如全检台满→缓存台) |
资源类型:
robot:机器人(互斥,同一时间只能一个 job 使用)temp_slot:缓存槽(1 个,工件暂存用)equipment_slot:设备槽位(接驳台/磨床/全检台/缓存台等)
资源操作:
acquire:独占获取(SELECT FOR UPDATE 事务锁),确保原子性check:非独占检查(SELECT FOR UPDATE 轻量锁),仅确认条件满足
信号角色:
param:参数信号,在 req 之前写入(如工件类型 M2022、位置号)req:请求信号,触发 PLC 动作done:完成信号,由 SignalRouter 异步监控,到达后触发 COMPLETEpost:后置信号,在 COMPLETE 阶段发送(如 M2102 检测请求)
一、产线概述
磨床自动化单元,由 1 台机器人串行搬运物料,串联 6 台设备完成从毛坯到成品的全流程加工。
设备清单见 data.sql 的 equipment + equipment_type 表,信号地址见 signals.sql。
机器人负责在设备间搬运工件,同一时间只能执行一个动作(串行互斥)。所有设备通过 PLC 控制,系统通过信号与 PLC 握手交互。
二、工艺步骤
OP10 接驳台上料
- 做什么:机器人从接驳台取毛坯
- 来源:接驳台的托盘(左右各一个,AGV 送达)
- 完成条件:机器人成功取到毛坯
- 异常:取料失败需人工介入
- 特殊情况:接驳台没料时暂停,等 AGV 送来
OP20 磨床磨削
- 做什么:机器人把毛坯放入磨床,等待磨削完成,取走成品
- 特殊处理:方形件需要先放换向机构换向,再放入磨床
- 换料:磨床已有成品时,机器人可一次完成「取成品+放毛坯」,减少搬运次数
- 完成条件:磨床发出磨削完成信号
- 异常:磨削超时/失败需人工介入
- 特殊情况:
- 磨床空时:直接放料(不用换料)
- 磨床有料且加工完成:换料
- 磨床有料但还在加工:等待
OP30 工件清洗
- 做什么:机器人把工件放到清洗工位,启动清洗,等待完成,取走
- 完成条件:清洗完成信号
- 异常:清洗超时需人工介入
(判断)全检台是否满位(OP35 全检台容量判断)
- 条件:全检台有空位 → 走 OP40 全检检测
- 条件:全检台满 + 缓存台有空位 → 走 OP50 缓存暂存
- 条件:全检台满 + 缓存台也满 → 不推进,等待下次调度重新判断
- 这是 recipe 中的 Decision 步骤,由引擎按优先级遍历决策分支
(判断)磨床取料前下游容量判断(OP20_DECIDE 磨床下游容量判断)
- 触发时机:M3600 磨床加工完成信号到达后,在 OP20_UNLOAD(取料)之前
- 目的:防止 robot 取料后下游全满无处可放,形成死锁(robot 持料等待缓存空、全检台 done 件等待 robot 空爪、缓存件等待全检台空)
- 条件:全检台有空位 → 正常取料(OP20_UNLOAD)
- 条件:缓存台有空位 → 正常取料(OP20_UNLOAD)
- 条件:全检台+缓存台均满 → 不取料,等待下次调度重新判断(robot 不持料,其他 job 可继续)
OP40 全检检测
- 做什么:机器人把工件放到全检台,等待 PLC 确认放料完成后,再通知人工可以开始检测
- 检测方式:纯人工检测,不区分合格/不合格,系统不参与判定
- 通知时机:全检台槽位装满 或 为工单最后一件工件时,发送 M2102 信号通知 PLC
- M2102 发送时机:仅在收到 PLC 放料完成信号(FullCheckPlaceDone)后检查并发送,不在放料请求发出时提前发送
- 完成条件:人工检测完成信号
- 异常:检测超时需人工介入
- 特殊情况:全检台满时,工件暂存缓存台
OP50 缓存暂存
- 做什么:全检台满时,机器人把工件暂存到缓存台
- 完成条件:成功放入缓存台
- 异常:缓存台也满了暂停,等全检台有空位
- 暂存完成后 robot/temp_slot 立即释放(工件在缓存台,不占用机器人,防止死锁)
OP50_UNLOAD 缓存取料
- 做什么:全检台有空位时,机器人从缓存台取回工件,随后放全检台
- 前置条件:FULL_CHECK 有空位才取料(check),防止取料后无位可放导致 robot 假占用
- 完成条件:成功从缓存台取出,缓存台槽位释放为 empty
- 回流:取料后 robot 持料直接进入 OP40_LOAD 放全检台,不再经过 OP35 重新判断
OP60 接驳台下料
- 做什么:机器人把成品放回接驳台托盘
- 完成条件:成品成功放入托盘
- 异常:放料失败需人工介入
- 特殊情况:接驳台目标槽位非空时拒绝放料
三、业务规则
接驳台
- 左右两个托盘(dock_no=1左, dock_no=2右),每托盘 42 个位置(1-42),共 84 个槽位
- 槽位状态由
equipment_slot表记录,状态包括:Empty(空)、Occupied(有料)、Processing(加工中)、Done(加工完成) - AGV 负责上料和下料(AGV 是外部系统,通过 HTTP 通讯)
接驳台互斥占用:
接驳台同时只能被一个角色占用(机器人/AGV/人工),防止并发操作:
| 当前占用 | 机器人取放 | AGV 进线 | AGV 离场 | 人工操作 |
|---|---|---|---|---|
| 空闲 | 允许 | 允许 | 允许 | 允许 |
| 机器人取放中 | — | 拒绝 | 允许 | 拒绝 |
| AGV 进线中 | 拒绝 | 拒绝 | 允许 | 拒绝 |
| 人工占用中 | 拒绝 | 拒绝 | 允许 | 仅解锁 |
- 机器人取放接驳台工件时,自动标记接驳台为 ROBOT 占用,完成后自动释放
- AGV 进线时标记接驳台为 AGV 占用,离场时释放
- AGV 离场不受任何占用影响(成品需尽快离开)
- 缓存台、磨床等其他设备不需要互斥占用(只有一个机器人操作)
接驳台完整流程:
- AGV 上料:AGV 将毛坯运到接驳台,所有槽位为毛坯(Occupied 状态)
- 加工循环:机器人从接驳台取毛坯 → 磨削 → 清洗 → 全检 → 放回接驳台成品
- 槽位状态流转:取毛坯时 Occupied→Empty,放成品时 Empty→Done
- AGV 下料:接驳台所有槽位变为 Done(成品)后,通知 AGV 运走
- 清零:AGV 运走后,PLC 发清零信号,软件清零槽位状态
槽位分配规则(核心):
- 先有槽位,后分配工件
- 创建工单时,必须检查接驳台有足够的空槽位才能创建
- 槽位按从小到大顺序分配(先分配编号小的空槽位)
- 不同接驳台独立分配,互不影响
无料暂停规则:
- 接驳台没料时,系统不挂起工件,而是等待 AGV 送货
- 未绑定槽位的工件(CREATED 状态,PositionRefId="")不会被调度,调度器自动跳过
- 工件绑定仅由 AGV 进线事件(
handleAgvRequestEntry)或人工「绑定槽位」触发,系统不做自动绑定轮询 - 若 MOM 工单启动时接驳台无货,
tryAutoCallMaterialOnStart自动触发叫料
磨床
- 放料时自动判断:磨床已有成品 → 换料(取走成品的同时放入毛坯);磨床空 → 直接放料
- 有料/无料状态由系统自动记录,不需要人工判断
- 放料动作本身就会触发磨床启动,不需要单独的启动信号
磨床换料规则:
- 首次上料:磨床为空,执行"放料"动作(不是换料)
- 正常换料:磨床有成品,执行"换料"动作(取成品+放毛坯一次完成)
- 最后一件:磨床有成品,但没有后续毛坯需要上料,执行"卸料"动作(只取不放)
- 空磨床拒绝换料:如果磨床是空的,系统不会执行换料动作,必须先走放料
换向机构
- 仅方形件使用,用于换向(旋转工件方向)
- 放上换向机构后 PLC 自动旋转,旋转完成发信号通知系统
全检台
- 纯人工检测,检测结果由人工判定,系统不判定 OK/NG
- 放料完成后,等待 PLC 确认放料完成(FullCheckPlaceDone),再检查是否需要通知检测
- 通知时机:全检台槽位装满 或 为工单最后一件工件时,发送 M2102 信号通知 PLC
- 全检台满时发布报警事件(ALARM_RAISED),管理后台可见提示「全检台已满」
缓存台
- 全检台满时暂存工件
- 缓存台暂存完成后,工件直接取料回流(OP50_UNLOAD),不再经过 OP35 重新判断
- 全检台完成检测出现空位后 → OP50_UNLOAD 从缓存台取工件 → OP40_LOAD 放入全检台
- 缓存台满时:OP35 判断全检台+缓存台均满 → 不推进,等待全检台有空位
磨床完工下游容量检查
- 磨床发出 M3600(GrinderMachiningDone)完成信号时,引擎推进到 OP20_DECIDE 决策步骤
- OP20_DECIDE 检查下游容量:全检台有空位或缓存台有空位 → 正常取料(OP20_UNLOAD)
- 全检台满 + 缓存台满 → 不取料,等待资源释放后重试(robot 不持料,防止死锁)
- 此机制由引擎的 decision 步骤天然支持,无需额外定时器轮询
清洗
- 机器人放料 → 启动清洗 → 等待完成 → 取走,全程机器人被占用
四、业务闭环
正常流程
创建工单 → OP10上料(取毛坯) → OP20磨削 → OP30清洗
→ OP40全检(或OP50缓存→回流OP40) → OP60下料(放成品) → 工单完成
工单开始
前置条件:
- 接驳台必须有足够的空槽位
- 同一产品分类不能有其他活跃工单
- 产品类型必须关联工艺路线
创建流程(人工创建):
- 用户选择产品类型和数量
- 选择接驳台(左/右托盘)
- 系统检查接驳台空槽位数量是否足够
- 系统创建工单(状态 Created),不创建 Job
- 用户点击「开始工单」→ 系统创建 Job 并启动调度
- 若接驳台无货,操作员手动叫料或放置物料后绑定槽位
启动流程(MOM 工单自动):
- MOM 轮询发现新工单 → 创建工单 → 回传 MOM 已接受 → 自动叫料
- MOM 叫料成功后,AGV 送货到接驳台
- AGV 到达 →
handleAgvRequestEntry自动绑定 Job 到槽位 → 触发调度
自动叫料触发时机:
| 触发点 | 说明 |
|---|---|
| MOM 轮询发现新工单 | processMomOrder → momCallMaterial |
| 手动启动 MOM 工单 | handleStartOrder → tryAutoCallMaterialOnStart |
| AGV 离场后补叫料 | replenishMaterial(AGV 取走成品后自动补叫下一批) |
| 人工叫料 | 前端「人工叫料」按钮 → handleManualCallMaterial |
自动绑定触发时机:
| 触发点 | 说明 |
|---|---|
| AGV 进线 | handleAgvRequestEntry(事件驱动,主要路径) |
| 人工绑定 | 管理后台接驳台页面「绑定槽位」→ handleBindDock |
工单中间
暂停条件(所有情况都暂停):
| 暂停原因 | 说明 | 恢复条件 |
|---|---|---|
| 接驳台没料 | 所有槽位都是 Empty 或 Done | AGV 送来新毛坯 |
| 全检台满 | 2 个槽位全部占用 | 检测完成释放槽位 |
| 缓存台满 | 1 个槽位被占用 | 全检台释放槽位,工件回流 |
| 磨床有料加工中 | 磨床正在加工,无法上料 | 磨床加工完成 |
| 换向机构有料换向中 | 换向机构正在换向 | 换向完成 |
工单完成前的停止规则:
- 当工单中所有工件都已经加工完成(最后一个工件离开磨床),系统停止向磨床上料
- 但系统继续完成后续工序:清洗 → 全检 → 放回接驳台
- 所有成品都放回接驳台后,工单才算真正完成
工单结尾
工单完成条件:
- 工单中所有工件状态都是 Completed
- 所有成品都已放回接驳台
- 接驳台对应槽位状态变为 Done
工单完成流程:
- 最后一个工件完成 OP60 接驳台下料
- 工件状态变为 Completed
- 接驳台槽位状态变为 Done
- 检查工单中所有工件是否都已完成
- 工单状态变为 Completed
- 通知 AGV:"接驳台有成品可以运走"
- 清理运行时状态
工单取消流程:
- 用户发起取消工单请求
- 将所有非终态工件标记为 Scrapped
- 释放所有设备槽位(磨床/换向机构/全检台)
- 释放缓存台占用
- 释放接驳台占用(槽位恢复为 Empty)
- 更新工单状态为 Cancelled
收尾特殊情况:
| 情况 | 处理方式 |
|---|---|
| 工单全部完成 | 所有工件完成,所有成品放回接驳台,工单自动标记完成 |
| 接驳台没料暂停 | 系统暂停调度,通知 AGV 上料,AGV 到位后恢复 |
| 全检台满暂停 | 工件暂存缓存台,缓存台也满则暂停,等全检台释放 |
| 缓存台满暂停 | 暂停调度,等待全检台释放槽位 |
| 磨床最后一件 | 加工完成后只卸料,不上料 |
| 工单暂停 | 暂停后不再调度新任务,当前正在加工的工件继续完成 |
| 工单取消 | 停止所有工件,释放所有设备槽位和缓存台占用 |
| 工件异常 | 单个工件挂起,不影响其他工件,需人工处理 |
| 断电恢复 | 启动时自动恢复未完成工单,检查工件状态一致性,异常部分人工确认 |
五、AGV 交互规则
AGV 上料触发
- 触发方式:事件驱动(MOM 叫料成功 → AGV 送货 → AGV 到达时回调
request-entry) - 绑定方式:AGV 进线
handleAgvRequestEntry自动绑定,或人工「绑定槽位」,系统无自动绑定轮询 - 达到后处理:
handleAgvRequestEntry自动绑定 Job 到槽位 → 触发trySchedule开始调度 - 幂等保护:同一接驳台已有工件时,AGV 重复进线请求直接返回成功
AGV 下料触发
- 当接驳台所有槽位都是 Done 时,系统通知 AGV 下料
- AGV 运走后,PLC 发清零信号
- 系统收到信号后,清空槽位状态为 Empty
AGV 离场处理
checkAgvDeparture在 MOM 轮询中检查:槽位全部空 + 无活跃工件 → 触发离场- 离场后:清除 AGV 占用、重置接驳台槽位、清理终态工件 dock 绑定、补叫料
AGV 通知方式
- 通过 HTTP 接口调用 AGV 系统
- 通知内容:接驳台位置、物料类型、操作类型(上料/下料)
- 系统等待 AGV 确认后再继续
六、人工操作规则
人工报工
未达到自动报工触发条件时,人工触发通知 AGV 取走成品:
- 操作员点击人工报工
- 前置校验:接驳台被机器人/AGV 占用时拒绝;同一接驳台报工成功后 60 秒内再次触发拒绝(防重复报工)
- 系统检查该接驳台是否有成品(Completed 状态的工件)
- 有成品 → 调用 MOM 接口通知 AGV 来取
- AGV 到达 → 取走成品 → AGV 离场 → 占用释放
- 无成品 → 提示"该接驳台无成品可报工"
人工报工/叫料本身不占用接驳台(不设置为 MANUAL 占用),避免阻止 AGV 进线;占用由 AGV 到达时自然发生。
人工叫料
人工触发通知 AGV 送来毛坯:
- 操作员点击人工叫料
- 前置校验:接驳台被机器人/AGV 占用时拒绝;同一接驳台叫料成功后 60 秒内再次触发拒绝(防重复叫料)
- 以内部工单计划数量计算尚缺毛坯;分配已足够则提示"无需叫料"
- 调用 MOM 接口叫料
- AGV 送货 → 到达 → AGV 进线 → 占用自动切换为 AGV
人工占用与解锁
用于故障排查或维护时临时冻结接驳台:
- 操作员点击人工占用 → 接驳台标记为 MANUAL 占用
- 占用期间:机器人不能取放、AGV 不能进线(AGV 离场不受影响)
- 排查/维护完成后 → 操作员手动解锁
- 解锁后视情况发起人工叫料或人工报工
人工占用只有一种类型,不区分叫料/维护子场景。解锁后不自动通知 AGV,由操作员主动操作。
七、设备状态检查清单
启动或恢复生产前,必须检查以下设备状态:
| 检查项 | 检查内容 | 正常状态 | 异常处理 |
|---|---|---|---|
| 接驳台 | 槽位是否有毛坯 | 至少有一个 Occupied | 通知 AGV 上料 |
| 磨床 | 是否有工件 | Empty 或 Done | 如为 Processing,等待完成 |
| 换向机构 | 是否有工件 | Empty | 如为 Processing,等待完成 |
| 全检台 | 是否有空位 | 至少有一个 Empty | 等待检测完成 |
| 缓存台 | 是否有空位 | 至少有一个 Empty | 等待全检台释放 |
| 清洗 | 是否就绪 | Ready | 等待设备就绪 |
八、常见问题处理
问题:接驳台没料
现象: 系统暂停调度,日志显示"接驳台无可用槽位"
处理:
- 检查 AGV 是否已送达毛坯
- 检查 PLC 信号是否正常
- 如果 AGV 未送达,手动通知 AGV 上料
- AGV 送达后,系统自动恢复调度
问题:全检台满
现象: 工件堆积在缓存台
处理:
- 通知检测人员加快检测
- 检查检测完成信号是否正常
- 等待全检台释放槽位
问题:磨床不换料
现象: 磨床有成品,但系统没有执行换料动作
检查:
- 是否有后续毛坯等待上料
- 缓存台是否有毛坯
- 如果没有后续毛坯,系统只执行卸料(正常行为)
问题:工件挂起
现象: 单个工件状态变为 Suspended,调度器跳过该工件,不再为其生成任务。
挂起原因分类:
| 挂起原因 | 触发场景 | 严重程度 |
|---|---|---|
order_paused |
工单暂停,所有非终态工件随工单一并挂起 | 正常,恢复工单自动恢复 |
manual |
操作员手动挂起 | 主动操作 |
step_timeout |
工序超时 | 需人工介入 |
上料/下料/换料失败: xxx |
机器人动作执行失败(含取料时接驳台无货) | 设备异常,需人工介入 |
处理:
- 查看预警通知中的
ACTION_FAILED报警,了解挂起原因 - 人工处理异常情况(设备故障、接驳台缺料等)
- 处理完成后恢复工件
边界场景:OP10 取料失败挂起后的恢复
发生条件: 工件在 OP10(接驳台上料)步骤执行 load_from_dock 时失败,被挂起。此时工件状态为 SUSPENDED,current_step_id 仍为 OP10,dock_equipment_id / dock_slot_no / position_ref_id 均为空(或指向取料失败的槽位)。
恢复路径与限制:
| 场景 | 能否自动恢复 | 说明 |
|---|---|---|
| 恢复工件后直接调度 | 否 | 工件恢复后状态变为 PROCESSING,但无接驳台绑定(dock_equipment_id 为空),调度器生成 KindLoadDock 时无法确定目标接驳台,动作被跳过 |
| AGV 后续送货到接驳台 | 否 | AGV 送货只更新槽位状态(Empty→Occupied),不自动绑定工件。工件与槽位是独立的,调度器不知道哪个槽位属于哪个工件 |
| 管理后台人工绑定槽位 | 是 | handleBindDock 匹配 CREATED 或 PROCESSING(含挂起恢复后)且 position_ref_id="" 的工件,绑定后自动触发调度 |
| 人工绑定槽位后再恢复 | 是 | 先通过管理后台绑定槽位,再恢复工件,调度器即可正确识别 |
正确的恢复操作顺序:
- 确认接驳台对应槽位已有物料(AGV 送达或人工放置)
- 在管理后台 → 接驳台页面,选择已有物料的空槽位,点击"绑定槽位"
handleBindDock会匹配当前工单下首个CREATED或PROCESSING且未绑定的工件
- 绑定成功后,工件获得
dock_equipment_id、dock_slot_no等字段 - 前端点击"恢复工件"
- 调度器生成
KindLoadDock动作,此时DockEquipmentID有效,取料正常执行
已知限制:
- 工件挂起后原始
dock_equipment_id等字段未保留,恢复后需通过管理后台重新绑定槽位 - 若接驳台无可用物料(所有槽位为空),需等待 AGV 送货或人工放置物料后再绑定
问题:AGV 送货与工件绑定
绑定时机: 工件绑定接驳台槽位发生在工单启动后,由人工通过管理后台触发 CmdBindDock。
绑定流程:
- 工单状态为 InProgress 时,管理后台的接驳台页面出现"绑定槽位"操作入口
- 操作员选择接驳台的某个空槽位,点击绑定
handleBindDock查找当前工单下首个status=CREATED AND position_ref_id=""的工件- 将该工件绑定到选中槽位,同时更新槽位状态为 Occupied
- 绑定后工件获得
dock_equipment_id、dock_slot_no、position_ref_id,调度器可在下一轮调度中为其生成KindLoadDock动作
绑定与挂起的交互:
- 如果工件在绑定前已被挂起,绑定操作无法匹配到该工件(因为 status 不是 CREATED)
- 如果工件在绑定后被挂起(如取料失败),恢复后
dock_equipment_id等信息可能已丢失,需重新绑定
问题:AGV 送货后工件自动恢复
当前行为: AGV 送货后,接驳台槽位状态更新为 Occupied,但挂起的工件不会自动恢复。
原因:
- 工件挂起是显式状态变更,需要显式恢复操作
- 系统不假设"槽位有货"等价于"工件可以取料",因为工件可能因其他原因挂起(如质量问题、设备故障)
- AGV 送货与工件调度是解耦的:AGV 负责物料搬运,EventLoop 负责工件调度
设计意图: 挂起是"人工介入"的信号,不应由系统自动解除。即使 AGV 补货完成,也需人工确认工件状态正常后再恢复。
九、事件日志(生产日志/预警通知)
所有事件经 EventBus 发布,同时推送 SSE(前端实时刷新)并异步写入 event_log 表(日志查询页)。
工单生命周期事件
| 事件类型 | 触发时机 | 发布位置 |
|---|---|---|
ORDER_CREATED |
创建工单 | create_work_order_logic.go |
ORDER_STARTED |
开始工单(有活跃工件) | eventloop handleStartOrder |
ORDER_PAUSED |
暂停工单 | eventloop handlePauseOrder / pause 逻辑无活跃工件分支 |
ORDER_RESUMED |
恢复工单 | eventloop handleResumeOrder / resume 逻辑无活跃工件分支 |
ORDER_CANCELLED |
取消工单 | eventloop handleCancelOrder / cancel 逻辑无活跃工件分支 |
ORDER_COMPLETED |
工单完工 | eventloop checkOrderCompletion |
工件生命周期事件
| 事件类型 | 触发时机 | 发布位置 |
|---|---|---|
JOB_COMPLETED |
工件全部工序完成 | eventloop |
JOB_SCRAPPED |
工件报废 | eventloop |
JOB_SUSPENDED |
工件挂起(手动或步骤超时) | eventloop handleSuspendJob / handleStepTimeout |
JOB_RESUMED |
工件恢复 | eventloop handleResumeJob |
JOB_REWORKED |
工件返工 | eventloop handleReworkJob |
JOB_DISCHARGED |
工件下线出料 | eventloop |
其他事件
- 物料流转:
LOAD/UNLOAD/EXCHANGE/REPLENISH - 加工:
MACHINE_START/MACHINE_DONE/INSPECTION_RESULT - 报警:
ALARM_RAISED/ALARM_ACKED - 人工交互:
MANUAL_ACTION_CREATED/MANUAL_ACTION_RESOLVED - MOM/AGV:
MOM_*/AGV_* - 缓存台:
TEMP_SLOT_CHANGED
说明:任何工单/工件状态变更都必须发布对应事件,保证日志查询+预警通知能完整回溯整个生产流程。前端
frontend/src/constants/event.ts与views/dashboard/event-log/index.tsx需与后端事件类型保持同步。
十、信号参考与精确时序
设备信号一览
接驳台(Dock, equipment_id=1/8)
| 逻辑名 | 信号名 | 地址 | 类型 | 说明 |
|---|---|---|---|---|
| 取料请求 | DockFetchReq | M2000 | bool | 机器人取料请求 |
| 取料位置 | DockFetchPos | M2001 | byte | 取料位置号(1-42) |
| 取料托盘 | DockFetchTray | M2002 | byte | 托盘号(1左/2右) |
| 取料完成 | DockFetchDone | M2009 | byte | PLC 取料完成 |
| 放料请求 | DockPlaceReq | M2010 | bool | 机器人放料请求 |
| 放料位置 | DockPlacePos | M2011 | byte | 放料位置号 |
| 放料托盘 | DockPlaceTray | M2012 | byte | 托盘号 |
| 放料完成 | DockPlaceDone | M2019 | byte | PLC 放料完成 |
磨床(Grinder, equipment_id=2)
| 逻辑名 | 信号名 | 地址 | 类型 | 说明 |
|---|---|---|---|---|
| 取料请求 | GrinderFetchReq | M2030 | bool | 机器人取成品 |
| 取料完成 | GrinderFetchDone | M2039 | byte | 取料完成 |
| 放料请求 | GrinderPlaceReq | M2040 | bool | 机器人放毛坯 |
| 放料完成 | GrinderPlaceDone | M2049 | byte | 放料完成 |
| 换料请求 | GrinderExchangeReq | M2050 | bool | 取成品+放毛坯一次完成 |
| 换料完成 | GrinderExchangeDone | M2059 | byte | 换料完成 |
| 加工完成 | GrinderMachiningDone | M3600.0 | bool | 磨削加工完成,触发取料 |
换向机构(TurnTable, equipment_id=3)—— 仅方形件使用
| 逻辑名 | 信号名 | 地址 | 类型 | 说明 |
|---|---|---|---|---|
| 取料请求 | TurnTableFetchReq | M2060 | bool | 机器人取料 |
| 取料完成 | TurnTableFetchDone | M2069 | byte | 取料完成 |
| 放料请求 | TurnTablePlaceReq | M2070 | bool | 放料+PLC自动旋转 |
| 放料完成 | TurnTablePlaceDone | M2079 | byte | 放料+旋转完成 |
注意:转换台没有独立的旋转信号。PLC 在收到 M2070 放料请求后自动完成旋转,M2079 同时表示放料和旋转完成。
清洗(Wash/AirBlow, equipment_id=4)
| 逻辑名 | 信号名 | 地址 | 类型 | 说明 |
|---|---|---|---|---|
| 启动请求 | WashStartReq | M2130 | bool | 启动清洗 |
| 清洗完成 | AirBlowCompleteDone | M2139 | byte | 清洗完成 |
全检台(FullCheck, equipment_id=6)
| 逻辑名 | 信号名 | 地址 | 类型 | 说明 |
|---|---|---|---|---|
| 放料请求 | FullCheckPlaceReq | M2100 | bool | 机器人放料 |
| 放料位置 | FullCheckPlacePos | M2101 | byte | 位置号(1-2) |
| 放料完成 | FullCheckPlaceDone | M2109 | byte | PLC 放料完成 |
| 检测请求 | FullCheckPlaceDoneRequestInspect | M2102 | bool | 通知人工检测 |
| 检测完成 | FullCheckInspectDone | M2098 | byte | 人工检测完成 |
| 取料请求 | FullCheckFetchReq | M2090 | bool | 机器人取成品 |
| 取料位置 | FullCheckFetchPos | M2091 | byte | 位置号 |
| 取料完成 | FullCheckFetchDone | M2099 | byte | 取料完成 |
| 换料请求 | FullCheckExchangeReq | M2080 | bool | 全检台换料 |
| 换料完成 | FullCheckExchangeDone | M2089 | byte | 换料完成 |
缓存台(Cache, equipment_id=5)
| 逻辑名 | 信号名 | 地址 | 类型 | 说明 |
|---|---|---|---|---|
| 取料请求 | CacheFetchReq | M2110 | bool | 机器人取料 |
| 取料位置 | CacheFetchPos | M2111 | byte | 位置号 |
| 取料完成 | CacheFetchDone | M2119 | byte | 取料完成 |
| 放料请求 | CachePlaceReq | M2120 | bool | 机器人放料 |
| 放料位置 | CachePlacePos | M2121 | byte | 位置号 |
| 放料完成 | CachePlaceDone | M2129 | byte | 放料完成 |
全局信号
| 信号名 | 地址 | 类型 | 说明 |
|---|---|---|---|
| CameraWorkType | M2022 | byte | 工件类型(每组操作前写入) |
信号握手时序
所有 PLC 动作遵循标准的 5 步握手时序:
1. 写参数(如有)→ 等 1 秒
2. 写 Req=true → 触发 PLC 动作
3. 立即返回(不等待 Done)
4. PLC 执行动作 → 完成后设 Done=true
5. SignalRouter 检测到 Done → 通知引擎 → COMPLETE 阶段
关键约束:
- Go 程序只写 Req=true,绝不写 Req=false(PLC 自行管理复位)
- 两次 PLC 写操作之间至少间隔 1 秒
- Done 信号由 SignalRouter 异步监控,不在业务代码中同步等待
- 收到 Done 信号后,需等待 3 秒再发送下一个 Req(确保 PLC 读取信号)
各步骤精确时序
OP10 接驳台取料
前置条件:robot=idle, temp_slot=free, DOCK slot=occupied
1. ACQUIRE: 获取 robot + temp_slot + DOCK occupied 槽位(事务)
2. EXECUTE:
a. 写 M2022 = 工件类型(byte)
b. 写 M2001 = 位置号(byte)
c. 写 M2002 = 托盘号(byte)
d. 等 1 秒
e. 写 M2000 = true(取料请求)
3. WAIT: 等 M2009 Done(byte≠0)
4. COMPLETE:
a. 释放 robot → idle
b. temp_slot → occupied(工件在缓存槽)
c. DOCK slot → empty
OP20 磨床放料(圆形件)/ OP25 转换台放料(方形件)
前置条件:robot=idle, 目标设备 slot=empty
1. ACQUIRE: 获取 robot + 目标设备 empty 槽位
2. EXECUTE:
a. 写 M2022 = 工件类型
b. 写 PlaceReq = true
c. 等 1 秒
3. WAIT: 等 PlaceDone
4. COMPLETE:
a. 释放 robot → idle
b. 释放 temp_slot → free
c. 目标设备 slot → occupied
OP20_WAIT 磨床等待加工
前置条件:GRINDER slot=occupied(确认工件在磨床上)
1. ACQUIRE: check GRINDER occupied(无资源获取)
2. EXECUTE: 无信号发送(纯等待)
3. WAIT: 等 M3600.0 GrinderMachiningDone
4. COMPLETE:
a. GRINDER slot → done(加工完成,等待取料)
OP20_UNLOAD 磨床取料
前置条件:robot=idle, temp_slot=free, GRINDER slot=done
1. ACQUIRE: 获取 robot + temp_slot + GRINDER done 槽位
2. EXECUTE: 写 GrinderFetchReq → 等 GrinderFetchDone
3. COMPLETE:
a. 释放 robot → idle
b. temp_slot → occupied(工件在缓存槽)
c. GRINDER slot → empty
OP30 清洗(工件在机器人夹爪上)
前置条件:robot=idle(持有中), temp_slot=occupied
1. ACQUIRE: 获取 robot + temp_slot occupied
2. EXECUTE: 写 WashStartReq → 等 AirBlowCompleteDone
3. COMPLETE:
a. 释放 temp_slot → free
b. robot 不释放!held_by_job_id 机制保证跨步骤持料
OP35 全检台容量判断(决策步骤)
前置条件:无(决策步骤不获取资源)
1. 查询 FULL_CHECK empty 槽位数
2. 分支1: empty >= 1 → 跳转 OP40_LOAD(全检放料)
3. 分支2: CACHE empty >= 1 → 跳转 OP50_LOAD(缓存暂存,全检台满时)
4. 都不匹配(全检台+缓存台均满)→ 等待资源变更后重试
OP20_DECIDE 磨床下游容量判断(决策步骤)
前置条件:无(决策步骤不获取资源)
1. 查询 FULL_CHECK empty 槽位数
2. 分支1: FULL_CHECK empty >= 1 → 跳转 OP20_UNLOAD(正常取料)
3. 分支2: CACHE empty >= 1 → 跳转 OP20_UNLOAD(正常取料)
4. 都不匹配(全检台+缓存台均满)→ 等待资源变更后重试
OP40 全检台放料
前置条件:robot=idle, temp_slot=occupied, FULL_CHECK slot=empty
1. ACQUIRE: 获取 robot + temp_slot + FULL_CHECK empty 槽位
2. EXECUTE:
a. 写 M2022 = 工件类型(byte)
b. 写 M2101 = 位置号(byte)
c. 等 1 秒
d. 写 M2100 = true(放料请求)
3. WAIT: 等 M2109 Done(byte≠0)
4. COMPLETE:
a. 释放 robot → idle
b. 释放 temp_slot → free
c. FULL_CHECK slot → occupied
d. 发送 M2102(通知人工检测)
OP40_WAIT 全检台等待检测
前置条件:FULL_CHECK slot=occupied
1. ACQUIRE: check FULL_CHECK occupied
2. WAIT: 等 FullCheckInspectDone(M2098)
3. COMPLETE: FULL_CHECK slot → done
OP60 接驳台下料
前置条件:robot=idle, temp_slot=occupied, DOCK slot=empty
1. ACQUIRE: 获取 robot + temp_slot + DOCK empty 槽位
2. EXECUTE: 写 DockPlaceReq → 等 DockPlaceDone
3. COMPLETE:
a. 释放 robot → idle
b. 释放 temp_slot → free
c. DOCK slot → done(等待 AGV 取走)
工艺路线对比
缸体工艺(圆形件,recipe_id=1)
OP10_LOAD(接驳台取料) → OP20_LOAD(磨床放料) → OP20_WAIT(等M3600)
→ OP20_DECIDE(下游容量判断) → OP20_UNLOAD(磨床取料) → OP30_LOAD(清洗)
→ OP35_DECIDE(容量判断) → OP40_LOAD(全检放料) / OP50_LOAD(缓存暂存→回流OP35)
→ OP40_WAIT(等M2098) → OP40_UNLOAD(全检取料) → OP60_LOAD(接驳台下料)
配油盘工艺(方形件,recipe_id=2)
OP10_LOAD(接驳台取料) → OP25_TURN_LOAD(转换台放料+旋转)
→ OP25_TURN_UNLOAD(转换台取料) → OP20_LOAD(磨床放料)
→ OP20_WAIT(等M3600) → OP20_DECIDE(下游容量判断) → OP20_UNLOAD(磨床取料)
→ OP30_LOAD(清洗) → OP35_DECIDE(容量判断) → OP40_LOAD / OP50_LOAD(缓存暂存) → OP50_UNLOAD(缓存取料)
→ OP40_WAIT → OP40_UNLOAD → OP60_LOAD(接驳台下料)
区别: 方形件在磨床放料前多了转换台放料+旋转+取料三步(OP25_TURN_LOAD + OP25_TURN_UNLOAD)。