plc_control/docs/superpowers/specs/2026-05-18-operation-system...

29 KiB
Raw Blame History

运转系统顺控引擎设计

日期2026-05-18

参考来源:

  • 运转系统逻辑说明.doc(说明书 14 章)
  • docs/运转系统实现方案.md(高层方案)
  • docs/superpowers/specs/2026-04-14-dual-app-shared-core-design.md(双应用共享核心架构)
  • 现有 crates/app_feeder_distributor 实现作为工程参考

1. 目标

在已经搭好的 crates/app_operation_system 骨架内,落地说明书中规定的整线自动控制能力:

  • 覆盖 8 个业务子系统回车线、前端码车道、机械臂、摆渡车、1 号干燥/焙烧窑、2 号干燥/焙烧窑、窑尾下摆渡车、卸砖机位。
  • 引擎语义遵循说明书第 1.4 与 13 章:"顺序控制 + 联锁保护 + 检测信号闭环确认 + 异常停留人工恢复"。
  • 双窑线1 号 / 2 号)采用同一套段模板,仅通过参数差异化,不写两套代码。
  • 复用 plc_platform_core 的接入层OPC UA / 点位 / 设备 / 事件 / WebSocket / 日志)。
  • 不引入 app_feeder_distributorunit + run_time/stop_time/acc_time/bl_time 业务模型。

非目标(首期):

  • 不做规则引擎或 DSL只支持固定 rule_kind 联锁判定。
  • 不做高级排程(最大化吞吐、动态优化),只做基于空位/资源占用的放行决策。
  • 不做权限/审计/历史回放。

2. 设计结论

决策 选择 原因
业务模型 station + segment + step + interlock 说明书是工位驱动的整线顺控,不是节拍式设备启停
unit 不复用 语义不匹配ops 自己建 process_segment
引擎调度单位 segment 每个 enabled segment 一个 tokio task对齐 feeder 引擎结构
双窑线参数化 同一段模板 + line_code 区分实例 对齐说明书第 11 章
联锁配置 数据库表 + 固定 rule_kind 枚举 首期不引入表达式语言
WebSocket 消息扩展 core 保持通用通道ops 使用业务 payload 分支 避免 plc_platform_core 反向依赖 ops 领域类型;前端仍只连一处
报警 event 表 + subject_type/subject_id + level=warn/error 复用现有事件表,同时支持按段 / 工位查询
公共资源互斥 app 内部命名锁注册表 + 租约/恢复策略 摆渡车 / 机械臂 / 卸砖机位等共享资源,防止 task 异常退出后长期占锁

3. 不沿用 feeder 模型的理由

ControlUnit 当前字段是 run_time_sec / stop_time_sec / acc_time_sec / bl_time_sec,语义是"运行 N 秒 → 停 M 秒 → 累计 K 秒后启动布料机 → 布料 L 秒"。

运转系统的核心动作完全不是这种节拍:

  • 说明书 8.2 要求"码车位到车确认 → 输送机构停止",是检测信号驱动,不是定时。
  • 说明书 10.1 要求"开门 → 门开到位确认 → 顶车 → 前位确认 → 顶车后退 → 后位确认 → 关门 → 门关到位确认",是 8 步串行带闭环。
  • 说明书 13 章明确要求"动作完成不得仅靠时间,必须结合限位、检测或反馈信号"。

因此引擎需要换语义:segment状态机 + 步骤step顺序 + 每步等待闭环信号

4. 领域模型

4.1 实体一览

source ──┐
         │
point ───┼─→ equipment
         │
         ├─→ station_signal ──→ station ──┐
         │                                              │
         └──────────────→ segment_step ──→ process_segment ──→ segment_runtime
                              │                  │
                              │                  ├──→ segment_interlock
                              │                  └──→ segment_resource
                              │
                              └──→ action_kind (枚举)

source / point / equipment 沿用平台层定义,不改动。

信号边界:

  • point.signal_role 是设备信号角色,例如 rem / flt / home / run / start_cmd / stop_cmd / open_cmd / close_cmd
  • station_signal.signal_role 是工位信号角色,例如 presence / vacancy / arrived / allow_in / done / fault
  • 同一个 point 可以同时被设备角色和工位角色引用,但两者语义分开维护。
  • vacancy 可由独立点位绑定,也可由 presence = false 推导。首期通过 station_signal.derived_from_role 表达推导关系,避免现场必须额外提供空位点。

4.2 新增对象

4.2.1 station(工位)

表示流程中的一个位置或交接位。

字段 类型 说明
id UUID
code TEXT UNIQUE ST-DRY1-IN
name TEXT 例 "1 号干燥窑进口位"
line_code TEXT NULL KILN_1 / KILN_2 / COMMON
segment_code TEXT NULL 用于分组(前端码车 / 双窑线 / 窑尾)
station_type TEXT load / dry_in / dry_step / dry_out / fire_in / fire_step / fire_out / transfer / unload / return
enabled BOOL
description TEXT NULL

4.2.2 station_signal(工位 ↔ 信号绑定)

字段 类型 说明
id UUID
station_id UUID FK
signal_role TEXT presence / vacancy / arrived / allow_in / done / fault
point_id UUID FK 绑定到具体点位
derived_from_role TEXT NULL presence,表示由同工位其他角色反向推导
invert_value BOOL 推导或读取时是否取反,默认 false
UNIQUE (station_id, signal_role)

4.2.3 process_segment(流程段)

字段 类型 说明
id UUID
code TEXT UNIQUE SEG-DRY1-INFEED
name TEXT
segment_type TEXT front_load / robot / front_release / front_transfer / kiln_infeed / kiln_step / kiln_outfeed / tail_transfer / tail_step / unload / return
line_code TEXT NULL KILN_1 / KILN_2 / COMMON
priority INT 公共资源冲突时使用
enabled BOOL
mode TEXT auto / remote_manual / local_manual / disabled
require_manual_ack_after_fault BOOL 故障解除后是否需要人工确认,默认 true
description TEXT NULL

模式语义:

  • local_manual:现场就地优先,软件不推进自动顺控;自动运行中检测到任一相关设备 rem=false 时,停止当前自动段并进入人工恢复路径。
  • remote_manual:允许通过软件发单步 / 单设备命令,但仍必须执行设备故障、通信质量、安全链和关键门位联锁。
  • auto:允许 supervisor 自动推进段状态机。
  • disabled:段任务不启动;已运行任务在下一次配置重载后退出。

4.2.4 segment_step(段步骤)

字段 类型 说明
id UUID
segment_id UUID FK
step_no INT 序号
step_code TEXT 步骤代号
action_kind TEXT 见下方动作模板表
target_equipment_id UUID NULL FK 例如顶车机
target_station_id UUID NULL FK 例如目标摆渡位
confirm_signal_role TEXT NULL 等待哪个信号角色为真
confirm_point_id UUID NULL FK 直接指定确认点位(覆盖 role
expected_value BOOL 信号到位的期望值(默认 true
timeout_ms INT 超时即报警转 Faulted
command_role TEXT NULL 设备命令角色,例 start_cmd / open_cmd / forward_cmd
stop_command_role TEXT NULL 到位或异常时需要发出的停止命令角色,例 stop_cmd
pulse_ms INT NULL 脉冲命令宽度;为空时按 action 默认值
hold_until_confirm BOOL true 表示命令保持到确认信号或故障false 表示脉冲后等待
cancel_on_fault BOOL 故障 / 模式切换 / 通信异常时是否执行停止命令,默认 true
next_step_no_on_success INT NULL 成功后跳转;为空表示顺序进入下一 step
next_step_no_on_failure INT NULL 失败后跳转;首期通常为空并进入 Faulted
on_timeout TEXT fault / retry / block,首期默认 fault
description TEXT NULL
UNIQUE (segment_id, step_no)

action_kind 枚举(首期):

含义
open_door 开门:向门机 open_cmd 发脉冲
close_door 关门
push_forward 顶车机前进
push_retract 顶车机后退复位
pull_run 拉引机拉车
pull_retract 拉引机复位
transfer_move_to 摆渡车移动到目标工位
step_once 节拍步进机执行一步
robot_permit 允许机械臂自动作业
robot_release 允许码车道放车
wait_signal 不发命令,仅等待 confirm_*
pulse_cmd 通用脉冲命令fallback

动作执行策略:

  • open_door / close_door / robot_permit 等短命令,默认 pulse_ms=300,命令发出后等待确认信号。
  • 对输送、顶车、拉引、步进等持续动作,默认 hold_until_confirm=true,到位后执行 stop_command_role
  • 对故障、急停、通信质量异常、自动切就地等中断场景,若 cancel_on_fault=true,先发停止 / 复位命令,再进入 FaultedManualAckRequired

4.2.5 segment_interlock(段联锁)

字段 类型 说明
id UUID
segment_id UUID FK
applies_to TEXT start_allow / start_deny / run_halt
rule_kind TEXT 见下方
point_id UUID NULL FK
station_id UUID NULL FK
equipment_id UUID NULL FK
expected_value BOOL NULL
description TEXT NULL

rule_kind 枚举(首期):

  • point_eq —— 指定 point 的值等于 expected_value
  • station_vacant —— 工位空(绑定的 vacancy 信号 = true 且 presence = false
  • station_occupied —— 工位有车
  • equipment_origin —— 设备在原位(角色 home
  • equipment_no_fault —— 设备无故障(flt = false
  • equipment_remote —— 设备远程(rem = true
  • safety_chain_ok —— 安全链路正常

未来可扩展 expression 类型,但首期不引入。

4.2.6 segment_runtime(段运行态,内存)

不落库(与 feeder UnitRuntime 一致,重启重置):

pub enum SegmentState {
    Idle,
    Checking,
    Executing,
    Confirming,
    Resetting,
    Completed,
    Blocked,
    Faulted,
    ManualAckRequired,
}

pub struct SegmentRuntime {
    pub segment_id: Uuid,
    pub state: SegmentState,
    pub auto_enabled: bool,
    pub current_step_no: Option<i32>,
    pub step_started_at: Option<DateTime<Utc>>,
    pub last_completed_at: Option<DateTime<Utc>>,
    pub blocked_reason: Option<String>,
    pub fault_message: Option<String>,
    pub manual_ack_required: bool,
    pub comm_locked: bool,
    pub rem_local: bool,
    pub held_resources: Vec<String>,
}

4.2.7 segment_resource(段资源声明)

字段 类型 说明
segment_id UUID FK
resource_key TEXT transfer_front / transfer_tail / robot_arm / unload_position / return_line
UNIQUE (segment_id, resource_key)

4.2.8 event 表归因扩展

现有 event 表保留 unit_id / equipment_id / source_id,为了支持 ops 按段、工位检索,新增通用归因字段:

字段 类型 说明
subject_type TEXT NULL segment / station / equipment / source / platform
subject_id UUID NULL 对应业务对象 ID

ops 事件写入规则:

  • 段级事件:subject_type='segment'subject_id=segment_id
  • 工位状态事件:subject_type='station'subject_id=station_id
  • 设备动作事件:优先保留 equipment_id,同时可按上下文设置 subject_type='segment'

4.3 双窑线参数化

不写两套硬编码逻辑。1 号与 2 号窑线的差异由:

  • process_segment.line_codeKILN_1 / KILN_2
  • segment_step.target_equipment_idtarget_station_id(指向各自的门机、顶车机、工位)
  • segment_interlock.point_id / station_id(指向各自工位的检测点)

承载。引擎读到的就是统一的 step 列表,与窑线无关。

5. 顺控引擎设计

5.1 结构(与 feeder 对齐)

crates/app_operation_system/src/
  app.rs                           // AppState 接入 segment_runtime + event_manager + resource_registry
  router.rs
  event.rs                         // AppEventops.*
  control/
    mod.rs
    engine.rs                      // supervisor + per-segment task
    runtime.rs                     // SegmentRuntime / SegmentRuntimeStore
    state.rs                       // SegmentState enum
    step_executor.rs               // 按 action_kind 调度
    interlock.rs                   // 通用允许/禁止/停机判定
    resource.rs                    // 摆渡车 / 机械臂 / 卸砖位 互斥
    simulate.rs                    // 开发态信号回灌
  handler/
    doc.rs                         (已存在)
    station.rs                     // CRUD + 信号绑定
    segment.rs                     // CRUD + step / interlock 配置
    control.rs                     // 段启停 / 手动动作 / 故障确认
    runtime.rs                     // overview / segment detail / station detail

5.2 段状态机

对应说明书 13.6

SegmentState 含义 出口
Idle 等待 auto 启动 Checking
Checking 评估 start_allow / start_deny 联锁 通过 → Executing;否则 → Blocked
Executing 已发出当前 step 的命令 Confirming
Confirming 等待 confirm_signal 到位 收到 → 下一步;超时 → Faulted
Resetting 等待执行机构复位(如顶车机后退) → 下一步或 Completed
Completed 段完成,输出完成信号 Idle(自动循环段)
Blocked 允许条件不满足 条件再次满足 → Checking
Faulted 故障或超时 故障解除 + 满足复位 → ManualAckRequiredIdle
ManualAckRequired 等待人工确认 API ack → Idle

5.3 段内执行循环

伪代码:

loop {
    reload segment + steps + interlocks
    run check_interlocks(state, run_halt)        // 运行中停机检测
    match state {
        Idle if auto_enabled => state = Checking,
        Checking => {
            if pass(start_allow) && !any(start_deny) {
                step = first_step
                state = Executing
            } else {
                blocked_reason = ...
                state = Blocked
            }
        }
        Executing => {
            execute(step.action_kind, step.target_*)  // 发命令
            state = Confirming
        }
        Confirming => {
            wait_signal(step.confirm_*, step.timeout_ms)
            on timeout → fault / retry / block by step.on_timeout
            on ok     → next_step_no_on_success or next step or Completed
        }
        Faulted => break and wait manual recovery
        ...
    }
    notify or fault_tick
}

wait_signal 复用与 feeder wait_phase 类似的 tokio::select! { sleep_until(deadline), notify, fault_tick } 模式,但终止条件是"绑定信号到达期望值"而非时间到。

5.4 step_executor

集中处理 action_kind 到具体写点动作:

  • 短命令类 action_kindplc_platform_core::control::command::send_pulse_command
  • 持续命令类 action_kind 先写 command_role,确认到位、超时或故障中断时按 stop_command_role 收尾。
  • transfer_move_to:写目标工位编号到摆渡车定位命令点位,等待 arrived 信号。
  • wait_signal:不发命令。
  • 各设备的 start_cmd / stop_cmd / open_cmd / close_cmd 信号角色复用 feeder 已有的 signal_role 命名空间equipment 表无需新表结构。

命令执行前必须重新检查:

  • 设备 rem=true
  • 设备 flt=false
  • 命令点与确认点 quality=Good
  • 当前段仍处于允许执行模式
  • 当前 step 仍是 runtime 中的 current_step_no

6. 联锁与异常

6.1 联锁判定顺序(对齐说明书 8.1 / 13

  1. 通信质量(任一绑定点 quality != Goodcomm_locked
  2. 就地 / 远程状态(rem=false)→ 停止自动并转人工恢复
  3. 安全联锁 / 急停 → Faulted
  4. 设备故障(flt = trueFaulted
  5. 门位联锁
  6. 机械臂联锁
  7. 工艺允许条件(空位 / 到位)
  8. 普通顺控条件

高优先级不满足时低优先级不再判断。

6.2 通用允许检查(自动注入到每段)

每段无论是否有显式 segment_interlock,引擎都执行以下通用检查(说明书 13.1

  • 目标工位空位
  • 本工位有车或动作前提
  • 执行机构原位
  • 设备无故障
  • 设备处于远程
  • 信号质量正常
  • 段引用的资源未被占用

6.3 异常恢复(说明书 13.5

  • 故障优先停止当前 step 的命令。
  • Faulted 保留 current_step_no,不跳步。
  • remote_manual 下允许人工执行复位动作,但复位动作仍执行安全、故障、门位和通信检查。
  • 故障物理消失后:
    • require_manual_ack_after_fault(默认 trueManualAckRequired
    • 否则自动回 Idle
  • POST /api/control/segment/{id}/ack-fault 用于人工确认。

7. 公共资源调度

说明书 3.3 / 3.4 指出前端码车系统、窑尾摆渡、回车线、卸砖线为公共段1 号 / 2 号窑线在此处汇合。

实现:

pub struct ResourceRegistry {
    inner: RwLock<HashMap<String, ResourceLease>>,
}

pub struct ResourceLease {
    pub owner_segment_id: Uuid,
    pub acquired_at: DateTime<Utc>,
    pub heartbeat_at: DateTime<Utc>,
}

资源 key 示例:transfer_front / transfer_tail / robot_arm / unload_position / return_line

段配置中以新表 segment_resource(segment_id, resource_key) 声明所需资源;段进入 Executing 前必须 try_acquire,进入 Completedrelease。冲突时停留 Blocked,附 blocked_reason = "resource_busy: transfer_front"

资源恢复策略:

  • 资源持有段每个状态循环刷新 heartbeat_at
  • 若 owner task 已退出、段被禁用、或 owner 已回到 Idle/Completedsupervisor 可回收租约。
  • Faulted 时是否释放资源按资源类型决定:机械臂区、卸砖位等可释放;摆渡车正在载车时不释放,必须人工确认或到达安全位后释放。
  • 资源等待超时只报警和进入 Blocked,不抢占低优先级段。首期不做死锁自动解除。

8. 事件与 WebSocket

8.1 业务事件命名空间 ops.*

event_type level
ops.segment.auto_started info
ops.segment.auto_stopped info
ops.segment.step_advanced info
ops.segment.completed info
ops.segment.blocked warn
ops.segment.fault_locked error
ops.segment.fault_acked info
ops.segment.comm_locked warn
ops.segment.comm_recovered info
ops.station.state_changed info
ops.alarm.action_timeout error
ops.alarm.signal_conflict error
ops.alarm.resource_busy warn

所有事件经 record_eventevent 表(复用平台机制)。

8.2 WebSocket 消息扩展

不把 ops 的 SegmentRuntime 类型放进 core。plc_platform_core::websocket::WsMessage 增加一个通用业务消息分支,业务 payload 由 app crate 构造:

pub enum WsMessage {
    // 已有 ...
    AppEvent(AppWsEvent),
}

pub struct AppWsEvent {
    pub app: String,          // "operation-system"
    pub event_type: String,   // "segment_runtime_changed" / "station_state_changed"
    pub data: serde_json::Value,
}

ops 侧约定:

  • event_type="segment_runtime_changed"data 序列化 SegmentRuntime
  • event_type="station_state_changed"data 包含 station_id / presence / vacancy / arrived / updated_at
  • feeder 前端忽略未知 AppEvent 或非本 app 的消息ops 前端只处理 app="operation-system"

这样仍保留单一 websocket 入口,但 core 不需要知道 ops 的领域模型。

9. API 设计

9.1 配置 API

GET    /api/station
POST   /api/station
GET    /api/station/{id}
PUT    /api/station/{id}
DELETE /api/station/{id}
POST   /api/station/{id}/signal      // 绑定信号
DELETE /api/station/{id}/signal/{role}

GET    /api/segment
POST   /api/segment
GET    /api/segment/{id}
GET    /api/segment/{id}/detail      // 含 step / interlock / resource
PUT    /api/segment/{id}
DELETE /api/segment/{id}
POST   /api/segment/{id}/step
PUT    /api/segment/{id}/step/{step_no}
DELETE /api/segment/{id}/step/{step_no}
POST   /api/segment/{id}/interlock
DELETE /api/segment/{id}/interlock/{interlock_id}

9.2 控制 API

POST /api/control/segment/{id}/start-auto
POST /api/control/segment/{id}/stop-auto
POST /api/control/segment/{id}/reset            // 强制回 Idle仅在 Faulted/Blocked 状态可用
POST /api/control/segment/{id}/ack-fault
POST /api/control/segment/{id}/manual-step      // remote_manual 下单步执行
POST /api/control/segment/batch-start-auto
POST /api/control/segment/batch-stop-auto

POST /api/control/equipment/{id}/manual-action  // remote_manual 下单设备动作,仍执行联锁

9.3 运行态 API

GET /api/runtime/overview            // 所有段 + 关键工位 + 报警计数
GET /api/runtime/segment/{id}
GET /api/runtime/station/{id}
GET /api/event?type=ops.*

10. 前端

复用 web/core 的源码、点位、设备、事件、日志、文档抽屉。

web/ops/ 增加:

  • 总览页:双窑线 + 公共段流程图(首版静态 SVG + 区域绑定段 / 工位状态)
  • 段卡片列表:展示 state / current_step / blocked_reason / fault_message
  • 工位状态视图:有车 / 空位 / 到位
  • 配置页:站点 / 段 / step / interlock 表格 + 表单
  • 手动操作:段启停 / 故障确认 / 复位

WebSocket 订阅 AppEvent(app="operation-system"),按 event_type 分发 segment_runtime_changedstation_state_changed 实时刷新。

11. 复用 vs 新增对照

模块 来源 用途
plc_platform_core::connection 复用 OPC UA 读写
plc_platform_core::control::command::send_pulse_command 复用 所有动作命令底层
plc_platform_core::event::record_event + EventInsert 复用 事件落库
plc_platform_core::event::MetadataCache 复用 + 扩展 通用化为按 (table, id) 查 codefeeder 用 unit/equipmentops 加 station/segment
plc_platform_core::websocket::WsMessage 重构 删除 UnitRuntimeChangedfeeder 业务),新增通用 AppEvent(AppWsEvent)feeder 和 ops 都走 AppEvent
plc_platform_core::handler::platform_routes 复用 source / point / equipment / tag / page
plc_platform_core::model::ControlUnit 迁出 core P-1 阶段下放到 feeder语义本就是 feeder 业务
plc_platform_core::control::runtime::{UnitRuntime, ControlRuntimeStore} 迁出 core 同上,含 DistributorRunning 这种 feeder 专属状态
plc_platform_core::service::control unit CRUD 迁出 core 下放到 feederevent 查询留 core
app_feeder_distributor::control::* 不复用 结构参考

P-1 阶段说明:上表中的"迁出 core"是清理动作,发生在 P0 之前。详见 §12。

12. 阶段计划

阶段 目标 主要工作
P-1 Core 业务清理 core 不再持有 feeder 业务模型 UnitRuntime / UnitRuntimeState / ControlRuntimeStore / ControlUnit / unit CRUD / WsMessage::UnitRuntimeChangedplc_platform_core 迁到 app_feeder_distributorWsMessage 新增 AppEvent(AppWsEvent) 分支并删除 UnitRuntimeChangedfeeder 引用全部调整;前端 ws 客户端按 app + event_type 分发;MetadataCache 通用化为 entity_code(table, id)。零行为变更feeder 通过现有 smoke test
P0 骨架对齐 app_operation_system 与 feeder 在依赖、AppState、bootstrap、tray、启动/退出链路对齐 Cargo.toml 补依赖AppState 加 EventManager + SegmentRuntimeStore + ResourceRegistry;启动接 connect_all_enabled_sources;启动 engine supervisor退出时断开数据源
P1 数据库迁移 & 模型 ops 配置表 + event 归因字段 + Rust model 新 migration 2026-05-1x_create_operation_system.sql;新增 station / station_signal / process_segment / segment_step / segment_interlock / segment_resource;扩展 event.subject_type/subject_idapp_operation_system::model 模块
P2 配置 API 站点 / 段 / step / interlock CRUD service::station / segmenthandlerrouter
P3 引擎 MVP 跑通 1 个段端到端(前端码车位进车段,说明书 8.2 enginestep_executorinterlockruntime;通用 AppEvent WebSocket 推送
P4 动作模板补全 覆盖 8 章 + 10 章典型动作 action_kind 实现 + simulate 反馈
P5 双窑线段模板化 通过段配置实现 1 号 / 2 号窑线 4 段(进口 / 内前移 / 出口) 段配置 seed端到端跑通
P6 资源调度 公共段互斥 ResourceRegistrysegment_resourceBlocked 路径完善
P7 公共段 摆渡车 / 卸砖 / 回车线 段实例 + 段间交接
P8 报警 & 异常恢复 超时报警、信号冲突、人工确认完整链路 AppEvent::Alarm*ack-fault API
P9 前端监控页 段卡片 + 工位状态 + 流程图 web/ops/html + JS
P10 配置前端 段 / 工位 / 联锁可视化配置 web/ops/html 表格表单

每阶段都要求:

  • cargo build -p app_operation_system 通过
  • 至少 1 个单元测试或 smoke test
  • 不破坏 app_feeder_distributor 编译

13. 风险与约束

13.1 主要风险

  • P-1 迁移破坏 feeder:从 core 把 unit 模型迁到 feeder 时容易漏改 import 或 ws 客户端调用。要求迁移单独成 commitfeeder 启动 + 单元测试 + ws 推送链路逐项验证。
  • 现场 I/O 清单缺失:说明书描述了逻辑关系但未明确每个工位 / 设备对应的具体点位。落地前必须补 I/O 对照表。
  • 段切分粒度:段切得太细 → 状态机膨胀;切得太粗 → 段内步骤过多。首期建议按说明书章节级切(一节 = 一段)。
  • WebSocket 领域边界:不得把 SegmentRuntime 放入 core否则 core 会反向依赖 ops 业务模型;采用通用 AppEvent payload。
  • 公共资源死锁:例如摆渡车被段 A 占用、段 A 又等卸砖位空(被段 B 占用)。首期通过段优先级与超时报警缓解,不引入死锁检测。
  • 持续命令收尾:输送、顶车、拉引等不是纯脉冲动作,必须在超时、故障和模式切换时明确停止命令。

13.2 约束

  • 首期不做规则引擎,所有联锁靠固定 rule_kind 枚举。
  • 首期段 / step 改动不做热加载——supervisor 每 10s 重读配置,与 feeder 一致。
  • 首期 segment_runtime 不持久化,重启全部回 Idle
  • 首期不做资源抢占;资源冲突只阻塞、报警和等待人工处理。

14. 验收标准

完成 P0P5 后应达到:

  • 仓库新增 6 张 ops 业务配置表,并扩展 event.subject_type/subject_id,与 feeder 业务表互不干扰。
  • app_operation_system 可独立编译为 exe可启动并连接 OPC UA 数据源。
  • 启动后具备 EventManagerSegmentRuntimeStoreResourceRegistry、engine supervisor退出时可断开数据源。
  • 至少 1 条段(例如 2 号干燥窑进口段,含 8 步)可通过配置驱动跑通:
    • 自动启停
    • 步骤顺序推进
    • 闭环信号确认
    • 持续动作到位后停止命令
    • 故障停步 + 人工确认
  • WebSocket 通过 AppEvent(app="operation-system") 推送段运行态变化、工位状态变化。
  • 前端可见段卡片与当前步骤进度。
  • event 表能按 ops.*subject_type/subject_id 查到全链路事件。

完成 P6P10 后应达到:

  • 1 号 / 2 号窑线全部 6 段(进口 / 内前移 / 出口 × 2 窑)跑通。
  • 公共段(前端码车、摆渡车、窑尾、卸砖、回车)跑通。
  • 报警分类齐全(说明书 13.4 全部 10 类)。
  • 监控前端 + 配置前端可用。

15. 后续可演进项(非首期)

  • 联锁 expression 类型:引入简单布尔表达式语言,替代 rule_kind 枚举。
  • 段历史持久化:将每段每次完成 / 故障写入 segment_run_history,支持时间线回放。
  • 现场调试视图:模拟点位值、单步推进、跳步授权(带操作员签名)。
  • 公共能力下沉:若后续出现第三套类似业务,再把 segment 引擎抽到 plc_platform_core::control::segment