aps-agent/docs/product/flex-simulation-guide.md

10 KiB
Raw Permalink Blame History

柔性排产 · 全流程模拟操作手册

面向:产品演示、方案讲解、验收。
场景:康尼芜湖「多品种小批量 + 设备可移动」柔性排产(高压线束 / PDU 共线)。
两种走法:A 一键脚本(最快看全貌)|B 逐接口操作(贴近真实系统)。
现场真实单:先跑 python scripts/load_kangni.py(或口令「导入完整生产路线」)替换演示 flex*,再用柔性排产;口径见 demand-data-intake.md 附「完整生产路线」。
数据口径见 demand-data-intake.md;需求背景见 demand-kangni-wuhu.md。


第一部分 · 自然语言:一次排产到底发生了什么

用大白话把整条链讲一遍。假设计划员接到一张订单「高压线束总成 100 套,7 天后交」。

1)设备不再绑死产线——「设备虚拟化」

传统做法:这条活固定走「线束产线」。但芜湖的现实是压接机今天在线束区、明天被调去 PDU 区。所以系统里每台设备是一份独立档案,记录它「能干哪几道工序、能不能移动、移动要多久、当前在哪个区、能装哪些模具」。产线不再是固定的钢筋水泥,而是用的时候临时拼出来的。

2)同类设备汇成一个「产能池」

系统不问「哪条线」,只问「哪道工序」。所有能做压接的设备(4 台可移动压接机)汇成一个压接能力池;所有能焊接的(1 台激光焊接机)汇成焊接池。排产时从池子里动态取设备,谁空闲、谁装了合适模具就用谁。

3)为这张订单临时拼一条「虚拟产线」

系统把订单按工艺路线展开成工序序列(来料检验→下线→压接→装配→测试→包装),然后逐道工序去对应能力池取一台设备,拼出一条虚拟产线 VL-FO-001:

  • 压接这道是瓶颈工序,从压接池挑一台负载最轻的压接机,并确认它装了适配模具(没装就算换型时间);
  • 如果这台压接机需要从别的区调过来,就把「移动耗时」插进时间轴(移动时不能生产);
  • 每道工序占用设备的一个时间槽,前道没干完后道不能开始。 排完这条虚拟产线就「拼完即用、用完即散」,设备回到池子等下一单。

4)产能到底有多少——「瓶颈产能法」

不再用「设备台数×理论工时×拍脑袋 70%」。系统只认最慢那道工序:

全厂日产能 = 瓶颈工序可用工时 ÷ 单件工时。

本场景里 PDU 的激光焊接只有 1 台(≈88 件/天),它就是天花板;而压接池 4 台并行看着能做 1920 件/天,那是虚高,没意义。哪道最慢,产能就由它说了算。

5)销售问「这批什么时候能交」——「交期承诺模拟」

系统不回答「按产能算 X 天」,而是把这张询单试着插进当前排程,给三个数:

  • 乐观(独占资源):最早能哪天完成;
  • 预计(和在制订单抢资源):大概率哪天完成;
  • 资源缺口:要更早,得加哪台设备 / 外包哪道工序。

6)计划总在变——「动态重排」

  • 紧急插单:来一张 VIP 急单,冻结当前窗口重排,急单优先占瓶颈资源,其余顺延;
  • 设备故障:某台设备停机,系统实时把它从能力池剔除,用剩下的重排。这里有个关键区别:可移动压接机坏一台,池子还有 3 台冗余,交期几乎不受影响;但激光焊接机就 1 台,一坏 PDU 直接停摆,系统立刻报「无可用设备」,提示上备机 / 外包 / 重新议交期。

一句话总结:任何时刻,系统都能回答计划员那三个问题——现在能做什么、做多少、什么时候做完。


第二部分 · 走法 A:一键脚本模拟(最快)

不用起服务、不用点页面,一条命令把上面 6 步全跑出来,全中文可读输出。

前置

# 仓库根目录,已建好 .venv 并 pip install -r requirements.txt
cd <aps-agent-repo>

运行

.venv\Scripts\python.exe scripts\flex_simulation.py

输出会分 7 段(对应上面的业务流程)

阶段 你会看到 怎么读
阶段 0 主数据/产能池 区域、每个能力池的设备清单(★=瓶颈)、模具、订单 确认「压接池 4 台可移动 / 焊接池 1 台」这类池结构
阶段 1 初始排产 5 条虚拟产线,每条逐工序打印:设备·模具·换型/移动/加工耗时·时间段 看「★瓶颈」那行是不是占了压接/焊接设备并挂了模具
阶段 2 瓶颈产能法 各池日产能表 + 限制性瓶颈 看「限制性瓶颈=激光焊接 88 件/天」,对照台账法虚高 1920
阶段 3 三模式对比 正排/倒排/瓶颈锚的延迟、准时单、最晚完工 压力下倒排明显更差(295h/0 准时),说明模式选择有意义
阶段 4 交期承诺 PDU 500 套的乐观/预计完工 + 缺口提示 看两个日期差多少,缺口指向焊接工序
阶段 5 紧急插单 插单前后虚拟产线数、最晚完工、急单排入时段 看急单是否优先占了瓶颈
阶段 6 设备故障 案例①压接机故障(有冗余)|案例②焊接机故障(停摆报错) 对比「池化韧性」与「单点瓶颈」两种结局

脚本是内存态确定性运行(种子固定),任何机器任何时间跑结果一致,适合反复演示。改数据后重跑即可。


第三部分 · 走法 B:逐接口操作(贴近真实系统)

先起后端,再按「看主数据 → 排产 → 看产能 → 问交期」的顺序调接口;或直接打开前端右侧「柔性工作台」点选同一条链路。

0)起服务

.venv\Scripts\python.exe -m uvicorn server.main:app --reload --port 8000

以下命令用 PowerShell 的 Invoke-RestMethod(另起一个终端)。

1)看柔性主数据与产能池(P0 只读)

Invoke-RestMethod http://localhost:8000/api/flex/world | ConvertTo-Json -Depth 6

返回:zones 区域、pools 能力池(含是否瓶颈/设备清单)、equipment 设备、molds 模具、orders 订单、以及最近一次排产的 virtualLines / workOrders / conflicts。

2)执行一次柔性排产(P1 直通,写草稿)

$body = @{ sortMode = "BOTTLENECK" } | ConvertTo-Json
Invoke-RestMethod -Method Post -ContentType "application/json" `
  -Uri http://localhost:8000/api/flex/schedule -Body $body
  • sortMode 可选 ASC(正排) / DESC(倒排) / BOTTLENECK(瓶颈锚),不传取默认瓶颈锚;
  • 可加 orderIds=@(1,2) 只排指定订单;
  • 返回摘要:vlCount 虚拟产线数、woCount 工单数、makespan 最晚完工、onTimeCount 准时单、conflictCount 冲突、bottleneck 瓶颈工序。

排完再调一次 GET /api/flex/world 看 virtualLines(每条虚拟产线的工序-设备-模具-时间)。

3)瓶颈产能法分析(P0 只读)

Invoke-RestMethod http://localhost:8000/api/flex/capacity | ConvertTo-Json -Depth 5

返回各池 dailyCapacity 日产能、workDays 本版本工作量折合天数、bottleneckPool 限制性瓶颈池。

4)交期承诺模拟(P0 只读沙盒,不改主干)

$body = @{ productCode = "PDU-UNIT"; quantity = 500 } | ConvertTo-Json
Invoke-RestMethod -Method Post -ContentType "application/json" `
  -Uri http://localhost:8000/api/flex/simulate-due -Body $body

返回 optimisticFinish 乐观完工、expectedFinish 预计完工、bottleneck 瓶颈提示。

接口速查

步骤 方法 端点 权级
看主数据/产能池/最新排产 GET /api/flex/world P0
执行柔性排产 POST /api/flex/schedule P1
瓶颈产能分析 GET /api/flex/capacity P0
交期承诺模拟 POST /api/flex/simulate-due P0(沙盒)

第四部分 · 走法 C:换成你的真实数据

模拟数据都在种子的 flex* 键里(server/state/seed.py 的 _seed_flex)。换真实数据不用改引擎,只需:

  1. 按 demand-data-intake.md 的 11 张表准备数据(P0 五张必填:区域 / 设备 / 工序 / 模具 / 工艺路线);
  2. 逐表替换 _seed_flex 里对应的 flexZones / flexEquipment / flexOperations / flexMolds / flexRoutings / flexBom / flexMaterials / flexTeams / flexCalendar / flexOrders / flexParams;
  3. 删除 server/data/world.json(若存在)让种子重播,或重启后端;
  4. 重跑走法 A 或 B 即可。

字段口径一致即可,编码自定;不要把工厂名/产品名写进引擎或意图,保持行业无关。


第五部分 · 验收清单(照着勾)

  • 阶段 0 能看到「压接池 4 台可移动 / 焊接池 1 台」的池结构与★瓶颈标记
  • 阶段 1 每条虚拟产线工序顺序正确、压接工序挂了适配模具、可移动设备有移动耗时痕迹
  • 阶段 2 限制性瓶颈=激光焊接(约 88 件/天),且明显低于压接池
  • 阶段 3 倒排在压力场景下延迟明显高于正排/瓶颈锚(模式选择有意义)
  • 阶段 4 交期给出乐观/预计两个日期 + 缺口指向焊接
  • 阶段 5 急单优先占瓶颈、其余顺延
  • 阶段 6 压接机故障影响小(池化韧性)、焊接机故障 PDU 停摆并报 NO_CAPABILITY
  • pytest tests/golden -q 全绿(当前 48 passed)

常见问题

  • 必须起后端吗? 走法 A 不用,纯内存跑;走法 B/前端需要 uvicorn。
  • 为什么三模式有时结果一样? 交期宽松、产能有余时三模式趋同;只有产能吃紧才分化(脚本阶段 3 / 工作台「三模式对比」会压缩交期制造压力)。
  • 重排是局部还是全量? 故障与急单当前为全量重排(L4);缩池体现 L1;窗内 L2/L3 为后续切片。
  • 前端在哪看? 右侧「柔性工作台」+ 视口柔性甘特/产能池;也可继续用脚本/接口。

变更登记见 ../CHANGELOG.md。